|
7 | 7 |
|
8 | 8 | /*
|
9 | 9 | Functions:
|
10 |
| - CGLM_INLINE bool glm_line_triangle_intersect(vec3 origin, |
11 |
| - vec3 direction, |
12 |
| - vec3 v0, |
13 |
| - vec3 v1, |
14 |
| - vec3 v2, |
15 |
| - float *d); |
| 10 | + CGLM_INLINE bool glm_ray_triangle(vec3 origin, |
| 11 | + vec3 direction, |
| 12 | + vec3 v0, |
| 13 | + vec3 v1, |
| 14 | + vec3 v2, |
| 15 | + float *d); |
| 16 | + CGLM_INLINE bool glm_ray_sphere(vec3 origin, |
| 17 | + vec3 dir, |
| 18 | + vec4 s, |
| 19 | + float * __restrict t1, |
| 20 | + float * __restrict t2) |
16 | 21 | */
|
17 | 22 |
|
18 | 23 | #ifndef cglm_ray_h
|
|
31 | 36 | * @param[in, out] d distance to intersection
|
32 | 37 | * @return whether there is intersection
|
33 | 38 | */
|
34 |
| - |
35 | 39 | CGLM_INLINE
|
36 | 40 | bool
|
37 | 41 | glm_ray_triangle(vec3 origin,
|
@@ -74,4 +78,70 @@ glm_ray_triangle(vec3 origin,
|
74 | 78 | return dist > epsilon;
|
75 | 79 | }
|
76 | 80 |
|
| 81 | +/*! |
| 82 | + * @brief ray sphere intersection |
| 83 | + * |
| 84 | + * @param[in] origin ray origin |
| 85 | + * @param[out] dir normalized ray direction |
| 86 | + * @param[in] s sphere [center.x, center.y, center.z, radii] |
| 87 | + * @param[in] t1 near point1 (closer to origin) |
| 88 | + * @param[in] t2 far point2 (farther from origin) |
| 89 | + */ |
| 90 | +CGLM_INLINE |
| 91 | +bool |
| 92 | +glm_ray_sphere(vec3 origin, |
| 93 | + vec3 dir, |
| 94 | + vec4 s, |
| 95 | + float * __restrict t1, |
| 96 | + float * __restrict t2) { |
| 97 | + vec3 dp; |
| 98 | + float r2, ddp, dpp, dscr, q, tmp, _t1, _t2; |
| 99 | + |
| 100 | + /* ensure dir is normalized */ |
| 101 | + glm_vec3_sub(s, origin, dp); |
| 102 | + |
| 103 | + ddp = glm_vec3_dot(dir, dp); |
| 104 | + dpp = glm_vec3_norm2(dp); |
| 105 | + |
| 106 | + /* compute the remedy term for numerical stability */ |
| 107 | + glm_vec3_mulsubs(dir, ddp, dp); /* dp: remedy term */ |
| 108 | + |
| 109 | + r2 = s[3] * s[3]; |
| 110 | + dscr = r2 - glm_vec3_norm2(dp); |
| 111 | + |
| 112 | + if (dscr < 0.0f) { |
| 113 | + /* no intersection */ |
| 114 | + return false; |
| 115 | + } |
| 116 | + |
| 117 | + dscr = sqrtf(dscr); |
| 118 | + q = (ddp >= 0.0f) ? (ddp + dscr) : (ddp - dscr); |
| 119 | + |
| 120 | + /* |
| 121 | + include Press, William H., Saul A. Teukolsky, |
| 122 | + William T. Vetterling, and Brian P. Flannery, |
| 123 | + "Numerical Recipes in C," Cambridge University Press, 1992. |
| 124 | + */ |
| 125 | + _t1 = q; |
| 126 | + _t2 = (dpp - r2) / q; |
| 127 | + |
| 128 | + /* adjust t1 and t2 to ensure t1 is the closer intersection */ |
| 129 | + if (_t1 > _t2) { |
| 130 | + tmp = _t1; |
| 131 | + _t1 = _t2; |
| 132 | + _t2 = tmp; |
| 133 | + } |
| 134 | + |
| 135 | + *t1 = _t1; |
| 136 | + *t2 = _t2; |
| 137 | + |
| 138 | + /* check if the closest intersection (t1) is behind the ray's origin */ |
| 139 | + if (_t1 < 0.0f && _t2 < 0.0f) { |
| 140 | + /* both intersections are behind the ray, no visible intersection */ |
| 141 | + return false; |
| 142 | + } |
| 143 | + |
| 144 | + return true; |
| 145 | +} |
| 146 | + |
77 | 147 | #endif
|
0 commit comments