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