forked from bit/DotRecastNetSim
move core files
This commit is contained in:
parent
af6c804330
commit
7b820fafd7
|
@ -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 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 };
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 };
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<RecastBuilderResult> 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -28,21 +28,13 @@ namespace DotRecast.Recast.Demo.UI;
|
||||||
public class RcViewSystem
|
public class RcViewSystem
|
||||||
{
|
{
|
||||||
private static readonly ILogger Logger = Log.ForContext<RecastDemo>();
|
private static readonly ILogger Logger = Log.ForContext<RecastDemo>();
|
||||||
// readonly NkAllocator allocator;
|
|
||||||
private readonly IWindow _window;
|
|
||||||
|
|
||||||
private readonly GL _gl;
|
|
||||||
|
|
||||||
// readonly NkColor background;
|
|
||||||
// readonly NkColor white;
|
|
||||||
private readonly IRcView[] _views;
|
private readonly IRcView[] _views;
|
||||||
private bool _mouseOverUI;
|
private bool _mouseOverUI;
|
||||||
public bool IsMouseOverUI() => _mouseOverUI;
|
public bool IsMouseOverUI() => _mouseOverUI;
|
||||||
|
|
||||||
public RcViewSystem(IWindow window, IInputContext input, params IRcView[] views)
|
public RcViewSystem(IWindow window, IInputContext input, params IRcView[] views)
|
||||||
{
|
{
|
||||||
_window = window;
|
|
||||||
_gl = GL.GetApi(window);
|
|
||||||
// setupClipboard(window);
|
// setupClipboard(window);
|
||||||
// glfwSetCharCallback(window, (w, codepoint) => nk_input_unicode(ctx, codepoint));
|
// glfwSetCharCallback(window, (w, codepoint) => nk_input_unicode(ctx, codepoint));
|
||||||
// glContext = new NuklearGL(this);
|
// glContext = new NuklearGL(this);
|
||||||
|
|
|
@ -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<RecastBuilderResult> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue