star-sf

Set of surface and volume scattering functions
git clone git://git.meso-star.fr/star-sf.git
Log | Files | Refs | README | LICENSE

test_ssf_phase.c (5192B)


      1 /* Copyright (C) 2016-2018, 2021-2025 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #include "ssf.h"
     17 #include "test_ssf_utils.h"
     18 
     19 static int phase_is_init = 0;
     20 
     21 struct ALIGN(64) phase {
     22   uint32_t id;
     23   struct ssp_rng* rng;
     24   double wi[3];
     25   double wo[3];
     26   double pdf;
     27   double value;
     28 };
     29 
     30 static res_T
     31 phase_init(struct mem_allocator* allocator, void* phase)
     32 {
     33   CHK(allocator != NULL);
     34   CHK(phase != NULL);
     35   CHK(IS_ALIGNED(phase, 64) == 1);
     36   ((struct phase*)phase)->id = 0xDECAFBAD;
     37   phase_is_init = 1;
     38   return RES_OK;
     39 }
     40 
     41 static void
     42 phase_release(void* phase)
     43 {
     44   CHK(phase != NULL);
     45   CHK(((struct phase*)phase)->id == 0xDECAFBAD);
     46   phase_is_init = 0;
     47 }
     48 
     49 static void
     50 phase_sample
     51   (void* data,
     52    struct ssp_rng* rng,
     53    const double wo[3],
     54    double wi[3],
     55    double* pdf)
     56 {
     57   struct phase* phase = data;
     58   CHK(phase != NULL);
     59   CHK(phase->rng == rng);
     60   CHK(d3_eq(phase->wo, wo) == 1);
     61   d3(wi, 1.0, 2.0, 3.0);
     62   if(pdf) *pdf = phase->pdf;
     63 }
     64 
     65 static double
     66 phase_eval
     67   (void* data,
     68    const double wo[3],
     69    const double wi[3])
     70 {
     71   struct phase* phase = data;
     72   CHK(phase != NULL);
     73   CHK(wi != NULL);
     74   CHK(wo != NULL);
     75   CHK(d3_eq(phase->wo, wo) == 1);
     76   CHK(d3_eq(phase->wi, wi) == 1);
     77   return phase->value;
     78 }
     79 
     80 static double
     81 phase_pdf
     82   (void* data,
     83    const double wo[3],
     84    const double wi[3])
     85 {
     86   struct phase* phase = data;
     87   CHK(phase != NULL);
     88   CHK(wi != NULL);
     89   CHK(wo != NULL);
     90   CHK(d3_eq(phase->wo, wo) == 1);
     91   CHK(d3_eq(phase->wi, wi) == 1);
     92   return phase->pdf;
     93 }
     94 
     95 int
     96 main(int argc, char** argv)
     97 {
     98   struct mem_allocator allocator;
     99   struct ssp_rng* rng;
    100   struct ssf_phase* phase = NULL;
    101   struct ssf_phase_type type = SSF_PHASE_TYPE_NULL;
    102   struct ssf_phase_type type2 = phase_dummy;
    103   struct phase* data = NULL;
    104   double wi[3];
    105   double pdf;
    106   (void)argc, (void)argv;
    107 
    108   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
    109   CHK(ssp_rng_create(&allocator, SSP_RNG_THREEFRY, &rng) == RES_OK);
    110 
    111   type.init = phase_init;
    112   type.release = phase_release;
    113   type.sample = phase_sample;
    114   type.eval = phase_eval;
    115   type.pdf = phase_pdf;
    116   type.sizeof_phase = sizeof(struct phase);
    117   type.alignof_phase = ALIGNOF(struct phase);
    118 
    119   CHK(ssf_phase_create(NULL, NULL, NULL) == RES_BAD_ARG);
    120   CHK(ssf_phase_create(&allocator, NULL, NULL) == RES_BAD_ARG);
    121   CHK(ssf_phase_create(NULL, &type, NULL) == RES_BAD_ARG);
    122   CHK(ssf_phase_create(&allocator, &type, NULL) == RES_BAD_ARG);
    123   CHK(ssf_phase_create(NULL, NULL, &phase) == RES_BAD_ARG);
    124   CHK(ssf_phase_create(&allocator, NULL, &phase) == RES_BAD_ARG);
    125 
    126   CHK(phase_is_init == 0);
    127   CHK(ssf_phase_create(NULL, &type, &phase) == RES_OK);
    128   CHK(phase_is_init == 1);
    129 
    130   CHK(ssf_phase_ref_get(NULL) == RES_BAD_ARG);
    131   CHK(ssf_phase_ref_get(phase) == RES_OK);
    132   CHK(ssf_phase_ref_put(NULL) == RES_BAD_ARG);
    133   CHK(ssf_phase_ref_put(phase) == RES_OK);
    134   CHK(phase_is_init == 1);
    135   CHK(ssf_phase_ref_put(phase) == RES_OK);
    136   CHK(phase_is_init == 0);
    137 
    138   type2.init = NULL;
    139   CHK(ssf_phase_create(&allocator, &type2, &phase) == RES_OK);
    140   CHK(ssf_phase_ref_put(phase) == RES_OK);
    141   type2.init = phase_dummy.init;
    142   type2.release = NULL;
    143   CHK(ssf_phase_create(&allocator, &type2, &phase) == RES_OK);
    144   CHK(ssf_phase_ref_put(phase) == RES_OK);
    145 
    146   type.sample = NULL;
    147   CHK(ssf_phase_create(&allocator, &type, &phase) == RES_BAD_ARG);
    148   CHK(phase_is_init == 0);
    149   type.sample = phase_sample;
    150   type.alignof_phase = 3;
    151   CHK(ssf_phase_create(&allocator, &type, &phase) == RES_BAD_ARG);
    152   CHK(phase_is_init == 0);
    153   type.alignof_phase = ALIGNOF(struct phase);
    154   CHK(ssf_phase_create(&allocator, &type, &phase) == RES_OK);
    155   CHK(phase_is_init == 1);
    156 
    157   CHK(ssf_phase_get_data(NULL, NULL) == RES_BAD_ARG);
    158   CHK(ssf_phase_get_data(phase, NULL) == RES_BAD_ARG);
    159   CHK(ssf_phase_get_data(NULL, (void**)&data) == RES_BAD_ARG);
    160   CHK(ssf_phase_get_data(phase, (void**)&data) == RES_OK);
    161 
    162   CHK(data->id == 0xDECAFBAD);
    163 
    164   d3_normalize(data->wo, d3(data->wo, -1, -1, 0));
    165   data->rng = rng;
    166   data->value = 0.1234;
    167   data->pdf = 4;
    168 
    169   pdf = 0;
    170   ssf_phase_sample(phase, rng, data->wo, wi, NULL);
    171   ssf_phase_sample(phase, rng, data->wo, wi, &pdf);
    172   CHK(pdf == 4);
    173 
    174   d3_normalize(data->wi, wi);
    175   data->value = 0.4567;
    176   CHK(ssf_phase_eval(phase, data->wo, data->wi) == data->value);
    177   data->pdf = 0.890;
    178   CHK(ssf_phase_pdf(phase, data->wo, data->wi) == data->pdf);
    179 
    180   CHK(ssf_phase_ref_put(phase) == RES_OK);
    181 
    182   CHK(ssp_rng_ref_put(rng) == RES_OK);
    183 
    184   check_memory_allocator(&allocator);
    185   mem_shutdown_proxy_allocator(&allocator);
    186   CHK(mem_allocated_size() == 0);
    187   return 0;
    188 }
    189