forked from bit/DotRecastNetSim
128 lines
4.3 KiB
C#
128 lines
4.3 KiB
C#
using System.Collections.Generic;
|
|
using DotRecast.Core.Numerics;
|
|
using System.Numerics;
|
|
using DotRecast.Detour.Extras.Jumplink;
|
|
using DotRecast.Recast.Geom;
|
|
using DotRecast.Recast.Toolset.Builder;
|
|
|
|
namespace DotRecast.Recast.Toolset.Tools
|
|
{
|
|
public class RcJumpLinkBuilderTool : IRcToolable
|
|
{
|
|
private readonly List<JumpLink> _links;
|
|
private JumpLinkBuilder _annotationBuilder;
|
|
private readonly int _selEdge = -1;
|
|
|
|
public RcJumpLinkBuilderTool()
|
|
{
|
|
_links = new List<JumpLink>();
|
|
}
|
|
|
|
|
|
public string GetName()
|
|
{
|
|
return "Annotation Builder";
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
_annotationBuilder = null;
|
|
}
|
|
|
|
public JumpLinkBuilder GetAnnotationBuilder()
|
|
{
|
|
return _annotationBuilder;
|
|
}
|
|
|
|
public int GetSelEdge()
|
|
{
|
|
return _selEdge;
|
|
}
|
|
|
|
public List<JumpLink> GetLinks()
|
|
{
|
|
return _links;
|
|
}
|
|
|
|
public void Build(IInputGeomProvider geom, RcNavMeshBuildSettings settings, IList<RcBuilderResult> results, RcJumpLinkBuilderToolConfig cfg)
|
|
{
|
|
if (_annotationBuilder == null)
|
|
{
|
|
if (0 < results.Count)
|
|
{
|
|
_annotationBuilder = new JumpLinkBuilder(results);
|
|
}
|
|
}
|
|
|
|
_links.Clear();
|
|
if (_annotationBuilder != null)
|
|
{
|
|
float cellSize = settings.cellSize;
|
|
float agentHeight = settings.agentHeight;
|
|
float agentRadius = settings.agentRadius;
|
|
float agentClimb = settings.agentMaxClimb;
|
|
float cellHeight = settings.cellHeight;
|
|
|
|
if ((cfg.buildTypes & JumpLinkType.EDGE_CLIMB_DOWN.Bit) != 0)
|
|
{
|
|
JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(
|
|
cellSize,
|
|
cellHeight,
|
|
agentRadius,
|
|
agentHeight,
|
|
agentClimb,
|
|
cfg.groundTolerance,
|
|
-agentRadius * 0.2f,
|
|
cellSize + 2 * agentRadius + cfg.climbDownDistance,
|
|
-cfg.climbDownMaxHeight,
|
|
-cfg.climbDownMinHeight,
|
|
0
|
|
);
|
|
_links.AddRange(_annotationBuilder.Build(config, JumpLinkType.EDGE_CLIMB_DOWN));
|
|
}
|
|
|
|
if ((cfg.buildTypes & JumpLinkType.EDGE_JUMP.Bit) != 0)
|
|
{
|
|
JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(
|
|
cellSize,
|
|
cellHeight,
|
|
agentRadius,
|
|
agentHeight,
|
|
agentClimb,
|
|
cfg.groundTolerance,
|
|
-agentRadius * 0.2f,
|
|
cfg.edgeJumpEndDistance,
|
|
-cfg.edgeJumpDownMaxHeight,
|
|
cfg.edgeJumpUpMaxHeight,
|
|
cfg.edgeJumpHeight
|
|
);
|
|
_links.AddRange(_annotationBuilder.Build(config, JumpLinkType.EDGE_JUMP));
|
|
}
|
|
|
|
if (cfg.buildOffMeshConnections)
|
|
{
|
|
int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO;
|
|
geom.RemoveOffMeshConnections(c => c.area == area);
|
|
_links.ForEach(l => AddOffMeshLink(l, geom, agentRadius));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AddOffMeshLink(JumpLink link, IInputGeomProvider geom, float agentRadius)
|
|
{
|
|
int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO;
|
|
int flags = SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP;
|
|
Vector3 prev = new Vector3();
|
|
for (int i = 0; i < link.startSamples.Length; i++)
|
|
{
|
|
Vector3 p = link.startSamples[i].p;
|
|
Vector3 q = link.endSamples[i].p;
|
|
if (i == 0 || RcVecUtils.Dist2D(prev, p) > agentRadius)
|
|
{
|
|
geom.AddOffMeshConnection(p, q, agentRadius, false, area, flags);
|
|
prev = p;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |