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; }); }); }
// Used for collision rendering public FlverSubmeshRenderer(Model parent, HKX colhkx, HKX.FSNPCustomParamCompressedMeshShape meshdata) { Parent = parent; var coldata = meshdata.GetMeshShapeData(); var tree = coldata.getMeshBVH(); var box = new DbgPrimWireBox(Transform.Default, Vector3.One, Color.Cyan); if (tree != null) { //DebugBVHDraw(tree, box); } var vertices = new VertexPositionColorNormalTangentTexture[coldata.SmallVertices.Size + coldata.LargeVertices.Size]; /*for (int i = 0; i < coldata.SmallVertices.Size; i++) * { * var vert = coldata.SmallVertices.GetArrayData().Elements[i].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax); * vertices[i] = new VertexPositionColorNormalTangentTexture(); * vertices[i].Position = new Vector3(vert.X, vert.Y, vert.Z); * }*/ var largebase = coldata.SmallVertices.Size; for (int i = 0; i < coldata.LargeVertices.Size; i++) { var vert = coldata.LargeVertices.GetArrayData().Elements[i].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax); vertices[i + largebase] = new VertexPositionColorNormalTangentTexture(); vertices[i + largebase].Position = new Vector3(vert.X, vert.Y, vert.Z); } MeshFacesets = new List <FlverSubmeshRendererFaceSet>(); int ch = 0; foreach (var chunk in coldata.Chunks.GetArrayData().Elements) { /*if (ch != 1) * { * ch++; * continue; * } * ch++;*/ /*var tree2 = chunk.getChunkBVH(); * if (tree2 != null) * { * DebugBVHDraw(tree2, box); * }*/ List <ushort> indices = new List <ushort>(); for (int i = 0; i < chunk.ByteIndicesLength; i++) { var tri = coldata.MeshIndices.GetArrayData().Elements[i + chunk.ByteIndicesIndex]; if (tri.Idx2 == tri.Idx3 && tri.Idx1 != tri.Idx2) { if (tri.Idx0 < chunk.VertexIndicesLength) { ushort index = (ushort)((uint)tri.Idx0 + chunk.SmallVerticesBase); indices.Add(index); var vert = coldata.SmallVertices.GetArrayData().Elements[index].Decompress(chunk.SmallVertexScale, chunk.SmallVertexOffset); vertices[index] = new VertexPositionColorNormalTangentTexture(); vertices[index].Position = new Vector3(vert.X, vert.Y, vert.Z); } else { indices.Add((ushort)(coldata.VertexIndices.GetArrayData().Elements[tri.Idx0 + chunk.VertexIndicesIndex - chunk.VertexIndicesLength].data + largebase)); } if (tri.Idx1 < chunk.VertexIndicesLength) { ushort index = (ushort)((uint)tri.Idx1 + chunk.SmallVerticesBase); indices.Add(index); var vert = coldata.SmallVertices.GetArrayData().Elements[index].Decompress(chunk.SmallVertexScale, chunk.SmallVertexOffset); vertices[index] = new VertexPositionColorNormalTangentTexture(); vertices[index].Position = new Vector3(vert.X, vert.Y, vert.Z); } else { indices.Add((ushort)(coldata.VertexIndices.GetArrayData().Elements[tri.Idx1 + chunk.VertexIndicesIndex - chunk.VertexIndicesLength].data + largebase)); } if (tri.Idx2 < chunk.VertexIndicesLength) { ushort index = (ushort)((uint)tri.Idx2 + chunk.SmallVerticesBase); indices.Add(index); var vert = coldata.SmallVertices.GetArrayData().Elements[index].Decompress(chunk.SmallVertexScale, chunk.SmallVertexOffset); vertices[index] = new VertexPositionColorNormalTangentTexture(); vertices[index].Position = new Vector3(vert.X, vert.Y, vert.Z); } else { indices.Add((ushort)(coldata.VertexIndices.GetArrayData().Elements[tri.Idx2 + chunk.VertexIndicesIndex - chunk.VertexIndicesLength].data + largebase)); } } } if (indices.Count > 0) { var newFaceSet = new FlverSubmeshRendererFaceSet() { BackfaceCulling = false, IsTriangleStrip = false, IndexBuffer = new IndexBuffer( GFX.Device, IndexElementSize.SixteenBits, indices.Count, BufferUsage.WriteOnly), IndexCount = indices.Count, }; newFaceSet.IndexBuffer.SetData(indices.Select(x => (ushort)x).ToArray()); MeshFacesets.Add(newFaceSet); } } Bounds = BoundingBox.CreateFromPoints(vertices.Select(x => x.Position)); VertBuffer = new VertexBuffer(GFX.Device, typeof(VertexPositionColorNormalTangentTexture), vertices.Length, BufferUsage.WriteOnly); VertBuffer.SetData(vertices); VertBufferBinding = new VertexBufferBinding(VertBuffer, 0, 0); }