Skip to content

Commit aa45d08

Browse files
committed
ray: ray sphere intersection
1 parent f1d4aea commit aa45d08

File tree

7 files changed

+167
-9
lines changed

7 files changed

+167
-9
lines changed

include/cglm/call/ray.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ glmc_ray_triangle(vec3 origin,
2020
vec3 v1,
2121
vec3 v2,
2222
float *d);
23-
23+
24+
CGLM_EXPORT
25+
bool
26+
glmc_ray_sphere(vec3 origin,
27+
vec3 dir,
28+
vec4 s,
29+
float * __restrict t1,
30+
float * __restrict t2);
31+
2432
#ifdef __cplusplus
2533
}
2634
#endif

include/cglm/ray.h

+77-7
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@
77

88
/*
99
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)
1621
*/
1722

1823
#ifndef cglm_ray_h
@@ -31,7 +36,6 @@
3136
* @param[in, out] d distance to intersection
3237
* @return whether there is intersection
3338
*/
34-
3539
CGLM_INLINE
3640
bool
3741
glm_ray_triangle(vec3 origin,
@@ -74,4 +78,70 @@ glm_ray_triangle(vec3 origin,
7478
return dist > epsilon;
7579
}
7680

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+
77147
#endif

include/cglm/struct.h

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ extern "C" {
4141
#include "struct/sphere.h"
4242
#include "struct/curve.h"
4343
#include "struct/affine2d.h"
44+
#include "struct/ray.h"
4445

4546
#ifdef __cplusplus
4647
}

include/cglm/struct/ray.h

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c), Recep Aslantas.
3+
*
4+
* MIT License (MIT), http://opensource.org/licenses/MIT
5+
* Full license can be found in the LICENSE file
6+
*/
7+
8+
#ifndef cglms_ray_h
9+
#define cglms_ray_h
10+
11+
#include "../common.h"
12+
#include "../types-struct.h"
13+
#include "../ray.h"
14+
15+
/* api definition */
16+
#define glms_ray_(NAME) CGLM_STRUCTAPI(ray, NAME)
17+
18+
/*!
19+
* @brief Möller–Trumbore ray-triangle intersection algorithm
20+
*
21+
* @param[in] origin origin of ray
22+
* @param[in] direction direction of ray
23+
* @param[in] v0 first vertex of triangle
24+
* @param[in] v1 second vertex of triangle
25+
* @param[in] v2 third vertex of triangle
26+
* @param[in, out] d distance to intersection
27+
* @return whether there is intersection
28+
*/
29+
CGLM_INLINE
30+
bool
31+
glms_ray_(triangle)(vec3s origin,
32+
vec3s direction,
33+
vec3s v0,
34+
vec3s v1,
35+
vec3s v2,
36+
float *d) {
37+
return glm_ray_triangle(origin.raw, direction.raw, v0.raw, v1.raw, v2.raw, d);
38+
}
39+
40+
/*!
41+
* @brief ray sphere intersection
42+
*
43+
* @param[in] origin ray origin
44+
* @param[out] dir normalized ray direction
45+
* @param[in] s sphere [center.x, center.y, center.z, radii]
46+
* @param[in] t1 near point1 (closer to origin)
47+
* @param[in] t2 far point2 (farther from origin)
48+
*/
49+
CGLM_INLINE
50+
bool
51+
glms_ray_(sphere)(vec3s origin,
52+
vec3s dir,
53+
vec4s s,
54+
float * __restrict t1,
55+
float * __restrict t2) {
56+
return glm_ray_sphere(origin.raw, dir.raw, s.raw, t1, t2);
57+
}
58+
59+
#endif /* cglms_ray_h */

src/ray.c

+17-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,21 @@ glmc_ray_triangle(vec3 origin,
99
vec3 v1,
1010
vec3 v2,
1111
float *d) {
12-
return glm_ray_triangle(origin, direction, v0, v1, v2, d);
12+
return glm_ray_triangle(origin, direction, v0, v1, v2, d);
13+
}
14+
15+
CGLM_EXPORT
16+
bool
17+
glmc_ray_sphere(vec3 origin,
18+
vec3 dir,
19+
vec4 s,
20+
float * __restrict t1,
21+
float * __restrict t2) {
22+
return glm_ray_sphere(origin, dir, s, t1, t2);
23+
}
24+
25+
CGLM_EXPORT
26+
void
27+
glmc_ray_at(vec3 orig, vec3 dir, float t, vec3 point) {
28+
glm_ray_at(orig, dir, t, point);
1329
}

win/cglm.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@
253253
<ClInclude Include="..\include\cglm\struct\plane.h" />
254254
<ClInclude Include="..\include\cglm\struct\project.h" />
255255
<ClInclude Include="..\include\cglm\struct\quat.h" />
256+
<ClInclude Include="..\include\cglm\struct\ray.h" />
256257
<ClInclude Include="..\include\cglm\struct\sphere.h" />
257258
<ClInclude Include="..\include\cglm\struct\vec2-ext.h" />
258259
<ClInclude Include="..\include\cglm\struct\vec2.h" />

win/cglm.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -729,5 +729,8 @@
729729
<ClInclude Include="..\include\cglm\struct\ivec4.h">
730730
<Filter>include\cglm\struct</Filter>
731731
</ClInclude>
732+
<ClInclude Include="..\include\cglm\struct\ray.h">
733+
<Filter>include\cglm\struct</Filter>
734+
</ClInclude>
732735
</ItemGroup>
733736
</Project>

0 commit comments

Comments
 (0)