forked from bit/DotRecastNetSim
float[3] to Vector3f
This commit is contained in:
parent
254ec50436
commit
535bbd38a4
|
@ -35,6 +35,15 @@ namespace DotRecast.Core
|
||||||
float dz = v2[i + 2] - v1[2];
|
float dz = v2[i + 2] - v1[2];
|
||||||
return dx * dx + dy * dy + dz * dz;
|
return dx * dx + dy * dy + dz * dz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float vDistSqr(Vector3f v1, Vector3f v2, int i)
|
||||||
|
{
|
||||||
|
float dx = v2[i] - v1[0];
|
||||||
|
float dy = v2[i + 1] - v1[1];
|
||||||
|
float dz = v2[i + 2] - v1[2];
|
||||||
|
return dx * dx + dy * dy + dz * dz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static float[] vCross(float[] v1, float[] v2)
|
public static float[] vCross(float[] v1, float[] v2)
|
||||||
{
|
{
|
||||||
|
@ -251,6 +260,13 @@ namespace DotRecast.Core
|
||||||
@out[2] = @in[2];
|
@out[2] = @in[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void vCopy(float[] @out, Vector3f @in)
|
||||||
|
{
|
||||||
|
@out[0] = @in[0];
|
||||||
|
@out[1] = @in[1];
|
||||||
|
@out[2] = @in[2];
|
||||||
|
}
|
||||||
|
|
||||||
public static void vCopy(ref Vector3f @out, float[] @in)
|
public static void vCopy(ref Vector3f @out, float[] @in)
|
||||||
{
|
{
|
||||||
@out.x = @in[0];
|
@out.x = @in[0];
|
||||||
|
|
|
@ -17,6 +17,7 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Core
|
namespace DotRecast.Core
|
||||||
{
|
{
|
||||||
|
@ -26,14 +27,16 @@ namespace DotRecast.Core
|
||||||
public float y;
|
public float y;
|
||||||
public float z;
|
public float z;
|
||||||
|
|
||||||
|
public static Vector3f Zero { get; } = new Vector3f(0, 0, 0);
|
||||||
|
|
||||||
public static Vector3f Of(float[] f)
|
public static Vector3f Of(float[] f)
|
||||||
{
|
{
|
||||||
return new Vector3f()
|
return new Vector3f(f[0], f[1], f[2]);
|
||||||
{
|
}
|
||||||
x = f[0],
|
|
||||||
y = f[1],
|
public static Vector3f Of(float x, float y, float z)
|
||||||
z = f[2],
|
{
|
||||||
};
|
return new Vector3f(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f(float x, float y, float z)
|
public Vector3f(float x, float y, float z)
|
||||||
|
|
|
@ -321,7 +321,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||||
/// @param[in] vel The movement velocity. [(x, y, z)]
|
/// @param[in] vel The movement velocity. [(x, y, z)]
|
||||||
/// @return True if the request was successfully submitted.
|
/// @return True if the request was successfully submitted.
|
||||||
public bool requestMoveVelocity(CrowdAgent agent, float[] vel)
|
public bool requestMoveVelocity(CrowdAgent agent, Vector3f vel)
|
||||||
{
|
{
|
||||||
// Initialize request.
|
// Initialize request.
|
||||||
agent.targetRef = 0;
|
agent.targetRef = 0;
|
||||||
|
@ -485,7 +485,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
// ag.corridor.trimInvalidPath(agentRef, agentPos, m_navquery,
|
// ag.corridor.trimInvalidPath(agentRef, agentPos, m_navquery,
|
||||||
// &m_filter);
|
// &m_filter);
|
||||||
ag.boundary.reset();
|
ag.boundary.reset();
|
||||||
vCopy(ag.npos, agentPos);
|
vCopy(ref ag.npos, agentPos);
|
||||||
|
|
||||||
replan = true;
|
replan = true;
|
||||||
}
|
}
|
||||||
|
@ -510,7 +510,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
ag.targetRef = fnp.succeeded() ? fnp.result.getNearestRef() : 0L;
|
ag.targetRef = fnp.succeeded() ? fnp.result.getNearestRef() : 0L;
|
||||||
if (fnp.succeeded())
|
if (fnp.succeeded())
|
||||||
{
|
{
|
||||||
vCopy(ag.targetPos, fnp.result.getNearestPos());
|
vCopy(ref ag.targetPos, fnp.result.getNearestPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
replan = true;
|
replan = true;
|
||||||
|
@ -626,14 +626,14 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vCopy(reqPos, ag.targetPos);
|
vCopy(ref reqPos, ag.targetPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Could not find path, start the request from current
|
// Could not find path, start the request from current
|
||||||
// location.
|
// location.
|
||||||
vCopy(reqPos, ag.npos);
|
vCopy(ref reqPos, ag.npos);
|
||||||
reqPath = new List<long>();
|
reqPath = new List<long>();
|
||||||
reqPath.Add(path[0]);
|
reqPath.Add(path[0]);
|
||||||
}
|
}
|
||||||
|
@ -722,7 +722,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply results.
|
// Apply results.
|
||||||
float[] targetPos = ag.targetPos;
|
var targetPos = ag.targetPos;
|
||||||
|
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
List<long> res = ag.targetPathQueryResult.path;
|
List<long> res = ag.targetPathQueryResult.path;
|
||||||
|
@ -866,7 +866,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
m_grid = new ProximityGrid(_config.maxAgentRadius * 3);
|
m_grid = new ProximityGrid(_config.maxAgentRadius * 3);
|
||||||
foreach (CrowdAgent ag in agents)
|
foreach (CrowdAgent ag in agents)
|
||||||
{
|
{
|
||||||
float[] p = ag.npos;
|
Vector3f p = ag.npos;
|
||||||
float r = ag.option.radius;
|
float r = ag.option.radius;
|
||||||
m_grid.addItem(ag, p[0] - r, p[2] - r, p[0] + r, p[2] + r);
|
m_grid.addItem(ag, p[0] - r, p[2] - r, p[0] + r, p[2] + r);
|
||||||
}
|
}
|
||||||
|
@ -901,7 +901,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
_telemetry.stop("buildNeighbours");
|
_telemetry.stop("buildNeighbours");
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<CrowdNeighbour> getNeighbours(float[] pos, float height, float range, CrowdAgent skip, ProximityGrid grid)
|
private List<CrowdNeighbour> getNeighbours(Vector3f pos, float height, float range, CrowdAgent skip, ProximityGrid grid)
|
||||||
{
|
{
|
||||||
List<CrowdNeighbour> result = new List<CrowdNeighbour>();
|
List<CrowdNeighbour> result = new List<CrowdNeighbour>();
|
||||||
HashSet<CrowdAgent> proxAgents = grid.queryItems(pos[0] - range, pos[2] - range, pos[0] + range, pos[2] + range);
|
HashSet<CrowdAgent> proxAgents = grid.queryItems(pos[0] - range, pos[2] - range, pos[0] + range, pos[2] + range);
|
||||||
|
@ -914,7 +914,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for overlap.
|
// Check for overlap.
|
||||||
float[] diff = vSub(pos, ag.npos);
|
Vector3f diff = vSub(pos, ag.npos);
|
||||||
if (Math.Abs(diff[1]) >= (height + ag.option.height) / 2.0f)
|
if (Math.Abs(diff[1]) >= (height + ag.option.height) / 2.0f)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -958,15 +958,15 @@ namespace DotRecast.Detour.Crowd
|
||||||
// and short cut to there.
|
// and short cut to there.
|
||||||
if ((ag.option.updateFlags & CrowdAgentParams.DT_CROWD_OPTIMIZE_VIS) != 0 && ag.corners.Count > 0)
|
if ((ag.option.updateFlags & CrowdAgentParams.DT_CROWD_OPTIMIZE_VIS) != 0 && ag.corners.Count > 0)
|
||||||
{
|
{
|
||||||
float[] target = ag.corners[Math.Min(1, ag.corners.Count - 1)].getPos();
|
Vector3f target = ag.corners[Math.Min(1, ag.corners.Count - 1)].getPos();
|
||||||
ag.corridor.optimizePathVisibility(target, ag.option.pathOptimizationRange, navQuery,
|
ag.corridor.optimizePathVisibility(target, ag.option.pathOptimizationRange, navQuery,
|
||||||
m_filters[ag.option.queryFilterType]);
|
m_filters[ag.option.queryFilterType]);
|
||||||
|
|
||||||
// Copy data for debug purposes.
|
// Copy data for debug purposes.
|
||||||
if (debugAgent == ag)
|
if (debugAgent == ag)
|
||||||
{
|
{
|
||||||
vCopy(debug.optStart, ag.corridor.getPos());
|
vCopy(ref debug.optStart, ag.corridor.getPos());
|
||||||
vCopy(debug.optEnd, target);
|
vCopy(ref debug.optEnd, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -974,8 +974,8 @@ namespace DotRecast.Detour.Crowd
|
||||||
// Copy data for debug purposes.
|
// Copy data for debug purposes.
|
||||||
if (debugAgent == ag)
|
if (debugAgent == ag)
|
||||||
{
|
{
|
||||||
vSet(debug.optStart, 0, 0, 0);
|
vSet(ref debug.optStart, 0, 0, 0);
|
||||||
vSet(debug.optEnd, 0, 0, 0);
|
vSet(ref debug.optEnd, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1051,7 +1051,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
|
|
||||||
if (ag.targetState == CrowdAgent.MoveRequestState.DT_CROWDAGENT_TARGET_VELOCITY)
|
if (ag.targetState == CrowdAgent.MoveRequestState.DT_CROWDAGENT_TARGET_VELOCITY)
|
||||||
{
|
{
|
||||||
vCopy(dvel, ag.targetPos);
|
vCopy(ref dvel, ag.targetPos);
|
||||||
ag.desiredSpeed = vLen(ag.targetPos);
|
ag.desiredSpeed = vLen(ag.targetPos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1088,7 +1088,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
{
|
{
|
||||||
CrowdAgent nei = ag.neis[j].agent;
|
CrowdAgent nei = ag.neis[j].agent;
|
||||||
|
|
||||||
float[] diff = vSub(ag.npos, nei.npos);
|
Vector3f diff = vSub(ag.npos, nei.npos);
|
||||||
diff[1] = 0;
|
diff[1] = 0;
|
||||||
|
|
||||||
float distSqr = vLenSqr(diff);
|
float distSqr = vLenSqr(diff);
|
||||||
|
@ -1124,7 +1124,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the desired velocity.
|
// Set the desired velocity.
|
||||||
vCopy(ag.dvel, dvel);
|
vCopy(ref ag.dvel, dvel);
|
||||||
}
|
}
|
||||||
|
|
||||||
_telemetry.stop("calculateSteering");
|
_telemetry.stop("calculateSteering");
|
||||||
|
@ -1155,15 +1155,15 @@ namespace DotRecast.Detour.Crowd
|
||||||
// Append neighbour segments as obstacles.
|
// Append neighbour segments as obstacles.
|
||||||
for (int j = 0; j < ag.boundary.getSegmentCount(); ++j)
|
for (int j = 0; j < ag.boundary.getSegmentCount(); ++j)
|
||||||
{
|
{
|
||||||
float[] s = ag.boundary.getSegment(j);
|
Vector3f[] s = ag.boundary.getSegment(j);
|
||||||
Vector3f s3 = new Vector3f();
|
Vector3f s3 = s[1];
|
||||||
Array.Copy(s, 3, s3, 0, 3);
|
//Array.Copy(s, 3, s3, 0, 3);
|
||||||
if (triArea2D(ag.npos, s, s3) < 0.0f)
|
if (triArea2D(ag.npos, s[0], s3) < 0.0f)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_obstacleQuery.addSegment(s, s3);
|
m_obstacleQuery.addSegment(s[0], s3);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObstacleAvoidanceDebugData vod = null;
|
ObstacleAvoidanceDebugData vod = null;
|
||||||
|
@ -1180,14 +1180,14 @@ namespace DotRecast.Detour.Crowd
|
||||||
|
|
||||||
if (adaptive)
|
if (adaptive)
|
||||||
{
|
{
|
||||||
Tuple<int, float[]> nsnvel = m_obstacleQuery.sampleVelocityAdaptive(ag.npos, ag.option.radius,
|
var nsnvel = m_obstacleQuery.sampleVelocityAdaptive(ag.npos, ag.option.radius,
|
||||||
ag.desiredSpeed, ag.vel, ag.dvel, option, vod);
|
ag.desiredSpeed, ag.vel, ag.dvel, option, vod);
|
||||||
ns = nsnvel.Item1;
|
ns = nsnvel.Item1;
|
||||||
ag.nvel = nsnvel.Item2;
|
ag.nvel = nsnvel.Item2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Tuple<int, float[]> nsnvel = m_obstacleQuery.sampleVelocityGrid(ag.npos, ag.option.radius,
|
var nsnvel = m_obstacleQuery.sampleVelocityGrid(ag.npos, ag.option.radius,
|
||||||
ag.desiredSpeed, ag.vel, ag.dvel, option, vod);
|
ag.desiredSpeed, ag.vel, ag.dvel, option, vod);
|
||||||
ns = nsnvel.Item1;
|
ns = nsnvel.Item1;
|
||||||
ag.nvel = nsnvel.Item2;
|
ag.nvel = nsnvel.Item2;
|
||||||
|
@ -1198,7 +1198,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If not using velocity planning, new velocity is directly the desired velocity.
|
// If not using velocity planning, new velocity is directly the desired velocity.
|
||||||
vCopy(ag.nvel, ag.dvel);
|
vCopy(ref ag.nvel, ag.dvel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1234,7 +1234,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
vSet(ag.disp, 0, 0, 0);
|
vSet(ref ag.disp, 0, 0, 0);
|
||||||
|
|
||||||
float w = 0;
|
float w = 0;
|
||||||
|
|
||||||
|
@ -1242,7 +1242,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
{
|
{
|
||||||
CrowdAgent nei = ag.neis[j].agent;
|
CrowdAgent nei = ag.neis[j].agent;
|
||||||
long idx1 = nei.idx;
|
long idx1 = nei.idx;
|
||||||
float[] diff = vSub(ag.npos, nei.npos);
|
Vector3f diff = vSub(ag.npos, nei.npos);
|
||||||
diff[1] = 0;
|
diff[1] = 0;
|
||||||
|
|
||||||
float dist = vLenSqr(diff);
|
float dist = vLenSqr(diff);
|
||||||
|
@ -1258,11 +1258,11 @@ namespace DotRecast.Detour.Crowd
|
||||||
// Agents on top of each other, try to choose diverging separation directions.
|
// Agents on top of each other, try to choose diverging separation directions.
|
||||||
if (idx0 > idx1)
|
if (idx0 > idx1)
|
||||||
{
|
{
|
||||||
vSet(diff, -ag.dvel[2], 0, ag.dvel[0]);
|
vSet(ref diff, -ag.dvel[2], 0, ag.dvel[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vSet(diff, ag.dvel[2], 0, -ag.dvel[0]);
|
vSet(ref diff, ag.dvel[2], 0, -ag.dvel[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pen = 0.01f;
|
pen = 0.01f;
|
||||||
|
@ -1311,7 +1311,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
// Move along navmesh.
|
// Move along navmesh.
|
||||||
ag.corridor.movePosition(ag.npos, navQuery, m_filters[ag.option.queryFilterType]);
|
ag.corridor.movePosition(ag.npos, navQuery, m_filters[ag.option.queryFilterType]);
|
||||||
// Get valid constrained position back.
|
// Get valid constrained position back.
|
||||||
vCopy(ag.npos, ag.corridor.getPos());
|
vCopy(ref ag.npos, ag.corridor.getPos());
|
||||||
|
|
||||||
// If not using path, truncate the corridor to just one poly.
|
// If not using path, truncate the corridor to just one poly.
|
||||||
if (ag.targetState == CrowdAgent.MoveRequestState.DT_CROWDAGENT_TARGET_NONE
|
if (ag.targetState == CrowdAgent.MoveRequestState.DT_CROWDAGENT_TARGET_NONE
|
||||||
|
@ -1361,8 +1361,8 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update velocity.
|
// Update velocity.
|
||||||
vSet(ag.vel, 0, 0, 0);
|
vSet(ref ag.vel, 0, 0, 0);
|
||||||
vSet(ag.dvel, 0, 0, 0);
|
vSet(ref ag.dvel, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_telemetry.stop("updateOffMeshConnections");
|
_telemetry.stop("updateOffMeshConnections");
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
private class Segment
|
private class Segment
|
||||||
{
|
{
|
||||||
/** Segment start/end */
|
/** Segment start/end */
|
||||||
public float[] s = new float[6];
|
public Vector3f[] s = new Vector3f[2];
|
||||||
|
|
||||||
/** Distance for pruning. */
|
/** Distance for pruning. */
|
||||||
public float d;
|
public float d;
|
||||||
|
@ -59,7 +59,13 @@ namespace DotRecast.Detour.Crowd
|
||||||
{
|
{
|
||||||
// Insert neighbour based on the distance.
|
// Insert neighbour based on the distance.
|
||||||
Segment seg = new Segment();
|
Segment seg = new Segment();
|
||||||
Array.Copy(s, seg.s, 6);
|
seg.s[0].x = s[0];
|
||||||
|
seg.s[0].y = s[1];
|
||||||
|
seg.s[0].z = s[2];
|
||||||
|
seg.s[1].x = s[3];
|
||||||
|
seg.s[1].y = s[4];
|
||||||
|
seg.s[1].z = s[5];
|
||||||
|
//Array.Copy(s, seg.s, 6);
|
||||||
seg.d = dist;
|
seg.d = dist;
|
||||||
if (0 == m_segs.Count)
|
if (0 == m_segs.Count)
|
||||||
{
|
{
|
||||||
|
@ -159,7 +165,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
return m_center;
|
return m_center;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getSegment(int j)
|
public Vector3f[] getSegment(int j)
|
||||||
{
|
{
|
||||||
return m_segs[j].s;
|
return m_segs[j].s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
{
|
{
|
||||||
if (m_nsegments >= m_maxSegments)
|
if (m_nsegments >= m_maxSegments)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ObstacleSegment seg = m_segments[m_nsegments++];
|
ObstacleSegment seg = m_segments[m_nsegments++];
|
||||||
vCopy(ref seg.p, p);
|
vCopy(ref seg.p, p);
|
||||||
vCopy(ref seg.q, q);
|
vCopy(ref seg.q, q);
|
||||||
|
@ -194,7 +195,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
return m_segments[i];
|
return m_segments[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepare(Vector3f pos, float[] dvel)
|
private void prepare(Vector3f pos, Vector3f dvel)
|
||||||
{
|
{
|
||||||
// Prepare obstacles
|
// Prepare obstacles
|
||||||
for (int i = 0; i < m_ncircles; ++i)
|
for (int i = 0; i < m_ncircles; ++i)
|
||||||
|
@ -235,10 +236,10 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SweepCircleCircleResult sweepCircleCircle(float[] c0, float r0, float[] v, float[] c1, float r1)
|
SweepCircleCircleResult sweepCircleCircle(Vector3f c0, float r0, Vector3f v, Vector3f c1, float r1)
|
||||||
{
|
{
|
||||||
const float EPS = 0.0001f;
|
const float EPS = 0.0001f;
|
||||||
float[] s = vSub(c1, c0);
|
Vector3f s = vSub(c1, c0);
|
||||||
float r = r0 + r1;
|
float r = r0 + r1;
|
||||||
float c = vDot2D(s, s) - r * r;
|
float c = vDot2D(s, s) - r * r;
|
||||||
float a = vDot2D(v, v);
|
float a = vDot2D(v, v);
|
||||||
|
@ -255,10 +256,10 @@ namespace DotRecast.Detour.Crowd
|
||||||
return new SweepCircleCircleResult(true, (b - rd) * a, (b + rd) * a);
|
return new SweepCircleCircleResult(true, (b - rd) * a, (b + rd) * a);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple<bool, float> isectRaySeg(float[] ap, float[] u, float[] bp, float[] bq)
|
Tuple<bool, float> isectRaySeg(Vector3f ap, Vector3f u, Vector3f bp, Vector3f bq)
|
||||||
{
|
{
|
||||||
float[] v = vSub(bq, bp);
|
Vector3f v = vSub(bq, bp);
|
||||||
float[] w = vSub(ap, bp);
|
Vector3f w = vSub(ap, bp);
|
||||||
float d = vPerp2D(u, v);
|
float d = vPerp2D(u, v);
|
||||||
if (Math.Abs(d) < 1e-6f)
|
if (Math.Abs(d) < 1e-6f)
|
||||||
return Tuple.Create(false, 0f);
|
return Tuple.Create(false, 0f);
|
||||||
|
@ -282,7 +283,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
* @param minPenalty
|
* @param minPenalty
|
||||||
* threshold penalty for early out
|
* threshold penalty for early out
|
||||||
*/
|
*/
|
||||||
private float processSample(float[] vcand, float cs, float[] pos, float rad, float[] vel, float[] dvel,
|
private float processSample(Vector3f vcand, float cs, Vector3f pos, float rad, Vector3f vel, Vector3f dvel,
|
||||||
float minPenalty, ObstacleAvoidanceDebugData debug)
|
float minPenalty, ObstacleAvoidanceDebugData debug)
|
||||||
{
|
{
|
||||||
// penalty for straying away from the desired and current velocities
|
// penalty for straying away from the desired and current velocities
|
||||||
|
@ -306,7 +307,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
ObstacleCircle cir = m_circles[i];
|
ObstacleCircle cir = m_circles[i];
|
||||||
|
|
||||||
// RVO
|
// RVO
|
||||||
float[] vab = vScale(vcand, 2);
|
Vector3f vab = vScale(vcand, 2);
|
||||||
vab = vSub(vab, vel);
|
vab = vSub(vab, vel);
|
||||||
vab = vSub(vab, cir.vel);
|
vab = vSub(vab, cir.vel);
|
||||||
|
|
||||||
|
@ -346,7 +347,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
if (seg.touch)
|
if (seg.touch)
|
||||||
{
|
{
|
||||||
// Special case when the agent is very close to the segment.
|
// Special case when the agent is very close to the segment.
|
||||||
float[] sdir = vSub(seg.q, seg.p);
|
Vector3f sdir = vSub(seg.q, seg.p);
|
||||||
Vector3f snorm = new Vector3f();
|
Vector3f snorm = new Vector3f();
|
||||||
snorm[0] = -sdir[2];
|
snorm[0] = -sdir[2];
|
||||||
snorm[2] = sdir[0];
|
snorm[2] = sdir[0];
|
||||||
|
@ -391,7 +392,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
return penalty;
|
return penalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tuple<int, float[]> sampleVelocityGrid(float[] pos, float rad, float vmax, float[] vel, float[] dvel,
|
public Tuple<int, Vector3f> sampleVelocityGrid(Vector3f pos, float rad, float vmax, Vector3f vel, Vector3f dvel,
|
||||||
ObstacleAvoidanceParams option, ObstacleAvoidanceDebugData debug)
|
ObstacleAvoidanceParams option, ObstacleAvoidanceDebugData debug)
|
||||||
{
|
{
|
||||||
prepare(pos, dvel);
|
prepare(pos, dvel);
|
||||||
|
@ -401,7 +402,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
m_invVmax = vmax > 0 ? 1.0f / vmax : float.MaxValue;
|
m_invVmax = vmax > 0 ? 1.0f / vmax : float.MaxValue;
|
||||||
|
|
||||||
Vector3f nvel = new Vector3f();
|
Vector3f nvel = new Vector3f();
|
||||||
vSet(nvel, 0f, 0f, 0f);
|
vSet(ref nvel, 0f, 0f, 0f);
|
||||||
|
|
||||||
if (debug != null)
|
if (debug != null)
|
||||||
debug.reset();
|
debug.reset();
|
||||||
|
@ -419,7 +420,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
for (int x = 0; x < m_params.gridSize; ++x)
|
for (int x = 0; x < m_params.gridSize; ++x)
|
||||||
{
|
{
|
||||||
Vector3f vcand = new Vector3f();
|
Vector3f vcand = new Vector3f();
|
||||||
vSet(vcand, cvx + x * cs - half, 0f, cvz + y * cs - half);
|
vSet(ref vcand, cvx + x * cs - half, 0f, cvz + y * cs - half);
|
||||||
|
|
||||||
if (sqr(vcand[0]) + sqr(vcand[2]) > sqr(vmax + cs / 2))
|
if (sqr(vcand[0]) + sqr(vcand[2]) > sqr(vmax + cs / 2))
|
||||||
continue;
|
continue;
|
||||||
|
@ -429,7 +430,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
if (penalty < minPenalty)
|
if (penalty < minPenalty)
|
||||||
{
|
{
|
||||||
minPenalty = penalty;
|
minPenalty = penalty;
|
||||||
vCopy(nvel, vcand);
|
vCopy(ref nvel, vcand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,7 +450,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
|
|
||||||
// vector normalization that ignores the y-component.
|
// vector normalization that ignores the y-component.
|
||||||
float[] dtRotate2D(float[] v, float ang)
|
Vector3f dtRotate2D(float[] v, float ang)
|
||||||
{
|
{
|
||||||
Vector3f dest = new Vector3f();
|
Vector3f dest = new Vector3f();
|
||||||
float c = (float)Math.Cos(ang);
|
float c = (float)Math.Cos(ang);
|
||||||
|
@ -462,8 +463,8 @@ namespace DotRecast.Detour.Crowd
|
||||||
|
|
||||||
static readonly float DT_PI = 3.14159265f;
|
static readonly float DT_PI = 3.14159265f;
|
||||||
|
|
||||||
public Tuple<int, float[]> sampleVelocityAdaptive(float[] pos, float rad, float vmax, float[] vel,
|
public Tuple<int, Vector3f> sampleVelocityAdaptive(Vector3f pos, float rad, float vmax, Vector3f vel,
|
||||||
float[] dvel, ObstacleAvoidanceParams option, ObstacleAvoidanceDebugData debug)
|
Vector3f dvel, ObstacleAvoidanceParams option, ObstacleAvoidanceDebugData debug)
|
||||||
{
|
{
|
||||||
prepare(pos, dvel);
|
prepare(pos, dvel);
|
||||||
m_params = option;
|
m_params = option;
|
||||||
|
@ -472,7 +473,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
m_invVmax = vmax > 0 ? 1.0f / vmax : float.MaxValue;
|
m_invVmax = vmax > 0 ? 1.0f / vmax : float.MaxValue;
|
||||||
|
|
||||||
Vector3f nvel = new Vector3f();
|
Vector3f nvel = new Vector3f();
|
||||||
vSet(nvel, 0f, 0f, 0f);
|
vSet(ref nvel, 0f, 0f, 0f);
|
||||||
|
|
||||||
if (debug != null)
|
if (debug != null)
|
||||||
debug.reset();
|
debug.reset();
|
||||||
|
@ -495,7 +496,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
float[] ddir = new float[6];
|
float[] ddir = new float[6];
|
||||||
vCopy(ddir, dvel);
|
vCopy(ddir, dvel);
|
||||||
dtNormalize2D(ddir);
|
dtNormalize2D(ddir);
|
||||||
float[] rotated = dtRotate2D(ddir, da * 0.5f); // rotated by da/2
|
Vector3f rotated = dtRotate2D(ddir, da * 0.5f); // rotated by da/2
|
||||||
ddir[3] = rotated[0];
|
ddir[3] = rotated[0];
|
||||||
ddir[4] = rotated[1];
|
ddir[4] = rotated[1];
|
||||||
ddir[5] = rotated[2];
|
ddir[5] = rotated[2];
|
||||||
|
@ -539,18 +540,18 @@ namespace DotRecast.Detour.Crowd
|
||||||
// Start sampling.
|
// Start sampling.
|
||||||
float cr = vmax * (1.0f - m_params.velBias);
|
float cr = vmax * (1.0f - m_params.velBias);
|
||||||
Vector3f res = new Vector3f();
|
Vector3f res = new Vector3f();
|
||||||
vSet(res, dvel[0] * m_params.velBias, 0, dvel[2] * m_params.velBias);
|
vSet(ref res, dvel[0] * m_params.velBias, 0, dvel[2] * m_params.velBias);
|
||||||
int ns = 0;
|
int ns = 0;
|
||||||
for (int k = 0; k < depth; ++k)
|
for (int k = 0; k < depth; ++k)
|
||||||
{
|
{
|
||||||
float minPenalty = float.MaxValue;
|
float minPenalty = float.MaxValue;
|
||||||
Vector3f bvel = new Vector3f();
|
Vector3f bvel = new Vector3f();
|
||||||
vSet(bvel, 0, 0, 0);
|
vSet(ref bvel, 0, 0, 0);
|
||||||
|
|
||||||
for (int i = 0; i < npat; ++i)
|
for (int i = 0; i < npat; ++i)
|
||||||
{
|
{
|
||||||
Vector3f vcand = new Vector3f();
|
Vector3f vcand = new Vector3f();
|
||||||
vSet(vcand, res[0] + pat[i * 2 + 0] * cr, 0f, res[2] + pat[i * 2 + 1] * cr);
|
vSet(ref vcand, res[0] + pat[i * 2 + 0] * cr, 0f, res[2] + pat[i * 2 + 1] * cr);
|
||||||
if (sqr(vcand[0]) + sqr(vcand[2]) > sqr(vmax + 0.001f))
|
if (sqr(vcand[0]) + sqr(vcand[2]) > sqr(vmax + 0.001f))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -559,16 +560,16 @@ namespace DotRecast.Detour.Crowd
|
||||||
if (penalty < minPenalty)
|
if (penalty < minPenalty)
|
||||||
{
|
{
|
||||||
minPenalty = penalty;
|
minPenalty = penalty;
|
||||||
vCopy(bvel, vcand);
|
vCopy(ref bvel, vcand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vCopy(res, bvel);
|
vCopy(ref res, bvel);
|
||||||
|
|
||||||
cr *= 0.5f;
|
cr *= 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
vCopy(nvel, res);
|
vCopy(ref nvel, res);
|
||||||
|
|
||||||
return Tuple.Create(ns, nvel);
|
return Tuple.Create(ns, nvel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,11 +460,10 @@ namespace DotRecast.Detour.Crowd
|
||||||
* @param filter
|
* @param filter
|
||||||
* The filter to apply to the operation.
|
* The filter to apply to the operation.
|
||||||
*/
|
*/
|
||||||
public bool moveTargetPosition(float[] npos, NavMeshQuery navquery, QueryFilter filter)
|
public bool moveTargetPosition(Vector3f npos, NavMeshQuery navquery, QueryFilter filter)
|
||||||
{
|
{
|
||||||
// Move along navmesh and update new position.
|
// Move along navmesh and update new position.
|
||||||
Result<MoveAlongSurfaceResult> masResult = navquery.moveAlongSurface(m_path[m_path.Count - 1], m_target,
|
Result<MoveAlongSurfaceResult> masResult = navquery.moveAlongSurface(m_path[m_path.Count - 1], m_target, npos, filter);
|
||||||
npos, filter);
|
|
||||||
if (masResult.succeeded())
|
if (masResult.succeeded())
|
||||||
{
|
{
|
||||||
m_path = mergeCorridorEndMoved(m_path, masResult.result.getVisited());
|
m_path = mergeCorridorEndMoved(m_path, masResult.result.getVisited());
|
||||||
|
@ -474,7 +473,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
* float h = m_target[1]; navquery->getPolyHeight(m_path[m_npath-1],
|
* float h = m_target[1]; navquery->getPolyHeight(m_path[m_npath-1],
|
||||||
* result, &h); result[1] = h;
|
* result, &h); result[1] = h;
|
||||||
*/
|
*/
|
||||||
vCopy(m_target, masResult.result.getResultPos());
|
vCopy(ref m_target, masResult.result.getResultPos());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,7 +527,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
// The first polyref is bad, use current safe values.
|
// The first polyref is bad, use current safe values.
|
||||||
vCopy(m_pos, safePos);
|
vCopy(ref m_pos, safePos);
|
||||||
m_path.Clear();
|
m_path.Clear();
|
||||||
m_path.Add(safeRef);
|
m_path.Add(safeRef);
|
||||||
}
|
}
|
||||||
|
@ -539,10 +538,10 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp target pos to last poly
|
// Clamp target pos to last poly
|
||||||
Result<float[]> result = navquery.closestPointOnPolyBoundary(m_path[m_path.Count - 1], m_target);
|
var result = navquery.closestPointOnPolyBoundary(m_path[m_path.Count - 1], m_target);
|
||||||
if (result.succeeded())
|
if (result.succeeded())
|
||||||
{
|
{
|
||||||
vCopy(m_target, result.result);
|
vCopy(ref m_target, result.result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,7 +578,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
*
|
*
|
||||||
* @return The current position within the corridor.
|
* @return The current position within the corridor.
|
||||||
*/
|
*/
|
||||||
public float[] getPos()
|
public Vector3f getPos()
|
||||||
{
|
{
|
||||||
return m_pos;
|
return m_pos;
|
||||||
}
|
}
|
||||||
|
@ -589,7 +588,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
*
|
*
|
||||||
* @return The current target within the corridor.
|
* @return The current target within the corridor.
|
||||||
*/
|
*/
|
||||||
public float[] getTarget()
|
public Vector3f getTarget()
|
||||||
{
|
{
|
||||||
return m_target;
|
return m_target;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Crowd
|
namespace DotRecast.Detour.Crowd
|
||||||
{
|
{
|
||||||
|
@ -76,7 +77,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathQueryResult request(long startRef, long endRef, float[] startPos, float[] endPos, QueryFilter filter)
|
public PathQueryResult request(long startRef, long endRef, Vector3f startPos, Vector3f endPos, QueryFilter filter)
|
||||||
{
|
{
|
||||||
if (queue.Count >= config.pathQueueSize)
|
if (queue.Count >= config.pathQueueSize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace DotRecast.Detour.Crowd.Tracking
|
||||||
normalizeArray(m_tpen, m_nsamples);
|
normalizeArray(m_tpen, m_nsamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSample(float[] vel, float ssize, float pen, float vpen, float vcpen, float spen, float tpen)
|
public void addSample(Vector3f vel, float ssize, float pen, float vpen, float vcpen, float spen, float tpen)
|
||||||
{
|
{
|
||||||
if (m_nsamples >= m_maxSamples)
|
if (m_nsamples >= m_maxSamples)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -17,17 +17,18 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using DotRecast.Core;
|
||||||
using DotRecast.Recast;
|
using DotRecast.Recast;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Dynamic.Colliders
|
namespace DotRecast.Detour.Dynamic.Colliders
|
||||||
{
|
{
|
||||||
public class CapsuleCollider : AbstractCollider
|
public class CapsuleCollider : AbstractCollider
|
||||||
{
|
{
|
||||||
private readonly float[] start;
|
private readonly Vector3f start;
|
||||||
private readonly float[] end;
|
private readonly Vector3f end;
|
||||||
private readonly float radius;
|
private readonly float radius;
|
||||||
|
|
||||||
public CapsuleCollider(float[] start, float[] end, float radius, int area, float flagMergeThreshold) :
|
public CapsuleCollider(Vector3f start, Vector3f end, float radius, int area, float flagMergeThreshold) :
|
||||||
base(area, flagMergeThreshold, bounds(start, end, radius))
|
base(area, flagMergeThreshold, bounds(start, end, radius))
|
||||||
{
|
{
|
||||||
this.start = start;
|
this.start = start;
|
||||||
|
@ -41,7 +42,7 @@ namespace DotRecast.Detour.Dynamic.Colliders
|
||||||
telemetry);
|
telemetry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] bounds(float[] start, float[] end, float radius)
|
private static float[] bounds(Vector3f start, Vector3f end, float radius)
|
||||||
{
|
{
|
||||||
return new float[]
|
return new float[]
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,17 +17,18 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using DotRecast.Core;
|
||||||
using DotRecast.Recast;
|
using DotRecast.Recast;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Dynamic.Colliders
|
namespace DotRecast.Detour.Dynamic.Colliders
|
||||||
{
|
{
|
||||||
public class CylinderCollider : AbstractCollider
|
public class CylinderCollider : AbstractCollider
|
||||||
{
|
{
|
||||||
private readonly float[] start;
|
private readonly Vector3f start;
|
||||||
private readonly float[] end;
|
private readonly Vector3f end;
|
||||||
private readonly float radius;
|
private readonly float radius;
|
||||||
|
|
||||||
public CylinderCollider(float[] start, float[] end, float radius, int area, float flagMergeThreshold) :
|
public CylinderCollider(Vector3f start, Vector3f end, float radius, int area, float flagMergeThreshold) :
|
||||||
base(area, flagMergeThreshold, bounds(start, end, radius))
|
base(area, flagMergeThreshold, bounds(start, end, radius))
|
||||||
{
|
{
|
||||||
this.start = start;
|
this.start = start;
|
||||||
|
@ -41,7 +42,7 @@ namespace DotRecast.Detour.Dynamic.Colliders
|
||||||
telemetry);
|
telemetry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] bounds(float[] start, float[] end, float radius)
|
private static float[] bounds(Vector3f start, Vector3f end, float radius)
|
||||||
{
|
{
|
||||||
return new float[]
|
return new float[]
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,16 +17,17 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using DotRecast.Core;
|
||||||
using DotRecast.Recast;
|
using DotRecast.Recast;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Dynamic.Colliders
|
namespace DotRecast.Detour.Dynamic.Colliders
|
||||||
{
|
{
|
||||||
public class SphereCollider : AbstractCollider
|
public class SphereCollider : AbstractCollider
|
||||||
{
|
{
|
||||||
private readonly float[] center;
|
private readonly Vector3f center;
|
||||||
private readonly float radius;
|
private readonly float radius;
|
||||||
|
|
||||||
public SphereCollider(float[] center, float radius, int area, float flagMergeThreshold) :
|
public SphereCollider(Vector3f center, float radius, int area, float flagMergeThreshold) :
|
||||||
base(area, flagMergeThreshold, bounds(center, radius))
|
base(area, flagMergeThreshold, bounds(center, radius))
|
||||||
{
|
{
|
||||||
this.center = center;
|
this.center = center;
|
||||||
|
@ -39,11 +40,15 @@ namespace DotRecast.Detour.Dynamic.Colliders
|
||||||
telemetry);
|
telemetry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] bounds(float[] center, float radius)
|
private static float[] bounds(Vector3f center, float radius)
|
||||||
{
|
{
|
||||||
return new float[]
|
return new float[]
|
||||||
{
|
{
|
||||||
center[0] - radius, center[1] - radius, center[2] - radius, center[0] + radius, center[1] + radius,
|
center[0] - radius,
|
||||||
|
center[1] - radius,
|
||||||
|
center[2] - radius,
|
||||||
|
center[0] + radius,
|
||||||
|
center[1] + radius,
|
||||||
center[2] + radius
|
center[2] + radius
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,6 +189,12 @@ public class DebugDraw
|
||||||
{
|
{
|
||||||
getOpenGlDraw().vertex(pos, color);
|
getOpenGlDraw().vertex(pos, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void vertex(Vector3f pos, int color)
|
||||||
|
{
|
||||||
|
getOpenGlDraw().vertex(pos, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void vertex(float x, float y, float z, int color)
|
public void vertex(float x, float y, float z, int color)
|
||||||
{
|
{
|
||||||
|
@ -254,12 +260,12 @@ public class DebugDraw
|
||||||
float dz = z1 - z0;
|
float dz = z1 - z0;
|
||||||
float len = (float)Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
float len = (float)Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
Vector3f prev = new Vector3f();
|
Vector3f prev = new Vector3f();
|
||||||
evalArc(x0, y0, z0, dx, dy, dz, len * h, PAD, prev);
|
evalArc(x0, y0, z0, dx, dy, dz, len * h, PAD, ref prev);
|
||||||
for (int i = 1; i <= NUM_ARC_PTS; ++i)
|
for (int i = 1; i <= NUM_ARC_PTS; ++i)
|
||||||
{
|
{
|
||||||
float u = PAD + i * ARC_PTS_SCALE;
|
float u = PAD + i * ARC_PTS_SCALE;
|
||||||
Vector3f pt = new Vector3f();
|
Vector3f pt = new Vector3f();
|
||||||
evalArc(x0, y0, z0, dx, dy, dz, len * h, u, pt);
|
evalArc(x0, y0, z0, dx, dy, dz, len * h, u, ref pt);
|
||||||
vertex(prev[0], prev[1], prev[2], col);
|
vertex(prev[0], prev[1], prev[2], col);
|
||||||
vertex(pt[0], pt[1], pt[2], col);
|
vertex(pt[0], pt[1], pt[2], col);
|
||||||
prev[0] = pt[0];
|
prev[0] = pt[0];
|
||||||
|
@ -270,22 +276,24 @@ public class DebugDraw
|
||||||
// End arrows
|
// End arrows
|
||||||
if (as0 > 0.001f)
|
if (as0 > 0.001f)
|
||||||
{
|
{
|
||||||
Vector3f p = new Vector3f(), q = new float[3];
|
Vector3f p = new Vector3f();
|
||||||
evalArc(x0, y0, z0, dx, dy, dz, len * h, PAD, p);
|
Vector3f q = new Vector3f();
|
||||||
evalArc(x0, y0, z0, dx, dy, dz, len * h, PAD + 0.05f, q);
|
evalArc(x0, y0, z0, dx, dy, dz, len * h, PAD, ref p);
|
||||||
|
evalArc(x0, y0, z0, dx, dy, dz, len * h, PAD + 0.05f, ref q);
|
||||||
appendArrowHead(p, q, as0, col);
|
appendArrowHead(p, q, as0, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (as1 > 0.001f)
|
if (as1 > 0.001f)
|
||||||
{
|
{
|
||||||
Vector3f p = new Vector3f(), q = new float[3];
|
Vector3f p = new Vector3f();
|
||||||
evalArc(x0, y0, z0, dx, dy, dz, len * h, 1 - PAD, p);
|
Vector3f q = new Vector3f();
|
||||||
evalArc(x0, y0, z0, dx, dy, dz, len * h, 1 - (PAD + 0.05f), q);
|
evalArc(x0, y0, z0, dx, dy, dz, len * h, 1 - PAD, ref p);
|
||||||
|
evalArc(x0, y0, z0, dx, dy, dz, len * h, 1 - (PAD + 0.05f), ref q);
|
||||||
appendArrowHead(p, q, as1, col);
|
appendArrowHead(p, q, as1, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void evalArc(float x0, float y0, float z0, float dx, float dy, float dz, float h, float u, float[] res)
|
private void evalArc(float x0, float y0, float z0, float dx, float dy, float dz, float h, float u, ref Vector3f res)
|
||||||
{
|
{
|
||||||
res[0] = x0 + dx * u;
|
res[0] = x0 + dx * u;
|
||||||
res[1] = y0 + dy * u + h * (1 - (u * 2 - 1) * (u * 2 - 1));
|
res[1] = y0 + dy * u + h * (1 - (u * 2 - 1) * (u * 2 - 1));
|
||||||
|
@ -376,15 +384,15 @@ public class DebugDraw
|
||||||
vertex(x1, y1, z1, col);
|
vertex(x1, y1, z1, col);
|
||||||
|
|
||||||
// End arrows
|
// End arrows
|
||||||
float[] p = new float[] { x0, y0, z0 };
|
Vector3f p = Vector3f.Of(x0, y0, z0);
|
||||||
float[] q = new float[] { x1, y1, z1 };
|
Vector3f q = Vector3f.Of(x1, y1, z1);
|
||||||
if (as0 > 0.001f)
|
if (as0 > 0.001f)
|
||||||
appendArrowHead(p, q, as0, col);
|
appendArrowHead(p, q, as0, col);
|
||||||
if (as1 > 0.001f)
|
if (as1 > 0.001f)
|
||||||
appendArrowHead(q, p, as1, col);
|
appendArrowHead(q, p, as1, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendArrowHead(float[] p, float[] q, float s, int col)
|
void appendArrowHead(Vector3f p, Vector3f q, float s, int col)
|
||||||
{
|
{
|
||||||
float eps = 0.001f;
|
float eps = 0.001f;
|
||||||
if (vdistSqr(p, q) < eps * eps)
|
if (vdistSqr(p, q) < eps * eps)
|
||||||
|
@ -392,12 +400,14 @@ public class DebugDraw
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f ax = new Vector3f(), ay = { 0, 1, 0 }, az = new float[3];
|
Vector3f ax = new Vector3f();
|
||||||
vsub(az, q, p);
|
Vector3f ay = Vector3f.Of(0, 1, 0);
|
||||||
vnormalize(az);
|
Vector3f az = new Vector3f();
|
||||||
vcross(ax, ay, az);
|
vsub(ref az, q, p);
|
||||||
vcross(ay, az, ax);
|
vnormalize(ref az);
|
||||||
vnormalize(ay);
|
vcross(ref ax, ay, az);
|
||||||
|
vcross(ref ay, az, ax);
|
||||||
|
vnormalize(ref ay);
|
||||||
|
|
||||||
vertex(p, col);
|
vertex(p, col);
|
||||||
// vertex(p[0]+az[0]*s+ay[0]*s/2, p[1]+az[1]*s+ay[1]*s/2, p[2]+az[2]*s+ay[2]*s/2, col);
|
// vertex(p[0]+az[0]*s+ay[0]*s/2, p[1]+az[1]*s+ay[1]*s/2, p[2]+az[2]*s+ay[2]*s/2, col);
|
||||||
|
@ -408,14 +418,14 @@ public class DebugDraw
|
||||||
vertex(p[0] + az[0] * s - ax[0] * s / 3, p[1] + az[1] * s - ax[1] * s / 3, p[2] + az[2] * s - ax[2] * s / 3, col);
|
vertex(p[0] + az[0] * s - ax[0] * s / 3, p[1] + az[1] * s - ax[1] * s / 3, p[2] + az[2] * s - ax[2] * s / 3, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void vcross(float[] dest, float[] v1, float[] v2)
|
public void vcross(ref Vector3f dest, Vector3f v1, Vector3f v2)
|
||||||
{
|
{
|
||||||
dest[0] = v1[1] * v2[2] - v1[2] * v2[1];
|
dest[0] = v1[1] * v2[2] - v1[2] * v2[1];
|
||||||
dest[1] = v1[2] * v2[0] - v1[0] * v2[2];
|
dest[1] = v1[2] * v2[0] - v1[0] * v2[2];
|
||||||
dest[2] = v1[0] * v2[1] - v1[1] * v2[0];
|
dest[2] = v1[0] * v2[1] - v1[1] * v2[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void vnormalize(float[] v)
|
public void vnormalize(ref Vector3f v)
|
||||||
{
|
{
|
||||||
float d = (float)(1.0f / Math.Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]));
|
float d = (float)(1.0f / Math.Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]));
|
||||||
v[0] *= d;
|
v[0] *= d;
|
||||||
|
@ -423,14 +433,14 @@ public class DebugDraw
|
||||||
v[2] *= d;
|
v[2] *= d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void vsub(float[] dest, float[] v1, float[] v2)
|
public void vsub(ref Vector3f dest, Vector3f v1, Vector3f v2)
|
||||||
{
|
{
|
||||||
dest[0] = v1[0] - v2[0];
|
dest[0] = v1[0] - v2[0];
|
||||||
dest[1] = v1[1] - v2[1];
|
dest[1] = v1[1] - v2[1];
|
||||||
dest[2] = v1[2] - v2[2];
|
dest[2] = v1[2] - v2[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
public float vdistSqr(float[] v1, float[] v2)
|
public float vdistSqr(Vector3f v1, Vector3f v2)
|
||||||
{
|
{
|
||||||
float x = v1[0] - v2[0];
|
float x = v1[0] - v2[0];
|
||||||
float y = v1[1] - v2[1];
|
float y = v1[1] - v2[1];
|
||||||
|
@ -578,7 +588,7 @@ public class DebugDraw
|
||||||
return _projectionMatrix;
|
return _projectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] viewMatrix(float[] cameraPos, float[] cameraEulers)
|
public float[] viewMatrix(Vector3f cameraPos, float[] cameraEulers)
|
||||||
{
|
{
|
||||||
float[] rx = GLU.build_4x4_rotation_matrix(cameraEulers[0], 1, 0, 0);
|
float[] rx = GLU.build_4x4_rotation_matrix(cameraEulers[0], 1, 0, 0);
|
||||||
float[] ry = GLU.build_4x4_rotation_matrix(cameraEulers[1], 0, 1, 0);
|
float[] ry = GLU.build_4x4_rotation_matrix(cameraEulers[1], 0, 1, 0);
|
||||||
|
@ -637,11 +647,6 @@ public class DebugDraw
|
||||||
return new float[] { px, py, pz, pw };
|
return new float[] { px, py, pz, pw };
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool frustumTest(float[] bmin, float[] bmax)
|
|
||||||
{
|
|
||||||
return frustumTest(new float[] { bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2] });
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool frustumTest(float[] bounds)
|
public bool frustumTest(float[] bounds)
|
||||||
{
|
{
|
||||||
foreach (float[] plane in frustumPlanes)
|
foreach (float[] plane in frustumPlanes)
|
||||||
|
@ -693,4 +698,9 @@ public class DebugDraw
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool frustumTest(Vector3f bmin, Vector3f bmax)
|
||||||
|
{
|
||||||
|
return frustumTest(new float[] { bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2] });
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using DotRecast.Core;
|
||||||
using Silk.NET.OpenGL;
|
using Silk.NET.OpenGL;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Draw;
|
namespace DotRecast.Recast.Demo.Draw;
|
||||||
|
@ -323,6 +324,12 @@ public class ModernOpenGLDraw : OpenGLDraw
|
||||||
{
|
{
|
||||||
vertices.Add(new OpenGLVertex(pos, color));
|
vertices.Add(new OpenGLVertex(pos, color));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void vertex(Vector3f pos, int color)
|
||||||
|
{
|
||||||
|
vertices.Add(new OpenGLVertex(pos, color));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void vertex(float[] pos, int color, float[] uv)
|
public void vertex(float[] pos, int color, float[] uv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using DotRecast.Core;
|
||||||
using Silk.NET.OpenGL;
|
using Silk.NET.OpenGL;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Draw;
|
namespace DotRecast.Recast.Demo.Draw;
|
||||||
|
@ -15,6 +16,7 @@ public interface OpenGLDraw
|
||||||
void vertex(float x, float y, float z, int color);
|
void vertex(float x, float y, float z, int color);
|
||||||
|
|
||||||
void vertex(float[] pos, int color);
|
void vertex(float[] pos, int color);
|
||||||
|
void vertex(Vector3f pos, int color);
|
||||||
|
|
||||||
void vertex(float[] pos, int color, float[] uv);
|
void vertex(float[] pos, int color, float[] uv);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,12 @@ public struct OpenGLVertex
|
||||||
this(pos[0], pos[1], pos[2], 0f, 0f, color)
|
this(pos[0], pos[1], pos[2], 0f, 0f, color)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OpenGLVertex(Vector3f pos, int color) :
|
||||||
|
this(pos[0], pos[1], pos[2], 0f, 0f, color)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public OpenGLVertex(float x, float y, float z, int color) :
|
public OpenGLVertex(float x, float y, float z, int color) :
|
||||||
this(x, y, z, 0f, 0f, color)
|
this(x, y, z, 0f, 0f, color)
|
||||||
|
|
|
@ -20,6 +20,7 @@ freely, subject to the following restrictions:
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core;
|
||||||
using DotRecast.Detour;
|
using DotRecast.Detour;
|
||||||
using DotRecast.Recast.Demo.Builder;
|
using DotRecast.Recast.Demo.Builder;
|
||||||
using Silk.NET.OpenGL;
|
using Silk.NET.OpenGL;
|
||||||
|
@ -529,7 +530,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
{
|
{
|
||||||
float alpha = 1f;
|
float alpha = 1f;
|
||||||
|
|
||||||
float[] orig = cset.bmin;
|
Vector3f orig = cset.bmin;
|
||||||
float cs = cset.cs;
|
float cs = cset.cs;
|
||||||
float ch = cset.ch;
|
float ch = cset.ch;
|
||||||
|
|
||||||
|
@ -540,7 +541,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
for (int i = 0; i < cset.conts.Count; ++i)
|
for (int i = 0; i < cset.conts.Count; ++i)
|
||||||
{
|
{
|
||||||
Contour cont = cset.conts[i];
|
Contour cont = cset.conts[i];
|
||||||
float[] pos = getContourCenter(cont, orig, cs, ch);
|
Vector3f pos = getContourCenter(cont, orig, cs, ch);
|
||||||
for (int j = 0; j < cont.nverts; ++j)
|
for (int j = 0; j < cont.nverts; ++j)
|
||||||
{
|
{
|
||||||
int v = j * 4;
|
int v = j * 4;
|
||||||
|
@ -552,7 +553,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
Contour cont2 = findContourFromSet(cset, (short)cont.verts[v + 3]);
|
Contour cont2 = findContourFromSet(cset, (short)cont.verts[v + 3]);
|
||||||
if (cont2 != null)
|
if (cont2 != null)
|
||||||
{
|
{
|
||||||
float[] pos2 = getContourCenter(cont2, orig, cs, ch);
|
Vector3f pos2 = getContourCenter(cont2, orig, cs, ch);
|
||||||
appendArc(pos[0], pos[1], pos[2], pos2[0], pos2[1], pos2[2], 0.25f, 0.6f, 0.6f, color);
|
appendArc(pos[0], pos[1], pos[2], pos2[0], pos2[1], pos2[2], 0.25f, 0.6f, 0.6f, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,14 +569,14 @@ public class RecastDebugDraw : DebugDraw
|
||||||
{
|
{
|
||||||
Contour cont = cset.conts[i];
|
Contour cont = cset.conts[i];
|
||||||
int col = duDarkenCol(duIntToCol(cont.reg, a));
|
int col = duDarkenCol(duIntToCol(cont.reg, a));
|
||||||
float[] pos = getContourCenter(cont, orig, cs, ch);
|
Vector3f pos = getContourCenter(cont, orig, cs, ch);
|
||||||
vertex(pos, col);
|
vertex(pos, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
end();
|
end();
|
||||||
}
|
}
|
||||||
|
|
||||||
private float[] getContourCenter(Contour cont, float[] orig, float cs, float ch)
|
private Vector3f getContourCenter(Contour cont, Vector3f orig, float cs, float ch)
|
||||||
{
|
{
|
||||||
Vector3f center = new Vector3f();
|
Vector3f center = new Vector3f();
|
||||||
center[0] = 0;
|
center[0] = 0;
|
||||||
|
@ -619,7 +620,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
|
|
||||||
public void debugDrawRawContours(ContourSet cset, float alpha)
|
public void debugDrawRawContours(ContourSet cset, float alpha)
|
||||||
{
|
{
|
||||||
float[] orig = cset.bmin;
|
Vector3f orig = cset.bmin;
|
||||||
float cs = cset.cs;
|
float cs = cset.cs;
|
||||||
float ch = cset.ch;
|
float ch = cset.ch;
|
||||||
|
|
||||||
|
@ -695,7 +696,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
public void debugDrawContours(ContourSet cset)
|
public void debugDrawContours(ContourSet cset)
|
||||||
{
|
{
|
||||||
float alpha = 1f;
|
float alpha = 1f;
|
||||||
float[] orig = cset.bmin;
|
Vector3f orig = cset.bmin;
|
||||||
float cs = cset.cs;
|
float cs = cset.cs;
|
||||||
float ch = cset.ch;
|
float ch = cset.ch;
|
||||||
|
|
||||||
|
@ -777,7 +778,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float[] orig = hf.bmin;
|
Vector3f orig = hf.bmin;
|
||||||
float cs = hf.cs;
|
float cs = hf.cs;
|
||||||
float ch = hf.ch;
|
float ch = hf.ch;
|
||||||
|
|
||||||
|
@ -809,7 +810,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
|
|
||||||
public void debugDrawHeightfieldWalkable(Heightfield hf)
|
public void debugDrawHeightfieldWalkable(Heightfield hf)
|
||||||
{
|
{
|
||||||
float[] orig = hf.bmin;
|
Vector3f orig = hf.bmin;
|
||||||
float cs = hf.cs;
|
float cs = hf.cs;
|
||||||
float ch = hf.ch;
|
float ch = hf.ch;
|
||||||
|
|
||||||
|
@ -942,7 +943,7 @@ public class RecastDebugDraw : DebugDraw
|
||||||
int nvp = mesh.nvp;
|
int nvp = mesh.nvp;
|
||||||
float cs = mesh.cs;
|
float cs = mesh.cs;
|
||||||
float ch = mesh.ch;
|
float ch = mesh.ch;
|
||||||
float[] orig = mesh.bmin;
|
Vector3f orig = mesh.bmin;
|
||||||
|
|
||||||
begin(DebugDrawPrimitives.TRIS);
|
begin(DebugDrawPrimitives.TRIS);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using DotRecast.Core;
|
||||||
using DotRecast.Recast.Geom;
|
using DotRecast.Recast.Geom;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Geom;
|
namespace DotRecast.Recast.Demo.Geom;
|
||||||
|
@ -31,8 +32,8 @@ public class DemoInputGeomProvider : InputGeomProvider
|
||||||
public readonly float[] vertices;
|
public readonly float[] vertices;
|
||||||
public readonly int[] faces;
|
public readonly int[] faces;
|
||||||
public readonly float[] normals;
|
public readonly float[] normals;
|
||||||
private readonly float[] bmin;
|
private readonly Vector3f bmin;
|
||||||
private readonly float[] bmax;
|
private readonly Vector3f bmax;
|
||||||
private readonly List<ConvexVolume> _convexVolumes = new();
|
private readonly List<ConvexVolume> _convexVolumes = new();
|
||||||
private readonly List<DemoOffMeshConnection> offMeshConnections = new();
|
private readonly List<DemoOffMeshConnection> offMeshConnections = new();
|
||||||
private readonly ChunkyTriMesh chunkyTriMesh;
|
private readonly ChunkyTriMesh chunkyTriMesh;
|
||||||
|
@ -100,7 +101,8 @@ public class DemoInputGeomProvider : InputGeomProvider
|
||||||
int v0 = faces[i] * 3;
|
int v0 = faces[i] * 3;
|
||||||
int v1 = faces[i + 1] * 3;
|
int v1 = faces[i + 1] * 3;
|
||||||
int v2 = faces[i + 2] * 3;
|
int v2 = faces[i + 2] * 3;
|
||||||
Vector3f e0 = new Vector3f(), e1 = new float[3];
|
Vector3f e0 = new Vector3f();
|
||||||
|
Vector3f e1 = new Vector3f();
|
||||||
for (int j = 0; j < 3; ++j)
|
for (int j = 0; j < 3; ++j)
|
||||||
{
|
{
|
||||||
e0[j] = vertices[v1 + j] - vertices[v0 + j];
|
e0[j] = vertices[v1 + j] - vertices[v0 + j];
|
||||||
|
@ -147,7 +149,7 @@ public class DemoInputGeomProvider : InputGeomProvider
|
||||||
offMeshConnections.RemoveAll(filter); // TODO : 확인 필요
|
offMeshConnections.RemoveAll(filter); // TODO : 확인 필요
|
||||||
}
|
}
|
||||||
|
|
||||||
public float? raycastMesh(float[] src, float[] dst)
|
public float? raycastMesh(float[] src, Vector3f dst)
|
||||||
{
|
{
|
||||||
// Prune hit ray.
|
// Prune hit ray.
|
||||||
float[] btminmax = Intersections.intersectSegmentAABB(src, dst, bmin, bmax);
|
float[] btminmax = Intersections.intersectSegmentAABB(src, dst, bmin, bmax);
|
||||||
|
|
|
@ -78,7 +78,7 @@ public class Intersections
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float[] intersectSegmentAABB(float[] sp, float[] sq, float[] amin, float[] amax)
|
public static float[] intersectSegmentAABB(float[] sp, Vector3f sq, Vector3f amin, Vector3f amax)
|
||||||
{
|
{
|
||||||
float EPS = 1e-6f;
|
float EPS = 1e-6f;
|
||||||
|
|
||||||
|
|
|
@ -91,10 +91,10 @@ public class RecastDemo
|
||||||
private float scrollZoom;
|
private float scrollZoom;
|
||||||
private readonly float[] origMousePos = new float[2];
|
private readonly float[] origMousePos = new float[2];
|
||||||
private readonly float[] origCameraEulers = new float[2];
|
private readonly float[] origCameraEulers = new float[2];
|
||||||
private readonly Vector3f origCameraPos = new Vector3f();
|
private Vector3f origCameraPos = new Vector3f();
|
||||||
|
|
||||||
private readonly float[] cameraEulers = { 45, -45 };
|
private readonly float[] cameraEulers = { 45, -45 };
|
||||||
private readonly float[] cameraPos = { 0, 0, 0 };
|
private Vector3f cameraPos = Vector3f.Of(0, 0, 0);
|
||||||
|
|
||||||
private readonly Vector3f rayStart = new Vector3f();
|
private readonly Vector3f rayStart = new Vector3f();
|
||||||
private readonly Vector3f rayEnd = new Vector3f();
|
private readonly Vector3f rayEnd = new Vector3f();
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class ConvexVolumeTool : Tool
|
||||||
sample = m_sample;
|
sample = m_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void handleClick(float[] s, float[] p, bool shift)
|
public override void handleClick(float[] s, Vector3f p, bool shift)
|
||||||
{
|
{
|
||||||
DemoInputGeomProvider geom = sample.getInputGeom();
|
DemoInputGeomProvider geom = sample.getInputGeom();
|
||||||
if (geom == null)
|
if (geom == null)
|
||||||
|
@ -80,9 +80,7 @@ public class ConvexVolumeTool : Tool
|
||||||
// Create
|
// Create
|
||||||
|
|
||||||
// If clicked on that last pt, create the shape.
|
// If clicked on that last pt, create the shape.
|
||||||
if (pts.Count > 0 && RecastMath.vDistSqr(p,
|
if (pts.Count > 0 && RecastMath.vDistSqr(p, Vector3f.Of(pts[pts.Count - 3], pts[pts.Count - 2], pts[pts.Count - 1]), 0) < 0.2f * 0.2f)
|
||||||
new float[] { pts[pts.Count - 3], pts[pts.Count - 2], pts[pts.Count - 1] },
|
|
||||||
0) < 0.2f * 0.2f)
|
|
||||||
{
|
{
|
||||||
if (hull.Count > 2)
|
if (hull.Count > 2)
|
||||||
{
|
{
|
||||||
|
@ -218,7 +216,7 @@ public class ConvexVolumeTool : Tool
|
||||||
{
|
{
|
||||||
hull.Clear();
|
hull.Clear();
|
||||||
pts.Clear();
|
pts.Clear();
|
||||||
|
|
||||||
DemoInputGeomProvider geom = sample.getInputGeom();
|
DemoInputGeomProvider geom = sample.getInputGeom();
|
||||||
if (geom != null)
|
if (geom != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -102,23 +102,23 @@ public class CrowdProfilingTool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float[] pos = null;
|
Vector3f? pos = null;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case AgentType.MOB:
|
case AgentType.MOB:
|
||||||
pos = getMobPosition(navquery, filter, pos);
|
pos = getMobPosition(navquery, filter);
|
||||||
break;
|
break;
|
||||||
case AgentType.VILLAGER:
|
case AgentType.VILLAGER:
|
||||||
pos = getVillagerPosition(navquery, filter, pos);
|
pos = getVillagerPosition(navquery, filter);
|
||||||
break;
|
break;
|
||||||
case AgentType.TRAVELLER:
|
case AgentType.TRAVELLER:
|
||||||
pos = getVillagerPosition(navquery, filter, pos);
|
pos = getVillagerPosition(navquery, filter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos != null)
|
if (pos != null)
|
||||||
{
|
{
|
||||||
addAgent(pos, type);
|
addAgent(pos.Value, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,18 +145,18 @@ public class CrowdProfilingTool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float[] getMobPosition(NavMeshQuery navquery, QueryFilter filter, float[] pos)
|
private Vector3f? getMobPosition(NavMeshQuery navquery, QueryFilter filter)
|
||||||
{
|
{
|
||||||
Result<FindRandomPointResult> result = navquery.findRandomPoint(filter, rnd);
|
Result<FindRandomPointResult> result = navquery.findRandomPoint(filter, rnd);
|
||||||
if (result.succeeded())
|
if (result.succeeded())
|
||||||
{
|
{
|
||||||
pos = result.result.getRandomPt();
|
return result.result.getRandomPt();
|
||||||
}
|
}
|
||||||
|
|
||||||
return pos;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float[] getVillagerPosition(NavMeshQuery navquery, QueryFilter filter, float[] pos)
|
private Vector3f? getVillagerPosition(NavMeshQuery navquery, QueryFilter filter)
|
||||||
{
|
{
|
||||||
if (0 < zones.Count)
|
if (0 < zones.Count)
|
||||||
{
|
{
|
||||||
|
@ -165,11 +165,11 @@ public class CrowdProfilingTool
|
||||||
zones[zone].getRandomPt(), zoneRadius, filter, rnd);
|
zones[zone].getRandomPt(), zoneRadius, filter, rnd);
|
||||||
if (result.succeeded())
|
if (result.succeeded())
|
||||||
{
|
{
|
||||||
pos = result.result.getRandomPt();
|
return result.result.getRandomPt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pos;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createZones()
|
private void createZones()
|
||||||
|
@ -403,7 +403,7 @@ public class CrowdProfilingTool
|
||||||
dd.depthMask(true);
|
dd.depthMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CrowdAgent addAgent(float[] p, AgentType type)
|
private CrowdAgent addAgent(Vector3f p, AgentType type)
|
||||||
{
|
{
|
||||||
CrowdAgentParams ap = agentParamsSupplier.Invoke();
|
CrowdAgentParams ap = agentParamsSupplier.Invoke();
|
||||||
ap.userData = new AgentData(type, p);
|
ap.userData = new AgentData(type, p);
|
||||||
|
@ -422,10 +422,10 @@ public class CrowdProfilingTool
|
||||||
public readonly AgentType type;
|
public readonly AgentType type;
|
||||||
public readonly Vector3f home = new Vector3f();
|
public readonly Vector3f home = new Vector3f();
|
||||||
|
|
||||||
public AgentData(AgentType type, float[] home)
|
public AgentData(AgentType type, Vector3f home)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
RecastVectors.copy(this.home, home);
|
RecastVectors.copy(ref this.home, home);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using DotRecast.Core;
|
||||||
using Silk.NET.Windowing;
|
using Silk.NET.Windowing;
|
||||||
using DotRecast.Detour;
|
using DotRecast.Detour;
|
||||||
using DotRecast.Detour.Crowd;
|
using DotRecast.Detour.Crowd;
|
||||||
|
@ -79,7 +80,7 @@ public class CrowdTool : Tool
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly Dictionary<long, AgentTrail> m_trails = new();
|
private readonly Dictionary<long, AgentTrail> m_trails = new();
|
||||||
private float[] m_targetPos;
|
private Vector3f m_targetPos;
|
||||||
private long m_targetRef;
|
private long m_targetRef;
|
||||||
private CrowdToolMode m_mode = CrowdToolMode.CREATE;
|
private CrowdToolMode m_mode = CrowdToolMode.CREATE;
|
||||||
private int m_modeIdx = CrowdToolMode.CREATE.Idx;
|
private int m_modeIdx = CrowdToolMode.CREATE.Idx;
|
||||||
|
@ -146,7 +147,7 @@ public class CrowdTool : Tool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void handleClick(float[] s, float[] p, bool shift)
|
public override void handleClick(float[] s, Vector3f p, bool shift)
|
||||||
{
|
{
|
||||||
if (m_mode == CrowdToolMode.PROFILING)
|
if (m_mode == CrowdToolMode.PROFILING)
|
||||||
{
|
{
|
||||||
|
@ -192,7 +193,7 @@ public class CrowdTool : Tool
|
||||||
if (nav != null && navquery != null)
|
if (nav != null && navquery != null)
|
||||||
{
|
{
|
||||||
QueryFilter filter = new DefaultQueryFilter();
|
QueryFilter filter = new DefaultQueryFilter();
|
||||||
float[] halfExtents = crowd.getQueryExtents();
|
Vector3f halfExtents = crowd.getQueryExtents();
|
||||||
Result<FindNearestPolyResult> result = navquery.findNearestPoly(p, halfExtents, filter);
|
Result<FindNearestPolyResult> result = navquery.findNearestPoly(p, halfExtents, filter);
|
||||||
long refs = result.result.getNearestRef();
|
long refs = result.result.getNearestRef();
|
||||||
if (refs != 0)
|
if (refs != 0)
|
||||||
|
@ -216,7 +217,7 @@ public class CrowdTool : Tool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAgent(float[] p)
|
private void addAgent(Vector3f p)
|
||||||
{
|
{
|
||||||
CrowdAgentParams ap = getAgentParams();
|
CrowdAgentParams ap = getAgentParams();
|
||||||
CrowdAgent ag = crowd.addAgent(p, ap);
|
CrowdAgent ag = crowd.addAgent(p, ap);
|
||||||
|
@ -258,15 +259,16 @@ public class CrowdTool : Tool
|
||||||
return ap;
|
return ap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CrowdAgent hitTestAgents(float[] s, float[] p)
|
private CrowdAgent hitTestAgents(float[] s, Vector3f p)
|
||||||
{
|
{
|
||||||
CrowdAgent isel = null;
|
CrowdAgent isel = null;
|
||||||
float tsel = float.MaxValue;
|
float tsel = float.MaxValue;
|
||||||
|
|
||||||
foreach (CrowdAgent ag in crowd.getActiveAgents())
|
foreach (CrowdAgent ag in crowd.getActiveAgents())
|
||||||
{
|
{
|
||||||
Vector3f bmin = new Vector3f(), bmax = new float[3];
|
Vector3f bmin = new Vector3f();
|
||||||
getAgentBounds(ag, bmin, bmax);
|
Vector3f bmax = new Vector3f();
|
||||||
|
getAgentBounds(ag, ref bmin, ref bmax);
|
||||||
float[] isect = Intersections.intersectSegmentAABB(s, p, bmin, bmax);
|
float[] isect = Intersections.intersectSegmentAABB(s, p, bmin, bmax);
|
||||||
if (null != isect)
|
if (null != isect)
|
||||||
{
|
{
|
||||||
|
@ -282,9 +284,9 @@ public class CrowdTool : Tool
|
||||||
return isel;
|
return isel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getAgentBounds(CrowdAgent ag, float[] bmin, float[] bmax)
|
private void getAgentBounds(CrowdAgent ag, ref Vector3f bmin, ref Vector3f bmax)
|
||||||
{
|
{
|
||||||
float[] p = ag.npos;
|
Vector3f p = ag.npos;
|
||||||
float r = ag.option.radius;
|
float r = ag.option.radius;
|
||||||
float h = ag.option.height;
|
float h = ag.option.height;
|
||||||
bmin[0] = p[0] - r;
|
bmin[0] = p[0] - r;
|
||||||
|
@ -295,7 +297,7 @@ public class CrowdTool : Tool
|
||||||
bmax[2] = p[2] + r;
|
bmax[2] = p[2] + r;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMoveTarget(float[] p, bool adjust)
|
private void setMoveTarget(Vector3f p, bool adjust)
|
||||||
{
|
{
|
||||||
if (sample == null || crowd == null)
|
if (sample == null || crowd == null)
|
||||||
return;
|
return;
|
||||||
|
@ -303,14 +305,14 @@ public class CrowdTool : Tool
|
||||||
// Find nearest point on navmesh and set move request to that location.
|
// Find nearest point on navmesh and set move request to that location.
|
||||||
NavMeshQuery navquery = sample.getNavMeshQuery();
|
NavMeshQuery navquery = sample.getNavMeshQuery();
|
||||||
QueryFilter filter = crowd.getFilter(0);
|
QueryFilter filter = crowd.getFilter(0);
|
||||||
float[] halfExtents = crowd.getQueryExtents();
|
Vector3f halfExtents = crowd.getQueryExtents();
|
||||||
|
|
||||||
if (adjust)
|
if (adjust)
|
||||||
{
|
{
|
||||||
// Request velocity
|
// Request velocity
|
||||||
if (m_agentDebug.agent != null)
|
if (m_agentDebug.agent != null)
|
||||||
{
|
{
|
||||||
float[] vel = calcVel(m_agentDebug.agent.npos, p, m_agentDebug.agent.option.maxSpeed);
|
float[] vel = calcVel(ref m_agentDebug.agent.npos, p, m_agentDebug.agent.option.maxSpeed);
|
||||||
crowd.requestMoveVelocity(m_agentDebug.agent, vel);
|
crowd.requestMoveVelocity(m_agentDebug.agent, vel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -341,11 +343,11 @@ public class CrowdTool : Tool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float[] calcVel(float[] pos, float[] tgt, float speed)
|
private Vector3f calcVel(Vector3f pos, Vector3f tgt, float speed)
|
||||||
{
|
{
|
||||||
float[] vel = vSub(tgt, pos);
|
Vector3f vel = vSub(tgt, pos);
|
||||||
vel[1] = 0.0f;
|
vel[1] = 0.0f;
|
||||||
vNormalize(vel);
|
vNormalize(ref vel);
|
||||||
return vScale(vel, speed);
|
return vScale(vel, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,9 +519,9 @@ public class CrowdTool : Tool
|
||||||
for (int j = 0; j < ag.boundary.getSegmentCount(); ++j)
|
for (int j = 0; j < ag.boundary.getSegmentCount(); ++j)
|
||||||
{
|
{
|
||||||
int col = duRGBA(192, 0, 128, 192);
|
int col = duRGBA(192, 0, 128, 192);
|
||||||
float[] s = ag.boundary.getSegment(j);
|
Vector3f[] s = ag.boundary.getSegment(j);
|
||||||
float[] s0 = new float[] { s[0], s[1], s[2] };
|
Vector3f s0 = s[0];
|
||||||
float[] s3 = new float[] { s[3], s[4], s[5] };
|
Vector3f s3 = s[1];
|
||||||
if (triArea2D(pos, s0, s3) < 0.0f)
|
if (triArea2D(pos, s0, s3) < 0.0f)
|
||||||
col = duDarkenCol(col);
|
col = duDarkenCol(col);
|
||||||
|
|
||||||
|
@ -562,7 +564,7 @@ public class CrowdTool : Tool
|
||||||
foreach (CrowdAgent ag in crowd.getActiveAgents())
|
foreach (CrowdAgent ag in crowd.getActiveAgents())
|
||||||
{
|
{
|
||||||
float radius = ag.option.radius;
|
float radius = ag.option.radius;
|
||||||
float[] pos = ag.npos;
|
Vector3f pos = ag.npos;
|
||||||
|
|
||||||
int col = duRGBA(0, 0, 0, 32);
|
int col = duRGBA(0, 0, 0, 32);
|
||||||
if (m_agentDebug.agent == ag)
|
if (m_agentDebug.agent == ag)
|
||||||
|
@ -575,7 +577,7 @@ public class CrowdTool : Tool
|
||||||
{
|
{
|
||||||
float height = ag.option.height;
|
float height = ag.option.height;
|
||||||
float radius = ag.option.radius;
|
float radius = ag.option.radius;
|
||||||
float[] pos = ag.npos;
|
Vector3f pos = ag.npos;
|
||||||
|
|
||||||
int col = duRGBA(220, 220, 220, 128);
|
int col = duRGBA(220, 220, 220, 128);
|
||||||
if (ag.targetState == CrowdAgent.MoveRequestState.DT_CROWDAGENT_TARGET_REQUESTING
|
if (ag.targetState == CrowdAgent.MoveRequestState.DT_CROWDAGENT_TARGET_REQUESTING
|
||||||
|
@ -611,7 +613,7 @@ public class CrowdTool : Tool
|
||||||
dd.begin(QUADS);
|
dd.begin(QUADS);
|
||||||
for (int j = 0; j < vod.getSampleCount(); ++j)
|
for (int j = 0; j < vod.getSampleCount(); ++j)
|
||||||
{
|
{
|
||||||
float[] p = vod.getSampleVelocity(j);
|
Vector3f p = vod.getSampleVelocity(j);
|
||||||
float sr = vod.getSampleSize(j);
|
float sr = vod.getSampleSize(j);
|
||||||
float pen = vod.getSamplePenalty(j);
|
float pen = vod.getSamplePenalty(j);
|
||||||
float pen2 = vod.getSamplePreferredSidePenalty(j);
|
float pen2 = vod.getSamplePreferredSidePenalty(j);
|
||||||
|
@ -632,9 +634,9 @@ public class CrowdTool : Tool
|
||||||
{
|
{
|
||||||
float radius = ag.option.radius;
|
float radius = ag.option.radius;
|
||||||
float height = ag.option.height;
|
float height = ag.option.height;
|
||||||
float[] pos = ag.npos;
|
Vector3f pos = ag.npos;
|
||||||
float[] vel = ag.vel;
|
Vector3f vel = ag.vel;
|
||||||
float[] dvel = ag.dvel;
|
Vector3f dvel = ag.dvel;
|
||||||
|
|
||||||
int col = duRGBA(220, 220, 220, 192);
|
int col = duRGBA(220, 220, 220, 192);
|
||||||
if (ag.targetState == CrowdAgent.MoveRequestState.DT_CROWDAGENT_TARGET_REQUESTING
|
if (ag.targetState == CrowdAgent.MoveRequestState.DT_CROWDAGENT_TARGET_REQUESTING
|
||||||
|
|
|
@ -134,7 +134,7 @@ public class DynamicUpdateTool : Tool
|
||||||
this.sample = sample;
|
this.sample = sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void handleClick(float[] s, float[] p, bool shift)
|
public override void handleClick(float[] s, Vector3f p, bool shift)
|
||||||
{
|
{
|
||||||
if (mode == DynamicUpdateToolMode.COLLIDERS)
|
if (mode == DynamicUpdateToolMode.COLLIDERS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class JumpLinkBuilderTool : Tool
|
||||||
annotationBuilder = null;
|
annotationBuilder = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void handleClick(float[] s, float[] p, bool shift)
|
public override void handleClick(float[] s, Vector3f p, bool shift)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class OffMeshConnectionTool : Tool
|
||||||
sample = m_sample;
|
sample = m_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void handleClick(float[] s, float[] p, bool shift)
|
public override void handleClick(float[] s, Vector3f p, bool shift)
|
||||||
{
|
{
|
||||||
DemoInputGeomProvider geom = sample.getInputGeom();
|
DemoInputGeomProvider geom = sample.getInputGeom();
|
||||||
if (geom == null)
|
if (geom == null)
|
||||||
|
|
|
@ -20,6 +20,7 @@ freely, subject to the following restrictions:
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core;
|
||||||
using DotRecast.Detour;
|
using DotRecast.Detour;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Tools;
|
namespace DotRecast.Recast.Demo.Tools;
|
||||||
|
@ -29,7 +30,7 @@ public static class PathUtils
|
||||||
private const int MAX_STEER_POINTS = 3;
|
private const int MAX_STEER_POINTS = 3;
|
||||||
|
|
||||||
|
|
||||||
public static SteerTarget getSteerTarget(NavMeshQuery navQuery, float[] startPos, float[] endPos,
|
public static SteerTarget getSteerTarget(NavMeshQuery navQuery, Vector3f startPos, Vector3f endPos,
|
||||||
float minTargetDist, List<long> path)
|
float minTargetDist, List<long> path)
|
||||||
{
|
{
|
||||||
// Find steer target.
|
// Find steer target.
|
||||||
|
@ -75,7 +76,7 @@ public static class PathUtils
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool inRange(float[] v1, float[] v2, float r, float h)
|
public static bool inRange(Vector3f v1, Vector3f v2, float r, float h)
|
||||||
{
|
{
|
||||||
float dx = v2[0] - v1[0];
|
float dx = v2[0] - v1[0];
|
||||||
float dy = v2[1] - v1[1];
|
float dy = v2[1] - v1[1];
|
||||||
|
|
|
@ -18,19 +18,20 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using DotRecast.Core;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Demo.Tools;
|
namespace DotRecast.Recast.Demo.Tools;
|
||||||
|
|
||||||
public class PolyUtils
|
public class PolyUtils
|
||||||
{
|
{
|
||||||
public static bool pointInPoly(float[] verts, float[] p)
|
public static bool pointInPoly(float[] verts, Vector3f p)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
bool c = false;
|
bool c = false;
|
||||||
for (i = 0, j = verts.Length / 3 - 1; i < verts.Length / 3; j = i++)
|
for (i = 0, j = verts.Length / 3 - 1; i < verts.Length / 3; j = i++)
|
||||||
{
|
{
|
||||||
float[] vi = new float[] { verts[i * 3], verts[i * 3 + 1], verts[i * 3 + 2] };
|
Vector3f vi = Vector3f.Of(verts[i * 3], verts[i * 3 + 1], verts[i * 3 + 2]);
|
||||||
float[] vj = new float[] { verts[j * 3], verts[j * 3 + 1], verts[j * 3 + 2] };
|
Vector3f vj = Vector3f.Of(verts[j * 3], verts[j * 3 + 1], verts[j * 3 + 2]);
|
||||||
if (((vi[2] > p[2]) != (vj[2] > p[2]))
|
if (((vi[2] > p[2]) != (vj[2] > p[2]))
|
||||||
&& (p[0] < (vj[0] - vi[0]) * (p[2] - vi[2]) / (vj[2] - vi[2]) + vi[0]))
|
&& (p[0] < (vj[0] - vi[0]) * (p[2] - vi[2]) / (vj[2] - vi[2]) + vi[0]))
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,10 +22,10 @@ public class TestNavmeshTool : Tool
|
||||||
private TestNavmeshToolMode m_toolMode => TestNavmeshToolMode.Values[m_toolModeIdx];
|
private TestNavmeshToolMode m_toolMode => TestNavmeshToolMode.Values[m_toolModeIdx];
|
||||||
private bool m_sposSet;
|
private bool m_sposSet;
|
||||||
private bool m_eposSet;
|
private bool m_eposSet;
|
||||||
private float[] m_spos;
|
private Vector3f m_spos;
|
||||||
private float[] m_epos;
|
private Vector3f m_epos;
|
||||||
private readonly DefaultQueryFilter m_filter;
|
private readonly DefaultQueryFilter m_filter;
|
||||||
private readonly float[] m_polyPickExt = new float[] { 2, 4, 2 };
|
private readonly Vector3f m_polyPickExt = Vector3f.Of(2, 4, 2);
|
||||||
private long m_startRef;
|
private long m_startRef;
|
||||||
private long m_endRef;
|
private long m_endRef;
|
||||||
private float[] m_hitPos;
|
private float[] m_hitPos;
|
||||||
|
@ -38,7 +38,7 @@ public class TestNavmeshTool : Tool
|
||||||
private List<long> m_parent;
|
private List<long> m_parent;
|
||||||
private float m_neighbourhoodRadius;
|
private float m_neighbourhoodRadius;
|
||||||
private readonly float[] m_queryPoly = new float[12];
|
private readonly float[] m_queryPoly = new float[12];
|
||||||
private List<float[]> m_smoothPath;
|
private List<Vector3f> m_smoothPath;
|
||||||
private Status m_pathFindStatus = Status.FAILURE;
|
private Status m_pathFindStatus = Status.FAILURE;
|
||||||
private bool enableRaycast = true;
|
private bool enableRaycast = true;
|
||||||
private readonly List<float[]> randomPoints = new();
|
private readonly List<float[]> randomPoints = new();
|
||||||
|
@ -58,17 +58,17 @@ public class TestNavmeshTool : Tool
|
||||||
this.m_sample = m_sample;
|
this.m_sample = m_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void handleClick(float[] s, float[] p, bool shift)
|
public override void handleClick(float[] s, Vector3f p, bool shift)
|
||||||
{
|
{
|
||||||
if (shift)
|
if (shift)
|
||||||
{
|
{
|
||||||
m_sposSet = true;
|
m_sposSet = true;
|
||||||
m_spos = ArrayUtils.CopyOf(p, p.Length);
|
m_spos = p;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_eposSet = true;
|
m_eposSet = true;
|
||||||
m_epos = ArrayUtils.CopyOf(p, p.Length);
|
m_epos = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
recalc();
|
recalc();
|
||||||
|
@ -94,7 +94,7 @@ public class TestNavmeshTool : Tool
|
||||||
ImGui.RadioButton(TestNavmeshToolMode.FIND_LOCAL_NEIGHBOURHOOD.Label, ref m_toolModeIdx, TestNavmeshToolMode.FIND_LOCAL_NEIGHBOURHOOD.Idx);
|
ImGui.RadioButton(TestNavmeshToolMode.FIND_LOCAL_NEIGHBOURHOOD.Label, ref m_toolModeIdx, TestNavmeshToolMode.FIND_LOCAL_NEIGHBOURHOOD.Idx);
|
||||||
ImGui.RadioButton(TestNavmeshToolMode.RANDOM_POINTS_IN_CIRCLE.Label, ref m_toolModeIdx, TestNavmeshToolMode.RANDOM_POINTS_IN_CIRCLE.Idx);
|
ImGui.RadioButton(TestNavmeshToolMode.RANDOM_POINTS_IN_CIRCLE.Label, ref m_toolModeIdx, TestNavmeshToolMode.RANDOM_POINTS_IN_CIRCLE.Idx);
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
||||||
// selecting mode
|
// selecting mode
|
||||||
ImGui.Text(m_toolMode.Label);
|
ImGui.Text(m_toolMode.Label);
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
@ -120,7 +120,7 @@ public class TestNavmeshTool : Tool
|
||||||
|
|
||||||
ImGui.Text("Common");
|
ImGui.Text("Common");
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
ImGui.Text("Include Flags");
|
ImGui.Text("Include Flags");
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGui.CheckboxFlags("Walk", ref includeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_WALK);
|
ImGui.CheckboxFlags("Walk", ref includeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_WALK);
|
||||||
|
@ -128,9 +128,9 @@ public class TestNavmeshTool : Tool
|
||||||
ImGui.CheckboxFlags("Door", ref includeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_DOOR);
|
ImGui.CheckboxFlags("Door", ref includeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_DOOR);
|
||||||
ImGui.CheckboxFlags("Jump", ref includeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP);
|
ImGui.CheckboxFlags("Jump", ref includeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP);
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
||||||
m_filter.setIncludeFlags(includeFlags);
|
m_filter.setIncludeFlags(includeFlags);
|
||||||
|
|
||||||
ImGui.Text("Exclude Flags");
|
ImGui.Text("Exclude Flags");
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGui.CheckboxFlags("Walk", ref excludeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_WALK);
|
ImGui.CheckboxFlags("Walk", ref excludeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_WALK);
|
||||||
|
@ -138,15 +138,16 @@ public class TestNavmeshTool : Tool
|
||||||
ImGui.CheckboxFlags("Door", ref excludeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_DOOR);
|
ImGui.CheckboxFlags("Door", ref excludeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_DOOR);
|
||||||
ImGui.CheckboxFlags("Jump", ref excludeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP);
|
ImGui.CheckboxFlags("Jump", ref excludeFlags, SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP);
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
||||||
m_filter.setExcludeFlags(excludeFlags);
|
m_filter.setExcludeFlags(excludeFlags);
|
||||||
|
|
||||||
bool previousEnableRaycast = enableRaycast;
|
bool previousEnableRaycast = enableRaycast;
|
||||||
ImGui.Checkbox("Raycast shortcuts", ref enableRaycast);
|
ImGui.Checkbox("Raycast shortcuts", ref enableRaycast);
|
||||||
|
|
||||||
if (previousToolMode != m_toolMode || m_straightPathOptions != previousStraightPathOptions
|
if (previousToolMode != m_toolMode || m_straightPathOptions != previousStraightPathOptions
|
||||||
|| previousIncludeFlags != includeFlags || previousExcludeFlags != excludeFlags
|
|| previousIncludeFlags != includeFlags || previousExcludeFlags != excludeFlags
|
||||||
|| previousEnableRaycast != enableRaycast || previousConstrainByCircle != constrainByCircle) {
|
|| previousEnableRaycast != enableRaycast || previousConstrainByCircle != constrainByCircle)
|
||||||
|
{
|
||||||
recalc();
|
recalc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,9 +194,8 @@ public class TestNavmeshTool : Tool
|
||||||
{
|
{
|
||||||
List<long> polys = new(m_polys);
|
List<long> polys = new(m_polys);
|
||||||
// Iterate over the path to find smooth path on the detail mesh surface.
|
// Iterate over the path to find smooth path on the detail mesh surface.
|
||||||
float[] iterPos = m_navQuery.closestPointOnPoly(m_startRef, m_spos).result.getClosest();
|
Vector3f iterPos = m_navQuery.closestPointOnPoly(m_startRef, m_spos).result.getClosest();
|
||||||
float[] targetPos = m_navQuery.closestPointOnPoly(polys[polys.Count - 1], m_epos).result
|
Vector3f targetPos = m_navQuery.closestPointOnPoly(polys[polys.Count - 1], m_epos).result.getClosest();
|
||||||
.getClosest();
|
|
||||||
|
|
||||||
float STEP_SIZE = 0.5f;
|
float STEP_SIZE = 0.5f;
|
||||||
float SLOP = 0.01f;
|
float SLOP = 0.01f;
|
||||||
|
|
|
@ -18,6 +18,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using DotRecast.Core;
|
||||||
using DotRecast.Recast.Demo.Draw;
|
using DotRecast.Recast.Demo.Draw;
|
||||||
using Silk.NET.Windowing;
|
using Silk.NET.Windowing;
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ public abstract class Tool
|
||||||
{
|
{
|
||||||
public abstract void setSample(Sample m_sample);
|
public abstract void setSample(Sample m_sample);
|
||||||
|
|
||||||
public abstract void handleClick(float[] s, float[] p, bool shift);
|
public abstract void handleClick(float[] s, Vector3f p, bool shift);
|
||||||
|
|
||||||
public abstract void handleRender(NavMeshRenderer renderer);
|
public abstract void handleRender(NavMeshRenderer renderer);
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace DotRecast.Recast
|
||||||
private const float EPSILON = 0.00001f;
|
private const float EPSILON = 0.00001f;
|
||||||
private static readonly int[] BOX_EDGES = new[] { 0, 1, 0, 2, 0, 4, 1, 3, 1, 5, 2, 3, 2, 6, 3, 7, 4, 5, 4, 6, 5, 7, 6, 7 };
|
private static readonly int[] BOX_EDGES = new[] { 0, 1, 0, 2, 0, 4, 1, 3, 1, 5, 2, 3, 2, 6, 3, 7, 4, 5, 4, 6, 5, 7, 6, 7 };
|
||||||
|
|
||||||
public static void rasterizeSphere(Heightfield hf, float[] center, float radius, int area, int flagMergeThr, Telemetry ctx)
|
public static void rasterizeSphere(Heightfield hf, Vector3f center, float radius, int area, int flagMergeThr, Telemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.startTimer("RASTERIZE_SPHERE");
|
ctx.startTimer("RASTERIZE_SPHERE");
|
||||||
float[] bounds =
|
float[] bounds =
|
||||||
|
@ -43,7 +43,7 @@ namespace DotRecast.Recast
|
||||||
ctx.stopTimer("RASTERIZE_SPHERE");
|
ctx.stopTimer("RASTERIZE_SPHERE");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void rasterizeCapsule(Heightfield hf, float[] start, float[] end, float radius, int area, int flagMergeThr,
|
public static void rasterizeCapsule(Heightfield hf, Vector3f start, Vector3f end, float radius, int area, int flagMergeThr,
|
||||||
Telemetry ctx)
|
Telemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.startTimer("RASTERIZE_CAPSULE");
|
ctx.startTimer("RASTERIZE_CAPSULE");
|
||||||
|
@ -53,13 +53,13 @@ namespace DotRecast.Recast
|
||||||
Math.Min(start[2], end[2]) - radius, Math.Max(start[0], end[0]) + radius, Math.Max(start[1], end[1]) + radius,
|
Math.Min(start[2], end[2]) - radius, Math.Max(start[0], end[0]) + radius, Math.Max(start[1], end[1]) + radius,
|
||||||
Math.Max(start[2], end[2]) + radius
|
Math.Max(start[2], end[2]) + radius
|
||||||
};
|
};
|
||||||
float[] axis = { end[0] - start[0], end[1] - start[1], end[2] - start[2] };
|
Vector3f axis = Vector3f.Of(end[0] - start[0], end[1] - start[1], end[2] - start[2]);
|
||||||
rasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
rasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
||||||
rectangle => intersectCapsule(rectangle, start, end, axis, radius * radius));
|
rectangle => intersectCapsule(rectangle, start, end, axis, radius * radius));
|
||||||
ctx.stopTimer("RASTERIZE_CAPSULE");
|
ctx.stopTimer("RASTERIZE_CAPSULE");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void rasterizeCylinder(Heightfield hf, float[] start, float[] end, float radius, int area, int flagMergeThr,
|
public static void rasterizeCylinder(Heightfield hf, Vector3f start, Vector3f end, float radius, int area, int flagMergeThr,
|
||||||
Telemetry ctx)
|
Telemetry ctx)
|
||||||
{
|
{
|
||||||
ctx.startTimer("RASTERIZE_CYLINDER");
|
ctx.startTimer("RASTERIZE_CYLINDER");
|
||||||
|
@ -69,7 +69,7 @@ namespace DotRecast.Recast
|
||||||
Math.Min(start[2], end[2]) - radius, Math.Max(start[0], end[0]) + radius, Math.Max(start[1], end[1]) + radius,
|
Math.Min(start[2], end[2]) - radius, Math.Max(start[0], end[0]) + radius, Math.Max(start[1], end[1]) + radius,
|
||||||
Math.Max(start[2], end[2]) + radius
|
Math.Max(start[2], end[2]) + radius
|
||||||
};
|
};
|
||||||
float[] axis = { end[0] - start[0], end[1] - start[1], end[2] - start[2] };
|
Vector3f axis = Vector3f.Of(end[0] - start[0], end[1] - start[1], end[2] - start[2]);
|
||||||
rasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
rasterizationFilledShape(hf, bounds, area, flagMergeThr,
|
||||||
rectangle => intersectCylinder(rectangle, start, end, axis, radius * radius));
|
rectangle => intersectCylinder(rectangle, start, end, axis, radius * radius));
|
||||||
ctx.stopTimer("RASTERIZE_CYLINDER");
|
ctx.stopTimer("RASTERIZE_CYLINDER");
|
||||||
|
@ -239,7 +239,7 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] intersectSphere(float[] rectangle, float[] center, float radiusSqr)
|
private static float[] intersectSphere(float[] rectangle, Vector3f center, float radiusSqr)
|
||||||
{
|
{
|
||||||
float x = Math.Max(rectangle[0], Math.Min(center[0], rectangle[2]));
|
float x = Math.Max(rectangle[0], Math.Min(center[0], rectangle[2]));
|
||||||
float y = rectangle[4];
|
float y = rectangle[4];
|
||||||
|
@ -274,7 +274,7 @@ namespace DotRecast.Recast
|
||||||
return new float[] { y + tmin, y + tmax };
|
return new float[] { y + tmin, y + tmax };
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] intersectCapsule(float[] rectangle, float[] start, float[] end, float[] axis, float radiusSqr)
|
private static float[] intersectCapsule(float[] rectangle, Vector3f start, Vector3f end, Vector3f axis, float radiusSqr)
|
||||||
{
|
{
|
||||||
float[] s = mergeIntersections(intersectSphere(rectangle, start, radiusSqr), intersectSphere(rectangle, end, radiusSqr));
|
float[] s = mergeIntersections(intersectSphere(rectangle, start, radiusSqr), intersectSphere(rectangle, end, radiusSqr));
|
||||||
float axisLen2dSqr = axis[0] * axis[0] + axis[2] * axis[2];
|
float axisLen2dSqr = axis[0] * axis[0] + axis[2] * axis[2];
|
||||||
|
@ -286,7 +286,7 @@ namespace DotRecast.Recast
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] intersectCylinder(float[] rectangle, float[] start, float[] end, float[] axis, float radiusSqr)
|
private static float[] intersectCylinder(float[] rectangle, Vector3f start, Vector3f end, Vector3f axis, float radiusSqr)
|
||||||
{
|
{
|
||||||
float[] s = mergeIntersections(
|
float[] s = mergeIntersections(
|
||||||
rayCylinderIntersection(new float[]
|
rayCylinderIntersection(new float[]
|
||||||
|
@ -315,7 +315,7 @@ namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
float x = rectangle[(i + 1) & 2];
|
float x = rectangle[(i + 1) & 2];
|
||||||
float z = rectangle[(i & 2) + 1];
|
float z = rectangle[(i & 2) + 1];
|
||||||
float[] a = { x, rectangle[4], z };
|
Vector3f a = Vector3f.Of(x, rectangle[4], z);
|
||||||
float dotAxisA = dot(axis, a);
|
float dotAxisA = dot(axis, a);
|
||||||
float t = (ds - dotAxisA) / axis[1];
|
float t = (ds - dotAxisA) / axis[1];
|
||||||
rectangleOnStartPlane[i][0] = x;
|
rectangleOnStartPlane[i][0] = x;
|
||||||
|
@ -337,7 +337,7 @@ namespace DotRecast.Recast
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] cylinderCapIntersection(float[] start, float radiusSqr, float[] s, int i, float[][] rectangleOnPlane)
|
private static float[] cylinderCapIntersection(Vector3f start, float radiusSqr, float[] s, int i, float[][] rectangleOnPlane)
|
||||||
{
|
{
|
||||||
int j = (i + 1) % 4;
|
int j = (i + 1) % 4;
|
||||||
// Ray against sphere intersection
|
// Ray against sphere intersection
|
||||||
|
@ -370,7 +370,7 @@ namespace DotRecast.Recast
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] slabsCylinderIntersection(float[] rectangle, float[] start, float[] end, float[] axis, float radiusSqr,
|
private static float[] slabsCylinderIntersection(float[] rectangle, Vector3f start, Vector3f end, Vector3f axis, float radiusSqr,
|
||||||
float[] s)
|
float[] s)
|
||||||
{
|
{
|
||||||
if (Math.Min(start[0], end[0]) < rectangle[0])
|
if (Math.Min(start[0], end[0]) < rectangle[0])
|
||||||
|
@ -396,12 +396,12 @@ namespace DotRecast.Recast
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] xSlabCylinderIntersection(float[] rectangle, float[] start, float[] axis, float radiusSqr, float x)
|
private static float[] xSlabCylinderIntersection(float[] rectangle, Vector3f start, Vector3f axis, float radiusSqr, float x)
|
||||||
{
|
{
|
||||||
return rayCylinderIntersection(xSlabRayIntersection(rectangle, start, axis, x), start, axis, radiusSqr);
|
return rayCylinderIntersection(xSlabRayIntersection(rectangle, start, axis, x), start, axis, radiusSqr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] xSlabRayIntersection(float[] rectangle, float[] start, float[] direction, float x)
|
private static float[] xSlabRayIntersection(float[] rectangle, Vector3f start, Vector3f direction, float x)
|
||||||
{
|
{
|
||||||
// 2d intersection of plane and segment
|
// 2d intersection of plane and segment
|
||||||
float t = (x - start[0]) / direction[0];
|
float t = (x - start[0]) / direction[0];
|
||||||
|
@ -409,12 +409,12 @@ namespace DotRecast.Recast
|
||||||
return new float[] { x, rectangle[4], z };
|
return new float[] { x, rectangle[4], z };
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] zSlabCylinderIntersection(float[] rectangle, float[] start, float[] axis, float radiusSqr, float z)
|
private static float[] zSlabCylinderIntersection(float[] rectangle, Vector3f start, Vector3f axis, float radiusSqr, float z)
|
||||||
{
|
{
|
||||||
return rayCylinderIntersection(zSlabRayIntersection(rectangle, start, axis, z), start, axis, radiusSqr);
|
return rayCylinderIntersection(zSlabRayIntersection(rectangle, start, axis, z), start, axis, radiusSqr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] zSlabRayIntersection(float[] rectangle, float[] start, float[] direction, float z)
|
private static float[] zSlabRayIntersection(float[] rectangle, Vector3f start, Vector3f direction, float z)
|
||||||
{
|
{
|
||||||
// 2d intersection of plane and segment
|
// 2d intersection of plane and segment
|
||||||
float t = (z - start[2]) / direction[2];
|
float t = (z - start[2]) / direction[2];
|
||||||
|
@ -423,10 +423,10 @@ namespace DotRecast.Recast
|
||||||
}
|
}
|
||||||
|
|
||||||
// Based on Christer Ericsons's "Real-Time Collision Detection"
|
// Based on Christer Ericsons's "Real-Time Collision Detection"
|
||||||
private static float[] rayCylinderIntersection(float[] point, float[] start, float[] axis, float radiusSqr)
|
private static float[] rayCylinderIntersection(float[] point, Vector3f start, Vector3f axis, float radiusSqr)
|
||||||
{
|
{
|
||||||
float[] d = axis;
|
Vector3f d = axis;
|
||||||
float[] m = { point[0] - start[0], point[1] - start[1], point[2] - start[2] };
|
Vector3f m = Vector3f.Of(point[0] - start[0], point[1] - start[1], point[2] - start[2]);
|
||||||
// float[] n = { 0, 1, 0 };
|
// float[] n = { 0, 1, 0 };
|
||||||
float md = dot(m, d);
|
float md = dot(m, d);
|
||||||
// float nd = dot(n, d);
|
// float nd = dot(n, d);
|
||||||
|
|
|
@ -234,5 +234,11 @@ namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
|
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float dot(Vector3f v1, Vector3f v2)
|
||||||
|
{
|
||||||
|
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,6 +20,7 @@ freely, subject to the following restrictions:
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Crowd.Test;
|
namespace DotRecast.Detour.Crowd.Test;
|
||||||
|
@ -36,22 +37,22 @@ public class AbstractCrowdTest
|
||||||
|
|
||||||
protected readonly long[] endRefs = { 281474976710721L, 281474976710767L, 281474976710758L, 281474976710731L, 281474976710772L };
|
protected readonly long[] endRefs = { 281474976710721L, 281474976710767L, 281474976710758L, 281474976710731L, 281474976710772L };
|
||||||
|
|
||||||
protected readonly float[][] startPoss =
|
protected readonly Vector3f[] startPoss =
|
||||||
{
|
{
|
||||||
new[] { 22.60652f, 10.197294f, -45.918674f },
|
Vector3f.Of(22.60652f, 10.197294f, -45.918674f),
|
||||||
new[] { 22.331268f, 10.197294f, -1.0401875f },
|
Vector3f.Of(22.331268f, 10.197294f, -1.0401875f),
|
||||||
new[] { 18.694363f, 15.803535f, -73.090416f },
|
Vector3f.Of(18.694363f, 15.803535f, -73.090416f),
|
||||||
new[] { 0.7453353f, 10.197294f, -5.94005f },
|
Vector3f.Of(0.7453353f, 10.197294f, -5.94005f),
|
||||||
new[] { -20.651257f, 5.904126f, -13.712508f }
|
Vector3f.Of(-20.651257f, 5.904126f, -13.712508f),
|
||||||
};
|
};
|
||||||
|
|
||||||
protected readonly float[][] endPoss =
|
protected readonly Vector3f[] endPoss =
|
||||||
{
|
{
|
||||||
new[] { 6.4576626f, 10.197294f, -18.33406f },
|
Vector3f.Of(6.4576626f, 10.197294f, -18.33406f),
|
||||||
new[] { -5.8023443f, 0.19729415f, 3.008419f },
|
Vector3f.Of(-5.8023443f, 0.19729415f, 3.008419f),
|
||||||
new[] { 38.423977f, 10.197294f, -0.116066754f },
|
Vector3f.Of(38.423977f, 10.197294f, -0.116066754f),
|
||||||
new[] { 0.8635526f, 10.197294f, -10.31032f },
|
Vector3f.Of(0.8635526f, 10.197294f, -10.31032f),
|
||||||
new[] { 18.784092f, 10.197294f, 3.0543678f }
|
Vector3f.Of(18.784092f, 10.197294f, 3.0543678f),
|
||||||
};
|
};
|
||||||
|
|
||||||
protected MeshData nmd;
|
protected MeshData nmd;
|
||||||
|
@ -110,7 +111,7 @@ public class AbstractCrowdTest
|
||||||
return ap;
|
return ap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addAgentGrid(int size, float distance, int updateFlags, int obstacleAvoidanceType, float[] startPos)
|
protected void addAgentGrid(int size, float distance, int updateFlags, int obstacleAvoidanceType, Vector3f startPos)
|
||||||
{
|
{
|
||||||
CrowdAgentParams ap = getAgentParams(updateFlags, obstacleAvoidanceType);
|
CrowdAgentParams ap = getAgentParams(updateFlags, obstacleAvoidanceType);
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
|
@ -126,15 +127,15 @@ public class AbstractCrowdTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setMoveTarget(float[] pos, bool adjust)
|
protected void setMoveTarget(Vector3f pos, bool adjust)
|
||||||
{
|
{
|
||||||
float[] ext = crowd.getQueryExtents();
|
Vector3f ext = crowd.getQueryExtents();
|
||||||
QueryFilter filter = crowd.getFilter(0);
|
QueryFilter filter = crowd.getFilter(0);
|
||||||
if (adjust)
|
if (adjust)
|
||||||
{
|
{
|
||||||
foreach (CrowdAgent ag in crowd.getActiveAgents())
|
foreach (CrowdAgent ag in crowd.getActiveAgents())
|
||||||
{
|
{
|
||||||
float[] vel = calcVel(ag.npos, pos, ag.option.maxSpeed);
|
Vector3f vel = calcVel(ag.npos, pos, ag.option.maxSpeed);
|
||||||
crowd.requestMoveVelocity(ag, vel);
|
crowd.requestMoveVelocity(ag, vel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,11 +149,11 @@ public class AbstractCrowdTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float[] calcVel(float[] pos, float[] tgt, float speed)
|
protected Vector3f calcVel(Vector3f pos, Vector3f tgt, float speed)
|
||||||
{
|
{
|
||||||
float[] vel = vSub(tgt, pos);
|
Vector3f vel = vSub(tgt, pos);
|
||||||
vel[1] = 0.0f;
|
vel[1] = 0.0f;
|
||||||
vNormalize(vel);
|
vNormalize(ref vel);
|
||||||
vel = vScale(vel, speed);
|
vel = vScale(vel, speed);
|
||||||
return vel;
|
return vel;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
@ -30,22 +31,22 @@ public class PathCorridorTest
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void setUp()
|
public void setUp()
|
||||||
{
|
{
|
||||||
corridor.reset(0, new float[] { 10, 20, 30 });
|
corridor.reset(0, Vector3f.Of(10, 20, 30));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void shouldKeepOriginalPathInFindCornersWhenNothingCanBePruned()
|
public void shouldKeepOriginalPathInFindCornersWhenNothingCanBePruned()
|
||||||
{
|
{
|
||||||
List<StraightPathItem> straightPath = new();
|
List<StraightPathItem> straightPath = new();
|
||||||
straightPath.Add(new StraightPathItem(new float[] { 11, 20, 30.00001f }, 0, 0));
|
straightPath.Add(new StraightPathItem(Vector3f.Of(11, 20, 30.00001f), 0, 0));
|
||||||
straightPath.Add(new StraightPathItem(new float[] { 12, 20, 30.00002f }, 0, 0));
|
straightPath.Add(new StraightPathItem(Vector3f.Of(12, 20, 30.00002f), 0, 0));
|
||||||
straightPath.Add(new StraightPathItem(new float[] { 11f, 21, 32f }, 0, 0));
|
straightPath.Add(new StraightPathItem(Vector3f.Of(11f, 21, 32f), 0, 0));
|
||||||
straightPath.Add(new StraightPathItem(new float[] { 11f, 21, 32f }, 0, 0));
|
straightPath.Add(new StraightPathItem(Vector3f.Of(11f, 21, 32f), 0, 0));
|
||||||
Result<List<StraightPathItem>> result = Results.success(straightPath);
|
Result<List<StraightPathItem>> result = Results.success(straightPath);
|
||||||
var mockQuery = new Mock<NavMeshQuery>(It.IsAny<NavMesh>());
|
var mockQuery = new Mock<NavMeshQuery>(It.IsAny<NavMesh>());
|
||||||
mockQuery.Setup(q => q.findStraightPath(
|
mockQuery.Setup(q => q.findStraightPath(
|
||||||
It.IsAny<float[]>(),
|
It.IsAny<Vector3f>(),
|
||||||
It.IsAny<float[]>(),
|
It.IsAny<Vector3f>(),
|
||||||
It.IsAny<List<long>>(),
|
It.IsAny<List<long>>(),
|
||||||
It.IsAny<int>(),
|
It.IsAny<int>(),
|
||||||
It.IsAny<int>())
|
It.IsAny<int>())
|
||||||
|
@ -59,17 +60,17 @@ public class PathCorridorTest
|
||||||
public void shouldPrunePathInFindCorners()
|
public void shouldPrunePathInFindCorners()
|
||||||
{
|
{
|
||||||
List<StraightPathItem> straightPath = new();
|
List<StraightPathItem> straightPath = new();
|
||||||
straightPath.Add(new StraightPathItem(new float[] { 10, 20, 30.00001f }, 0, 0)); // too close
|
straightPath.Add(new StraightPathItem(Vector3f.Of(10, 20, 30.00001f), 0, 0)); // too close
|
||||||
straightPath.Add(new StraightPathItem(new float[] { 10, 20, 30.00002f }, 0, 0)); // too close
|
straightPath.Add(new StraightPathItem(Vector3f.Of(10, 20, 30.00002f), 0, 0)); // too close
|
||||||
straightPath.Add(new StraightPathItem(new float[] { 11f, 21, 32f }, 0, 0));
|
straightPath.Add(new StraightPathItem(Vector3f.Of(11f, 21, 32f), 0, 0));
|
||||||
straightPath.Add(new StraightPathItem(new float[] { 12f, 22, 33f }, NavMeshQuery.DT_STRAIGHTPATH_OFFMESH_CONNECTION, 0)); // offmesh
|
straightPath.Add(new StraightPathItem(Vector3f.Of(12f, 22, 33f), NavMeshQuery.DT_STRAIGHTPATH_OFFMESH_CONNECTION, 0)); // offmesh
|
||||||
straightPath.Add(new StraightPathItem(new float[] { 11f, 21, 32f }, NavMeshQuery.DT_STRAIGHTPATH_OFFMESH_CONNECTION, 0)); // offmesh
|
straightPath.Add(new StraightPathItem(Vector3f.Of(11f, 21, 32f), NavMeshQuery.DT_STRAIGHTPATH_OFFMESH_CONNECTION, 0)); // offmesh
|
||||||
Result<List<StraightPathItem>> result = Results.success(straightPath);
|
Result<List<StraightPathItem>> result = Results.success(straightPath);
|
||||||
|
|
||||||
var mockQuery = new Mock<NavMeshQuery>(It.IsAny<NavMesh>());
|
var mockQuery = new Mock<NavMeshQuery>(It.IsAny<NavMesh>());
|
||||||
var s = mockQuery.Setup(q => q.findStraightPath(
|
var s = mockQuery.Setup(q => q.findStraightPath(
|
||||||
It.IsAny<float[]>(),
|
It.IsAny<Vector3f>(),
|
||||||
It.IsAny<float[]>(),
|
It.IsAny<Vector3f>(),
|
||||||
It.IsAny<List<long>>(),
|
It.IsAny<List<long>>(),
|
||||||
It.IsAny<int>(),
|
It.IsAny<int>(),
|
||||||
It.IsAny<int>())
|
It.IsAny<int>())
|
||||||
|
|
|
@ -10,10 +10,10 @@ namespace DotRecast.Detour.Dynamic.Test;
|
||||||
|
|
||||||
public class DynamicNavMeshTest
|
public class DynamicNavMeshTest
|
||||||
{
|
{
|
||||||
private static readonly float[] START_POS = new float[] { 70.87453f, 0.0010070801f, 86.69021f };
|
private static readonly Vector3f START_POS = Vector3f.Of(70.87453f, 0.0010070801f, 86.69021f);
|
||||||
private static readonly float[] END_POS = new float[] { -50.22061f, 0.0010070801f, -70.761444f };
|
private static readonly Vector3f END_POS = Vector3f.Of(-50.22061f, 0.0010070801f, -70.761444f);
|
||||||
private static readonly float[] EXTENT = new float[] { 0.1f, 0.1f, 0.1f };
|
private static readonly Vector3f EXTENT = Vector3f.Of(0.1f, 0.1f, 0.1f);
|
||||||
private static readonly float[] SPHERE_POS = new float[] { 45.381645f, 0.0010070801f, 52.68981f };
|
private static readonly Vector3f SPHERE_POS = Vector3f.Of(45.381645f, 0.0010070801f, 52.68981f);
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -47,8 +47,8 @@ public class VoxelFileReaderTest
|
||||||
Assert.That(f.tiles[0].cellHeight, Is.EqualTo(0.001f));
|
Assert.That(f.tiles[0].cellHeight, Is.EqualTo(0.001f));
|
||||||
Assert.That(f.tiles[0].width, Is.EqualTo(810));
|
Assert.That(f.tiles[0].width, Is.EqualTo(810));
|
||||||
Assert.That(f.tiles[0].depth, Is.EqualTo(810));
|
Assert.That(f.tiles[0].depth, Is.EqualTo(810));
|
||||||
Assert.That(f.tiles[0].boundsMin, Is.EqualTo(new float[] { -101.25f, 0f, -101.25f }));
|
Assert.That(f.tiles[0].boundsMin, Is.EqualTo(Vector3f.Of(-101.25f, 0f, -101.25f)));
|
||||||
Assert.That(f.tiles[0].boundsMax, Is.EqualTo(new float[] { 101.25f, 5.0f, 101.25f }));
|
Assert.That(f.tiles[0].boundsMax, Is.EqualTo(Vector3f.Of(101.25f, 5.0f, 101.25f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -74,7 +74,7 @@ public class VoxelFileReaderTest
|
||||||
Assert.That(f.tiles[0].cellHeight, Is.EqualTo(0.001f));
|
Assert.That(f.tiles[0].cellHeight, Is.EqualTo(0.001f));
|
||||||
Assert.That(f.tiles[0].width, Is.EqualTo(90));
|
Assert.That(f.tiles[0].width, Is.EqualTo(90));
|
||||||
Assert.That(f.tiles[0].depth, Is.EqualTo(90));
|
Assert.That(f.tiles[0].depth, Is.EqualTo(90));
|
||||||
Assert.That(f.tiles[0].boundsMin, Is.EqualTo(new float[] { -101.25f, 0f, -101.25f }));
|
Assert.That(f.tiles[0].boundsMin, Is.EqualTo(Vector3f.Of(-101.25f, 0f, -101.25f)));
|
||||||
Assert.That(f.tiles[0].boundsMax, Is.EqualTo(new float[] { -78.75f, 5.0f, -78.75f }));
|
Assert.That(f.tiles[0].boundsMax, Is.EqualTo(Vector3f.Of(-78.75f, 5.0f, -78.75f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -49,8 +49,8 @@ public class VoxelFileReaderWriterTest
|
||||||
Assert.That(f.tiles[0].width, Is.EqualTo(810));
|
Assert.That(f.tiles[0].width, Is.EqualTo(810));
|
||||||
Assert.That(f.tiles[0].depth, Is.EqualTo(810));
|
Assert.That(f.tiles[0].depth, Is.EqualTo(810));
|
||||||
Assert.That(f.tiles[0].spanData.Length, Is.EqualTo(9021024));
|
Assert.That(f.tiles[0].spanData.Length, Is.EqualTo(9021024));
|
||||||
Assert.That(f.tiles[0].boundsMin, Is.EqualTo(new[] { -101.25f, 0f, -101.25f }));
|
Assert.That(f.tiles[0].boundsMin, Is.EqualTo(Vector3f.Of(-101.25f, 0f, -101.25f)));
|
||||||
Assert.That(f.tiles[0].boundsMax, Is.EqualTo(new[] { 101.25f, 5.0f, 101.25f }));
|
Assert.That(f.tiles[0].boundsMax, Is.EqualTo(Vector3f.Of(101.25f, 5.0f, 101.25f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(false)]
|
[TestCase(false)]
|
||||||
|
@ -80,8 +80,8 @@ public class VoxelFileReaderWriterTest
|
||||||
Assert.That(f.tiles[0].spanData.Length, Is.EqualTo(104952));
|
Assert.That(f.tiles[0].spanData.Length, Is.EqualTo(104952));
|
||||||
Assert.That(f.tiles[5].spanData.Length, Is.EqualTo(109080));
|
Assert.That(f.tiles[5].spanData.Length, Is.EqualTo(109080));
|
||||||
Assert.That(f.tiles[18].spanData.Length, Is.EqualTo(113400));
|
Assert.That(f.tiles[18].spanData.Length, Is.EqualTo(113400));
|
||||||
Assert.That(f.tiles[0].boundsMin, Is.EqualTo(new[] { -101.25f, 0f, -101.25f }));
|
Assert.That(f.tiles[0].boundsMin, Is.EqualTo(Vector3f.Of(-101.25f, 0f, -101.25f)));
|
||||||
Assert.That(f.tiles[0].boundsMax, Is.EqualTo(new[] { -78.75f, 5.0f, -78.75f }));
|
Assert.That(f.tiles[0].boundsMax, Is.EqualTo(Vector3f.Of(-78.75f, 5.0f, -78.75f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private VoxelFile readWriteRead(BinaryReader bis, bool compression)
|
private VoxelFile readWriteRead(BinaryReader bis, bool compression)
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class VoxelQueryTest
|
||||||
{
|
{
|
||||||
private const int TILE_WIDTH = 100;
|
private const int TILE_WIDTH = 100;
|
||||||
private const int TILE_DEPTH = 90;
|
private const int TILE_DEPTH = 90;
|
||||||
private static readonly float[] ORIGIN = new float[] { 50, 10, 40 };
|
private static readonly Vector3f ORIGIN = Vector3f.Of(50, 10, 40);
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -32,8 +32,8 @@ public class UnityAStarPathfindingImporterTest
|
||||||
public void test_v4_0_6()
|
public void test_v4_0_6()
|
||||||
{
|
{
|
||||||
NavMesh mesh = loadNavMesh("graph.zip");
|
NavMesh mesh = loadNavMesh("graph.zip");
|
||||||
float[] startPos = new float[] { 8.200293f, 2.155071f, -26.176147f };
|
Vector3f startPos = Vector3f.Of(8.200293f, 2.155071f, -26.176147f);
|
||||||
float[] endPos = new float[] { 11.971109f, 0.000000f, 8.663261f };
|
Vector3f endPos = Vector3f.Of(11.971109f, 0.000000f, 8.663261f);
|
||||||
Result<List<long>> path = findPath(mesh, startPos, endPos);
|
Result<List<long>> path = findPath(mesh, startPos, endPos);
|
||||||
Assert.That(path.status, Is.EqualTo(Status.SUCCSESS));
|
Assert.That(path.status, Is.EqualTo(Status.SUCCSESS));
|
||||||
Assert.That(path.result.Count, Is.EqualTo(57));
|
Assert.That(path.result.Count, Is.EqualTo(57));
|
||||||
|
@ -44,8 +44,8 @@ public class UnityAStarPathfindingImporterTest
|
||||||
public void test_v4_1_16()
|
public void test_v4_1_16()
|
||||||
{
|
{
|
||||||
NavMesh mesh = loadNavMesh("graph_v4_1_16.zip");
|
NavMesh mesh = loadNavMesh("graph_v4_1_16.zip");
|
||||||
float[] startPos = new float[] { 22.93f, -2.37f, -5.11f };
|
Vector3f startPos = Vector3f.Of(22.93f, -2.37f, -5.11f);
|
||||||
float[] endPos = new float[] { 16.81f, -2.37f, 25.52f };
|
Vector3f endPos = Vector3f.Of(16.81f, -2.37f, 25.52f);
|
||||||
Result<List<long>> path = findPath(mesh, startPos, endPos);
|
Result<List<long>> path = findPath(mesh, startPos, endPos);
|
||||||
Assert.That(path.status.isSuccess(), Is.True);
|
Assert.That(path.status.isSuccess(), Is.True);
|
||||||
Assert.That(path.result.Count, Is.EqualTo(15));
|
Assert.That(path.result.Count, Is.EqualTo(15));
|
||||||
|
@ -56,7 +56,7 @@ public class UnityAStarPathfindingImporterTest
|
||||||
public void testBoundsTree()
|
public void testBoundsTree()
|
||||||
{
|
{
|
||||||
NavMesh mesh = loadNavMesh("test_boundstree.zip");
|
NavMesh mesh = loadNavMesh("test_boundstree.zip");
|
||||||
float[] position = { 387.52988f, 19.997f, 368.86282f };
|
Vector3f position = Vector3f.Of(387.52988f, 19.997f, 368.86282f);
|
||||||
|
|
||||||
int[] tilePos = mesh.calcTileLoc(position);
|
int[] tilePos = mesh.calcTileLoc(position);
|
||||||
long tileRef = mesh.getTileRefAt(tilePos[0], tilePos[1], 0);
|
long tileRef = mesh.getTileRefAt(tilePos[0], tilePos[1], 0);
|
||||||
|
@ -87,7 +87,7 @@ public class UnityAStarPathfindingImporterTest
|
||||||
return meshes[0];
|
return meshes[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<List<long>> findPath(NavMesh mesh, float[] startPos, float[] endPos)
|
private Result<List<long>> findPath(NavMesh mesh, Vector3f startPos, Vector3f endPos)
|
||||||
{
|
{
|
||||||
// Perform a simple pathfinding
|
// Perform a simple pathfinding
|
||||||
NavMeshQuery query = new NavMeshQuery(mesh);
|
NavMeshQuery query = new NavMeshQuery(mesh);
|
||||||
|
@ -97,19 +97,19 @@ public class UnityAStarPathfindingImporterTest
|
||||||
return query.findPath(polys[0].getNearestRef(), polys[1].getNearestRef(), startPos, endPos, filter);
|
return query.findPath(polys[0].getNearestRef(), polys[1].getNearestRef(), startPos, endPos, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FindNearestPolyResult[] getNearestPolys(NavMesh mesh, params float[][] positions)
|
private FindNearestPolyResult[] getNearestPolys(NavMesh mesh, params Vector3f[] positions)
|
||||||
{
|
{
|
||||||
NavMeshQuery query = new NavMeshQuery(mesh);
|
NavMeshQuery query = new NavMeshQuery(mesh);
|
||||||
QueryFilter filter = new DefaultQueryFilter();
|
QueryFilter filter = new DefaultQueryFilter();
|
||||||
float[] extents = new float[] { 0.1f, 0.1f, 0.1f };
|
Vector3f extents = Vector3f.Of(0.1f, 0.1f, 0.1f);
|
||||||
|
|
||||||
FindNearestPolyResult[] results = new FindNearestPolyResult[positions.Length];
|
FindNearestPolyResult[] results = new FindNearestPolyResult[positions.Length];
|
||||||
for (int i = 0; i < results.Length; i++)
|
for (int i = 0; i < results.Length; i++)
|
||||||
{
|
{
|
||||||
float[] position = positions[i];
|
Vector3f position = positions[i];
|
||||||
Result<FindNearestPolyResult> result = query.findNearestPoly(position, extents, filter);
|
Result<FindNearestPolyResult> result = query.findNearestPoly(position, extents, filter);
|
||||||
Assert.That(result.succeeded(), Is.True);
|
Assert.That(result.succeeded(), Is.True);
|
||||||
Assert.That(result.result.getNearestPos(), Is.Not.Null, "Nearest start position is null!");
|
Assert.That(result.result.getNearestPos(), Is.Not.EqualTo(Vector3f.Zero), "Nearest start position is null!");
|
||||||
results[i] = result.result;
|
results[i] = result.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -32,22 +33,22 @@ public abstract class AbstractDetourTest
|
||||||
281474976710721L, 281474976710767L, 281474976710758L, 281474976710731L, 281474976710772L
|
281474976710721L, 281474976710767L, 281474976710758L, 281474976710731L, 281474976710772L
|
||||||
};
|
};
|
||||||
|
|
||||||
protected static readonly float[][] startPoss =
|
protected static readonly Vector3f[] startPoss =
|
||||||
{
|
{
|
||||||
new[] { 22.60652f, 10.197294f, -45.918674f },
|
Vector3f.Of(22.60652f, 10.197294f, -45.918674f),
|
||||||
new[] { 22.331268f, 10.197294f, -1.0401875f },
|
Vector3f.Of(22.331268f, 10.197294f, -1.0401875f),
|
||||||
new[] { 18.694363f, 15.803535f, -73.090416f },
|
Vector3f.Of(18.694363f, 15.803535f, -73.090416f),
|
||||||
new[] { 0.7453353f, 10.197294f, -5.94005f },
|
Vector3f.Of(0.7453353f, 10.197294f, -5.94005f),
|
||||||
new[] { -20.651257f, 5.904126f, -13.712508f }
|
Vector3f.Of(-20.651257f, 5.904126f, -13.712508f)
|
||||||
};
|
};
|
||||||
|
|
||||||
protected static readonly float[][] endPoss =
|
protected static readonly Vector3f[] endPoss =
|
||||||
{
|
{
|
||||||
new[] { 6.4576626f, 10.197294f, -18.33406f },
|
Vector3f.Of(6.4576626f, 10.197294f, -18.33406f),
|
||||||
new[] { -5.8023443f, 0.19729415f, 3.008419f },
|
Vector3f.Of(-5.8023443f, 0.19729415f, 3.008419f),
|
||||||
new[] { 38.423977f, 10.197294f, -0.116066754f },
|
Vector3f.Of(38.423977f, 10.197294f, -0.116066754f),
|
||||||
new[] { 0.8635526f, 10.197294f, -10.31032f },
|
Vector3f.Of(0.8635526f, 10.197294f, -10.31032f),
|
||||||
new[] { 18.784092f, 10.197294f, 3.0543678f }
|
Vector3f.Of(18.784092f, 10.197294f, 3.0543678f),
|
||||||
};
|
};
|
||||||
|
|
||||||
protected NavMeshQuery query;
|
protected NavMeshQuery query;
|
||||||
|
|
|
@ -16,6 +16,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -48,7 +49,7 @@ public class FindDistanceToWallTest : AbstractDetourTest
|
||||||
QueryFilter filter = new DefaultQueryFilter();
|
QueryFilter filter = new DefaultQueryFilter();
|
||||||
for (int i = 0; i < startRefs.Length; i++)
|
for (int i = 0; i < startRefs.Length; i++)
|
||||||
{
|
{
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
Result<FindDistanceToWallResult> result = query.findDistanceToWall(startRefs[i], startPos, 3.5f, filter);
|
Result<FindDistanceToWallResult> result = query.findDistanceToWall(startRefs[i], startPos, 3.5f, filter);
|
||||||
FindDistanceToWallResult hit = result.result;
|
FindDistanceToWallResult hit = result.result;
|
||||||
Assert.That(hit.getDistance(), Is.EqualTo(DISTANCES_TO_WALL[i]).Within(0.001f));
|
Assert.That(hit.getDistance(), Is.EqualTo(DISTANCES_TO_WALL[i]).Within(0.001f));
|
||||||
|
|
|
@ -16,6 +16,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -54,7 +55,7 @@ public class FindLocalNeighbourhoodTest : AbstractDetourTest
|
||||||
QueryFilter filter = new DefaultQueryFilter();
|
QueryFilter filter = new DefaultQueryFilter();
|
||||||
for (int i = 0; i < startRefs.Length; i++)
|
for (int i = 0; i < startRefs.Length; i++)
|
||||||
{
|
{
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
Result<FindLocalNeighbourhoodResult> poly = query.findLocalNeighbourhood(startRefs[i], startPos, 3.5f,
|
Result<FindLocalNeighbourhoodResult> poly = query.findLocalNeighbourhood(startRefs[i], startPos, 3.5f,
|
||||||
filter);
|
filter);
|
||||||
Assert.That(poly.result.getRefs().Count, Is.EqualTo(REFS[i].Length));
|
Assert.That(poly.result.getRefs().Count, Is.EqualTo(REFS[i].Length));
|
||||||
|
|
|
@ -16,6 +16,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -35,10 +36,10 @@ public class FindNearestPolyTest : AbstractDetourTest
|
||||||
public void testFindNearestPoly()
|
public void testFindNearestPoly()
|
||||||
{
|
{
|
||||||
QueryFilter filter = new DefaultQueryFilter();
|
QueryFilter filter = new DefaultQueryFilter();
|
||||||
float[] extents = { 2, 4, 2 };
|
Vector3f extents = Vector3f.Of(2, 4, 2);
|
||||||
for (int i = 0; i < startRefs.Length; i++)
|
for (int i = 0; i < startRefs.Length; i++)
|
||||||
{
|
{
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
Result<FindNearestPolyResult> poly = query.findNearestPoly(startPos, extents, filter);
|
Result<FindNearestPolyResult> poly = query.findNearestPoly(startPos, extents, filter);
|
||||||
Assert.That(poly.succeeded(), Is.True);
|
Assert.That(poly.succeeded(), Is.True);
|
||||||
Assert.That(poly.result.getNearestRef(), Is.EqualTo(POLY_REFS[i]));
|
Assert.That(poly.result.getNearestRef(), Is.EqualTo(POLY_REFS[i]));
|
||||||
|
@ -56,7 +57,7 @@ public class FindNearestPolyTest : AbstractDetourTest
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCost(float[] pa, float[] pb, long prevRef, MeshTile prevTile, Poly prevPoly, long curRef, MeshTile curTile,
|
public float getCost(Vector3f pa, Vector3f pb, long prevRef, MeshTile prevTile, Poly prevPoly, long curRef, MeshTile curTile,
|
||||||
Poly curPoly, long nextRef, MeshTile nextTile, Poly nextPoly)
|
Poly curPoly, long nextRef, MeshTile nextTile, Poly nextPoly)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -67,10 +68,10 @@ public class FindNearestPolyTest : AbstractDetourTest
|
||||||
public void shouldReturnStartPosWhenNoPolyIsValid()
|
public void shouldReturnStartPosWhenNoPolyIsValid()
|
||||||
{
|
{
|
||||||
var filter = new EmptyQueryFilter();
|
var filter = new EmptyQueryFilter();
|
||||||
float[] extents = { 2, 4, 2 };
|
Vector3f extents = Vector3f.Of(2, 4, 2);
|
||||||
for (int i = 0; i < startRefs.Length; i++)
|
for (int i = 0; i < startRefs.Length; i++)
|
||||||
{
|
{
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
Result<FindNearestPolyResult> poly = query.findNearestPoly(startPos, extents, filter);
|
Result<FindNearestPolyResult> poly = query.findNearestPoly(startPos, extents, filter);
|
||||||
Assert.That(poly.succeeded(), Is.True);
|
Assert.That(poly.succeeded(), Is.True);
|
||||||
Assert.That(poly.result.getNearestRef(), Is.EqualTo(0L));
|
Assert.That(poly.result.getNearestRef(), Is.EqualTo(0L));
|
||||||
|
|
|
@ -17,6 +17,7 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -69,59 +70,59 @@ public class FindPathTest : AbstractDetourTest
|
||||||
{
|
{
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
new StraightPathItem(new float[] { 22.606520f, 10.197294f, -45.918674f }, 1, 281474976710696L),
|
new StraightPathItem(Vector3f.Of(22.606520f, 10.197294f, -45.918674f), 1, 281474976710696L),
|
||||||
new StraightPathItem(new float[] { 3.484785f, 10.197294f, -34.241272f }, 0, 281474976710713L),
|
new StraightPathItem(Vector3f.Of(3.484785f, 10.197294f, -34.241272f), 0, 281474976710713L),
|
||||||
new StraightPathItem(new float[] { 1.984785f, 10.197294f, -31.241272f }, 0, 281474976710712L),
|
new StraightPathItem(Vector3f.Of(1.984785f, 10.197294f, -31.241272f), 0, 281474976710712L),
|
||||||
new StraightPathItem(new float[] { 1.984785f, 10.197294f, -29.741272f }, 0, 281474976710727L),
|
new StraightPathItem(Vector3f.Of(1.984785f, 10.197294f, -29.741272f), 0, 281474976710727L),
|
||||||
new StraightPathItem(new float[] { 2.584784f, 10.197294f, -27.941273f }, 0, 281474976710730L),
|
new StraightPathItem(Vector3f.Of(2.584784f, 10.197294f, -27.941273f), 0, 281474976710730L),
|
||||||
new StraightPathItem(new float[] { 6.457663f, 10.197294f, -18.334061f }, 2, 0L)
|
new StraightPathItem(Vector3f.Of(6.457663f, 10.197294f, -18.334061f), 2, 0L)
|
||||||
},
|
},
|
||||||
|
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
new StraightPathItem(new float[] { 22.331268f, 10.197294f, -1.040187f }, 1, 281474976710773L),
|
new StraightPathItem(Vector3f.Of(22.331268f, 10.197294f, -1.040187f), 1, 281474976710773L),
|
||||||
new StraightPathItem(new float[] { 9.784786f, 10.197294f, -2.141273f }, 0, 281474976710755L),
|
new StraightPathItem(Vector3f.Of(9.784786f, 10.197294f, -2.141273f), 0, 281474976710755L),
|
||||||
new StraightPathItem(new float[] { 7.984783f, 10.197294f, -2.441269f }, 0, 281474976710753L),
|
new StraightPathItem(Vector3f.Of(7.984783f, 10.197294f, -2.441269f), 0, 281474976710753L),
|
||||||
new StraightPathItem(new float[] { 1.984785f, 10.197294f, -8.441269f }, 0, 281474976710752L),
|
new StraightPathItem(Vector3f.Of(1.984785f, 10.197294f, -8.441269f), 0, 281474976710752L),
|
||||||
new StraightPathItem(new float[] { -4.315216f, 10.197294f, -15.341270f }, 0, 281474976710724L),
|
new StraightPathItem(Vector3f.Of(-4.315216f, 10.197294f, -15.341270f), 0, 281474976710724L),
|
||||||
new StraightPathItem(new float[] { -8.215216f, 10.197294f, -17.441269f }, 0, 281474976710728L),
|
new StraightPathItem(Vector3f.Of(-8.215216f, 10.197294f, -17.441269f), 0, 281474976710728L),
|
||||||
new StraightPathItem(new float[] { -10.015216f, 10.197294f, -17.741272f }, 0, 281474976710738L),
|
new StraightPathItem(Vector3f.Of(-10.015216f, 10.197294f, -17.741272f), 0, 281474976710738L),
|
||||||
new StraightPathItem(new float[] { -11.815216f, 9.997294f, -17.441269f }, 0, 281474976710736L),
|
new StraightPathItem(Vector3f.Of(-11.815216f, 9.997294f, -17.441269f), 0, 281474976710736L),
|
||||||
new StraightPathItem(new float[] { -17.815216f, 5.197294f, -11.441269f }, 0, 281474976710735L),
|
new StraightPathItem(Vector3f.Of(-17.815216f, 5.197294f, -11.441269f), 0, 281474976710735L),
|
||||||
new StraightPathItem(new float[] { -17.815216f, 5.197294f, -8.441269f }, 0, 281474976710746L),
|
new StraightPathItem(Vector3f.Of(-17.815216f, 5.197294f, -8.441269f), 0, 281474976710746L),
|
||||||
new StraightPathItem(new float[] { -11.815216f, 0.197294f, 3.008419f }, 2, 0L)
|
new StraightPathItem(Vector3f.Of(-11.815216f, 0.197294f, 3.008419f), 2, 0L)
|
||||||
},
|
},
|
||||||
|
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
new StraightPathItem(new float[] { 18.694363f, 15.803535f, -73.090416f }, 1, 281474976710680L),
|
new StraightPathItem(Vector3f.Of(18.694363f, 15.803535f, -73.090416f), 1, 281474976710680L),
|
||||||
new StraightPathItem(new float[] { 17.584785f, 10.197294f, -49.841274f }, 0, 281474976710697L),
|
new StraightPathItem(Vector3f.Of(17.584785f, 10.197294f, -49.841274f), 0, 281474976710697L),
|
||||||
new StraightPathItem(new float[] { 17.284786f, 10.197294f, -48.041275f }, 0, 281474976710695L),
|
new StraightPathItem(Vector3f.Of(17.284786f, 10.197294f, -48.041275f), 0, 281474976710695L),
|
||||||
new StraightPathItem(new float[] { 16.084785f, 10.197294f, -45.341274f }, 0, 281474976710694L),
|
new StraightPathItem(Vector3f.Of(16.084785f, 10.197294f, -45.341274f), 0, 281474976710694L),
|
||||||
new StraightPathItem(new float[] { 3.484785f, 10.197294f, -34.241272f }, 0, 281474976710713L),
|
new StraightPathItem(Vector3f.Of(3.484785f, 10.197294f, -34.241272f), 0, 281474976710713L),
|
||||||
new StraightPathItem(new float[] { 1.984785f, 10.197294f, -31.241272f }, 0, 281474976710712L),
|
new StraightPathItem(Vector3f.Of(1.984785f, 10.197294f, -31.241272f), 0, 281474976710712L),
|
||||||
new StraightPathItem(new float[] { 1.984785f, 10.197294f, -8.441269f }, 0, 281474976710753L),
|
new StraightPathItem(Vector3f.Of(1.984785f, 10.197294f, -8.441269f), 0, 281474976710753L),
|
||||||
new StraightPathItem(new float[] { 7.984783f, 10.197294f, -2.441269f }, 0, 281474976710755L),
|
new StraightPathItem(Vector3f.Of(7.984783f, 10.197294f, -2.441269f), 0, 281474976710755L),
|
||||||
new StraightPathItem(new float[] { 9.784786f, 10.197294f, -2.141273f }, 0, 281474976710768L),
|
new StraightPathItem(Vector3f.Of(9.784786f, 10.197294f, -2.141273f), 0, 281474976710768L),
|
||||||
new StraightPathItem(new float[] { 38.423977f, 10.197294f, -0.116067f }, 2, 0L)
|
new StraightPathItem(Vector3f.Of(38.423977f, 10.197294f, -0.116067f), 2, 0L)
|
||||||
},
|
},
|
||||||
|
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
new StraightPathItem(new float[] { 0.745335f, 10.197294f, -5.940050f }, 1, 281474976710753L),
|
new StraightPathItem(Vector3f.Of(0.745335f, 10.197294f, -5.940050f), 1, 281474976710753L),
|
||||||
new StraightPathItem(new float[] { 0.863553f, 10.197294f, -10.310320f }, 2, 0L)
|
new StraightPathItem(Vector3f.Of(0.863553f, 10.197294f, -10.310320f), 2, 0L)
|
||||||
},
|
},
|
||||||
|
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
new StraightPathItem(new float[] { -20.651257f, 5.904126f, -13.712508f }, 1, 281474976710733L),
|
new StraightPathItem(Vector3f.Of(-20.651257f, 5.904126f, -13.712508f), 1, 281474976710733L),
|
||||||
new StraightPathItem(new float[] { -11.815216f, 9.997294f, -17.441269f }, 0, 281474976710738L),
|
new StraightPathItem(Vector3f.Of(-11.815216f, 9.997294f, -17.441269f), 0, 281474976710738L),
|
||||||
new StraightPathItem(new float[] { -10.015216f, 10.197294f, -17.741272f }, 0, 281474976710728L),
|
new StraightPathItem(Vector3f.Of(-10.015216f, 10.197294f, -17.741272f), 0, 281474976710728L),
|
||||||
new StraightPathItem(new float[] { -8.215216f, 10.197294f, -17.441269f }, 0, 281474976710724L),
|
new StraightPathItem(Vector3f.Of(-8.215216f, 10.197294f, -17.441269f), 0, 281474976710724L),
|
||||||
new StraightPathItem(new float[] { -4.315216f, 10.197294f, -15.341270f }, 0, 281474976710729L),
|
new StraightPathItem(Vector3f.Of(-4.315216f, 10.197294f, -15.341270f), 0, 281474976710729L),
|
||||||
new StraightPathItem(new float[] { 1.984785f, 10.197294f, -8.441269f }, 0, 281474976710753L),
|
new StraightPathItem(Vector3f.Of(1.984785f, 10.197294f, -8.441269f), 0, 281474976710753L),
|
||||||
new StraightPathItem(new float[] { 7.984783f, 10.197294f, -2.441269f }, 0, 281474976710755L),
|
new StraightPathItem(Vector3f.Of(7.984783f, 10.197294f, -2.441269f), 0, 281474976710755L),
|
||||||
new StraightPathItem(new float[] { 18.784092f, 10.197294f, 3.054368f }, 2, 0L)
|
new StraightPathItem(Vector3f.Of(18.784092f, 10.197294f, 3.054368f), 2, 0L)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,8 +134,8 @@ public class FindPathTest : AbstractDetourTest
|
||||||
{
|
{
|
||||||
long startRef = startRefs[i];
|
long startRef = startRefs[i];
|
||||||
long endRef = endRefs[i];
|
long endRef = endRefs[i];
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
float[] endPos = endPoss[i];
|
Vector3f endPos = endPoss[i];
|
||||||
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
||||||
Assert.That(path.status, Is.EqualTo(STATUSES[i]));
|
Assert.That(path.status, Is.EqualTo(STATUSES[i]));
|
||||||
Assert.That(path.result.Count, Is.EqualTo(RESULTS[i].Length));
|
Assert.That(path.result.Count, Is.EqualTo(RESULTS[i].Length));
|
||||||
|
@ -153,8 +154,8 @@ public class FindPathTest : AbstractDetourTest
|
||||||
{
|
{
|
||||||
long startRef = startRefs[i];
|
long startRef = startRefs[i];
|
||||||
long endRef = endRefs[i];
|
long endRef = endRefs[i];
|
||||||
float[] startPos = startPoss[i];
|
var startPos = startPoss[i];
|
||||||
float[] endPos = endPoss[i];
|
var endPos = endPoss[i];
|
||||||
query.initSlicedFindPath(startRef, endRef, startPos, endPos, filter, NavMeshQuery.DT_FINDPATH_ANY_ANGLE);
|
query.initSlicedFindPath(startRef, endRef, startPos, endPos, filter, NavMeshQuery.DT_FINDPATH_ANY_ANGLE);
|
||||||
Status status = Status.IN_PROGRESS;
|
Status status = Status.IN_PROGRESS;
|
||||||
while (status == Status.IN_PROGRESS)
|
while (status == Status.IN_PROGRESS)
|
||||||
|
@ -182,8 +183,8 @@ public class FindPathTest : AbstractDetourTest
|
||||||
// startRefs.Length; i++) {
|
// startRefs.Length; i++) {
|
||||||
long startRef = startRefs[i];
|
long startRef = startRefs[i];
|
||||||
long endRef = endRefs[i];
|
long endRef = endRefs[i];
|
||||||
float[] startPos = startPoss[i];
|
var startPos = startPoss[i];
|
||||||
float[] endPos = endPoss[i];
|
var endPos = endPoss[i];
|
||||||
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
||||||
Result<List<StraightPathItem>> result = query.findStraightPath(startPos, endPos, path.result,
|
Result<List<StraightPathItem>> result = query.findStraightPath(startPos, endPos, path.result,
|
||||||
int.MaxValue, 0);
|
int.MaxValue, 0);
|
||||||
|
|
|
@ -16,6 +16,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -102,7 +103,7 @@ public class FindPolysAroundCircleTest : AbstractDetourTest
|
||||||
for (int i = 0; i < startRefs.Length; i++)
|
for (int i = 0; i < startRefs.Length; i++)
|
||||||
{
|
{
|
||||||
long startRef = startRefs[i];
|
long startRef = startRefs[i];
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
Result<FindPolysAroundResult> result = query.findPolysAroundCircle(startRef, startPos, 7.5f, filter);
|
Result<FindPolysAroundResult> result = query.findPolysAroundCircle(startRef, startPos, 7.5f, filter);
|
||||||
Assert.That(result.succeeded(), Is.True);
|
Assert.That(result.succeeded(), Is.True);
|
||||||
FindPolysAroundResult polys = result.result;
|
FindPolysAroundResult polys = result.result;
|
||||||
|
|
|
@ -16,6 +16,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -129,9 +130,8 @@ public class FindPolysAroundShapeTest : AbstractDetourTest
|
||||||
for (int i = 0; i < startRefs.Length; i++)
|
for (int i = 0; i < startRefs.Length; i++)
|
||||||
{
|
{
|
||||||
long startRef = startRefs[i];
|
long startRef = startRefs[i];
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
Result<FindPolysAroundResult> polys = query.findPolysAroundShape(startRef,
|
Result<FindPolysAroundResult> polys = query.findPolysAroundShape(startRef, getQueryPoly(startPos, endPoss[i]), filter);
|
||||||
getQueryPoly(startPos, endPoss[i]), filter);
|
|
||||||
Assert.That(polys.result.getRefs().Count, Is.EqualTo(REFS[i].Length));
|
Assert.That(polys.result.getRefs().Count, Is.EqualTo(REFS[i].Length));
|
||||||
for (int v = 0; v < REFS[i].Length; v++)
|
for (int v = 0; v < REFS[i].Length; v++)
|
||||||
{
|
{
|
||||||
|
@ -151,7 +151,7 @@ public class FindPolysAroundShapeTest : AbstractDetourTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float[] getQueryPoly(float[] m_spos, float[] m_epos)
|
private float[] getQueryPoly(Vector3f m_spos, Vector3f m_epos)
|
||||||
{
|
{
|
||||||
float nx = (m_epos[2] - m_spos[2]) * 0.25f;
|
float nx = (m_epos[2] - m_spos[2]) * 0.25f;
|
||||||
float nz = -(m_epos[0] - m_spos[0]) * 0.25f;
|
float nz = -(m_epos[0] - m_spos[0]) * 0.25f;
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class MeshSetReaderWriterTest
|
||||||
NavMeshSetHeader header = new NavMeshSetHeader();
|
NavMeshSetHeader header = new NavMeshSetHeader();
|
||||||
header.magic = NavMeshSetHeader.NAVMESHSET_MAGIC;
|
header.magic = NavMeshSetHeader.NAVMESHSET_MAGIC;
|
||||||
header.version = NavMeshSetHeader.NAVMESHSET_VERSION;
|
header.version = NavMeshSetHeader.NAVMESHSET_VERSION;
|
||||||
vCopy(header.option.orig, geom.getMeshBoundsMin());
|
vCopy(ref header.option.orig, geom.getMeshBoundsMin());
|
||||||
header.option.tileWidth = m_tileSize * m_cellSize;
|
header.option.tileWidth = m_tileSize * m_cellSize;
|
||||||
header.option.tileHeight = m_tileSize * m_cellSize;
|
header.option.tileHeight = m_tileSize * m_cellSize;
|
||||||
header.option.maxTiles = m_maxTiles;
|
header.option.maxTiles = m_maxTiles;
|
||||||
|
|
|
@ -16,6 +16,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -69,8 +70,8 @@ public class MoveAlongSurfaceTest : AbstractDetourTest
|
||||||
for (int i = 0; i < startRefs.Length; i++)
|
for (int i = 0; i < startRefs.Length; i++)
|
||||||
{
|
{
|
||||||
long startRef = startRefs[i];
|
long startRef = startRefs[i];
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
float[] endPos = endPoss[i];
|
Vector3f endPos = endPoss[i];
|
||||||
Result<MoveAlongSurfaceResult> result = query.moveAlongSurface(startRef, startPos, endPos, filter);
|
Result<MoveAlongSurfaceResult> result = query.moveAlongSurface(startRef, startPos, endPos, filter);
|
||||||
Assert.That(result.succeeded(), Is.True);
|
Assert.That(result.succeeded(), Is.True);
|
||||||
MoveAlongSurfaceResult path = result.result;
|
MoveAlongSurfaceResult path = result.result;
|
||||||
|
|
|
@ -16,6 +16,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -28,7 +29,7 @@ public class PolygonByCircleConstraintTest
|
||||||
public void shouldHandlePolygonFullyInsideCircle()
|
public void shouldHandlePolygonFullyInsideCircle()
|
||||||
{
|
{
|
||||||
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
|
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
|
||||||
float[] center = { 1, 0, 1 };
|
Vector3f center = Vector3f.Of(1, 0, 1);
|
||||||
float[] constrained = constraint.aply(polygon, center, 6);
|
float[] constrained = constraint.aply(polygon, center, 6);
|
||||||
|
|
||||||
Assert.That(constrained, Is.EqualTo(polygon));
|
Assert.That(constrained, Is.EqualTo(polygon));
|
||||||
|
@ -39,7 +40,7 @@ public class PolygonByCircleConstraintTest
|
||||||
{
|
{
|
||||||
int expectedSize = 21;
|
int expectedSize = 21;
|
||||||
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
|
float[] polygon = { -2, 0, 2, 2, 0, 2, 2, 0, -2, -2, 0, -2 };
|
||||||
float[] center = { 2, 0, 0 };
|
Vector3f center = Vector3f.Of(2, 0, 0);
|
||||||
|
|
||||||
float[] constrained = constraint.aply(polygon, center, 3);
|
float[] constrained = constraint.aply(polygon, center, 3);
|
||||||
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
||||||
|
@ -51,7 +52,7 @@ public class PolygonByCircleConstraintTest
|
||||||
{
|
{
|
||||||
int expectedSize = 12 * 3;
|
int expectedSize = 12 * 3;
|
||||||
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
||||||
float[] center = { -1, 0, -1 };
|
Vector3f center = Vector3f.Of(-1, 0, -1);
|
||||||
float[] constrained = constraint.aply(polygon, center, 2);
|
float[] constrained = constraint.aply(polygon, center, 2);
|
||||||
|
|
||||||
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
||||||
|
@ -69,7 +70,7 @@ public class PolygonByCircleConstraintTest
|
||||||
{
|
{
|
||||||
int expectedSize = 9 * 3;
|
int expectedSize = 9 * 3;
|
||||||
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
||||||
float[] center = { -2, 0, -1 };
|
Vector3f center = Vector3f.Of(-2, 0, -1);
|
||||||
float[] constrained = constraint.aply(polygon, center, 3);
|
float[] constrained = constraint.aply(polygon, center, 3);
|
||||||
|
|
||||||
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
||||||
|
@ -81,7 +82,7 @@ public class PolygonByCircleConstraintTest
|
||||||
{
|
{
|
||||||
int expectedSize = 7 * 3;
|
int expectedSize = 7 * 3;
|
||||||
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
float[] polygon = { -4, 0, 0, -3, 0, 3, 2, 0, 3, 3, 0, -3, -2, 0, -4 };
|
||||||
float[] center = { 4, 0, 0 };
|
Vector3f center = Vector3f.Of(4, 0, 0);
|
||||||
float[] constrained = constraint.aply(polygon, center, 4);
|
float[] constrained = constraint.aply(polygon, center, 4);
|
||||||
|
|
||||||
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
Assert.That(constrained.Length, Is.EqualTo(expectedSize));
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class TestTiledNavMeshBuilder
|
||||||
{
|
{
|
||||||
// Create empty nav mesh
|
// Create empty nav mesh
|
||||||
NavMeshParams navMeshParams = new NavMeshParams();
|
NavMeshParams navMeshParams = new NavMeshParams();
|
||||||
copy(navMeshParams.orig, m_geom.getMeshBoundsMin());
|
copy(ref navMeshParams.orig, m_geom.getMeshBoundsMin());
|
||||||
navMeshParams.tileWidth = m_tileSize * m_cellSize;
|
navMeshParams.tileWidth = m_tileSize * m_cellSize;
|
||||||
navMeshParams.tileHeight = m_tileSize * m_cellSize;
|
navMeshParams.tileHeight = m_tileSize * m_cellSize;
|
||||||
navMeshParams.maxTiles = 128;
|
navMeshParams.maxTiles = 128;
|
||||||
|
|
|
@ -17,6 +17,7 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
@ -40,8 +41,8 @@ public class TiledFindPathTest
|
||||||
|
|
||||||
protected static readonly long[] START_REFS = { 281475015507969L };
|
protected static readonly long[] START_REFS = { 281475015507969L };
|
||||||
protected static readonly long[] END_REFS = { 281474985099266L };
|
protected static readonly long[] END_REFS = { 281474985099266L };
|
||||||
protected static readonly float[][] START_POS = { new[] { 39.447338f, 9.998177f, -0.784811f } };
|
protected static readonly Vector3f[] START_POS = { Vector3f.Of(39.447338f, 9.998177f, -0.784811f) };
|
||||||
protected static readonly float[][] END_POS = { new[] { 19.292645f, 11.611748f, -57.750366f } };
|
protected static readonly Vector3f[] END_POS = { Vector3f.Of(19.292645f, 11.611748f, -57.750366f) };
|
||||||
|
|
||||||
protected NavMeshQuery query;
|
protected NavMeshQuery query;
|
||||||
protected NavMesh navmesh;
|
protected NavMesh navmesh;
|
||||||
|
@ -66,8 +67,8 @@ public class TiledFindPathTest
|
||||||
{
|
{
|
||||||
long startRef = START_REFS[i];
|
long startRef = START_REFS[i];
|
||||||
long endRef = END_REFS[i];
|
long endRef = END_REFS[i];
|
||||||
float[] startPos = START_POS[i];
|
Vector3f startPos = START_POS[i];
|
||||||
float[] endPos = END_POS[i];
|
Vector3f endPos = END_POS[i];
|
||||||
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
||||||
Assert.That(path.status, Is.EqualTo(STATUSES[i]));
|
Assert.That(path.status, Is.EqualTo(STATUSES[i]));
|
||||||
Assert.That(path.result.Count, Is.EqualTo(RESULTS[i].Length));
|
Assert.That(path.result.Count, Is.EqualTo(RESULTS[i].Length));
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class AbstractTileCacheTest
|
||||||
int[] twh = Recast.Recast.calcTileCount(geom.getMeshBoundsMin(), geom.getMeshBoundsMax(), m_cellSize, m_tileSize, m_tileSize);
|
int[] twh = Recast.Recast.calcTileCount(geom.getMeshBoundsMin(), geom.getMeshBoundsMax(), m_cellSize, m_tileSize, m_tileSize);
|
||||||
option.ch = m_cellHeight;
|
option.ch = m_cellHeight;
|
||||||
option.cs = m_cellSize;
|
option.cs = m_cellSize;
|
||||||
vCopy(option.orig, geom.getMeshBoundsMin());
|
vCopy(ref option.orig, geom.getMeshBoundsMin());
|
||||||
option.height = m_tileSize;
|
option.height = m_tileSize;
|
||||||
option.width = m_tileSize;
|
option.width = m_tileSize;
|
||||||
option.walkableHeight = m_agentHeight;
|
option.walkableHeight = m_agentHeight;
|
||||||
|
@ -64,7 +64,7 @@ public class AbstractTileCacheTest
|
||||||
option.maxTiles = twh[0] * twh[1] * EXPECTED_LAYERS_PER_TILE;
|
option.maxTiles = twh[0] * twh[1] * EXPECTED_LAYERS_PER_TILE;
|
||||||
option.maxObstacles = 128;
|
option.maxObstacles = 128;
|
||||||
NavMeshParams navMeshParams = new NavMeshParams();
|
NavMeshParams navMeshParams = new NavMeshParams();
|
||||||
copy(navMeshParams.orig, geom.getMeshBoundsMin());
|
copy(ref navMeshParams.orig, geom.getMeshBoundsMin());
|
||||||
navMeshParams.tileWidth = m_tileSize * m_cellSize;
|
navMeshParams.tileWidth = m_tileSize * m_cellSize;
|
||||||
navMeshParams.tileHeight = m_tileSize * m_cellSize;
|
navMeshParams.tileHeight = m_tileSize * m_cellSize;
|
||||||
navMeshParams.maxTiles = 256;
|
navMeshParams.maxTiles = 256;
|
||||||
|
|
|
@ -98,8 +98,8 @@ public class TestTileLayerBuilder : AbstractTileLayersBuilder
|
||||||
header.tx = tx;
|
header.tx = tx;
|
||||||
header.ty = ty;
|
header.ty = ty;
|
||||||
header.tlayer = i;
|
header.tlayer = i;
|
||||||
vCopy(header.bmin, layer.bmin);
|
vCopy(ref header.bmin, layer.bmin);
|
||||||
vCopy(header.bmax, layer.bmax);
|
vCopy(ref header.bmax, layer.bmax);
|
||||||
|
|
||||||
// Tile info.
|
// Tile info.
|
||||||
header.width = layer.width;
|
header.width = layer.width;
|
||||||
|
|
|
@ -28,8 +28,8 @@ namespace DotRecast.Detour.TileCache.Test;
|
||||||
|
|
||||||
public class TileCacheFindPathTest : AbstractTileCacheTest
|
public class TileCacheFindPathTest : AbstractTileCacheTest
|
||||||
{
|
{
|
||||||
private readonly float[] start = { 39.44734f, 9.998177f, -0.784811f };
|
private readonly Vector3f start = Vector3f.Of(39.44734f, 9.998177f, -0.784811f);
|
||||||
private readonly float[] end = { 19.292645f, 11.611748f, -57.750366f };
|
private readonly Vector3f end = Vector3f.Of(19.292645f, 11.611748f, -57.750366f);
|
||||||
private readonly NavMesh navmesh;
|
private readonly NavMesh navmesh;
|
||||||
private readonly NavMeshQuery query;
|
private readonly NavMeshQuery query;
|
||||||
|
|
||||||
|
@ -46,18 +46,17 @@ public class TileCacheFindPathTest : AbstractTileCacheTest
|
||||||
public void testFindPath()
|
public void testFindPath()
|
||||||
{
|
{
|
||||||
QueryFilter filter = new DefaultQueryFilter();
|
QueryFilter filter = new DefaultQueryFilter();
|
||||||
float[] extents = new float[] { 2f, 4f, 2f };
|
Vector3f extents = Vector3f.Of(2f, 4f, 2f);
|
||||||
Result<FindNearestPolyResult> findPolyStart = query.findNearestPoly(start, extents, filter);
|
Result<FindNearestPolyResult> findPolyStart = query.findNearestPoly(start, extents, filter);
|
||||||
Result<FindNearestPolyResult> findPolyEnd = query.findNearestPoly(end, extents, filter);
|
Result<FindNearestPolyResult> findPolyEnd = query.findNearestPoly(end, extents, filter);
|
||||||
long startRef = findPolyStart.result.getNearestRef();
|
long startRef = findPolyStart.result.getNearestRef();
|
||||||
long endRef = findPolyEnd.result.getNearestRef();
|
long endRef = findPolyEnd.result.getNearestRef();
|
||||||
float[] startPos = findPolyStart.result.getNearestPos();
|
Vector3f startPos = findPolyStart.result.getNearestPos();
|
||||||
float[] endPos = findPolyEnd.result.getNearestPos();
|
Vector3f endPos = findPolyEnd.result.getNearestPos();
|
||||||
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
||||||
int maxStraightPath = 256;
|
int maxStraightPath = 256;
|
||||||
int options = 0;
|
int options = 0;
|
||||||
Result<List<StraightPathItem>> pathStr = query.findStraightPath(startPos, endPos, path.result, maxStraightPath,
|
Result<List<StraightPathItem>> pathStr = query.findStraightPath(startPos, endPos, path.result, maxStraightPath, options);
|
||||||
options);
|
|
||||||
Assert.That(pathStr.result.Count, Is.EqualTo(8));
|
Assert.That(pathStr.result.Count, Is.EqualTo(8));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -30,8 +30,8 @@ public class TileCacheNavigationTest : AbstractTileCacheTest
|
||||||
{
|
{
|
||||||
protected readonly long[] startRefs = { 281475006070787L };
|
protected readonly long[] startRefs = { 281475006070787L };
|
||||||
protected readonly long[] endRefs = { 281474986147841L };
|
protected readonly long[] endRefs = { 281474986147841L };
|
||||||
protected readonly float[][] startPoss = { new[] { 39.447338f, 9.998177f, -0.784811f } };
|
protected readonly Vector3f[] startPoss = { Vector3f.Of(39.447338f, 9.998177f, -0.784811f) };
|
||||||
protected readonly float[][] endPoss = { new[] { 19.292645f, 11.611748f, -57.750366f } };
|
protected readonly Vector3f[] endPoss = { Vector3f.Of(19.292645f, 11.611748f, -57.750366f) };
|
||||||
private readonly Status[] statuses = { Status.SUCCSESS };
|
private readonly Status[] statuses = { Status.SUCCSESS };
|
||||||
|
|
||||||
private readonly long[][] results =
|
private readonly long[][] results =
|
||||||
|
@ -86,8 +86,8 @@ public class TileCacheNavigationTest : AbstractTileCacheTest
|
||||||
{
|
{
|
||||||
long startRef = startRefs[i];
|
long startRef = startRefs[i];
|
||||||
long endRef = endRefs[i];
|
long endRef = endRefs[i];
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
float[] endPos = endPoss[i];
|
Vector3f endPos = endPoss[i];
|
||||||
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter);
|
||||||
Assert.That(path.status, Is.EqualTo(statuses[i]));
|
Assert.That(path.status, Is.EqualTo(statuses[i]));
|
||||||
Assert.That(path.result.Count, Is.EqualTo(results[i].Length));
|
Assert.That(path.result.Count, Is.EqualTo(results[i].Length));
|
||||||
|
@ -106,8 +106,8 @@ public class TileCacheNavigationTest : AbstractTileCacheTest
|
||||||
{
|
{
|
||||||
long startRef = startRefs[i];
|
long startRef = startRefs[i];
|
||||||
long endRef = endRefs[i];
|
long endRef = endRefs[i];
|
||||||
float[] startPos = startPoss[i];
|
Vector3f startPos = startPoss[i];
|
||||||
float[] endPos = endPoss[i];
|
Vector3f endPos = endPoss[i];
|
||||||
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter, new DefaultQueryHeuristic(0.0f),
|
Result<List<long>> path = query.findPath(startRef, endRef, startPos, endPos, filter, new DefaultQueryHeuristic(0.0f),
|
||||||
0, 0);
|
0, 0);
|
||||||
Assert.That(path.status, Is.EqualTo(statuses[i]));
|
Assert.That(path.status, Is.EqualTo(statuses[i]));
|
||||||
|
|
Loading…
Reference in New Issue