star-sf

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

commit 4fe8e6e919eafceb6473491e755e67e3d3c30975
parent a80a7778c48e5f4585271766956e7d7fe9f39296
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 18 Jul 2018 16:24:45 +0200

Test the phase function API

Diffstat:
Mcmake/CMakeLists.txt | 1+
Asrc/test_ssf_phase.c | 189+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 190 insertions(+), 0 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -115,6 +115,7 @@ if(NOT NO_TEST) new_test(test_ssf_lambertian_reflection) new_test(test_ssf_microfacet_distribution) new_test(test_ssf_microfacet_reflection) + new_test(test_ssf_phase) new_test(test_ssf_specular_reflection) new_test(test_ssf_thin_specular_dielectric) diff --git a/src/test_ssf_phase.c b/src/test_ssf_phase.c @@ -0,0 +1,189 @@ +/* Copyright (C) |Meso|Star> 2016-2018 (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "ssf.h" +#include "test_ssf_utils.h" + +static int phase_is_init = 0; + +struct ALIGN(64) phase { + uint32_t id; + struct ssp_rng* rng; + double wi[3]; + double wo[3]; + double pdf; + double value; +}; + + +static res_T +phase_init(struct mem_allocator* allocator, void* phase) +{ + CHK(allocator != NULL); + CHK(phase != NULL); + CHK(IS_ALIGNED(phase, 64) == 1); + ((struct phase*)phase)->id = 0xDECAFBAD; + phase_is_init = 1; + return RES_OK; +} + +static void +phase_release(void* phase) +{ + CHK(phase != NULL); + CHK(((struct phase*)phase)->id == 0xDECAFBAD); + phase_is_init = 0; +} + +static double +phase_sample + (void* data, + struct ssp_rng* rng, + const double wo[3], + double wi[3], + double* pdf) +{ + struct phase* phase = data; + CHK(phase != NULL); + CHK(phase->rng == rng); + CHK(d3_eq(phase->wo, wo) == 1); + d3(wi, 1.0, 2.0, 3.0); + *pdf = phase->pdf; + return phase->value; +} + +static double +phase_eval + (void* data, + const double wo[3], + const double wi[3]) +{ + struct phase* phase = data; + CHK(phase != NULL); + CHK(wi != NULL); + CHK(wo != NULL); + CHK(d3_eq(phase->wo, wo) == 1); + CHK(d3_eq(phase->wi, wi) == 1); + return phase->value; +} + +static double +phase_pdf + (void* data, + const double wo[3], + const double wi[3]) +{ + struct phase* phase = data; + CHK(phase != NULL); + CHK(wi != NULL); + CHK(wo != NULL); + CHK(d3_eq(phase->wo, wo) == 1); + CHK(d3_eq(phase->wi, wi) == 1); + return phase->pdf; +} + +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct ssp_rng* rng; + struct ssf_phase* phase = NULL; + struct ssf_phase_type type = SSF_PHASE_TYPE_NULL; + struct phase* data = NULL; + double wi[3]; + double pdf; + (void)argc, (void)argv; + + mem_init_proxy_allocator(&allocator, &mem_default_allocator); + CHK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng) == RES_OK); + + type.init = phase_init; + type.release = phase_release; + type.sample = phase_sample; + type.eval = phase_eval; + type.pdf = phase_pdf; + type.sizeof_phase = sizeof(struct phase); + type.alignof_phase = ALIGNOF(struct phase); + + CHK(ssf_phase_create(NULL, NULL, NULL) == RES_BAD_ARG); + CHK(ssf_phase_create(&allocator, NULL, NULL) == RES_BAD_ARG); + CHK(ssf_phase_create(NULL, &type, NULL) == RES_BAD_ARG); + CHK(ssf_phase_create(&allocator, &type, NULL) == RES_BAD_ARG); + CHK(ssf_phase_create(NULL, NULL, &phase) == RES_BAD_ARG); + CHK(ssf_phase_create(&allocator, NULL, &phase) == RES_BAD_ARG); + + CHK(phase_is_init == 0); + CHK(ssf_phase_create(NULL, &type, &phase) == RES_OK); + CHK(phase_is_init == 1); + + CHK(ssf_phase_ref_get(NULL) == RES_BAD_ARG); + CHK(ssf_phase_ref_get(phase) == RES_OK); + CHK(ssf_phase_ref_put(NULL) == RES_BAD_ARG); + CHK(ssf_phase_ref_put(phase) == RES_OK); + CHK(phase_is_init == 1); + CHK(ssf_phase_ref_put(phase) == RES_OK); + CHK(phase_is_init == 0); + + type.init = NULL; + CHK(ssf_phase_create(&allocator, &type, &phase) == RES_BAD_ARG); + CHK(phase_is_init == 0); + type.init = phase_init; + type.release = NULL; + CHK(ssf_phase_create(&allocator, &type, &phase) == RES_BAD_ARG); + CHK(phase_is_init == 0); + type.release = phase_release; + type.sample = NULL; + CHK(ssf_phase_create(&allocator, &type, &phase) == RES_BAD_ARG); + CHK(phase_is_init == 0); + type.sample = phase_sample; + type.alignof_phase = 3; + CHK(ssf_phase_create(&allocator, &type, &phase) == RES_BAD_ARG); + CHK(phase_is_init == 0); + type.alignof_phase = ALIGNOF(struct phase); + CHK(ssf_phase_create(&allocator, &type, &phase) == RES_OK); + CHK(phase_is_init == 1); + + CHK(ssf_phase_get_data(NULL, NULL) == RES_BAD_ARG); + CHK(ssf_phase_get_data(phase, NULL) == RES_BAD_ARG); + CHK(ssf_phase_get_data(NULL, (void**)&data) == RES_BAD_ARG); + CHK(ssf_phase_get_data(phase, (void**)&data) == RES_OK); + + CHK(data->id == 0xDECAFBAD); + + d3_normalize(data->wo, d3(data->wo, -1, -1, 0)); + data->rng = rng; + data->value = 0.1234; + data->pdf = 4; + + CHK(ssf_phase_sample(phase, rng, data->wo, wi, &pdf) == 0.1234); + CHK(ssf_phase_sample(phase, rng, data->wo, wi, &pdf) == 0.1234); + CHK(pdf == 4); + + d3_normalize(data->wi, wi); + data->value = 0.4567; + CHK(ssf_phase_eval(phase, data->wo, data->wi) == data->value); + data->pdf = 0.890; + CHK(ssf_phase_pdf(phase, data->wo, data->wi) == data->pdf); + + CHK(ssf_phase_ref_put(phase) == RES_OK); + + CHK(ssp_rng_ref_put(rng) == RES_OK); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHK(mem_allocated_size() == 0); + return 0; +} +