1+ import type { Mesh } from "../rendering/types/mesh" ;
2+ import { mul_mat4_vec4 } from "./matrix_operators" ;
3+ import { vec4 , type Line , type mat4 , type vec3 } from "./types" ;
4+
5+ export function ray_intersects_ellipsoid (
6+ line :Line ,
7+ inverse_model :mat4 ,
8+ radius_reciprocal :vec3
9+ ) : boolean {
10+ if ( ! inverse_model ) return false ;
11+
12+ const local_origin = mul_mat4_vec4 ( inverse_model , vec4 ( line . point [ 0 ] , line . point [ 1 ] , line . point [ 2 ] , 1.0 ) ) ;
13+ const local_dir = mul_mat4_vec4 ( inverse_model , vec4 ( line . directional_vector [ 0 ] , line . directional_vector [ 1 ] , line . directional_vector [ 2 ] , 0.0 ) ) ;
14+
15+
16+ const [ ux , uy , uz , uu ] = local_dir ;
17+ const px = local_origin [ 0 ] ;
18+ const py = local_origin [ 1 ]
19+ const pz = local_origin [ 2 ]
20+
21+ const [ recip_a , recip_b , recip_c ] = radius_reciprocal ;
22+ const A = ux * ux * recip_a + uy * uy * recip_b + uz * uz * recip_c ;
23+ const B = 2 * ( px * ux * recip_a + py * uy * recip_b + pz * uz * recip_c ) ;
24+ const C = px * px * recip_a + py * py * recip_b + pz * pz * recip_c - 1 ;
25+
26+ if ( C <= 0 ) return true ;
27+
28+ if ( B > 0 ) return false ;
29+
30+ const delta = B * B - 4 * A * C ;
31+ return delta >= 0 ;
32+ }
33+
34+ export function ray_intersects_triangles (
35+ ray : Line ,
36+ mesh : Mesh ,
37+ inverse_model : mat4
38+ ) : boolean {
39+ const local_origin = mul_mat4_vec4 ( inverse_model , vec4 ( ray . point [ 0 ] , ray . point [ 1 ] , ray . point [ 2 ] , 1.0 ) ) ;
40+ const local_dir = mul_mat4_vec4 ( inverse_model , vec4 ( ray . directional_vector [ 0 ] , ray . directional_vector [ 1 ] , ray . directional_vector [ 2 ] , 0.0 ) ) ;
41+
42+ const ox = local_origin [ 0 ] ;
43+ const oy = local_origin [ 1 ] ;
44+ const oz = local_origin [ 2 ] ;
45+
46+ const dx = local_dir [ 0 ] ;
47+ const dy = local_dir [ 1 ] ;
48+ const dz = local_dir [ 2 ] ;
49+
50+ const vertices = mesh . vertices ;
51+ const indices = mesh . indices ;
52+
53+ const EPSILON = 0.00001 ;
54+
55+ for ( let i = 0 ; i < indices . length ; i += 3 ) {
56+ const i0 = indices [ i ] * 3 ;
57+ const i1 = indices [ i + 1 ] * 3 ;
58+ const i2 = indices [ i + 2 ] * 3 ;
59+
60+ const v0x = vertices [ i0 ] ;
61+ const v0y = vertices [ i0 + 1 ] ;
62+ const v0z = vertices [ i0 + 2 ] ;
63+
64+ const v1x = vertices [ i1 ] ;
65+ const v1y = vertices [ i1 + 1 ] ;
66+ const v1z = vertices [ i1 + 2 ] ;
67+
68+ const v2x = vertices [ i2 ] ;
69+ const v2y = vertices [ i2 + 1 ] ;
70+ const v2z = vertices [ i2 + 2 ] ;
71+
72+ const e1x = v1x - v0x ;
73+ const e1y = v1y - v0y ;
74+ const e1z = v1z - v0z ;
75+
76+ const e2x = v2x - v0x ;
77+ const e2y = v2y - v0y ;
78+ const e2z = v2z - v0z ;
79+
80+ const hx = dy * e2z - dz * e2y ;
81+ const hy = dz * e2x - dx * e2z ;
82+ const hz = dx * e2y - dy * e2x ;
83+
84+ const a = e1x * hx + e1y * hy + e1z * hz ;
85+
86+ if ( a > - EPSILON && a < EPSILON ) {
87+ continue ;
88+ }
89+
90+ const f = 1.0 / a ;
91+
92+ const sx = ox - v0x ;
93+ const sy = oy - v0y ;
94+ const sz = oz - v0z ;
95+
96+ const u = f * ( sx * hx + sy * hy + sz * hz ) ;
97+ if ( u < 0.0 || u > 1.0 ) {
98+ continue ;
99+ }
100+
101+ const qx = sy * e1z - sz * e1y ;
102+ const qy = sz * e1x - sx * e1z ;
103+ const qz = sx * e1y - sy * e1x ;
104+ const v = f * ( dx * qx + dy * qy + dz * qz ) ;
105+ if ( v < 0.0 || u + v > 1.0 ) {
106+ continue ;
107+ }
108+ const t = f * ( e2x * qx + e2y * qy + e2z * qz ) ;
109+
110+ if ( t > EPSILON && t < 1.0 ) {
111+ return true ;
112+ }
113+ }
114+
115+ return false ;
116+ }
0 commit comments