I'm playing around with OpenGL and trying to generate a navMesh with DotRecast. I'm a bit stuck because the detail mesh is always null after mesh generation.
I'm using a left hand coord system:
Im generating terrain mesh from a hightmap. The mesh is squared with a length of 800.0f (-400.0f to 400.0f) and a height between 0.0f and 40.0f. It has a grid of 256x256 cells divided into two triangular polygons each.
I'm converting my mesh to a right hand system before I pass it to the Geo provider:
public static class MeshConverter
{
public static MeshData<VertexPositionNormalTexture, uint> ConvertMeshToRightHandSystem(this MeshData<VertexPositionNormalTexture, uint> meshData)
{
var convertedVertices = new VertexPositionNormalTexture[meshData.Vertices.Length];
for (int i = 0; i < meshData.Vertices.Length; i++)
{
var vertex = meshData.Vertices[i];
// Swap X and Z for position and normal to convert the mesh for Recast
var newPosition = new Vector3D<float>(vertex.Position.Z, vertex.Position.Y, vertex.Position.X);
var newNormal = new Vector3D<float>(vertex.Normal.Z, vertex.Normal.Y, vertex.Normal.X);
convertedVertices[i] = new VertexPositionNormalTexture(newPosition, newNormal, vertex.TexCoords);
}
// The order of indices might need to be adjusted to correct the winding order.
// Since we have swapped axes, the orientation of triangles could be affected.
// For this specific case (just axis swap), it might not be necessary, but it should be tested.
var convertedIndices = new uint[meshData.Indices.Length];
for (int i = 0; i < meshData.Indices.Length; i += 3)
{
// Directly copy the indices as no direct impact on winding order is expected
convertedIndices[i] = meshData.Indices[i];
convertedIndices[i + 1] = meshData.Indices[i + 1];
convertedIndices[i + 2] = meshData.Indices[i + 2];
}
return new MeshData<VertexPositionNormalTexture, uint>(convertedVertices, convertedIndices);
}
}
And afterwards I try to generate the nav mesh:
var meshInRightHandSystem = mesh.ConvertMeshToRightHandSystem();
float[] vertexArray = meshInRightHandSystem.Vertices.SelectMany(v => new[] { v.Position.X, v.Position.Y, v.Position.Z }).ToArray();
int[] indexArray = meshInRightHandSystem.Indices.Select(i => (int)i).ToArray();
var geomProvider = new DemoInputGeomProvider(vertexArray, indexArray);
var partitionType = RcPartition.WATERSHED;
float tileSize = 800 / 256; // Die Größe eines Tiles, basierend auf der Größe deines Terrains und der Anzahl der Tiles
float cellSize = tileSize / 2; // Wie detailliert jedes Voxel sein sollte, kleinere Werte führen zu detaillierteren NavMeshes
float cellHeight = 0.2f; // Die Höhe jedes Voxels, kleinere Werte führen zu einem detaillierteren NavMesh
float agentHeight = 2.0f; // Die Höhe des Agenten, der das NavMesh nutzen wird
float agentRadius = 0.6f; // Der Radius des Agenten, der das NavMesh nutzen wird
float agentMaxClimb = 0.9f; // Die maximale Steigung, die der Agent überwinden kann
float agentMaxSlope = 45.0f; // Der maximale Neigungswinkel, den der Agent noch begehen kann
int regionMinSize = 8; // Die minimale Größe einer Region, die noch als begehbar betrachtet wird (in Voxeln)
int regionMergeSize = 20; // Die minimale Größe von Regionen, die zusammengeführt werden sollen (in Voxeln)
float edgeMaxLen = 12.0f; // Die maximale Länge der Kanten des NavMeshes (längere Kanten werden aufgeteilt)
float edgeMaxError = 1.3f; // Der maximale Fehler von Kantenverläufen im NavMesh
int vertsPerPoly = 6; // Die maximale Anzahl von Vertices pro Polygon
float detailSampleDist = 6.0f; // Der Abstand für die Detail-Mesh-Sampling, größer als 0 aktiviert das Detail-Mesh
float detailSampleMaxError = 1.0f; // Der maximale Sampling-Fehler für das Detail-Mesh
RcConfig recastConfig = new RcConfig(
true,
(int)tileSize,
(int)tileSize,
borderSize: 0,
partitionType,
cellSize,
cellHeight,
agentMaxSlope,
agentHeight,
agentRadius,
agentMaxClimb,
regionMinSize,
regionMergeSize,
edgeMaxLen,
edgeMaxError,
vertsPerPoly,
detailSampleDist,
detailSampleMaxError,
true,
true,
true,
SampleAreaModifications.SAMPLE_AREAMOD_GROUND,
true);
var recastBuilderConfig = new RcBuilderConfig(recastConfig, geomProvider.GetMeshBoundsMin(), geomProvider.GetMeshBoundsMax());
RcBuilder rcBuilder = new RcBuilder();
RcBuilderResult rcResult = rcBuilder.Build(geomProvider, recastBuilderConfig);
RcPolyMesh polyMesh = rcResult.GetMesh();
for (int i = 0; i < polyMesh.npolys; ++i)
{
polyMesh.flags[i] = 1;
}
RcPolyMeshDetail polyMeshDetail = rcResult.GetMeshDetail();
The poly mesh detail is always null. What I am doing wrong?
Hi,
I'm playing around with OpenGL and trying to generate a navMesh with DotRecast. I'm a bit stuck because the detail mesh is always
null
after mesh generation.I'm using a left hand coord system:
Im generating terrain mesh from a hightmap. The mesh is squared with a length of 800.0f (-400.0f to 400.0f) and a height between 0.0f and 40.0f. It has a grid of 256x256 cells divided into two triangular polygons each.
I'm converting my mesh to a right hand system before I pass it to the Geo provider:
And afterwards I try to generate the nav mesh:
The poly mesh detail is always
null
. What I am doing wrong?