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; }); }); }