2023-03-14 08:02:43 +03:00
|
|
|
using System;
|
2023-03-28 19:52:26 +03:00
|
|
|
using DotRecast.Core;
|
2023-03-14 08:02:43 +03:00
|
|
|
|
2023-03-16 19:09:10 +03:00
|
|
|
namespace DotRecast.Detour.Extras.Jumplink
|
|
|
|
{
|
2023-03-16 19:48:49 +03:00
|
|
|
class EdgeSamplerFactory
|
|
|
|
{
|
|
|
|
public EdgeSampler get(JumpLinkBuilderConfig acfg, JumpLinkType type, Edge edge)
|
|
|
|
{
|
|
|
|
EdgeSampler es = null;
|
2023-03-26 07:51:30 +03:00
|
|
|
switch (type.Bit)
|
2023-03-16 19:48:49 +03:00
|
|
|
{
|
2023-03-26 07:51:30 +03:00
|
|
|
case JumpLinkType.EDGE_JUMP_BIT:
|
2023-03-16 19:48:49 +03:00
|
|
|
es = initEdgeJumpSampler(acfg, edge);
|
|
|
|
break;
|
2023-03-26 07:51:30 +03:00
|
|
|
case JumpLinkType.EDGE_CLIMB_DOWN_BIT:
|
2023-03-16 19:48:49 +03:00
|
|
|
es = initClimbDownSampler(acfg, edge);
|
|
|
|
break;
|
2023-03-26 07:51:30 +03:00
|
|
|
case JumpLinkType.EDGE_JUMP_OVER_BIT:
|
2023-03-16 19:48:49 +03:00
|
|
|
default:
|
|
|
|
throw new ArgumentException("Unsupported jump type " + type);
|
|
|
|
}
|
2023-03-16 19:09:10 +03:00
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
return es;
|
|
|
|
}
|
2023-03-14 08:02:43 +03:00
|
|
|
|
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
private EdgeSampler initEdgeJumpSampler(JumpLinkBuilderConfig acfg, Edge edge)
|
|
|
|
{
|
|
|
|
EdgeSampler es = new EdgeSampler(edge, new JumpTrajectory(acfg.jumpHeight));
|
|
|
|
es.start.height = acfg.agentClimb * 2;
|
2023-03-28 18:03:33 +03:00
|
|
|
Vector3f offset = new Vector3f();
|
2023-03-28 19:52:26 +03:00
|
|
|
trans2d(ref offset, es.az, es.ay, new Vector2f { x = acfg.startDistance, y = -acfg.agentClimb, });
|
|
|
|
vadd(ref es.start.p, edge.sp, offset);
|
|
|
|
vadd(ref es.start.q, edge.sq, offset);
|
2023-03-14 08:02:43 +03:00
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
float dx = acfg.endDistance - 2 * acfg.agentRadius;
|
|
|
|
float cs = acfg.cellSize;
|
|
|
|
int nsamples = Math.Max(2, (int)Math.Ceiling(dx / cs));
|
2023-03-14 08:02:43 +03:00
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
for (int j = 0; j < nsamples; ++j)
|
|
|
|
{
|
|
|
|
float v = (float)j / (float)(nsamples - 1);
|
|
|
|
float ox = 2 * acfg.agentRadius + dx * v;
|
2023-03-28 19:52:26 +03:00
|
|
|
trans2d(ref offset, es.az, es.ay, new Vector2f { x = ox, y = acfg.minHeight });
|
2023-03-16 19:48:49 +03:00
|
|
|
GroundSegment end = new GroundSegment();
|
|
|
|
end.height = acfg.heightRange;
|
2023-03-28 19:52:26 +03:00
|
|
|
vadd(ref end.p, edge.sp, offset);
|
|
|
|
vadd(ref end.q, edge.sq, offset);
|
2023-03-16 19:48:49 +03:00
|
|
|
es.end.Add(end);
|
|
|
|
}
|
2023-03-14 08:02:43 +03:00
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
return es;
|
|
|
|
}
|
2023-03-14 08:02:43 +03:00
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
private EdgeSampler initClimbDownSampler(JumpLinkBuilderConfig acfg, Edge edge)
|
|
|
|
{
|
|
|
|
EdgeSampler es = new EdgeSampler(edge, new ClimbTrajectory());
|
|
|
|
es.start.height = acfg.agentClimb * 2;
|
2023-03-28 18:03:33 +03:00
|
|
|
Vector3f offset = new Vector3f();
|
2023-03-28 19:52:26 +03:00
|
|
|
trans2d(ref offset, es.az, es.ay, new Vector2f() { x = acfg.startDistance, y = -acfg.agentClimb });
|
|
|
|
vadd(ref es.start.p, edge.sp, offset);
|
|
|
|
vadd(ref es.start.q, edge.sq, offset);
|
2023-03-14 08:02:43 +03:00
|
|
|
|
2023-03-28 19:52:26 +03:00
|
|
|
trans2d(ref offset, es.az, es.ay, new Vector2f() { x = acfg.endDistance, y = acfg.minHeight });
|
2023-03-14 08:02:43 +03:00
|
|
|
GroundSegment end = new GroundSegment();
|
|
|
|
end.height = acfg.heightRange;
|
2023-03-28 19:52:26 +03:00
|
|
|
vadd(ref end.p, edge.sp, offset);
|
|
|
|
vadd(ref end.q, edge.sq, offset);
|
2023-03-14 08:02:43 +03:00
|
|
|
es.end.Add(end);
|
2023-03-16 19:48:49 +03:00
|
|
|
return es;
|
2023-03-14 08:02:43 +03:00
|
|
|
}
|
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
private void vadd(float[] dest, float[] v1, float[] v2)
|
|
|
|
{
|
|
|
|
dest[0] = v1[0] + v2[0];
|
|
|
|
dest[1] = v1[1] + v2[1];
|
|
|
|
dest[2] = v1[2] + v2[2];
|
|
|
|
}
|
2023-03-28 19:52:26 +03:00
|
|
|
|
|
|
|
private void vadd(ref Vector3f dest, Vector3f v1, Vector3f v2)
|
|
|
|
{
|
|
|
|
dest[0] = v1[0] + v2[0];
|
|
|
|
dest[1] = v1[1] + v2[1];
|
|
|
|
dest[2] = v1[2] + v2[2];
|
|
|
|
}
|
|
|
|
|
2023-03-14 08:02:43 +03:00
|
|
|
|
2023-03-16 19:48:49 +03:00
|
|
|
private void trans2d(float[] dst, float[] ax, float[] ay, float[] pt)
|
|
|
|
{
|
|
|
|
dst[0] = ax[0] * pt[0] + ay[0] * pt[1];
|
|
|
|
dst[1] = ax[1] * pt[0] + ay[1] * pt[1];
|
|
|
|
dst[2] = ax[2] * pt[0] + ay[2] * pt[1];
|
|
|
|
}
|
2023-03-28 19:52:26 +03:00
|
|
|
|
|
|
|
private void trans2d(ref Vector3f dst, Vector3f ax, Vector3f ay, Vector2f pt)
|
|
|
|
{
|
|
|
|
dst[0] = ax[0] * pt[0] + ay[0] * pt[1];
|
|
|
|
dst[1] = ax[1] * pt[0] + ay[1] * pt[1];
|
|
|
|
dst[2] = ax[2] * pt[0] + ay[2] * pt[1];
|
|
|
|
}
|
|
|
|
|
2023-03-14 08:02:43 +03:00
|
|
|
}
|
2023-03-16 19:09:10 +03:00
|
|
|
}
|