Skip to content

Commit 894b86e

Browse files
committed
Intersect methods
1 parent 2dfc3ea commit 894b86e

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

Scripts/Util/MeshUtils.cs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using ElasticSea.Framework.Extensions;
12
using UnityEngine;
23

34
namespace ElasticSea.Framework.Scripts.Util
@@ -126,5 +127,94 @@ public static Mesh Cube()
126127
mesh.uv = uvs;
127128
return mesh;
128129
}
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+
}
129219
}
130220
}

0 commit comments

Comments
 (0)