forked from mirror/DotRecast
for unity3d
This commit is contained in:
parent
cfe8378f1d
commit
17891c2d43
|
@ -1,97 +0,0 @@
|
|||
using DotRecast.Detour;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Builder;
|
||||
|
||||
public abstract class AbstractNavMeshBuilder
|
||||
{
|
||||
protected NavMeshDataCreateParams GetNavMeshCreateParams(DemoInputGeomProvider m_geom, float m_cellSize,
|
||||
float m_cellHeight, float m_agentHeight, float m_agentRadius, float m_agentMaxClimb,
|
||||
RecastBuilderResult rcResult)
|
||||
{
|
||||
PolyMesh m_pmesh = rcResult.GetMesh();
|
||||
PolyMeshDetail m_dmesh = rcResult.GetMeshDetail();
|
||||
NavMeshDataCreateParams option = new NavMeshDataCreateParams();
|
||||
for (int i = 0; i < m_pmesh.npolys; ++i)
|
||||
{
|
||||
m_pmesh.flags[i] = 1;
|
||||
}
|
||||
|
||||
option.verts = m_pmesh.verts;
|
||||
option.vertCount = m_pmesh.nverts;
|
||||
option.polys = m_pmesh.polys;
|
||||
option.polyAreas = m_pmesh.areas;
|
||||
option.polyFlags = m_pmesh.flags;
|
||||
option.polyCount = m_pmesh.npolys;
|
||||
option.nvp = m_pmesh.nvp;
|
||||
if (m_dmesh != null)
|
||||
{
|
||||
option.detailMeshes = m_dmesh.meshes;
|
||||
option.detailVerts = m_dmesh.verts;
|
||||
option.detailVertsCount = m_dmesh.nverts;
|
||||
option.detailTris = m_dmesh.tris;
|
||||
option.detailTriCount = m_dmesh.ntris;
|
||||
}
|
||||
|
||||
option.walkableHeight = m_agentHeight;
|
||||
option.walkableRadius = m_agentRadius;
|
||||
option.walkableClimb = m_agentMaxClimb;
|
||||
option.bmin = m_pmesh.bmin;
|
||||
option.bmax = m_pmesh.bmax;
|
||||
option.cs = m_cellSize;
|
||||
option.ch = m_cellHeight;
|
||||
option.buildBvTree = true;
|
||||
|
||||
option.offMeshConCount = m_geom.GetOffMeshConnections().Count;
|
||||
option.offMeshConVerts = new float[option.offMeshConCount * 6];
|
||||
option.offMeshConRad = new float[option.offMeshConCount];
|
||||
option.offMeshConDir = new int[option.offMeshConCount];
|
||||
option.offMeshConAreas = new int[option.offMeshConCount];
|
||||
option.offMeshConFlags = new int[option.offMeshConCount];
|
||||
option.offMeshConUserID = new int[option.offMeshConCount];
|
||||
for (int i = 0; i < option.offMeshConCount; i++)
|
||||
{
|
||||
DemoOffMeshConnection offMeshCon = m_geom.GetOffMeshConnections()[i];
|
||||
for (int j = 0; j < 6; j++)
|
||||
{
|
||||
option.offMeshConVerts[6 * i + j] = offMeshCon.verts[j];
|
||||
}
|
||||
|
||||
option.offMeshConRad[i] = offMeshCon.radius;
|
||||
option.offMeshConDir[i] = offMeshCon.bidir ? 1 : 0;
|
||||
option.offMeshConAreas[i] = offMeshCon.area;
|
||||
option.offMeshConFlags[i] = offMeshCon.flags;
|
||||
}
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
protected MeshData UpdateAreaAndFlags(MeshData meshData)
|
||||
{
|
||||
// Update poly flags from areas.
|
||||
for (int i = 0; i < meshData.polys.Length; ++i)
|
||||
{
|
||||
if (meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_WALKABLE)
|
||||
{
|
||||
meshData.polys[i].SetArea(SampleAreaModifications.SAMPLE_POLYAREA_TYPE_GROUND);
|
||||
}
|
||||
|
||||
if (meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_GROUND
|
||||
|| meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_GRASS
|
||||
|| meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_ROAD)
|
||||
{
|
||||
meshData.polys[i].flags = SampleAreaModifications.SAMPLE_POLYFLAGS_WALK;
|
||||
}
|
||||
else if (meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_WATER)
|
||||
{
|
||||
meshData.polys[i].flags = SampleAreaModifications.SAMPLE_POLYFLAGS_SWIM;
|
||||
}
|
||||
else if (meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_DOOR)
|
||||
{
|
||||
meshData.polys[i].flags = SampleAreaModifications.SAMPLE_POLYFLAGS_DOOR;
|
||||
}
|
||||
}
|
||||
|
||||
return meshData;
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
|
||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Builder;
|
||||
|
||||
public class SampleAreaModifications
|
||||
{
|
||||
public const int SAMPLE_POLYAREA_TYPE_GROUND = 0x0;
|
||||
public const int SAMPLE_POLYAREA_TYPE_WATER = 0x1;
|
||||
public const int SAMPLE_POLYAREA_TYPE_ROAD = 0x2;
|
||||
public const int SAMPLE_POLYAREA_TYPE_DOOR = 0x3;
|
||||
public const int SAMPLE_POLYAREA_TYPE_GRASS = 0x4;
|
||||
public const int SAMPLE_POLYAREA_TYPE_JUMP = 0x5;
|
||||
public const int SAMPLE_POLYAREA_TYPE_JUMP_AUTO = 0x6;
|
||||
public const int SAMPLE_POLYAREA_TYPE_WALKABLE = 0x3f;
|
||||
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_WALKABLE = new(SAMPLE_POLYAREA_TYPE_WALKABLE);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_GROUND = new(SAMPLE_POLYAREA_TYPE_GROUND);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_WATER = new(SAMPLE_POLYAREA_TYPE_WATER);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_ROAD = new(SAMPLE_POLYAREA_TYPE_ROAD);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_GRASS = new(SAMPLE_POLYAREA_TYPE_GRASS);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_DOOR = new(SAMPLE_POLYAREA_TYPE_DOOR);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_JUMP = new(SAMPLE_POLYAREA_TYPE_JUMP);
|
||||
|
||||
public static readonly ImmutableArray<AreaModification> Values = ImmutableArray.Create(
|
||||
SAMPLE_AREAMOD_WALKABLE,
|
||||
SAMPLE_AREAMOD_GROUND,
|
||||
SAMPLE_AREAMOD_WATER,
|
||||
SAMPLE_AREAMOD_ROAD,
|
||||
SAMPLE_AREAMOD_GRASS,
|
||||
SAMPLE_AREAMOD_DOOR,
|
||||
SAMPLE_AREAMOD_JUMP
|
||||
);
|
||||
|
||||
public static AreaModification OfValue(int value)
|
||||
{
|
||||
return Values.FirstOrDefault(x => x.Value == value, SAMPLE_AREAMOD_GRASS);
|
||||
}
|
||||
|
||||
public static readonly int SAMPLE_POLYFLAGS_WALK = 0x01; // Ability to walk (ground, grass, road)
|
||||
public static readonly int SAMPLE_POLYFLAGS_SWIM = 0x02; // Ability to swim (water).
|
||||
public static readonly int SAMPLE_POLYFLAGS_DOOR = 0x04; // Ability to move through doors.
|
||||
public static readonly int SAMPLE_POLYFLAGS_JUMP = 0x08; // Ability to jump.
|
||||
public static readonly int SAMPLE_POLYFLAGS_DISABLED = 0x10; // Disabled polygon
|
||||
public static readonly int SAMPLE_POLYFLAGS_ALL = 0xffff; // All abilities.
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using DotRecast.Detour;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Builder;
|
||||
|
||||
public class SoloNavMeshBuilder : AbstractNavMeshBuilder
|
||||
{
|
||||
public Tuple<IList<RecastBuilderResult>, NavMesh> Build(DemoInputGeomProvider geom, PartitionType partitionType,
|
||||
float cellSize, float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
|
||||
float agentMaxSlope, int regionMinSize, int regionMergeSize, float edgeMaxLen, float edgeMaxError,
|
||||
int vertsPerPoly, float detailSampleDist, float detailSampleMaxError, bool filterLowHangingObstacles,
|
||||
bool filterLedgeSpans, bool filterWalkableLowHeightSpans)
|
||||
{
|
||||
RecastBuilderResult rcResult = BuildRecastResult(geom, partitionType, cellSize, cellHeight, agentHeight,
|
||||
agentRadius, agentMaxClimb, agentMaxSlope, regionMinSize, regionMergeSize, edgeMaxLen, edgeMaxError,
|
||||
vertsPerPoly, detailSampleDist, detailSampleMaxError, filterLowHangingObstacles, filterLedgeSpans,
|
||||
filterWalkableLowHeightSpans);
|
||||
return Tuple.Create(ImmutableArray.Create(rcResult) as IList<RecastBuilderResult>,
|
||||
BuildNavMesh(
|
||||
BuildMeshData(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, rcResult),
|
||||
vertsPerPoly));
|
||||
}
|
||||
|
||||
private NavMesh BuildNavMesh(MeshData meshData, int vertsPerPoly)
|
||||
{
|
||||
return new NavMesh(meshData, vertsPerPoly, 0);
|
||||
}
|
||||
|
||||
private RecastBuilderResult BuildRecastResult(DemoInputGeomProvider geom, PartitionType partitionType, float cellSize,
|
||||
float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb, float agentMaxSlope,
|
||||
int regionMinSize, int regionMergeSize, float edgeMaxLen, float edgeMaxError, int vertsPerPoly,
|
||||
float detailSampleDist, float detailSampleMaxError, bool filterLowHangingObstacles, bool filterLedgeSpans,
|
||||
bool filterWalkableLowHeightSpans)
|
||||
{
|
||||
RecastConfig cfg = new RecastConfig(partitionType, cellSize, cellHeight, agentMaxSlope, filterLowHangingObstacles,
|
||||
filterLedgeSpans, filterWalkableLowHeightSpans, agentHeight, agentRadius, agentMaxClimb, regionMinSize,
|
||||
regionMergeSize, edgeMaxLen, edgeMaxError, vertsPerPoly, detailSampleDist, detailSampleMaxError,
|
||||
SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE, true);
|
||||
RecastBuilderConfig bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax());
|
||||
RecastBuilder rcBuilder = new RecastBuilder();
|
||||
return rcBuilder.Build(geom, bcfg);
|
||||
}
|
||||
|
||||
private MeshData BuildMeshData(DemoInputGeomProvider geom, float cellSize, float cellHeight, float agentHeight,
|
||||
float agentRadius, float agentMaxClimb, RecastBuilderResult result)
|
||||
{
|
||||
NavMeshDataCreateParams option = GetNavMeshCreateParams(geom, cellSize, cellHeight, agentHeight, agentRadius,
|
||||
agentMaxClimb, result);
|
||||
return UpdateAreaAndFlags(NavMeshBuilder.CreateNavMeshData(option));
|
||||
}
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using DotRecast.Core;
|
||||
using DotRecast.Detour;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using static DotRecast.Core.RcMath;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Builder;
|
||||
|
||||
public class TileNavMeshBuilder : AbstractNavMeshBuilder
|
||||
{
|
||||
public TileNavMeshBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
public Tuple<IList<RecastBuilderResult>, NavMesh> Build(DemoInputGeomProvider geom, PartitionType partitionType,
|
||||
float cellSize, float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
|
||||
float agentMaxSlope, int regionMinSize, int regionMergeSize, float edgeMaxLen, float edgeMaxError,
|
||||
int vertsPerPoly, float detailSampleDist, float detailSampleMaxError, bool filterLowHangingObstacles,
|
||||
bool filterLedgeSpans, bool filterWalkableLowHeightSpans, int tileSize)
|
||||
{
|
||||
List<RecastBuilderResult> rcResult = BuildRecastResult(geom, partitionType, cellSize, cellHeight, agentHeight,
|
||||
agentRadius, agentMaxClimb, agentMaxSlope, regionMinSize, regionMergeSize, edgeMaxLen, edgeMaxError,
|
||||
vertsPerPoly, detailSampleDist, detailSampleMaxError, filterLowHangingObstacles, filterLedgeSpans,
|
||||
filterWalkableLowHeightSpans, tileSize);
|
||||
return Tuple.Create((IList<RecastBuilderResult>)rcResult,
|
||||
BuildNavMesh(geom,
|
||||
BuildMeshData(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, rcResult),
|
||||
cellSize, tileSize, vertsPerPoly));
|
||||
}
|
||||
|
||||
private List<RecastBuilderResult> BuildRecastResult(DemoInputGeomProvider geom, PartitionType partitionType,
|
||||
float cellSize, float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
|
||||
float agentMaxSlope, int regionMinSize, int regionMergeSize, float edgeMaxLen, float edgeMaxError,
|
||||
int vertsPerPoly, float detailSampleDist, float detailSampleMaxError, bool filterLowHangingObstacles,
|
||||
bool filterLedgeSpans, bool filterWalkableLowHeightSpans, int tileSize)
|
||||
{
|
||||
RecastConfig cfg = new RecastConfig(true, tileSize, tileSize, RecastConfig.CalcBorder(agentRadius, cellSize),
|
||||
partitionType, cellSize, cellHeight, agentMaxSlope, filterLowHangingObstacles, filterLedgeSpans,
|
||||
filterWalkableLowHeightSpans, agentHeight, agentRadius, agentMaxClimb,
|
||||
regionMinSize * regionMinSize * cellSize * cellSize,
|
||||
regionMergeSize * regionMergeSize * cellSize * cellSize, edgeMaxLen, edgeMaxError, vertsPerPoly,
|
||||
true, detailSampleDist, detailSampleMaxError, SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE);
|
||||
RecastBuilder rcBuilder = new RecastBuilder();
|
||||
return rcBuilder.BuildTiles(geom, cfg, Task.Factory);
|
||||
}
|
||||
|
||||
private NavMesh BuildNavMesh(DemoInputGeomProvider geom, List<MeshData> meshData, float cellSize, int tileSize,
|
||||
int vertsPerPoly)
|
||||
{
|
||||
NavMeshParams navMeshParams = new NavMeshParams();
|
||||
navMeshParams.orig.x = geom.GetMeshBoundsMin().x;
|
||||
navMeshParams.orig.y = geom.GetMeshBoundsMin().y;
|
||||
navMeshParams.orig.z = geom.GetMeshBoundsMin().z;
|
||||
navMeshParams.tileWidth = tileSize * cellSize;
|
||||
navMeshParams.tileHeight = tileSize * cellSize;
|
||||
|
||||
// Snprintf(text, 64, "Tiles %d x %d", tw, th);
|
||||
|
||||
navMeshParams.maxTiles = GetMaxTiles(geom, cellSize, tileSize);
|
||||
navMeshParams.maxPolys = GetMaxPolysPerTile(geom, cellSize, tileSize);
|
||||
NavMesh navMesh = new NavMesh(navMeshParams, vertsPerPoly);
|
||||
meshData.ForEach(md => navMesh.AddTile(md, 0, 0));
|
||||
return navMesh;
|
||||
}
|
||||
|
||||
public int GetMaxTiles(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
||||
{
|
||||
int tileBits = GetTileBits(geom, cellSize, tileSize);
|
||||
return 1 << tileBits;
|
||||
}
|
||||
|
||||
public int GetMaxPolysPerTile(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
||||
{
|
||||
int polyBits = 22 - GetTileBits(geom, cellSize, tileSize);
|
||||
return 1 << polyBits;
|
||||
}
|
||||
|
||||
private int GetTileBits(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
||||
{
|
||||
Recast.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
||||
int tw = (gw + tileSize - 1) / tileSize;
|
||||
int th = (gh + tileSize - 1) / tileSize;
|
||||
int tileBits = Math.Min(DetourCommon.Ilog2(DetourCommon.NextPow2(tw * th)), 14);
|
||||
return tileBits;
|
||||
}
|
||||
|
||||
public int[] GetTiles(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
||||
{
|
||||
Recast.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
||||
int tw = (gw + tileSize - 1) / tileSize;
|
||||
int th = (gh + tileSize - 1) / tileSize;
|
||||
return new int[] { tw, th };
|
||||
}
|
||||
|
||||
private List<MeshData> BuildMeshData(DemoInputGeomProvider geom, float cellSize, float cellHeight, float agentHeight,
|
||||
float agentRadius, float agentMaxClimb, List<RecastBuilderResult> results)
|
||||
{
|
||||
// Add tiles to nav mesh
|
||||
List<MeshData> meshData = new();
|
||||
foreach (RecastBuilderResult result in results)
|
||||
{
|
||||
int x = result.tileX;
|
||||
int z = result.tileZ;
|
||||
NavMeshDataCreateParams option = GetNavMeshCreateParams(geom, cellSize, cellHeight, agentHeight,
|
||||
agentRadius, agentMaxClimb, result);
|
||||
option.tileX = x;
|
||||
option.tileZ = z;
|
||||
MeshData md = NavMeshBuilder.CreateNavMeshData(option);
|
||||
if (md != null)
|
||||
{
|
||||
meshData.Add(UpdateAreaAndFlags(md));
|
||||
}
|
||||
}
|
||||
|
||||
return meshData;
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ freely, subject to the following restrictions:
|
|||
|
||||
using System;
|
||||
using DotRecast.Core;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Draw;
|
||||
|
|
|
@ -21,8 +21,8 @@ freely, subject to the following restrictions:
|
|||
using System.Collections.Generic;
|
||||
using DotRecast.Core;
|
||||
using DotRecast.Detour;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
using DotRecast.Recast.Demo.UI;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Draw;
|
||||
|
|
|
@ -24,7 +24,7 @@ using System.Numerics;
|
|||
using DotRecast.Core;
|
||||
using DotRecast.Detour;
|
||||
using DotRecast.Detour.QueryResults;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Draw;
|
||||
|
|
|
@ -1,226 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
|
||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using DotRecast.Core;
|
||||
using DotRecast.Recast.Geom;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Geom;
|
||||
|
||||
public class DemoInputGeomProvider : IInputGeomProvider
|
||||
{
|
||||
public readonly float[] vertices;
|
||||
public readonly int[] faces;
|
||||
public readonly float[] normals;
|
||||
private readonly RcVec3f bmin;
|
||||
private readonly RcVec3f bmax;
|
||||
private readonly List<ConvexVolume> _convexVolumes = new();
|
||||
private readonly List<DemoOffMeshConnection> offMeshConnections = new();
|
||||
private readonly TriMesh _mesh;
|
||||
|
||||
public DemoInputGeomProvider(List<float> vertexPositions, List<int> meshFaces) :
|
||||
this(MapVertices(vertexPositions), MapFaces(meshFaces))
|
||||
{
|
||||
}
|
||||
|
||||
private static int[] MapFaces(List<int> meshFaces)
|
||||
{
|
||||
int[] faces = new int[meshFaces.Count];
|
||||
for (int i = 0; i < faces.Length; i++)
|
||||
{
|
||||
faces[i] = meshFaces[i];
|
||||
}
|
||||
|
||||
return faces;
|
||||
}
|
||||
|
||||
private static float[] MapVertices(List<float> vertexPositions)
|
||||
{
|
||||
float[] vertices = new float[vertexPositions.Count];
|
||||
for (int i = 0; i < vertices.Length; i++)
|
||||
{
|
||||
vertices[i] = vertexPositions[i];
|
||||
}
|
||||
|
||||
return vertices;
|
||||
}
|
||||
|
||||
public DemoInputGeomProvider(float[] vertices, int[] faces)
|
||||
{
|
||||
this.vertices = vertices;
|
||||
this.faces = faces;
|
||||
normals = new float[faces.Length];
|
||||
CalculateNormals();
|
||||
bmin = RcVec3f.Zero;
|
||||
bmax = RcVec3f.Zero;
|
||||
RcVec3f.Copy(ref bmin, vertices, 0);
|
||||
RcVec3f.Copy(ref bmax, vertices, 0);
|
||||
for (int i = 1; i < vertices.Length / 3; i++)
|
||||
{
|
||||
bmin.Min(vertices, i * 3);
|
||||
bmax.Max(vertices, i * 3);
|
||||
}
|
||||
|
||||
_mesh = new TriMesh(vertices, faces);
|
||||
}
|
||||
|
||||
public RcVec3f GetMeshBoundsMin()
|
||||
{
|
||||
return bmin;
|
||||
}
|
||||
|
||||
public RcVec3f GetMeshBoundsMax()
|
||||
{
|
||||
return bmax;
|
||||
}
|
||||
|
||||
public void CalculateNormals()
|
||||
{
|
||||
for (int i = 0; i < faces.Length; i += 3)
|
||||
{
|
||||
int v0 = faces[i] * 3;
|
||||
int v1 = faces[i + 1] * 3;
|
||||
int v2 = faces[i + 2] * 3;
|
||||
RcVec3f e0 = new RcVec3f();
|
||||
RcVec3f e1 = new RcVec3f();
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
e0[j] = vertices[v1 + j] - vertices[v0 + j];
|
||||
e1[j] = vertices[v2 + j] - vertices[v0 + j];
|
||||
}
|
||||
|
||||
normals[i] = e0.y * e1.z - e0.z * e1.y;
|
||||
normals[i + 1] = e0.z * e1.x - e0.x * e1.z;
|
||||
normals[i + 2] = e0.x * e1.y - e0.y * e1.x;
|
||||
float d = (float)Math.Sqrt(normals[i] * normals[i] + normals[i + 1] * normals[i + 1] + normals[i + 2] * normals[i + 2]);
|
||||
if (d > 0)
|
||||
{
|
||||
d = 1.0f / d;
|
||||
normals[i] *= d;
|
||||
normals[i + 1] *= d;
|
||||
normals[i + 2] *= d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IList<ConvexVolume> ConvexVolumes()
|
||||
{
|
||||
return _convexVolumes;
|
||||
}
|
||||
|
||||
public IEnumerable<TriMesh> Meshes()
|
||||
{
|
||||
return ImmutableArray.Create(_mesh);
|
||||
}
|
||||
|
||||
public List<DemoOffMeshConnection> GetOffMeshConnections()
|
||||
{
|
||||
return offMeshConnections;
|
||||
}
|
||||
|
||||
public void AddOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags)
|
||||
{
|
||||
offMeshConnections.Add(new DemoOffMeshConnection(start, end, radius, bidir, area, flags));
|
||||
}
|
||||
|
||||
public void RemoveOffMeshConnections(Predicate<DemoOffMeshConnection> filter)
|
||||
{
|
||||
//offMeshConnections.RetainAll(offMeshConnections.Stream().Filter(c -> !filter.Test(c)).Collect(ToList()));
|
||||
offMeshConnections.RemoveAll(filter); // TODO : 확인 필요
|
||||
}
|
||||
|
||||
public float? RaycastMesh(RcVec3f src, RcVec3f dst)
|
||||
{
|
||||
// Prune hit ray.
|
||||
if (!Intersections.IsectSegAABB(src, dst, bmin, bmax, out var btmin, out var btmax))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
float[] p = new float[2];
|
||||
float[] q = new float[2];
|
||||
p[0] = src.x + (dst.x - src.x) * btmin;
|
||||
p[1] = src.z + (dst.z - src.z) * btmin;
|
||||
q[0] = src.x + (dst.x - src.x) * btmax;
|
||||
q[1] = src.z + (dst.z - src.z) * btmax;
|
||||
|
||||
List<ChunkyTriMeshNode> chunks = _mesh.chunkyTriMesh.GetChunksOverlappingSegment(p, q);
|
||||
if (0 == chunks.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
float tmin = 1.0f;
|
||||
bool hit = false;
|
||||
foreach (ChunkyTriMeshNode chunk in chunks)
|
||||
{
|
||||
int[] tris = chunk.tris;
|
||||
for (int j = 0; j < chunk.tris.Length; j += 3)
|
||||
{
|
||||
RcVec3f v1 = RcVec3f.Of(
|
||||
vertices[tris[j] * 3],
|
||||
vertices[tris[j] * 3 + 1],
|
||||
vertices[tris[j] * 3 + 2]
|
||||
);
|
||||
RcVec3f v2 = RcVec3f.Of(
|
||||
vertices[tris[j + 1] * 3],
|
||||
vertices[tris[j + 1] * 3 + 1],
|
||||
vertices[tris[j + 1] * 3 + 2]
|
||||
);
|
||||
RcVec3f v3 = RcVec3f.Of(
|
||||
vertices[tris[j + 2] * 3],
|
||||
vertices[tris[j + 2] * 3 + 1],
|
||||
vertices[tris[j + 2] * 3 + 2]
|
||||
);
|
||||
float? t = Intersections.IntersectSegmentTriangle(src, dst, v1, v2, v3);
|
||||
if (null != t)
|
||||
{
|
||||
if (t.Value < tmin)
|
||||
{
|
||||
tmin = t.Value;
|
||||
}
|
||||
|
||||
hit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hit ? tmin : null;
|
||||
}
|
||||
|
||||
|
||||
public void AddConvexVolume(float[] verts, float minh, float maxh, AreaModification areaMod)
|
||||
{
|
||||
ConvexVolume volume = new ConvexVolume();
|
||||
volume.verts = verts;
|
||||
volume.hmin = minh;
|
||||
volume.hmax = maxh;
|
||||
volume.areaMod = areaMod;
|
||||
_convexVolumes.Add(volume);
|
||||
}
|
||||
|
||||
public void ClearConvexVolumes()
|
||||
{
|
||||
_convexVolumes.Clear();
|
||||
}
|
||||
}
|
|
@ -35,9 +35,9 @@ using DotRecast.Core;
|
|||
using DotRecast.Detour;
|
||||
using DotRecast.Detour.Extras.Unity.Astar;
|
||||
using DotRecast.Detour.Io;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using DotRecast.Recast.Demo.Draw;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
using DotRecast.Recast.Demo.Tools;
|
||||
using DotRecast.Recast.Demo.UI;
|
||||
using static DotRecast.Core.RcMath;
|
||||
|
@ -385,10 +385,12 @@ public class RecastDemo
|
|||
var renderGl = _gl.GetStringS(GLEnum.Renderer);
|
||||
var glslString = _gl.GetStringS(GLEnum.ShadingLanguageVersion);
|
||||
|
||||
Logger.Debug(vendor);
|
||||
Logger.Debug(version);
|
||||
Logger.Debug(renderGl);
|
||||
Logger.Debug(glslString);
|
||||
var workingDirectory = Directory.GetCurrentDirectory();
|
||||
Logger.Information($"working directory - {workingDirectory}");
|
||||
Logger.Information(vendor);
|
||||
Logger.Information(version);
|
||||
Logger.Information(renderGl);
|
||||
Logger.Information(glslString);
|
||||
|
||||
|
||||
DemoInputGeomProvider geom = LoadInputMesh(Loader.ToBytes("nav_test.obj"));
|
||||
|
|
|
@ -21,7 +21,7 @@ freely, subject to the following restrictions:
|
|||
using System.Collections.Generic;
|
||||
using DotRecast.Detour;
|
||||
using DotRecast.Recast.Demo.Draw;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
|
||||
using DotRecast.Recast.Demo.UI;
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Silk.NET.Windowing;
|
||||
using DotRecast.Core;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using DotRecast.Recast.Demo.Draw;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
using ImGuiNET;
|
||||
using static DotRecast.Recast.Demo.Draw.DebugDraw;
|
||||
using static DotRecast.Recast.Demo.Draw.DebugDrawPrimitives;
|
||||
|
|
|
@ -24,7 +24,7 @@ using DotRecast.Core;
|
|||
using DotRecast.Detour;
|
||||
using DotRecast.Detour.Crowd;
|
||||
using DotRecast.Detour.QueryResults;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using DotRecast.Recast.Demo.Draw;
|
||||
using ImGuiNET;
|
||||
using Silk.NET.Windowing;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
|
||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -26,9 +27,9 @@ using DotRecast.Detour;
|
|||
using DotRecast.Detour.Crowd;
|
||||
using DotRecast.Detour.Crowd.Tracking;
|
||||
using DotRecast.Detour.QueryResults;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using DotRecast.Recast.Demo.Draw;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
using ImGuiNET;
|
||||
using static DotRecast.Recast.Demo.Draw.DebugDraw;
|
||||
using static DotRecast.Recast.Demo.Draw.DebugDrawPrimitives;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Tools;
|
||||
|
||||
|
|
|
@ -30,9 +30,9 @@ using DotRecast.Core;
|
|||
using DotRecast.Detour.Dynamic;
|
||||
using DotRecast.Detour.Dynamic.Colliders;
|
||||
using DotRecast.Detour.Dynamic.Io;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using DotRecast.Recast.Demo.Draw;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
using DotRecast.Recast.Demo.Tools.Gizmos;
|
||||
using DotRecast.Recast.Demo.UI;
|
||||
using ImGuiNET;
|
||||
|
|
|
@ -21,9 +21,9 @@ using System.Linq;
|
|||
using DotRecast.Core;
|
||||
using Silk.NET.Windowing;
|
||||
using DotRecast.Detour.Extras.Jumplink;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using DotRecast.Recast.Demo.Draw;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
using ImGuiNET;
|
||||
using static DotRecast.Core.RcMath;
|
||||
using static DotRecast.Recast.Demo.Draw.DebugDraw;
|
||||
|
|
|
@ -21,9 +21,9 @@ freely, subject to the following restrictions:
|
|||
using System;
|
||||
using Silk.NET.Windowing;
|
||||
using DotRecast.Core;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using DotRecast.Recast.Demo.Draw;
|
||||
using DotRecast.Recast.Demo.Geom;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
using ImGuiNET;
|
||||
using static DotRecast.Recast.Demo.Draw.DebugDraw;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||
using DotRecast.Core;
|
||||
using DotRecast.Detour;
|
||||
using DotRecast.Detour.QueryResults;
|
||||
using DotRecast.Recast.Demo.Builder;
|
||||
using DotRecast.Recast.DemoTool.Builder;
|
||||
using DotRecast.Recast.Demo.Draw;
|
||||
using ImGuiNET;
|
||||
using static DotRecast.Core.RcMath;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
|
||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
using DotRecast.Detour;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
|
||||
namespace DotRecast.Recast.DemoTool.Builder
|
||||
{
|
||||
public abstract class AbstractNavMeshBuilder
|
||||
{
|
||||
protected NavMeshDataCreateParams GetNavMeshCreateParams(DemoInputGeomProvider m_geom, float m_cellSize,
|
||||
float m_cellHeight, float m_agentHeight, float m_agentRadius, float m_agentMaxClimb,
|
||||
RecastBuilderResult rcResult)
|
||||
{
|
||||
PolyMesh m_pmesh = rcResult.GetMesh();
|
||||
PolyMeshDetail m_dmesh = rcResult.GetMeshDetail();
|
||||
NavMeshDataCreateParams option = new NavMeshDataCreateParams();
|
||||
for (int i = 0; i < m_pmesh.npolys; ++i)
|
||||
{
|
||||
m_pmesh.flags[i] = 1;
|
||||
}
|
||||
|
||||
option.verts = m_pmesh.verts;
|
||||
option.vertCount = m_pmesh.nverts;
|
||||
option.polys = m_pmesh.polys;
|
||||
option.polyAreas = m_pmesh.areas;
|
||||
option.polyFlags = m_pmesh.flags;
|
||||
option.polyCount = m_pmesh.npolys;
|
||||
option.nvp = m_pmesh.nvp;
|
||||
if (m_dmesh != null)
|
||||
{
|
||||
option.detailMeshes = m_dmesh.meshes;
|
||||
option.detailVerts = m_dmesh.verts;
|
||||
option.detailVertsCount = m_dmesh.nverts;
|
||||
option.detailTris = m_dmesh.tris;
|
||||
option.detailTriCount = m_dmesh.ntris;
|
||||
}
|
||||
|
||||
option.walkableHeight = m_agentHeight;
|
||||
option.walkableRadius = m_agentRadius;
|
||||
option.walkableClimb = m_agentMaxClimb;
|
||||
option.bmin = m_pmesh.bmin;
|
||||
option.bmax = m_pmesh.bmax;
|
||||
option.cs = m_cellSize;
|
||||
option.ch = m_cellHeight;
|
||||
option.buildBvTree = true;
|
||||
|
||||
option.offMeshConCount = m_geom.GetOffMeshConnections().Count;
|
||||
option.offMeshConVerts = new float[option.offMeshConCount * 6];
|
||||
option.offMeshConRad = new float[option.offMeshConCount];
|
||||
option.offMeshConDir = new int[option.offMeshConCount];
|
||||
option.offMeshConAreas = new int[option.offMeshConCount];
|
||||
option.offMeshConFlags = new int[option.offMeshConCount];
|
||||
option.offMeshConUserID = new int[option.offMeshConCount];
|
||||
for (int i = 0; i < option.offMeshConCount; i++)
|
||||
{
|
||||
DemoOffMeshConnection offMeshCon = m_geom.GetOffMeshConnections()[i];
|
||||
for (int j = 0; j < 6; j++)
|
||||
{
|
||||
option.offMeshConVerts[6 * i + j] = offMeshCon.verts[j];
|
||||
}
|
||||
|
||||
option.offMeshConRad[i] = offMeshCon.radius;
|
||||
option.offMeshConDir[i] = offMeshCon.bidir ? 1 : 0;
|
||||
option.offMeshConAreas[i] = offMeshCon.area;
|
||||
option.offMeshConFlags[i] = offMeshCon.flags;
|
||||
}
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
protected MeshData UpdateAreaAndFlags(MeshData meshData)
|
||||
{
|
||||
// Update poly flags from areas.
|
||||
for (int i = 0; i < meshData.polys.Length; ++i)
|
||||
{
|
||||
if (meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_WALKABLE)
|
||||
{
|
||||
meshData.polys[i].SetArea(SampleAreaModifications.SAMPLE_POLYAREA_TYPE_GROUND);
|
||||
}
|
||||
|
||||
if (meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_GROUND
|
||||
|| meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_GRASS
|
||||
|| meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_ROAD)
|
||||
{
|
||||
meshData.polys[i].flags = SampleAreaModifications.SAMPLE_POLYFLAGS_WALK;
|
||||
}
|
||||
else if (meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_WATER)
|
||||
{
|
||||
meshData.polys[i].flags = SampleAreaModifications.SAMPLE_POLYFLAGS_SWIM;
|
||||
}
|
||||
else if (meshData.polys[i].GetArea() == SampleAreaModifications.SAMPLE_POLYAREA_TYPE_DOOR)
|
||||
{
|
||||
meshData.polys[i].flags = SampleAreaModifications.SAMPLE_POLYFLAGS_DOOR;
|
||||
}
|
||||
}
|
||||
|
||||
return meshData;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
|
||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace DotRecast.Recast.DemoTool.Builder
|
||||
{
|
||||
|
||||
public class SampleAreaModifications
|
||||
{
|
||||
public const int SAMPLE_POLYAREA_TYPE_GROUND = 0x0;
|
||||
public const int SAMPLE_POLYAREA_TYPE_WATER = 0x1;
|
||||
public const int SAMPLE_POLYAREA_TYPE_ROAD = 0x2;
|
||||
public const int SAMPLE_POLYAREA_TYPE_DOOR = 0x3;
|
||||
public const int SAMPLE_POLYAREA_TYPE_GRASS = 0x4;
|
||||
public const int SAMPLE_POLYAREA_TYPE_JUMP = 0x5;
|
||||
public const int SAMPLE_POLYAREA_TYPE_JUMP_AUTO = 0x6;
|
||||
public const int SAMPLE_POLYAREA_TYPE_WALKABLE = 0x3f;
|
||||
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_WALKABLE = new AreaModification(SAMPLE_POLYAREA_TYPE_WALKABLE);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_GROUND = new AreaModification(SAMPLE_POLYAREA_TYPE_GROUND);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_WATER = new AreaModification(SAMPLE_POLYAREA_TYPE_WATER);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_ROAD = new AreaModification(SAMPLE_POLYAREA_TYPE_ROAD);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_GRASS = new AreaModification(SAMPLE_POLYAREA_TYPE_GRASS);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_DOOR = new AreaModification(SAMPLE_POLYAREA_TYPE_DOOR);
|
||||
public static readonly AreaModification SAMPLE_AREAMOD_JUMP = new AreaModification(SAMPLE_POLYAREA_TYPE_JUMP);
|
||||
|
||||
public static readonly ImmutableArray<AreaModification> Values = ImmutableArray.Create(
|
||||
SAMPLE_AREAMOD_WALKABLE,
|
||||
SAMPLE_AREAMOD_GROUND,
|
||||
SAMPLE_AREAMOD_WATER,
|
||||
SAMPLE_AREAMOD_ROAD,
|
||||
SAMPLE_AREAMOD_GRASS,
|
||||
SAMPLE_AREAMOD_DOOR,
|
||||
SAMPLE_AREAMOD_JUMP
|
||||
);
|
||||
|
||||
public static AreaModification OfValue(int value)
|
||||
{
|
||||
return Values.FirstOrDefault(x => x.Value == value) ?? SAMPLE_AREAMOD_GRASS;
|
||||
}
|
||||
|
||||
public static readonly int SAMPLE_POLYFLAGS_WALK = 0x01; // Ability to walk (ground, grass, road)
|
||||
public static readonly int SAMPLE_POLYFLAGS_SWIM = 0x02; // Ability to swim (water).
|
||||
public static readonly int SAMPLE_POLYFLAGS_DOOR = 0x04; // Ability to move through doors.
|
||||
public static readonly int SAMPLE_POLYFLAGS_JUMP = 0x08; // Ability to jump.
|
||||
public static readonly int SAMPLE_POLYFLAGS_DISABLED = 0x10; // Disabled polygon
|
||||
public static readonly int SAMPLE_POLYFLAGS_ALL = 0xffff; // All abilities.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using DotRecast.Detour;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
|
||||
namespace DotRecast.Recast.DemoTool.Builder
|
||||
{
|
||||
public class SoloNavMeshBuilder : AbstractNavMeshBuilder
|
||||
{
|
||||
public Tuple<IList<RecastBuilderResult>, NavMesh> Build(DemoInputGeomProvider geom, PartitionType partitionType,
|
||||
float cellSize, float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
|
||||
float agentMaxSlope, int regionMinSize, int regionMergeSize, float edgeMaxLen, float edgeMaxError,
|
||||
int vertsPerPoly, float detailSampleDist, float detailSampleMaxError, bool filterLowHangingObstacles,
|
||||
bool filterLedgeSpans, bool filterWalkableLowHeightSpans)
|
||||
{
|
||||
RecastBuilderResult rcResult = BuildRecastResult(geom, partitionType, cellSize, cellHeight, agentHeight,
|
||||
agentRadius, agentMaxClimb, agentMaxSlope, regionMinSize, regionMergeSize, edgeMaxLen, edgeMaxError,
|
||||
vertsPerPoly, detailSampleDist, detailSampleMaxError, filterLowHangingObstacles, filterLedgeSpans,
|
||||
filterWalkableLowHeightSpans);
|
||||
return Tuple.Create(ImmutableArray.Create(rcResult) as IList<RecastBuilderResult>,
|
||||
BuildNavMesh(
|
||||
BuildMeshData(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, rcResult),
|
||||
vertsPerPoly));
|
||||
}
|
||||
|
||||
private NavMesh BuildNavMesh(MeshData meshData, int vertsPerPoly)
|
||||
{
|
||||
return new NavMesh(meshData, vertsPerPoly, 0);
|
||||
}
|
||||
|
||||
private RecastBuilderResult BuildRecastResult(DemoInputGeomProvider geom, PartitionType partitionType, float cellSize,
|
||||
float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb, float agentMaxSlope,
|
||||
int regionMinSize, int regionMergeSize, float edgeMaxLen, float edgeMaxError, int vertsPerPoly,
|
||||
float detailSampleDist, float detailSampleMaxError, bool filterLowHangingObstacles, bool filterLedgeSpans,
|
||||
bool filterWalkableLowHeightSpans)
|
||||
{
|
||||
RecastConfig cfg = new RecastConfig(partitionType, cellSize, cellHeight, agentMaxSlope, filterLowHangingObstacles,
|
||||
filterLedgeSpans, filterWalkableLowHeightSpans, agentHeight, agentRadius, agentMaxClimb, regionMinSize,
|
||||
regionMergeSize, edgeMaxLen, edgeMaxError, vertsPerPoly, detailSampleDist, detailSampleMaxError,
|
||||
SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE, true);
|
||||
RecastBuilderConfig bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax());
|
||||
RecastBuilder rcBuilder = new RecastBuilder();
|
||||
return rcBuilder.Build(geom, bcfg);
|
||||
}
|
||||
|
||||
private MeshData BuildMeshData(DemoInputGeomProvider geom, float cellSize, float cellHeight, float agentHeight,
|
||||
float agentRadius, float agentMaxClimb, RecastBuilderResult result)
|
||||
{
|
||||
NavMeshDataCreateParams option = GetNavMeshCreateParams(geom, cellSize, cellHeight, agentHeight, agentRadius,
|
||||
agentMaxClimb, result);
|
||||
return UpdateAreaAndFlags(NavMeshBuilder.CreateNavMeshData(option));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using DotRecast.Core;
|
||||
using DotRecast.Detour;
|
||||
using DotRecast.Recast.DemoTool.Geom;
|
||||
using static DotRecast.Core.RcMath;
|
||||
|
||||
namespace DotRecast.Recast.DemoTool.Builder
|
||||
{
|
||||
public class TileNavMeshBuilder : AbstractNavMeshBuilder
|
||||
{
|
||||
public TileNavMeshBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
public Tuple<IList<RecastBuilderResult>, NavMesh> Build(DemoInputGeomProvider geom, PartitionType partitionType,
|
||||
float cellSize, float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
|
||||
float agentMaxSlope, int regionMinSize, int regionMergeSize, float edgeMaxLen, float edgeMaxError,
|
||||
int vertsPerPoly, float detailSampleDist, float detailSampleMaxError, bool filterLowHangingObstacles,
|
||||
bool filterLedgeSpans, bool filterWalkableLowHeightSpans, int tileSize)
|
||||
{
|
||||
List<RecastBuilderResult> rcResult = BuildRecastResult(geom, partitionType, cellSize, cellHeight, agentHeight,
|
||||
agentRadius, agentMaxClimb, agentMaxSlope, regionMinSize, regionMergeSize, edgeMaxLen, edgeMaxError,
|
||||
vertsPerPoly, detailSampleDist, detailSampleMaxError, filterLowHangingObstacles, filterLedgeSpans,
|
||||
filterWalkableLowHeightSpans, tileSize);
|
||||
return Tuple.Create((IList<RecastBuilderResult>)rcResult,
|
||||
BuildNavMesh(geom,
|
||||
BuildMeshData(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, rcResult),
|
||||
cellSize, tileSize, vertsPerPoly));
|
||||
}
|
||||
|
||||
private List<RecastBuilderResult> BuildRecastResult(DemoInputGeomProvider geom, PartitionType partitionType,
|
||||
float cellSize, float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
|
||||
float agentMaxSlope, int regionMinSize, int regionMergeSize, float edgeMaxLen, float edgeMaxError,
|
||||
int vertsPerPoly, float detailSampleDist, float detailSampleMaxError, bool filterLowHangingObstacles,
|
||||
bool filterLedgeSpans, bool filterWalkableLowHeightSpans, int tileSize)
|
||||
{
|
||||
RecastConfig cfg = new RecastConfig(true, tileSize, tileSize, RecastConfig.CalcBorder(agentRadius, cellSize),
|
||||
partitionType, cellSize, cellHeight, agentMaxSlope, filterLowHangingObstacles, filterLedgeSpans,
|
||||
filterWalkableLowHeightSpans, agentHeight, agentRadius, agentMaxClimb,
|
||||
regionMinSize * regionMinSize * cellSize * cellSize,
|
||||
regionMergeSize * regionMergeSize * cellSize * cellSize, edgeMaxLen, edgeMaxError, vertsPerPoly,
|
||||
true, detailSampleDist, detailSampleMaxError, SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE);
|
||||
RecastBuilder rcBuilder = new RecastBuilder();
|
||||
return rcBuilder.BuildTiles(geom, cfg, Task.Factory);
|
||||
}
|
||||
|
||||
private NavMesh BuildNavMesh(DemoInputGeomProvider geom, List<MeshData> meshData, float cellSize, int tileSize,
|
||||
int vertsPerPoly)
|
||||
{
|
||||
NavMeshParams navMeshParams = new NavMeshParams();
|
||||
navMeshParams.orig.x = geom.GetMeshBoundsMin().x;
|
||||
navMeshParams.orig.y = geom.GetMeshBoundsMin().y;
|
||||
navMeshParams.orig.z = geom.GetMeshBoundsMin().z;
|
||||
navMeshParams.tileWidth = tileSize * cellSize;
|
||||
navMeshParams.tileHeight = tileSize * cellSize;
|
||||
|
||||
// Snprintf(text, 64, "Tiles %d x %d", tw, th);
|
||||
|
||||
navMeshParams.maxTiles = GetMaxTiles(geom, cellSize, tileSize);
|
||||
navMeshParams.maxPolys = GetMaxPolysPerTile(geom, cellSize, tileSize);
|
||||
NavMesh navMesh = new NavMesh(navMeshParams, vertsPerPoly);
|
||||
meshData.ForEach(md => navMesh.AddTile(md, 0, 0));
|
||||
return navMesh;
|
||||
}
|
||||
|
||||
public int GetMaxTiles(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
||||
{
|
||||
int tileBits = GetTileBits(geom, cellSize, tileSize);
|
||||
return 1 << tileBits;
|
||||
}
|
||||
|
||||
public int GetMaxPolysPerTile(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
||||
{
|
||||
int polyBits = 22 - GetTileBits(geom, cellSize, tileSize);
|
||||
return 1 << polyBits;
|
||||
}
|
||||
|
||||
private int GetTileBits(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
||||
{
|
||||
Recast.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
||||
int tw = (gw + tileSize - 1) / tileSize;
|
||||
int th = (gh + tileSize - 1) / tileSize;
|
||||
int tileBits = Math.Min(DetourCommon.Ilog2(DetourCommon.NextPow2(tw * th)), 14);
|
||||
return tileBits;
|
||||
}
|
||||
|
||||
public int[] GetTiles(DemoInputGeomProvider geom, float cellSize, int tileSize)
|
||||
{
|
||||
Recast.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh);
|
||||
int tw = (gw + tileSize - 1) / tileSize;
|
||||
int th = (gh + tileSize - 1) / tileSize;
|
||||
return new int[] { tw, th };
|
||||
}
|
||||
|
||||
private List<MeshData> BuildMeshData(DemoInputGeomProvider geom, float cellSize, float cellHeight, float agentHeight,
|
||||
float agentRadius, float agentMaxClimb, List<RecastBuilderResult> results)
|
||||
{
|
||||
// Add tiles to nav mesh
|
||||
List<MeshData> meshData = new List<MeshData>();
|
||||
foreach (RecastBuilderResult result in results)
|
||||
{
|
||||
int x = result.tileX;
|
||||
int z = result.tileZ;
|
||||
NavMeshDataCreateParams option = GetNavMeshCreateParams(geom, cellSize, cellHeight, agentHeight,
|
||||
agentRadius, agentMaxClimb, result);
|
||||
option.tileX = x;
|
||||
option.tileZ = z;
|
||||
MeshData md = NavMeshBuilder.CreateNavMeshData(option);
|
||||
if (md != null)
|
||||
{
|
||||
meshData.Add(UpdateAreaAndFlags(md));
|
||||
}
|
||||
}
|
||||
|
||||
return meshData;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org
|
||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using DotRecast.Core;
|
||||
using DotRecast.Recast.Geom;
|
||||
|
||||
namespace DotRecast.Recast.DemoTool.Geom
|
||||
{
|
||||
public class DemoInputGeomProvider : IInputGeomProvider
|
||||
{
|
||||
public readonly float[] vertices;
|
||||
public readonly int[] faces;
|
||||
public readonly float[] normals;
|
||||
private readonly RcVec3f bmin;
|
||||
private readonly RcVec3f bmax;
|
||||
private readonly List<ConvexVolume> _convexVolumes = new List<ConvexVolume>();
|
||||
private readonly List<DemoOffMeshConnection> offMeshConnections = new List<DemoOffMeshConnection>();
|
||||
private readonly TriMesh _mesh;
|
||||
|
||||
public DemoInputGeomProvider(List<float> vertexPositions, List<int> meshFaces) :
|
||||
this(MapVertices(vertexPositions), MapFaces(meshFaces))
|
||||
{
|
||||
}
|
||||
|
||||
private static int[] MapFaces(List<int> meshFaces)
|
||||
{
|
||||
int[] faces = new int[meshFaces.Count];
|
||||
for (int i = 0; i < faces.Length; i++)
|
||||
{
|
||||
faces[i] = meshFaces[i];
|
||||
}
|
||||
|
||||
return faces;
|
||||
}
|
||||
|
||||
private static float[] MapVertices(List<float> vertexPositions)
|
||||
{
|
||||
float[] vertices = new float[vertexPositions.Count];
|
||||
for (int i = 0; i < vertices.Length; i++)
|
||||
{
|
||||
vertices[i] = vertexPositions[i];
|
||||
}
|
||||
|
||||
return vertices;
|
||||
}
|
||||
|
||||
public DemoInputGeomProvider(float[] vertices, int[] faces)
|
||||
{
|
||||
this.vertices = vertices;
|
||||
this.faces = faces;
|
||||
normals = new float[faces.Length];
|
||||
CalculateNormals();
|
||||
bmin = RcVec3f.Zero;
|
||||
bmax = RcVec3f.Zero;
|
||||
RcVec3f.Copy(ref bmin, vertices, 0);
|
||||
RcVec3f.Copy(ref bmax, vertices, 0);
|
||||
for (int i = 1; i < vertices.Length / 3; i++)
|
||||
{
|
||||
bmin.Min(vertices, i * 3);
|
||||
bmax.Max(vertices, i * 3);
|
||||
}
|
||||
|
||||
_mesh = new TriMesh(vertices, faces);
|
||||
}
|
||||
|
||||
public RcVec3f GetMeshBoundsMin()
|
||||
{
|
||||
return bmin;
|
||||
}
|
||||
|
||||
public RcVec3f GetMeshBoundsMax()
|
||||
{
|
||||
return bmax;
|
||||
}
|
||||
|
||||
public void CalculateNormals()
|
||||
{
|
||||
for (int i = 0; i < faces.Length; i += 3)
|
||||
{
|
||||
int v0 = faces[i] * 3;
|
||||
int v1 = faces[i + 1] * 3;
|
||||
int v2 = faces[i + 2] * 3;
|
||||
RcVec3f e0 = new RcVec3f();
|
||||
RcVec3f e1 = new RcVec3f();
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
e0[j] = vertices[v1 + j] - vertices[v0 + j];
|
||||
e1[j] = vertices[v2 + j] - vertices[v0 + j];
|
||||
}
|
||||
|
||||
normals[i] = e0.y * e1.z - e0.z * e1.y;
|
||||
normals[i + 1] = e0.z * e1.x - e0.x * e1.z;
|
||||
normals[i + 2] = e0.x * e1.y - e0.y * e1.x;
|
||||
float d = (float)Math.Sqrt(normals[i] * normals[i] + normals[i + 1] * normals[i + 1] + normals[i + 2] * normals[i + 2]);
|
||||
if (d > 0)
|
||||
{
|
||||
d = 1.0f / d;
|
||||
normals[i] *= d;
|
||||
normals[i + 1] *= d;
|
||||
normals[i + 2] *= d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IList<ConvexVolume> ConvexVolumes()
|
||||
{
|
||||
return _convexVolumes;
|
||||
}
|
||||
|
||||
public IEnumerable<TriMesh> Meshes()
|
||||
{
|
||||
return ImmutableArray.Create(_mesh);
|
||||
}
|
||||
|
||||
public List<DemoOffMeshConnection> GetOffMeshConnections()
|
||||
{
|
||||
return offMeshConnections;
|
||||
}
|
||||
|
||||
public void AddOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags)
|
||||
{
|
||||
offMeshConnections.Add(new DemoOffMeshConnection(start, end, radius, bidir, area, flags));
|
||||
}
|
||||
|
||||
public void RemoveOffMeshConnections(Predicate<DemoOffMeshConnection> filter)
|
||||
{
|
||||
//offMeshConnections.RetainAll(offMeshConnections.Stream().Filter(c -> !filter.Test(c)).Collect(ToList()));
|
||||
offMeshConnections.RemoveAll(filter); // TODO : 확인 필요
|
||||
}
|
||||
|
||||
public float? RaycastMesh(RcVec3f src, RcVec3f dst)
|
||||
{
|
||||
// Prune hit ray.
|
||||
if (!Intersections.IsectSegAABB(src, dst, bmin, bmax, out var btmin, out var btmax))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
float[] p = new float[2];
|
||||
float[] q = new float[2];
|
||||
p[0] = src.x + (dst.x - src.x) * btmin;
|
||||
p[1] = src.z + (dst.z - src.z) * btmin;
|
||||
q[0] = src.x + (dst.x - src.x) * btmax;
|
||||
q[1] = src.z + (dst.z - src.z) * btmax;
|
||||
|
||||
List<ChunkyTriMeshNode> chunks = _mesh.chunkyTriMesh.GetChunksOverlappingSegment(p, q);
|
||||
if (0 == chunks.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
float? tmin = 1.0f;
|
||||
bool hit = false;
|
||||
foreach (ChunkyTriMeshNode chunk in chunks)
|
||||
{
|
||||
int[] tris = chunk.tris;
|
||||
for (int j = 0; j < chunk.tris.Length; j += 3)
|
||||
{
|
||||
RcVec3f v1 = RcVec3f.Of(
|
||||
vertices[tris[j] * 3],
|
||||
vertices[tris[j] * 3 + 1],
|
||||
vertices[tris[j] * 3 + 2]
|
||||
);
|
||||
RcVec3f v2 = RcVec3f.Of(
|
||||
vertices[tris[j + 1] * 3],
|
||||
vertices[tris[j + 1] * 3 + 1],
|
||||
vertices[tris[j + 1] * 3 + 2]
|
||||
);
|
||||
RcVec3f v3 = RcVec3f.Of(
|
||||
vertices[tris[j + 2] * 3],
|
||||
vertices[tris[j + 2] * 3 + 1],
|
||||
vertices[tris[j + 2] * 3 + 2]
|
||||
);
|
||||
float? t = Intersections.IntersectSegmentTriangle(src, dst, v1, v2, v3);
|
||||
if (null != t)
|
||||
{
|
||||
if (t.Value < tmin)
|
||||
{
|
||||
tmin = t.Value;
|
||||
}
|
||||
|
||||
hit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hit
|
||||
? tmin
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
public void AddConvexVolume(float[] verts, float minh, float maxh, AreaModification areaMod)
|
||||
{
|
||||
ConvexVolume volume = new ConvexVolume();
|
||||
volume.verts = verts;
|
||||
volume.hmin = minh;
|
||||
volume.hmax = maxh;
|
||||
volume.areaMod = areaMod;
|
||||
_convexVolumes.Add(volume);
|
||||
}
|
||||
|
||||
public void ClearConvexVolumes()
|
||||
{
|
||||
_convexVolumes.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,28 +20,29 @@ freely, subject to the following restrictions:
|
|||
|
||||
using DotRecast.Core;
|
||||
|
||||
namespace DotRecast.Recast.Demo.Geom;
|
||||
|
||||
public class DemoOffMeshConnection
|
||||
namespace DotRecast.Recast.DemoTool.Geom
|
||||
{
|
||||
public readonly float[] verts;
|
||||
public readonly float radius;
|
||||
public readonly bool bidir;
|
||||
public readonly int area;
|
||||
public readonly int flags;
|
||||
|
||||
public DemoOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags)
|
||||
public class DemoOffMeshConnection
|
||||
{
|
||||
verts = new float[6];
|
||||
verts[0] = start.x;
|
||||
verts[1] = start.y;
|
||||
verts[2] = start.z;
|
||||
verts[3] = end.x;
|
||||
verts[4] = end.y;
|
||||
verts[5] = end.z;
|
||||
this.radius = radius;
|
||||
this.bidir = bidir;
|
||||
this.area = area;
|
||||
this.flags = flags;
|
||||
public readonly float[] verts;
|
||||
public readonly float radius;
|
||||
public readonly bool bidir;
|
||||
public readonly int area;
|
||||
public readonly int flags;
|
||||
|
||||
public DemoOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags)
|
||||
{
|
||||
verts = new float[6];
|
||||
verts[0] = start.x;
|
||||
verts[1] = start.y;
|
||||
verts[2] = start.z;
|
||||
verts[3] = end.x;
|
||||
verts[4] = end.y;
|
||||
verts[5] = end.z;
|
||||
this.radius = radius;
|
||||
this.bidir = bidir;
|
||||
this.area = area;
|
||||
this.flags = flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
Recast4J Copyright (c) 2015 Piotr Piastucki piotr@jtilia.org
|
||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org
|
||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
Loading…
Reference in New Issue