internal static Vector3 TransformVert(System.Numerics.Vector3 vert, HKX2.hknpBodyCinfo body)
        {
            var newVert = new Vector3(vert.X, vert.Y, vert.Z);

            if (body == null)
            {
                return(newVert);
            }

            Vector3 trans = new Vector3(body.m_position.X, body.m_position.Y, body.m_position.Z);

            return(Vector3.Transform(newVert, body.m_orientation) + trans);
        }
        unsafe private void ProcessMesh(HKX2.fsnpCustomParamCompressedMeshShape mesh, HKX2.hknpBodyCinfo bodyinfo, CollisionSubmesh dest)
        {
            var verts   = new List <Vector3>();
            var indices = new List <int>();

            var coldata = mesh.m_data;

            foreach (var section in coldata.m_meshTree.m_sections)
            {
                for (int i = 0; i < (section.m_primitives.m_data & 0xFF); i++)
                {
                    var tri = coldata.m_meshTree.m_primitives[i + (int)(section.m_primitives.m_data >> 8)];
                    //if (tri.Idx2 == tri.Idx3 && tri.Idx1 != tri.Idx2)
                    //{

                    if (tri.m_indices_0 == 0xDE && tri.m_indices_1 == 0xAD && tri.m_indices_2 == 0xDE && tri.m_indices_3 == 0xAD)
                    {
                        continue; // Don't know what to do with this shape yet
                    }

                    uint sharedVerticesLength = section.m_sharedVertices.m_data & 0xFF;
                    uint sharedVerticesIndex  = section.m_sharedVertices.m_data >> 8;
                    var  smallVertexOffset    = new Vector3(section.m_codecParms_0, section.m_codecParms_1, section.m_codecParms_2);
                    var  smallVertexScale     = new Vector3(section.m_codecParms_3, section.m_codecParms_4, section.m_codecParms_5);
                    if (tri.m_indices_0 < sharedVerticesLength)
                    {
                        ushort index = (ushort)((uint)tri.m_indices_0 + section.m_firstPackedVertex);
                        indices.Add(verts.Count);

                        var vert = coldata.DecompressPackedVertex(coldata.m_meshTree.m_packedVertices[index], smallVertexScale, smallVertexOffset);
                        verts.Add(TransformVert(vert, bodyinfo));
                    }
                    else
                    {
                        ushort index = (ushort)(coldata.m_meshTree.m_sharedVerticesIndex[(int)(tri.m_indices_0 + sharedVerticesIndex - sharedVerticesLength)]);
                        indices.Add(verts.Count);

                        var vert = coldata.DecompressSharedVertex(coldata.m_meshTree.m_sharedVertices[index], coldata.m_meshTree.m_domain.m_min, coldata.m_meshTree.m_domain.m_max);
                        verts.Add(TransformVert(vert, bodyinfo));
                    }

                    if (tri.m_indices_1 < sharedVerticesLength)
                    {
                        ushort index = (ushort)((uint)tri.m_indices_1 + section.m_firstPackedVertex);
                        indices.Add(verts.Count);

                        var vert = coldata.DecompressPackedVertex(coldata.m_meshTree.m_packedVertices[index], smallVertexScale, smallVertexOffset);
                        verts.Add(TransformVert(vert, bodyinfo));
                    }
                    else
                    {
                        ushort index = (ushort)(coldata.m_meshTree.m_sharedVerticesIndex[(int)(tri.m_indices_1 + sharedVerticesIndex - sharedVerticesLength)]);
                        indices.Add(verts.Count);

                        var vert = coldata.DecompressSharedVertex(coldata.m_meshTree.m_sharedVertices[index], coldata.m_meshTree.m_domain.m_min, coldata.m_meshTree.m_domain.m_max);
                        verts.Add(TransformVert(vert, bodyinfo));
                    }

                    if (tri.m_indices_2 < sharedVerticesLength)
                    {
                        ushort index = (ushort)((uint)tri.m_indices_2 + section.m_firstPackedVertex);
                        indices.Add(verts.Count);

                        var vert = coldata.DecompressPackedVertex(coldata.m_meshTree.m_packedVertices[index], smallVertexScale, smallVertexOffset);
                        verts.Add(TransformVert(vert, bodyinfo));
                    }
                    else
                    {
                        ushort index = (ushort)(coldata.m_meshTree.m_sharedVerticesIndex[(int)(tri.m_indices_2 + sharedVerticesIndex - sharedVerticesLength)]);
                        indices.Add(verts.Count);

                        var vert = coldata.DecompressSharedVertex(coldata.m_meshTree.m_sharedVertices[index], coldata.m_meshTree.m_domain.m_min, coldata.m_meshTree.m_domain.m_max);
                        verts.Add(TransformVert(vert, bodyinfo));
                    }

                    if (tri.m_indices_2 != tri.m_indices_3)
                    {
                        indices.Add(verts.Count);
                        verts.Add(verts[verts.Count - 3]);
                        indices.Add(verts.Count);
                        verts.Add(verts[verts.Count - 2]);
                        if (tri.m_indices_3 < sharedVerticesLength)
                        {
                            ushort index = (ushort)((uint)tri.m_indices_3 + section.m_firstPackedVertex);
                            indices.Add(verts.Count);

                            var vert = coldata.DecompressPackedVertex(coldata.m_meshTree.m_packedVertices[index], smallVertexScale, smallVertexOffset);
                            verts.Add(TransformVert(vert, bodyinfo));
                        }
                        else
                        {
                            ushort index = (ushort)(coldata.m_meshTree.m_sharedVerticesIndex[(int)(tri.m_indices_3 + sharedVerticesIndex - sharedVerticesLength)]);
                            indices.Add(verts.Count);

                            var vert = coldata.DecompressSharedVertex(coldata.m_meshTree.m_sharedVertices[index], coldata.m_meshTree.m_domain.m_min, coldata.m_meshTree.m_domain.m_max);
                            verts.Add(TransformVert(vert, bodyinfo));
                        }
                    }
                }
            }

            dest.PickingIndices  = indices.ToArray();
            dest.PickingVertices = verts.ToArray();

            var MeshIndices  = new int[indices.Count];
            var MeshVertices = new CollisionLayout[indices.Count];
            var factory      = Scene.Renderer.Factory;

            for (int i = 0; i < indices.Count; i += 3)
            {
                var vert1 = verts[indices[i]];
                var vert2 = verts[indices[i + 1]];
                var vert3 = verts[indices[i + 2]];

                MeshVertices[i]     = new CollisionLayout();
                MeshVertices[i + 1] = new CollisionLayout();
                MeshVertices[i + 2] = new CollisionLayout();

                MeshVertices[i].Position     = vert1;
                MeshVertices[i + 1].Position = vert2;
                MeshVertices[i + 2].Position = vert3;
                var n = Vector3.Normalize(Vector3.Cross(MeshVertices[i + 2].Position - MeshVertices[i].Position, MeshVertices[i + 1].Position - MeshVertices[i].Position));
                MeshVertices[i].Normal[0]     = (sbyte)(n.X * 127.0f);
                MeshVertices[i].Normal[1]     = (sbyte)(n.Y * 127.0f);
                MeshVertices[i].Normal[2]     = (sbyte)(n.Z * 127.0f);
                MeshVertices[i + 1].Normal[0] = (sbyte)(n.X * 127.0f);
                MeshVertices[i + 1].Normal[1] = (sbyte)(n.Y * 127.0f);
                MeshVertices[i + 1].Normal[2] = (sbyte)(n.Z * 127.0f);
                MeshVertices[i + 2].Normal[0] = (sbyte)(n.X * 127.0f);
                MeshVertices[i + 2].Normal[1] = (sbyte)(n.Y * 127.0f);
                MeshVertices[i + 2].Normal[2] = (sbyte)(n.Z * 127.0f);

                MeshVertices[i].Color[0]           = (byte)(53);
                MeshVertices[i].Color[1]           = (byte)(157);
                MeshVertices[i].Color[2]           = (byte)(255);
                MeshVertices[i].Color[3]           = (byte)(255);
                MeshVertices[i + 1].Color[0]       = (byte)(53);
                MeshVertices[i + 1].Color[1]       = (byte)(157);
                MeshVertices[i + 1].Color[2]       = (byte)(255);
                MeshVertices[i + 1].Color[3]       = (byte)(255);
                MeshVertices[i + 2].Color[0]       = (byte)(53);
                MeshVertices[i + 2].Color[1]       = (byte)(157);
                MeshVertices[i + 2].Color[2]       = (byte)(255);
                MeshVertices[i + 2].Color[3]       = (byte)(255);
                MeshVertices[i].Barycentric[0]     = 0;
                MeshVertices[i].Barycentric[1]     = 0;
                MeshVertices[i + 1].Barycentric[0] = 1;
                MeshVertices[i + 1].Barycentric[1] = 0;
                MeshVertices[i + 2].Barycentric[0] = 0;
                MeshVertices[i + 2].Barycentric[1] = 1;

                MeshIndices[i]     = i;
                MeshIndices[i + 1] = i + 1;
                MeshIndices[i + 2] = i + 2;
            }

            dest.VertexCount = MeshVertices.Length;
            dest.IndexCount  = MeshIndices.Length;

            uint buffersize = (uint)dest.IndexCount * 4u;

            fixed(void *ptr = dest.PickingVertices)
            {
                dest.Bounds = BoundingBox.CreateFromPoints((Vector3 *)ptr, dest.PickingVertices.Count(), 12, Quaternion.Identity, Vector3.Zero, Vector3.One);
            }

            uint vbuffersize = (uint)MeshVertices.Length * CollisionLayout.SizeInBytes;

            dest.GeomBuffer = Scene.Renderer.GeometryBufferAllocator.Allocate(vbuffersize, buffersize, (int)CollisionLayout.SizeInBytes, 4, (h) =>
            {
                h.FillIBuffer(MeshIndices, () =>
                {
                    MeshIndices = null;
                });
                h.FillVBuffer(MeshVertices, () =>
                {
                    MeshVertices = null;
                });
            });
        }