test_s3d_sample_sphere.c (4440B)
1 /* Copyright (C) 2015-2023, 2026 |Méso|Star> (contact@meso-star.com) 2 * 3 * This file is part of Star-3D. 4 * 5 * Star-3D is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * Star-3D is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with Star-3D. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #include "s3d.h" 19 #include "test_s3d_utils.h" 20 21 #include <rsys/float2.h> 22 #include <rsys/float3.h> 23 24 int 25 main(int argc, char** argv) 26 { 27 struct mem_allocator allocator; 28 struct s3d_attrib attr0; 29 struct s3d_attrib attr1; 30 struct s3d_primitive prim0; 31 struct s3d_primitive prim1; 32 struct s3d_device* dev; 33 struct s3d_shape* sphere0; 34 struct s3d_shape* sphere1; 35 struct s3d_scene* scn; 36 struct s3d_scene_view* view; 37 unsigned sphere0_id; 38 unsigned sphere1_id; 39 float center[3]; 40 float st0[2]; 41 float st1[2]; 42 int N = 10000; 43 int i; 44 float sum; 45 float E, V, SE; 46 (void)argc, (void)argv; 47 48 CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); 49 CHK(s3d_device_create(NULL, &allocator, 0, &dev) == RES_OK); 50 CHK(s3d_scene_create(dev, &scn) == RES_OK); 51 52 CHK(s3d_shape_create_sphere(dev, &sphere0) == RES_OK); 53 CHK(s3d_shape_create_sphere(dev, &sphere1) == RES_OK); 54 CHK(s3d_shape_get_id(sphere0, &sphere0_id) == RES_OK); 55 CHK(s3d_shape_get_id(sphere1, &sphere1_id) == RES_OK); 56 57 CHK(s3d_sphere_setup(sphere0, f3(center,-1.5, 0, 0), 2) == RES_OK); 58 CHK(s3d_sphere_setup(sphere1, f3(center, 1.5, 0, 0), 2) == RES_OK); 59 CHK(s3d_scene_attach_shape(scn, sphere0) == RES_OK); 60 CHK(s3d_scene_attach_shape(scn, sphere1) == RES_OK); 61 62 CHK(s3d_scene_view_create(scn, S3D_SAMPLE, &view) == RES_OK); 63 CHK(s3d_scene_view_sample(view, 0, 0, 0, &prim0, st0) == RES_OK); 64 CHK(prim0.prim_id == 0); 65 CHK(prim0.geom_id == sphere0_id || prim0.geom_id == sphere1_id); 66 CHK(prim0.inst_id == S3D_INVALID_ID); 67 68 CHK(s3d_scene_view_sample(view, 0, 0, 0, &prim1, st1) == RES_OK); 69 CHK(S3D_PRIMITIVE_EQ(&prim0, &prim1)); 70 CHK(f2_eq(st0, st1)); 71 72 CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_0, st0, &attr0) == RES_BAD_ARG); 73 CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_1, st0, &attr0) == RES_BAD_ARG); 74 CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_2, st0, &attr0) == RES_BAD_ARG); 75 CHK(s3d_primitive_get_attrib(&prim0, S3D_ATTRIB_3, st0, &attr0) == RES_BAD_ARG); 76 CHK(s3d_primitive_get_attrib(&prim0, S3D_POSITION, st0, &attr0) == RES_OK); 77 CHK(s3d_primitive_get_attrib 78 (&prim0, S3D_GEOMETRY_NORMAL, st0, &attr1) == RES_OK); 79 80 if(prim0.geom_id == sphere0_id) { 81 f3_sub(attr0.value, attr0.value, f3(center,-1.5, 0, 0)); 82 } else { 83 f3_sub(attr0.value, attr0.value, f3(center, 1.5, 0, 0)); 84 } 85 f3_mulf(attr1.value, attr1.value, 2.f); 86 CHK(f3_eq_eps(attr0.value, attr1.value, 1.e-3f)); 87 88 /* Check that 50 percents of samples lie onto "sphere0" */ 89 sum = 0; 90 FOR_EACH(i, 0, N) { 91 const float u = rand_canonic(); 92 const float v = rand_canonic(); 93 const float w = rand_canonic(); 94 95 CHK(s3d_scene_view_sample(view, u, v, w, &prim0, st0) == RES_OK); 96 if(prim0.geom_id == sphere0_id) { 97 sum += 1; 98 } 99 100 CHK(s3d_primitive_get_attrib(&prim0, S3D_POSITION, st0, &attr0) == RES_OK); 101 CHK(s3d_primitive_get_attrib 102 (&prim0, S3D_GEOMETRY_NORMAL, st0, &attr1) == RES_OK); 103 104 if(prim0.geom_id == sphere0_id) { 105 f3_sub(attr0.value, attr0.value, f3(center,-1.5, 0, 0)); 106 } else { 107 f3_sub(attr0.value, attr0.value, f3(center, 1.5, 0, 0)); 108 } 109 f3_mulf(attr1.value, attr1.value, 2.f); 110 CHK(f3_eq_eps(attr0.value, attr1.value, 1.e-3f)); 111 } 112 E = sum / (float)N; 113 V = sum / (float)N - E*E; 114 SE = (float)sqrt(V/(float)N); 115 CHK(eq_epsf(E, 0.5, 2*SE)); 116 117 CHK(s3d_device_ref_put(dev) == RES_OK); 118 CHK(s3d_scene_ref_put(scn) == RES_OK); 119 CHK(s3d_shape_ref_put(sphere0) == RES_OK); 120 CHK(s3d_shape_ref_put(sphere1) == RES_OK); 121 CHK(s3d_scene_view_ref_put(view) == RES_OK); 122 123 check_memory_allocator(&allocator); 124 mem_shutdown_proxy_allocator(&allocator); 125 CHK(mem_allocated_size() == 0); 126 return 0; 127 } 128