unsafe private void ProcessMesh(HKX.FSNPCustomParamCompressedMeshShape mesh, HKX.HKNPBodyCInfo bodyinfo, CollisionSubmesh dest) { var verts = new List <Vector3>(); var indices = new List <int>(); var coldata = mesh.GetMeshShapeData(); foreach (var section in coldata.sections.GetArrayData().Elements) { for (int i = 0; i < section.primitivesLength; i++) { var tri = coldata.primitives.GetArrayData().Elements[i + section.primitivesIndex]; //if (tri.Idx2 == tri.Idx3 && tri.Idx1 != tri.Idx2) //{ if (tri.Idx0 == 0xDE && tri.Idx1 == 0xAD && tri.Idx2 == 0xDE && tri.Idx3 == 0xAD) { continue; // Don't know what to do with this shape yet } if (tri.Idx0 < section.sharedVerticesLength) { ushort index = (ushort)((uint)tri.Idx0 + section.firstPackedVertex); indices.Add(verts.Count); var vert = coldata.packedVertices.GetArrayData().Elements[index].Decompress(section.SmallVertexScale, section.SmallVertexOffset); verts.Add(TransformVert(vert, bodyinfo)); } else { ushort index = (ushort)(coldata.sharedVerticesIndex.GetArrayData().Elements[tri.Idx0 + section.sharedVerticesIndex - section.sharedVerticesLength].data); indices.Add(verts.Count); var vert = coldata.sharedVertices.GetArrayData().Elements[index].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax); verts.Add(TransformVert(vert, bodyinfo)); } if (tri.Idx1 < section.sharedVerticesLength) { ushort index = (ushort)((uint)tri.Idx1 + section.firstPackedVertex); indices.Add(verts.Count); var vert = coldata.packedVertices.GetArrayData().Elements[index].Decompress(section.SmallVertexScale, section.SmallVertexOffset); verts.Add(TransformVert(vert, bodyinfo)); } else { ushort index = (ushort)(coldata.sharedVerticesIndex.GetArrayData().Elements[tri.Idx1 + section.sharedVerticesIndex - section.sharedVerticesLength].data); indices.Add(verts.Count); var vert = coldata.sharedVertices.GetArrayData().Elements[index].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax); verts.Add(TransformVert(vert, bodyinfo)); } if (tri.Idx2 < section.sharedVerticesLength) { ushort index = (ushort)((uint)tri.Idx2 + section.firstPackedVertex); indices.Add(verts.Count); var vert = coldata.packedVertices.GetArrayData().Elements[index].Decompress(section.SmallVertexScale, section.SmallVertexOffset); verts.Add(TransformVert(vert, bodyinfo)); } else { ushort index = (ushort)(coldata.sharedVerticesIndex.GetArrayData().Elements[tri.Idx2 + section.sharedVerticesIndex - section.sharedVerticesLength].data); indices.Add(verts.Count); var vert = coldata.sharedVertices.GetArrayData().Elements[index].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax); verts.Add(TransformVert(vert, bodyinfo)); } if (tri.Idx2 != tri.Idx3) { indices.Add(verts.Count); verts.Add(verts[verts.Count - 3]); indices.Add(verts.Count); verts.Add(verts[verts.Count - 2]); if (tri.Idx3 < section.sharedVerticesLength) { ushort index = (ushort)((uint)tri.Idx3 + section.firstPackedVertex); indices.Add(verts.Count); var vert = coldata.packedVertices.GetArrayData().Elements[index].Decompress(section.SmallVertexScale, section.SmallVertexOffset); verts.Add(TransformVert(vert, bodyinfo)); } else { ushort index = (ushort)(coldata.sharedVerticesIndex.GetArrayData().Elements[tri.Idx3 + section.sharedVerticesIndex - section.sharedVerticesLength].data); indices.Add(verts.Count); var vert = coldata.sharedVertices.GetArrayData().Elements[index].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax); 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; }); }); }
unsafe private void ProcessMesh(HKX.HKPStorageExtendedMeshShapeMeshSubpartStorage mesh, CollisionSubmesh dest) { var verts = mesh.Vertices.GetArrayData().Elements; var indices = mesh.Indices16.GetArrayData().Elements; var MeshIndices = new int[(indices.Count / 4) * 3]; var MeshVertices = new CollisionLayout[(indices.Count / 4) * 3]; dest.PickingVertices = new Vector3[(indices.Count / 4) * 3]; dest.PickingIndices = new int[(indices.Count / 4) * 3]; var factory = Scene.Renderer.Factory; for (int id = 0; id < indices.Count; id += 4) { int i = (id / 4) * 3; var vert1 = mesh.Vertices[mesh.Indices16[id].data].Vector; var vert2 = mesh.Vertices[mesh.Indices16[id + 1].data].Vector; var vert3 = mesh.Vertices[mesh.Indices16[id + 2].data].Vector; MeshVertices[i] = new CollisionLayout(); MeshVertices[i + 1] = new CollisionLayout(); MeshVertices[i + 2] = new CollisionLayout(); MeshVertices[i].Position = new Vector3(vert1.X, vert1.Y, vert1.Z); MeshVertices[i + 1].Position = new Vector3(vert2.X, vert2.Y, vert2.Z); MeshVertices[i + 2].Position = new Vector3(vert3.X, vert3.Y, vert3.Z); dest.PickingVertices[i] = new Vector3(vert1.X, vert1.Y, vert1.Z); dest.PickingVertices[i + 1] = new Vector3(vert2.X, vert2.Y, vert2.Z); dest.PickingVertices[i + 2] = new Vector3(vert3.X, vert3.Y, vert3.Z); 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.PickingIndices[i] = i; dest.PickingIndices[i + 1] = i + 1; dest.PickingIndices[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; }); }); }
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; }); }); }