Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Mesh DetaiIs are null after mesh generation #59

Open
lehmamic opened this issue Feb 22, 2024 · 1 comment
Open

Question: Mesh DetaiIs are null after mesh generation #59

lehmamic opened this issue Feb 22, 2024 · 1 comment

Comments

@lehmamic
Copy link

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:
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.

Terrain Mesh

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?

@ikpil
Copy link
Owner

ikpil commented Feb 26, 2024

I'm sorry.
I've been busy with work, so I couldn't focus.
There's a bundle of code for conversion in UniRecast. Could you please take a look?

If it doesn't work, please let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants