test_s3d_sample_sphere.c (4413B)
1 /* Copyright (C) 2015-2023 |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 "s3d.h" 17 #include "test_s3d_utils.h" 18 19 #include <rsys/float2.h> 20 #include <rsys/float3.h> 21 22 int 23 main(int argc, char** argv) 24 { 25 struct mem_allocator allocator; 26 struct s3d_attrib attr0; 27 struct s3d_attrib attr1; 28 struct s3d_primitive prim0; 29 struct s3d_primitive prim1; 30 struct s3d_device* dev; 31 struct s3d_shape* sphere0; 32 struct s3d_shape* sphere1; 33 struct s3d_scene* scn; 34 struct s3d_scene_view* view; 35 unsigned sphere0_id; 36 unsigned sphere1_id; 37 float center[3]; 38 float st0[2]; 39 float st1[2]; 40 int N = 10000; 41 int i; 42 float sum; 43 float E, V, SE; 44 (void)argc, (void)argv; 45 46 CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); 47 CHK(s3d_device_create(NULL, &allocator, 0, &dev) == RES_OK); 48 CHK(s3d_scene_create(dev, &scn) == RES_OK); 49 50 CHK(s3d_shape_create_sphere(dev, &sphere0) == RES_OK); 51 CHK(s3d_shape_create_sphere(dev, &sphere1) == RES_OK); 52 CHK(s3d_shape_get_id(sphere0, &sphere0_id) == RES_OK); 53 CHK(s3d_shape_get_id(sphere1, &sphere1_id) == RES_OK); 54 55 CHK(s3d_sphere_setup(sphere0, f3(center,-1.5, 0, 0), 2) == RES_OK); 56 CHK(s3d_sphere_setup(sphere1, f3(center, 1.5, 0, 0), 2) == RES_OK); 57 CHK(s3d_scene_attach_shape(scn, sphere0) == RES_OK); 58 CHK(s3d_scene_attach_shape(scn, sphere1) == RES_OK); 59 60 CHK(s3d_scene_view_create(scn, S3D_SAMPLE, &view) == RES_OK); 61 CHK(s3d_scene_view_sample(view, 0, 0, 0, &prim0, st0) == RES_OK); 62 CHK(prim0.prim_id == 0); 63 CHK(prim0.geom_id == sphere0_id || prim0.geom_id == sphere1_id); 64 CHK(prim0.inst_id == S3D_INVALID_ID); 65 66 CHK(s3d_scene_view_sample(view, 0, 0, 0, &prim1, st1) == RES_OK); 67 CHK(S3D_PRIMITIVE_EQ(&prim0, &prim1)); 68 CHK(f2_eq(st0, st1)); 69 70 CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_0, st0, &attr0) == RES_BAD_ARG); 71 CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_1, st0, &attr0) == RES_BAD_ARG); 72 CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_2, st0, &attr0) == RES_BAD_ARG); 73 CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_3, st0, &attr0) == RES_BAD_ARG); 74 CHK(s3d_primitive_get_attrib(&prim0, S3D_POSITION, st0, &attr0) == RES_OK); 75 CHK(s3d_primitive_get_attrib 76 (&prim0, S3D_GEOMETRY_NORMAL, st0, &attr1) == RES_OK); 77 78 if(prim0.geom_id == sphere0_id) { 79 f3_sub(attr0.value, attr0.value, f3(center,-1.5, 0, 0)); 80 } else { 81 f3_sub(attr0.value, attr0.value, f3(center, 1.5, 0, 0)); 82 } 83 f3_mulf(attr1.value, attr1.value, 2.f); 84 CHK(f3_eq_eps(attr0.value, attr1.value, 1.e-3f)); 85 86 /* Check that 50 percents of samples lie onto "sphere0" */ 87 sum = 0; 88 FOR_EACH(i, 0, N) { 89 const float u = rand_canonic(); 90 const float v = rand_canonic(); 91 const float w = rand_canonic(); 92 93 CHK(s3d_scene_view_sample(view, u, v, w, &prim0, st0) == RES_OK); 94 if(prim0.geom_id == sphere0_id) { 95 sum += 1; 96 } 97 98 CHK(s3d_primitive_get_attrib(&prim0, S3D_POSITION, st0, &attr0) == RES_OK); 99 CHK(s3d_primitive_get_attrib 100 (&prim0, S3D_GEOMETRY_NORMAL, st0, &attr1) == RES_OK); 101 102 if(prim0.geom_id == sphere0_id) { 103 f3_sub(attr0.value, attr0.value, f3(center,-1.5, 0, 0)); 104 } else { 105 f3_sub(attr0.value, attr0.value, f3(center, 1.5, 0, 0)); 106 } 107 f3_mulf(attr1.value, attr1.value, 2.f); 108 CHK(f3_eq_eps(attr0.value, attr1.value, 1.e-3f)); 109 } 110 E = sum / (float)N; 111 V = sum / (float)N - E*E; 112 SE = (float)sqrt(V/(float)N); 113 CHK(eq_epsf(E, 0.5, 2*SE)); 114 115 CHK(s3d_device_ref_put(dev) == RES_OK); 116 CHK(s3d_scene_ref_put(scn) == RES_OK); 117 CHK(s3d_shape_ref_put(sphere0) == RES_OK); 118 CHK(s3d_shape_ref_put(sphere1) == RES_OK); 119 CHK(s3d_scene_view_ref_put(view) == RES_OK); 120 121 check_memory_allocator(&allocator); 122 mem_shutdown_proxy_allocator(&allocator); 123 CHK(mem_allocated_size() == 0); 124 return 0; 125 } 126