diff --git a/src/DotRecast.Core/Intersections.cs b/src/DotRecast.Core/Intersections.cs
new file mode 100644
index 0000000..e48c5c8
--- /dev/null
+++ b/src/DotRecast.Core/Intersections.cs
@@ -0,0 +1,133 @@
+/*
+recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+using System;
+using DotRecast.Core;
+using static DotRecast.Core.RecastMath;
+
+namespace DotRecast.Core
+{
+ public static class Intersections
+ {
+ public static float? intersectSegmentTriangle(Vector3f sp, Vector3f sq, Vector3f a, Vector3f b, Vector3f c)
+ {
+ float v, w;
+ Vector3f ab = vSub(b, a);
+ Vector3f ac = vSub(c, a);
+ Vector3f qp = vSub(sp, sq);
+
+ // Compute triangle normal. Can be precalculated or cached if
+ // intersecting multiple segments against the same triangle
+ Vector3f norm = vCross(ab, ac);
+
+ // Compute denominator d. If d <= 0, segment is parallel to or points
+ // away from triangle, so exit early
+ float d = vDot(qp, norm);
+ if (d <= 0.0f)
+ {
+ return null;
+ }
+
+ // Compute intersection t value of pq with plane of triangle. A ray
+ // intersects iff 0 <= t. Segment intersects iff 0 <= t <= 1. Delay
+ // dividing by d until intersection has been found to pierce triangle
+ Vector3f ap = vSub(sp, a);
+ float t = vDot(ap, norm);
+ if (t < 0.0f)
+ {
+ return null;
+ }
+
+ if (t > d)
+ {
+ return null; // For segment; exclude this code line for a ray test
+ }
+
+ // Compute barycentric coordinate components and test if within bounds
+ Vector3f e = vCross(qp, ap);
+ v = vDot(ac, e);
+ if (v < 0.0f || v > d)
+ {
+ return null;
+ }
+
+ w = -vDot(ab, e);
+ if (w < 0.0f || v + w > d)
+ {
+ return null;
+ }
+
+ // Segment/ray intersects triangle. Perform delayed division
+ t /= d;
+
+ return t;
+ }
+
+ public static float[] intersectSegmentAABB(Vector3f sp, Vector3f sq, Vector3f amin, Vector3f amax)
+ {
+ float EPS = 1e-6f;
+
+ Vector3f d = new Vector3f();
+ d[0] = sq[0] - sp[0];
+ d[1] = sq[1] - sp[1];
+ d[2] = sq[2] - sp[2];
+ float tmin = 0.0f;
+ float tmax = 1.0f;
+
+ for (int i = 0; i < 3; i++)
+ {
+ if (Math.Abs(d[i]) < EPS)
+ {
+ if (sp[i] < amin[i] || sp[i] > amax[i])
+ {
+ return null;
+ }
+ }
+ else
+ {
+ float ood = 1.0f / d[i];
+ float t1 = (amin[i] - sp[i]) * ood;
+ float t2 = (amax[i] - sp[i]) * ood;
+ if (t1 > t2)
+ {
+ float tmp = t1;
+ t1 = t2;
+ t2 = tmp;
+ }
+
+ if (t1 > tmin)
+ {
+ tmin = t1;
+ }
+
+ if (t2 < tmax)
+ {
+ tmax = t2;
+ }
+
+ if (tmin > tmax)
+ {
+ return null;
+ }
+ }
+ }
+
+ return new float[] { tmin, tmax };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DotRecast.Detour/DotRecast.Detour.csproj b/src/DotRecast.Detour/DotRecast.Detour.csproj
index 4ee2241..b49b2e6 100644
--- a/src/DotRecast.Detour/DotRecast.Detour.csproj
+++ b/src/DotRecast.Detour/DotRecast.Detour.csproj
@@ -2,7 +2,6 @@
netstandard2.1
-
diff --git a/src/DotRecast.Detour/NavMeshRaycast.cs b/src/DotRecast.Detour/NavMeshRaycast.cs
new file mode 100644
index 0000000..b379d27
--- /dev/null
+++ b/src/DotRecast.Detour/NavMeshRaycast.cs
@@ -0,0 +1,98 @@
+/*
+recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+using DotRecast.Core;
+
+namespace DotRecast.Detour
+{
+
+ /**
+ * Simple helper to find an intersection between a ray and a nav mesh
+ */
+ public static class NavMeshRaycast
+ {
+ public static float? raycast(NavMesh mesh, Vector3f src, Vector3f dst)
+ {
+ for (int t = 0; t < mesh.getMaxTiles(); ++t)
+ {
+ MeshTile tile = mesh.getTile(t);
+ if (tile != null && tile.data != null)
+ {
+ float? intersection = raycast(tile, src, dst);
+ if (null != intersection)
+ {
+ return intersection;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static float? raycast(MeshTile tile, Vector3f sp, Vector3f sq)
+ {
+ for (int i = 0; i < tile.data.header.polyCount; ++i)
+ {
+ Poly p = tile.data.polys[i];
+ if (p.getType() == Poly.DT_POLYTYPE_OFFMESH_CONNECTION)
+ {
+ continue;
+ }
+
+ PolyDetail pd = tile.data.detailMeshes[i];
+
+ if (pd != null)
+ {
+ Vector3f[] verts = new Vector3f[3];
+ for (int j = 0; j < pd.triCount; ++j)
+ {
+ int t = (pd.triBase + j) * 4;
+ for (int k = 0; k < 3; ++k)
+ {
+ int v = tile.data.detailTris[t + k];
+ if (v < p.vertCount)
+ {
+ verts[k][0] = tile.data.verts[p.verts[v] * 3];
+ verts[k][1] = tile.data.verts[p.verts[v] * 3 + 1];
+ verts[k][2] = tile.data.verts[p.verts[v] * 3 + 2];
+ }
+ else
+ {
+ verts[k][0] = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3];
+ verts[k][1] = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 1];
+ verts[k][2] = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 2];
+ }
+ }
+
+ float? intersection = Intersections.intersectSegmentTriangle(sp, sq, verts[0], verts[1], verts[2]);
+ if (null != intersection)
+ {
+ return intersection;
+ }
+ }
+ }
+ else
+ {
+ // FIXME: Use Poly if PolyDetail is unavailable
+ }
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DotRecast.Detour/NavMeshUtils.cs b/src/DotRecast.Detour/NavMeshUtils.cs
new file mode 100644
index 0000000..1d25dc5
--- /dev/null
+++ b/src/DotRecast.Detour/NavMeshUtils.cs
@@ -0,0 +1,51 @@
+/*
+recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+using System;
+using DotRecast.Core;
+using DotRecast.Detour;
+
+namespace DotRecast.Detour
+{
+ public static class NavMeshUtils
+ {
+ public static Vector3f[] getNavMeshBounds(NavMesh mesh)
+ {
+ Vector3f bmin = Vector3f.Of(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
+ Vector3f bmax = Vector3f.Of(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);
+ for (int t = 0; t < mesh.getMaxTiles(); ++t)
+ {
+ MeshTile tile = mesh.getTile(t);
+ if (tile != null && tile.data != null)
+ {
+ for (int i = 0; i < tile.data.verts.Length; i += 3)
+ {
+ bmin[0] = Math.Min(bmin[0], tile.data.verts[i]);
+ bmin[1] = Math.Min(bmin[1], tile.data.verts[i + 1]);
+ bmin[2] = Math.Min(bmin[2], tile.data.verts[i + 2]);
+ bmax[0] = Math.Max(bmax[0], tile.data.verts[i]);
+ bmax[1] = Math.Max(bmax[1], tile.data.verts[i + 1]);
+ bmax[2] = Math.Max(bmax[2], tile.data.verts[i + 2]);
+ }
+ }
+ }
+
+ return new[] { bmin, bmax };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DotRecast.Recast.Demo/Geom/Intersections.cs b/src/DotRecast.Recast.Demo/Geom/Intersections.cs
deleted file mode 100644
index 886e47d..0000000
--- a/src/DotRecast.Recast.Demo/Geom/Intersections.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
-recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-*/
-
-using System;
-using DotRecast.Core;
-using static DotRecast.Core.RecastMath;
-
-namespace DotRecast.Recast.Demo.Geom;
-
-public class Intersections
-{
- public static float? intersectSegmentTriangle(Vector3f sp, Vector3f sq, Vector3f a, Vector3f b, Vector3f c)
- {
- float v, w;
- Vector3f ab = vSub(b, a);
- Vector3f ac = vSub(c, a);
- Vector3f qp = vSub(sp, sq);
-
- // Compute triangle normal. Can be precalculated or cached if
- // intersecting multiple segments against the same triangle
- Vector3f norm = vCross(ab, ac);
-
- // Compute denominator d. If d <= 0, segment is parallel to or points
- // away from triangle, so exit early
- float d = vDot(qp, norm);
- if (d <= 0.0f)
- {
- return null;
- }
-
- // Compute intersection t value of pq with plane of triangle. A ray
- // intersects iff 0 <= t. Segment intersects iff 0 <= t <= 1. Delay
- // dividing by d until intersection has been found to pierce triangle
- Vector3f ap = vSub(sp, a);
- float t = vDot(ap, norm);
- if (t < 0.0f)
- {
- return null;
- }
-
- if (t > d)
- {
- return null; // For segment; exclude this code line for a ray test
- }
-
- // Compute barycentric coordinate components and test if within bounds
- Vector3f e = vCross(qp, ap);
- v = vDot(ac, e);
- if (v < 0.0f || v > d)
- {
- return null;
- }
-
- w = -vDot(ab, e);
- if (w < 0.0f || v + w > d)
- {
- return null;
- }
-
- // Segment/ray intersects triangle. Perform delayed division
- t /= d;
-
- return t;
- }
-
- public static float[] intersectSegmentAABB(Vector3f sp, Vector3f sq, Vector3f amin, Vector3f amax)
- {
- float EPS = 1e-6f;
-
- Vector3f d = new Vector3f();
- d[0] = sq[0] - sp[0];
- d[1] = sq[1] - sp[1];
- d[2] = sq[2] - sp[2];
- float tmin = 0.0f;
- float tmax = 1.0f;
-
- for (int i = 0; i < 3; i++)
- {
- if (Math.Abs(d[i]) < EPS)
- {
- if (sp[i] < amin[i] || sp[i] > amax[i])
- {
- return null;
- }
- }
- else
- {
- float ood = 1.0f / d[i];
- float t1 = (amin[i] - sp[i]) * ood;
- float t2 = (amax[i] - sp[i]) * ood;
- if (t1 > t2)
- {
- float tmp = t1;
- t1 = t2;
- t2 = tmp;
- }
-
- if (t1 > tmin)
- {
- tmin = t1;
- }
-
- if (t2 < tmax)
- {
- tmax = t2;
- }
-
- if (tmin > tmax)
- {
- return null;
- }
- }
- }
-
- return new float[] { tmin, tmax };
- }
-}
\ No newline at end of file
diff --git a/src/DotRecast.Recast.Demo/Geom/NavMeshRaycast.cs b/src/DotRecast.Recast.Demo/Geom/NavMeshRaycast.cs
deleted file mode 100644
index 4ed609c..0000000
--- a/src/DotRecast.Recast.Demo/Geom/NavMeshRaycast.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
-recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-*/
-
-using DotRecast.Core;
-using DotRecast.Detour;
-
-namespace DotRecast.Recast.Demo.Geom;
-
-/**
- * Simple helper to find an intersection between a ray and a nav mesh
- */
-public class NavMeshRaycast
-{
- public static float? raycast(NavMesh mesh, Vector3f src, Vector3f dst)
- {
- for (int t = 0; t < mesh.getMaxTiles(); ++t)
- {
- MeshTile tile = mesh.getTile(t);
- if (tile != null && tile.data != null)
- {
- float? intersection = raycast(tile, src, dst);
- if (null != intersection)
- {
- return intersection;
- }
- }
- }
-
- return null;
- }
-
- private static float? raycast(MeshTile tile, Vector3f sp, Vector3f sq)
- {
- for (int i = 0; i < tile.data.header.polyCount; ++i)
- {
- Poly p = tile.data.polys[i];
- if (p.getType() == Poly.DT_POLYTYPE_OFFMESH_CONNECTION)
- {
- continue;
- }
-
- PolyDetail pd = tile.data.detailMeshes[i];
-
- if (pd != null)
- {
- Vector3f[] verts = new Vector3f[3];
- for (int j = 0; j < pd.triCount; ++j)
- {
- int t = (pd.triBase + j) * 4;
- for (int k = 0; k < 3; ++k)
- {
- int v = tile.data.detailTris[t + k];
- if (v < p.vertCount)
- {
- verts[k][0] = tile.data.verts[p.verts[v] * 3];
- verts[k][1] = tile.data.verts[p.verts[v] * 3 + 1];
- verts[k][2] = tile.data.verts[p.verts[v] * 3 + 2];
- }
- else
- {
- verts[k][0] = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3];
- verts[k][1] = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 1];
- verts[k][2] = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 2];
- }
- }
-
- float? intersection = Intersections.intersectSegmentTriangle(sp, sq, verts[0], verts[1], verts[2]);
- if (null != intersection)
- {
- return intersection;
- }
- }
- }
- else
- {
- // FIXME: Use Poly if PolyDetail is unavailable
- }
- }
-
- return null;
- }
-}
\ No newline at end of file
diff --git a/src/DotRecast.Recast.Demo/Geom/NavMeshUtils.cs b/src/DotRecast.Recast.Demo/Geom/NavMeshUtils.cs
deleted file mode 100644
index 9b2de0c..0000000
--- a/src/DotRecast.Recast.Demo/Geom/NavMeshUtils.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-*/
-
-using System;
-using DotRecast.Core;
-using DotRecast.Detour;
-
-namespace DotRecast.Recast.Demo.Geom;
-
-public class NavMeshUtils
-{
- public static Vector3f[] getNavMeshBounds(NavMesh mesh)
- {
- Vector3f bmin = Vector3f.Of(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
- Vector3f bmax = Vector3f.Of(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);
- for (int t = 0; t < mesh.getMaxTiles(); ++t)
- {
- MeshTile tile = mesh.getTile(t);
- if (tile != null && tile.data != null)
- {
- for (int i = 0; i < tile.data.verts.Length; i += 3)
- {
- bmin[0] = Math.Min(bmin[0], tile.data.verts[i]);
- bmin[1] = Math.Min(bmin[1], tile.data.verts[i + 1]);
- bmin[2] = Math.Min(bmin[2], tile.data.verts[i + 2]);
- bmax[0] = Math.Max(bmax[0], tile.data.verts[i]);
- bmax[1] = Math.Max(bmax[1], tile.data.verts[i + 1]);
- bmax[2] = Math.Max(bmax[2], tile.data.verts[i + 2]);
- }
- }
- }
-
- return new[] { bmin, bmax };
- }
-}
\ No newline at end of file
diff --git a/src/DotRecast.Recast.Demo/Geom/PolyMeshRaycast.cs b/src/DotRecast.Recast.Demo/Geom/PolyMeshRaycast.cs
deleted file mode 100644
index 684562d..0000000
--- a/src/DotRecast.Recast.Demo/Geom/PolyMeshRaycast.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-*/
-
-using System.Collections.Generic;
-using DotRecast.Core;
-
-namespace DotRecast.Recast.Demo.Geom;
-
-public class PolyMeshRaycast
-{
- public static float? raycast(IList results, Vector3f src, Vector3f dst)
- {
- foreach (RecastBuilderResult result in results)
- {
- if (result.getMeshDetail() != null)
- {
- float? intersection = raycast(result.getMesh(), result.getMeshDetail(), src, dst);
- if (null != intersection)
- {
- return intersection;
- }
- }
- }
-
- return null;
- }
-
- private static float? raycast(PolyMesh poly, PolyMeshDetail meshDetail, Vector3f sp, Vector3f sq)
- {
- if (meshDetail != null)
- {
- for (int i = 0; i < meshDetail.nmeshes; ++i)
- {
- int m = i * 4;
- int bverts = meshDetail.meshes[m];
- int btris = meshDetail.meshes[m + 2];
- int ntris = meshDetail.meshes[m + 3];
- int verts = bverts * 3;
- int tris = btris * 4;
- for (int j = 0; j < ntris; ++j)
- {
- Vector3f[] vs = new Vector3f[3];
- for (int k = 0; k < 3; ++k)
- {
- vs[k][0] = meshDetail.verts[verts + meshDetail.tris[tris + j * 4 + k] * 3];
- vs[k][1] = meshDetail.verts[verts + meshDetail.tris[tris + j * 4 + k] * 3 + 1];
- vs[k][2] = meshDetail.verts[verts + meshDetail.tris[tris + j * 4 + k] * 3 + 2];
- }
-
- float? intersection = Intersections.intersectSegmentTriangle(sp, sq, vs[0], vs[1], vs[2]);
- if (null != intersection)
- {
- return intersection;
- }
- }
- }
- }
- else
- {
- // TODO: check PolyMesh instead
- }
-
- return null;
- }
-}
\ No newline at end of file
diff --git a/src/DotRecast.Recast.Demo/UI/RcViewSystem.cs b/src/DotRecast.Recast.Demo/UI/RcViewSystem.cs
index f0a4eee..4aead3a 100644
--- a/src/DotRecast.Recast.Demo/UI/RcViewSystem.cs
+++ b/src/DotRecast.Recast.Demo/UI/RcViewSystem.cs
@@ -28,21 +28,13 @@ namespace DotRecast.Recast.Demo.UI;
public class RcViewSystem
{
private static readonly ILogger Logger = Log.ForContext();
- // readonly NkAllocator allocator;
- private readonly IWindow _window;
-
- private readonly GL _gl;
-
- // readonly NkColor background;
- // readonly NkColor white;
+
private readonly IRcView[] _views;
private bool _mouseOverUI;
public bool IsMouseOverUI() => _mouseOverUI;
public RcViewSystem(IWindow window, IInputContext input, params IRcView[] views)
{
- _window = window;
- _gl = GL.GetApi(window);
// setupClipboard(window);
// glfwSetCharCallback(window, (w, codepoint) => nk_input_unicode(ctx, codepoint));
// glContext = new NuklearGL(this);
diff --git a/src/DotRecast.Recast/PolyMeshRaycast.cs b/src/DotRecast.Recast/PolyMeshRaycast.cs
new file mode 100644
index 0000000..fc29961
--- /dev/null
+++ b/src/DotRecast.Recast/PolyMeshRaycast.cs
@@ -0,0 +1,82 @@
+/*
+recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+using System.Collections.Generic;
+using DotRecast.Core;
+
+namespace DotRecast.Recast
+{
+
+ public static class PolyMeshRaycast
+ {
+ public static float? raycast(IList results, Vector3f src, Vector3f dst)
+ {
+ foreach (RecastBuilderResult result in results)
+ {
+ if (result.getMeshDetail() != null)
+ {
+ float? intersection = raycast(result.getMesh(), result.getMeshDetail(), src, dst);
+ if (null != intersection)
+ {
+ return intersection;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static float? raycast(PolyMesh poly, PolyMeshDetail meshDetail, Vector3f sp, Vector3f sq)
+ {
+ if (meshDetail != null)
+ {
+ for (int i = 0; i < meshDetail.nmeshes; ++i)
+ {
+ int m = i * 4;
+ int bverts = meshDetail.meshes[m];
+ int btris = meshDetail.meshes[m + 2];
+ int ntris = meshDetail.meshes[m + 3];
+ int verts = bverts * 3;
+ int tris = btris * 4;
+ for (int j = 0; j < ntris; ++j)
+ {
+ Vector3f[] vs = new Vector3f[3];
+ for (int k = 0; k < 3; ++k)
+ {
+ vs[k][0] = meshDetail.verts[verts + meshDetail.tris[tris + j * 4 + k] * 3];
+ vs[k][1] = meshDetail.verts[verts + meshDetail.tris[tris + j * 4 + k] * 3 + 1];
+ vs[k][2] = meshDetail.verts[verts + meshDetail.tris[tris + j * 4 + k] * 3 + 2];
+ }
+
+ float? intersection = Intersections.intersectSegmentTriangle(sp, sq, vs[0], vs[1], vs[2]);
+ if (null != intersection)
+ {
+ return intersection;
+ }
+ }
+ }
+ }
+ else
+ {
+ // TODO: check PolyMesh instead
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file