{"record":{"id":"9e0df2a4c6209b74","repo":"stride3d/stride","slug":"meshdata-is-not-simple","errorCode":null,"errorMessage":"meshData is not simple.","messagePattern":"meshData is not simple\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Rendering/Extensions/TNBExtensions.cs","lineNumber":23,"sourceCode":"using Stride.Graphics.Data;\nusing Stride.Rendering;\n\nnamespace Stride.Extensions\n{\n    public static class TNBExtensions\n    {\n        /// <summary>\n        /// Generates the tangents and binormals for this mesh data.\n        /// Tangents and bitangents will be encoded as float4:\n        /// float3 for tangent and an additional float for handedness (1 or -1),\n        /// so that bitangent can be reconstructed.\n        /// More info at http://www.terathon.com/code/tangent.html\n        /// </summary>\n        /// <param name=\"meshData\">The mesh data.</param>\n        public static unsafe void GenerateTangentBinormal(this MeshDraw meshData)\n        {\n            if (!meshData.IsSimple())\n                throw new ArgumentException(\"meshData is not simple.\");\n\n            if (meshData.PrimitiveType != PrimitiveType.TriangleList\n                && meshData.PrimitiveType != PrimitiveType.TriangleListWithAdjacency)\n                throw new NotImplementedException();\n\n            var oldVertexBufferBinding = meshData.VertexBuffers[0];\n            var indexBufferBinding = meshData.IndexBuffer;\n            var indexData = indexBufferBinding?.Buffer.GetSerializationData().Content;\n\n            var oldVertexStride = oldVertexBufferBinding.Declaration.VertexStride;\n            var bufferData = oldVertexBufferBinding.Buffer.GetSerializationData().Content;\n\n            fixed (byte* indexBufferStart = indexData)\n            fixed (byte* oldBuffer = bufferData)\n            {\n                var result = VertexHelper.GenerateTangentBinormal(\n                    vertexDeclaration: oldVertexBufferBinding.Declaration,\n                    vertexBufferData: (nint)oldBuffer,","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Rendering/Extensions/TNBExtensions.cs#L5-L41","documentation":"GenerateTangentBinormal computes per-vertex tangents and binormals and only supports 'simple' meshes — a single vertex buffer containing all attributes. This ArgumentException is thrown when meshData.IsSimple() returns false (multiple vertex buffers or non-simple layout), because the tangent math indexes directly into VertexBuffers[0].","triggerScenarios":"Calling GenerateTangentBinormal on a MeshDraw with multiple vertex buffers, or one whose declaration is not a simple interleaved layout.","commonSituations":"Meshes with split position/attribute streams; multi-buffer meshes produced by merge tooling; forgetting to check IsSimple before generating tangents.","solutions":["Re-interleave the mesh into one vertex buffer so IsSimple() is true, then compute tangents","Compute tangents manually for multi-buffer meshes (parallel arrays) instead of using this extension","Skip tangent generation and supply tangents from the asset/importer"],"exampleFix":"// before\nmesh.GenerateTangentBinormal(); // multi-buffer mesh\n// after\nif (mesh.IsSimple())\n    mesh.GenerateTangentBinormal();\nelse\n    mesh = RebuildSingleBuffer(mesh); // then GenerateTangentBinormal","handlingStrategy":"validation","validationCode":"if (mesh.IsSimple()) mesh.GenerateTangentBinormal();\nelse mesh = RebuildSingleBuffer(mesh); // then generate tangents","typeGuard":"static bool CanGenerateTangents(MeshDraw mesh) => mesh.IsSimple();","tryCatchPattern":"try { mesh.GenerateTangentBinormal(); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"not simple\")) {\n    mesh = RebuildSingleBuffer(mesh);\n    mesh.GenerateTangentBinormal();\n}","preventionTips":["Ensure meshData.IsSimple() holds before any tangent/BINORMAL post-processing","Rebuild multi-buffer meshes into a single interleaved buffer at import","Automate tangent generation inside the asset pipeline where layout is guaranteed"],"tags":["csharp","rendering","tangent-space"],"backgroundTag":"invalid-argument-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}