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