コード例 #1
0
        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;
                });
            });
        }
コード例 #2
0
        // 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);
        }