1
+ using ElasticSea . Framework . Extensions ;
1
2
using UnityEngine ;
2
3
3
4
namespace ElasticSea . Framework . Scripts . Util
@@ -126,5 +127,94 @@ public static Mesh Cube()
126
127
mesh . uv = uvs ;
127
128
return mesh ;
128
129
}
130
+
131
+ public static float Intersect ( this Mesh mesh , Ray ray )
132
+ {
133
+ var vertices = mesh . vertices ;
134
+ var triangles = mesh . triangles ;
135
+
136
+ for ( int i = 0 ; i < triangles . Length ; i += 3 )
137
+ {
138
+ var v0 = vertices [ triangles [ i + 0 ] ] ;
139
+ var v1 = vertices [ triangles [ i + 1 ] ] ;
140
+ var v2 = vertices [ triangles [ i + 2 ] ] ;
141
+
142
+ var intersectRayTriangle = IntersectRayTriangle ( ray , v0 , v1 , v2 ) ;
143
+ if ( float . IsNaN ( intersectRayTriangle ) == false )
144
+ {
145
+ return intersectRayTriangle ;
146
+ }
147
+ }
148
+
149
+ return float . NaN ;
150
+ }
151
+
152
+ public static bool Intersect ( this Mesh mesh , Vector3 from , Vector3 to , out Vector3 hit )
153
+ {
154
+ var ray = new Ray ( from , to - from ) ;
155
+ var distanceHit = mesh . Intersect ( ray ) ;
156
+
157
+ hit = Vector3 . zero ;
158
+
159
+ if ( float . IsNaN ( distanceHit ) )
160
+ {
161
+ return false ;
162
+ }
163
+
164
+ if ( distanceHit > from . Distance ( to ) )
165
+ {
166
+ return false ;
167
+ }
168
+
169
+ hit = ray . origin + ray . direction * distanceHit ;
170
+ return true ;
171
+ }
172
+
173
+ const float kEpsilon = 0.000001f ;
174
+
175
+ /// <summary>
176
+ /// Ray-versus-triangle intersection test suitable for ray-tracing etc.
177
+ /// Port of Möller–Trumbore algorithm c++ version from:
178
+ /// https://en.wikipedia.org/wiki/Möller–Trumbore_intersection_algorithm
179
+ /// </summary>
180
+ /// <returns><c>The distance along the ray to the intersection</c> if one exists, <c>NaN</c> if one does not.</returns>
181
+ /// <param name="ray">Le ray.</param>
182
+ /// <param name="v0">A vertex of the triangle.</param>
183
+ /// <param name="v1">A vertex of the triangle.</param>
184
+ /// <param name="v2">A vertex of the triangle.</param>
185
+ public static float IntersectRayTriangle ( Ray ray , Vector3 v0 , Vector3 v1 , Vector3 v2 ) {
186
+
187
+ // edges from v1 & v2 to v0.
188
+ Vector3 e1 = v1 - v0 ;
189
+ Vector3 e2 = v2 - v0 ;
190
+
191
+ Vector3 h = Vector3 . Cross ( ray . direction , e2 ) ;
192
+ float a = Vector3 . Dot ( e1 , h ) ;
193
+ if ( ( a > - kEpsilon ) && ( a < kEpsilon ) ) {
194
+ return float . NaN ;
195
+ }
196
+
197
+ float f = 1.0f / a ;
198
+
199
+ Vector3 s = ray . origin - v0 ;
200
+ float u = f * Vector3 . Dot ( s , h ) ;
201
+ if ( ( u < 0.0f ) || ( u > 1.0f ) ) {
202
+ return float . NaN ;
203
+ }
204
+
205
+ Vector3 q = Vector3 . Cross ( s , e1 ) ;
206
+ float v = f * Vector3 . Dot ( ray . direction , q ) ;
207
+ if ( ( v < 0.0f ) || ( u + v > 1.0f ) ) {
208
+ return float . NaN ;
209
+ }
210
+
211
+ float t = f * Vector3 . Dot ( e2 , q ) ;
212
+ if ( t > kEpsilon ) {
213
+ return t ;
214
+ }
215
+ else {
216
+ return float . NaN ;
217
+ }
218
+ }
129
219
}
130
220
}
0 commit comments