コード例 #1
0
        internal static Vector3 TransformVert(System.Numerics.Vector3 vert, HKX.HKNPBodyCInfo body)
        {
            var newVert = new Vector3(vert.X, vert.Y, vert.Z);

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

            Vector3    trans = new Vector3(body.Position.Vector.X, body.Position.Vector.Y, body.Position.Vector.Z);
            Quaternion quat  = new Quaternion(body.Orientation.Vector.X, body.Orientation.Vector.Y, body.Orientation.Vector.Z, body.Orientation.Vector.W);

            return(Vector3.Transform(newVert, quat) + trans);
        }
コード例 #2
0
        private bool LoadInternal(AccessLevel al)
        {
            if (al == AccessLevel.AccessFull || al == AccessLevel.AccessGPUOptimizedOnly)
            {
                Bounds = new BoundingBox();
                var  submeshes = new List <CollisionSubmesh>();
                bool first     = true;
                foreach (var obj in Hkx.DataSection.Objects)
                {
                    if (obj is HKX.HKPStorageExtendedMeshShapeMeshSubpartStorage col)
                    {
                        var mesh = new CollisionSubmesh();
                        ProcessMesh(col, mesh);
                        if (first)
                        {
                            Bounds = mesh.Bounds;
                            first  = false;
                        }
                        else
                        {
                            Bounds = BoundingBox.Combine(Bounds, mesh.Bounds);
                        }
                        submeshes.Add(mesh);
                    }
                    if (obj is HKX.FSNPCustomParamCompressedMeshShape ncol)
                    {
                        // Find a body data for this
                        HKX.HKNPBodyCInfo bodyInfo = null;
                        foreach (var scene in Hkx.DataSection.Objects)
                        {
                            if (scene is HKX.HKNPPhysicsSystemData)
                            {
                                var sys = (HKX.HKNPPhysicsSystemData)scene;
                                foreach (HKX.HKNPBodyCInfo info in sys.Bodies.GetArrayData().Elements)
                                {
                                    if (info.ShapeReference.DestObject == ncol)
                                    {
                                        bodyInfo = info;
                                        break;
                                    }
                                }
                                break;
                            }

                            try
                            {
                                var mesh = new CollisionSubmesh();
                                ProcessMesh(ncol, bodyInfo, mesh);
                                if (first)
                                {
                                    Bounds = mesh.Bounds;
                                    first  = false;
                                }
                                else
                                {
                                    Bounds = BoundingBox.Combine(Bounds, mesh.Bounds);
                                }
                                submeshes.Add(mesh);
                            }
                            catch (Exception e)
                            {
                                // Debug failing cases later
                            }
                        }
                    }
                    //Bounds = BoundingBox.CreateMerged(Bounds, GPUMeshes[i].Bounds);
                }
                GPUMeshes = submeshes.ToArray();
            }

            if (al == AccessLevel.AccessGPUOptimizedOnly)
            {
                Hkx = null;
            }
            return(true);
        }
コード例 #3
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;
                });
            });
        }
コード例 #4
0
ファイル: CollisionUtilities.cs プロジェクト: esmayl/dstools
    public static void ImportDS3CollisionHKX(HKX hkx, string assetName)
    {
        var verts   = new List <Vector3>();
        var normals = new List <Vector3>();
        var indices = new List <int>();

        foreach (var col in hkx.DataSection.Objects)
        {
            if (col is HKX.FSNPCustomParamCompressedMeshShape)
            {
                // Find a body data for this
                HKX.HKNPBodyCInfo bodyInfo = null;
                foreach (var scene in hkx.DataSection.Objects)
                {
                    if (scene is HKX.HKNPPhysicsSystemData)
                    {
                        var sys = (HKX.HKNPPhysicsSystemData)scene;
                        foreach (HKX.HKNPBodyCInfo info in sys.Bodies.GetArrayData().Elements)
                        {
                            if (info.ShapeReference.DestObject == col)
                            {
                                bodyInfo = info;
                                break;
                            }
                        }
                        break;
                    }
                }

                var meshdata = (HKX.FSNPCustomParamCompressedMeshShape)col;
                var coldata  = meshdata.GetMeshShapeData();

                foreach (var chunk in coldata.Chunks.GetArrayData().Elements)
                {
                    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(verts.Count);

                            var vert = coldata.SmallVertices.GetArrayData().Elements[index].Decompress(chunk.SmallVertexScale, chunk.SmallVertexOffset);
                            verts.Add(TransformVert(vert, bodyInfo));
                        }
                        else
                        {
                            ushort index = (ushort)(coldata.VertexIndices.GetArrayData().Elements[tri.Idx0 + chunk.VertexIndicesIndex - chunk.VertexIndicesLength].data);
                            indices.Add(verts.Count);

                            var vert = coldata.LargeVertices.GetArrayData().Elements[index].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax);
                            verts.Add(TransformVert(vert, bodyInfo));
                        }

                        if (tri.Idx1 < chunk.VertexIndicesLength)
                        {
                            ushort index = (ushort)((uint)tri.Idx1 + chunk.SmallVerticesBase);
                            indices.Add(verts.Count);

                            var vert = coldata.SmallVertices.GetArrayData().Elements[index].Decompress(chunk.SmallVertexScale, chunk.SmallVertexOffset);
                            verts.Add(TransformVert(vert, bodyInfo));
                        }
                        else
                        {
                            ushort index = (ushort)(coldata.VertexIndices.GetArrayData().Elements[tri.Idx1 + chunk.VertexIndicesIndex - chunk.VertexIndicesLength].data);
                            indices.Add(verts.Count);

                            var vert = coldata.LargeVertices.GetArrayData().Elements[index].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax);
                            verts.Add(TransformVert(vert, bodyInfo));
                        }

                        if (tri.Idx2 < chunk.VertexIndicesLength)
                        {
                            ushort index = (ushort)((uint)tri.Idx2 + chunk.SmallVerticesBase);
                            indices.Add(verts.Count);

                            var vert = coldata.SmallVertices.GetArrayData().Elements[index].Decompress(chunk.SmallVertexScale, chunk.SmallVertexOffset);
                            verts.Add(TransformVert(vert, bodyInfo));
                        }
                        else
                        {
                            ushort index = (ushort)(coldata.VertexIndices.GetArrayData().Elements[tri.Idx2 + chunk.VertexIndicesIndex - chunk.VertexIndicesLength].data);
                            indices.Add(verts.Count);

                            var vert = coldata.LargeVertices.GetArrayData().Elements[index].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax);
                            verts.Add(TransformVert(vert, bodyInfo));
                        }

                        if (tri.Idx2 != tri.Idx3)
                        {
                            verts.Add(verts[verts.Count - 2]);
                            verts.Add(verts[verts.Count - 1]);
                            indices.Add(indices[indices.Count - 2]);
                            indices.Add(indices[indices.Count - 1]);
                            if (tri.Idx3 < chunk.VertexIndicesLength)
                            {
                                ushort index = (ushort)((uint)tri.Idx3 + chunk.SmallVerticesBase);
                                indices.Add(verts.Count);

                                var vert = coldata.SmallVertices.GetArrayData().Elements[index].Decompress(chunk.SmallVertexScale, chunk.SmallVertexOffset);
                                verts.Add(TransformVert(vert, bodyInfo));
                            }
                            else
                            {
                                ushort index = (ushort)(coldata.VertexIndices.GetArrayData().Elements[tri.Idx3 + chunk.VertexIndicesIndex - chunk.VertexIndicesLength].data);
                                indices.Add(verts.Count);

                                var vert = coldata.LargeVertices.GetArrayData().Elements[index].Decompress(coldata.BoundingBoxMin, coldata.BoundingBoxMax);
                                verts.Add(TransformVert(vert, bodyInfo));
                            }
                        }
                        //}
                    }
                }
            }
        }

        if (indices.Count == 0)
        {
            return;
        }

        var mesh = new Mesh();

        mesh.indexFormat  = UnityEngine.Rendering.IndexFormat.UInt32;
        mesh.subMeshCount = 1;
        mesh.SetVertices(verts);
        mesh.SetTriangles(indices.ToArray(), 0, true);
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();

        AssetDatabase.CreateAsset(mesh, assetName + ".mesh");

        // Setup a game object asset
        GameObject obj = new GameObject(Path.GetFileNameWithoutExtension(assetName));

        obj.AddComponent <MeshFilter>();
        obj.AddComponent <MeshRenderer>();
        obj.GetComponent <MeshFilter>().mesh       = mesh;
        obj.GetComponent <MeshRenderer>().material = AssetDatabase.LoadAssetAtPath <Material>("Assets/dstools/Materials/CollisionMeshMaterial.mat");

        PrefabUtility.SaveAsPrefabAsset(obj, assetName + ".prefab");
        Object.DestroyImmediate(obj);
    }