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_bsdf.c (5881B)


      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 #include <rsys/double3.h>
     20 
     21 static int bsdf_is_init = 0;
     22 
     23 struct ALIGN(64) bsdf {
     24   uint32_t id;
     25   struct ssp_rng* rng;
     26   double wi[3];
     27   double wo[3];
     28   double N[3];
     29   double reflectivity;
     30   double value;
     31   double pdf;
     32   double rho;
     33 };
     34 
     35 static res_T
     36 bsdf_init(struct mem_allocator* allocator, void* bsdf)
     37 {
     38   CHK(allocator != NULL);
     39   CHK(bsdf != NULL);
     40   CHK(IS_ALIGNED(bsdf, 64) == 1);
     41   ((struct bsdf*)bsdf)->id = 0xDECAFBAD;
     42   bsdf_is_init = 1;
     43   return RES_OK;
     44 }
     45 
     46 static void
     47 bsdf_release(void* bsdf)
     48 {
     49   CHK(bsdf != NULL);
     50   CHK(((struct bsdf*)bsdf)->id == 0xDECAFBAD);
     51   bsdf_is_init = 0;
     52 }
     53 
     54 static double
     55 bsdf_sample
     56   (void* bsdf,
     57    struct ssp_rng* rng,
     58    const double wo[3],
     59    const double N[3],
     60    double wi[3],
     61    int* type,
     62    double* pdf)
     63 {
     64   struct bsdf* BxDF = bsdf;
     65   CHK(BxDF != NULL);
     66   CHK(BxDF->rng == rng);
     67   CHK(d3_eq(BxDF->wo, wo) == 1);
     68   CHK(d3_eq(BxDF->N, N) == 1);
     69   d3(wi, 1.0, 2.0, 3.0);
     70   if(type) *type = 314;
     71   if(pdf) *pdf = 4;
     72   return BxDF->reflectivity;
     73 }
     74 
     75 static double
     76 bsdf_eval
     77   (void* bsdf,
     78    const double wo[3],
     79    const double N[3],
     80    const double wi[3])
     81 {
     82   struct bsdf* BxDF = bsdf;
     83   CHK(BxDF != NULL);
     84   CHK(wi != NULL);
     85   CHK(wo != NULL);
     86   CHK(d3_eq(BxDF->wo, wo) == 1);
     87   CHK(d3_eq(BxDF->N, N) == 1);
     88   CHK(d3_eq(BxDF->wi, wi) == 1);
     89   return BxDF->value;
     90 }
     91 
     92 static double
     93 bsdf_pdf
     94   (void* bsdf,
     95    const double wo[3],
     96    const double N[3],
     97    const double wi[3])
     98 {
     99   struct bsdf* BxDF = bsdf;
    100   CHK(BxDF != NULL);
    101   CHK(wi != NULL);
    102   CHK(wo != NULL);
    103   CHK(d3_eq(BxDF->wo, wo) == 1);
    104   CHK(d3_eq(BxDF->N, N) == 1);
    105   CHK(d3_eq(BxDF->wi, wi) == 1);
    106   return BxDF->pdf;
    107 }
    108 
    109 int
    110 main(int argc, char** argv)
    111 {
    112   struct mem_allocator allocator;
    113   struct ssp_rng* rng;
    114   struct bsdf* data;
    115   struct ssf_bsdf* bsdf;
    116   struct ssf_bsdf_type type = SSF_BXDF_TYPE_NULL;
    117   struct ssf_bsdf_type type2 = bsdf_dummy;
    118   double wo[3];
    119   double N[3];
    120   double wi[4];
    121   double pdf;
    122   int i;
    123   (void)argc, (void)argv;
    124 
    125   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
    126   CHK(ssp_rng_create(&allocator, SSP_RNG_THREEFRY, &rng) == RES_OK);
    127 
    128   type.init = bsdf_init;
    129   type.release = bsdf_release;
    130   type.sample = bsdf_sample;
    131   type.eval = bsdf_eval;
    132   type.pdf = bsdf_pdf;
    133   type.sizeof_bsdf = sizeof(struct bsdf);
    134   type.alignof_bsdf = ALIGNOF(struct bsdf);
    135 
    136   CHK(ssf_bsdf_create(NULL, NULL, NULL) == RES_BAD_ARG);
    137   CHK(ssf_bsdf_create(&allocator, NULL, NULL) == RES_BAD_ARG);
    138   CHK(ssf_bsdf_create(NULL, &type, NULL) == RES_BAD_ARG);
    139   CHK(ssf_bsdf_create(&allocator, &type, NULL) == RES_BAD_ARG);
    140   CHK(ssf_bsdf_create(NULL, NULL, &bsdf) == RES_BAD_ARG);
    141   CHK(ssf_bsdf_create(&allocator, NULL, &bsdf) == RES_BAD_ARG);
    142 
    143   CHK(bsdf_is_init == 0);
    144   CHK(ssf_bsdf_create(NULL, &type, &bsdf) == RES_OK);
    145   CHK(bsdf_is_init == 1);
    146 
    147   CHK(ssf_bsdf_ref_get(NULL) == RES_BAD_ARG);
    148   CHK(ssf_bsdf_ref_get(bsdf) == RES_OK);
    149   CHK(ssf_bsdf_ref_put(NULL) == RES_BAD_ARG);
    150   CHK(ssf_bsdf_ref_put(bsdf) == RES_OK);
    151   CHK(bsdf_is_init == 1);
    152   CHK(ssf_bsdf_ref_put(bsdf) == RES_OK);
    153   CHK(bsdf_is_init == 0);
    154 
    155   CHK(ssf_bsdf_create(&allocator, &type, &bsdf) == RES_OK);
    156   CHK(bsdf_is_init == 1);
    157   CHK(ssf_bsdf_ref_put(bsdf) == RES_OK);
    158   CHK(bsdf_is_init == 0);
    159 
    160   type2.init = NULL;
    161   CHK(ssf_bsdf_create(&allocator, &type2, &bsdf) == RES_OK);
    162   CHK(ssf_bsdf_ref_put(bsdf) == RES_OK);
    163   type2.init = bsdf_dummy.init;
    164   type2.release = NULL;
    165   CHK(ssf_bsdf_create(&allocator, &type2, &bsdf) == RES_OK);
    166   CHK(ssf_bsdf_ref_put(bsdf) == RES_OK);
    167 
    168   type.sample = NULL;
    169   CHK(ssf_bsdf_create(&allocator, &type, &bsdf) == RES_BAD_ARG);
    170   CHK(bsdf_is_init == 0);
    171   type.sample = bsdf_sample;
    172   type.alignof_bsdf = 3;
    173   CHK(ssf_bsdf_create(&allocator, &type, &bsdf) == RES_BAD_ARG);
    174   CHK(bsdf_is_init == 0);
    175   type.alignof_bsdf = ALIGNOF(struct bsdf);
    176   CHK(ssf_bsdf_create(&allocator, &type, &bsdf) == RES_OK);
    177   CHK(bsdf_is_init == 1);
    178 
    179   CHK(ssf_bsdf_get_data(NULL, NULL) == RES_BAD_ARG);
    180   CHK(ssf_bsdf_get_data(bsdf, NULL) == RES_BAD_ARG);
    181   CHK(ssf_bsdf_get_data(NULL, (void**)&data) == RES_BAD_ARG);
    182   CHK(ssf_bsdf_get_data(bsdf, (void**)&data) == RES_OK);
    183 
    184   CHK(data->id == 0xDECAFBAD);
    185 
    186   d3_normalize(wo, d3(wo, -1, -1, 0));
    187   d3(N, 0.0, 1.0, 0.0);
    188   d3_set(data->wo, wo);
    189   d3_set(data->N, N);
    190   data->rng = rng;
    191   data->reflectivity = 0.1234;
    192 
    193   i = 0, pdf = 0;
    194   CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, &i, NULL) == 0.1234);
    195   CHK(i == 314);
    196   CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, NULL, &pdf) == 0.1234);
    197   CHK(pdf == 4);
    198   CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, NULL, NULL) == 0.1234);
    199 
    200   data->reflectivity = 0.314;
    201   CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, &i, &pdf) == 0.314);
    202 
    203   d3_normalize(wi, wi);
    204   d3_set(data->wi, wi);
    205   data->value = 0.4567;
    206   CHK(ssf_bsdf_eval(bsdf, wo, N, wi) == data->value);
    207   data->pdf = 0.890;
    208   CHK(ssf_bsdf_pdf(bsdf, wo, N, wi) == data->pdf);
    209 
    210   CHK(bsdf_is_init == 1);
    211   CHK(ssf_bsdf_ref_put(bsdf) == RES_OK);
    212   CHK(bsdf_is_init == 0);
    213 
    214   CHK(ssp_rng_ref_put(rng) == RES_OK);
    215 
    216   check_memory_allocator(&allocator);
    217   mem_shutdown_proxy_allocator(&allocator);
    218   CHK(mem_allocated_size() == 0);
    219   return 0;
    220 }
    221