s3d_sphere.h (2562B)
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 #ifndef S3D_SPHERE_H 19 #define S3D_SPHERE_H 20 21 #include "s3d_c.h" 22 23 #include <rsys/ref_count.h> 24 #include <rsys/float3.h> 25 26 struct sphere { 27 float pos[3]; 28 float radius; 29 struct s3d_device* dev; 30 struct hit_filter filter; 31 ref_T ref; 32 }; 33 34 extern LOCAL_SYM res_T 35 sphere_create 36 (struct s3d_device* dev, 37 struct sphere** sphere); 38 39 extern LOCAL_SYM void 40 sphere_ref_get 41 (struct sphere* sphere); 42 43 extern LOCAL_SYM void 44 sphere_ref_put 45 (struct sphere* sphere); 46 47 static INLINE int 48 sphere_is_degenerated(const struct sphere* sphere) 49 { 50 ASSERT(sphere); 51 return sphere->radius < 0; 52 } 53 54 static INLINE void 55 sphere_compute_aabb 56 (const struct sphere* sphere, 57 float lower[3], 58 float upper[3]) 59 { 60 ASSERT(sphere && lower && upper); 61 if(sphere_is_degenerated(sphere)) { 62 f3_splat(lower, FLT_MAX); 63 f3_splat(upper,-FLT_MAX); 64 } else { 65 f3_subf(lower, sphere->pos, sphere->radius); 66 f3_addf(upper, sphere->pos, sphere->radius); 67 } 68 } 69 70 static INLINE float 71 sphere_compute_area(const struct sphere* sphere) 72 { 73 float r; 74 ASSERT(sphere); 75 r = sphere->radius; 76 return (float)(4*PI*r*r); 77 } 78 79 static INLINE float 80 sphere_compute_volume(const struct sphere* sphere) 81 { 82 float r; 83 ASSERT(sphere); 84 r = sphere->radius; 85 return (float)(4*PI*r*r*r/3); 86 } 87 88 static FINLINE void 89 sphere_normal_to_uv(const float normal[3], float uv[2]) 90 { 91 float u, v, cos_theta; 92 ASSERT(normal && uv && f3_is_normalized(normal)); 93 94 cos_theta = normal[2]; 95 96 v = (1.f - cos_theta) * 0.5f; 97 if(absf(cos_theta) == 1) { 98 u = 0; 99 } else if(eq_epsf(normal[0], 0.f, 1.e-6f)) { 100 u = normal[1] > 0 ? 0.25f : 0.75f; 101 } else { 102 double phi = atan2f(normal[1], normal[0]); /* phi in [-PI, PI] */ 103 if(phi < 0) phi = 2*PI + phi; /* phi in [0, 2PI] */ 104 u = (float)(phi / (2*PI)); 105 } 106 uv[0] = u; 107 uv[1] = v; 108 } 109 110 #endif /* S3D_SPHERE_H */