Beispiel #1
0
        /// <summary>
        /// Initialize a new <see cref="RwMeshListNode"/> using a <see cref="RwGeometryNode"/> and the primitive id for the split data.
        /// </summary>
        /// <param name="geometryNode"></param>
        /// <param name="primitiveType"></param>
        public RwMeshListNode(RwGeometryNode geometryNode, RwPrimitiveType primitiveType = RwPrimitiveType.TriangleStrip, RwNode parent = null)
            : base(RwNodeId.RwMeshListNode, parent)
        {
            // set id and prim count
            mPrimitiveType = primitiveType;
            //mPrimitiveCount = geometryNode.TriangleCount;

            // pass 1: order the triangles by ascending material id
            var sortedTriangles = geometryNode.Triangles.OrderBy(tri => tri.MatId);

            // pass 2: split the indices
            List <ushort>[] matSplitsIndices   = new List <ushort> [geometryNode.MaterialCount];
            List <ushort>   curMatSplitIndices = null;
            int             curMatIdx          = -1;

            foreach (var tri in sortedTriangles)
            {
                if (tri.MatId != curMatIdx)
                {
                    if (curMatIdx != -1)
                    {
                        matSplitsIndices[curMatIdx] = curMatSplitIndices;
                    }

                    curMatIdx          = tri.MatId;
                    curMatSplitIndices = new List <ushort>();
                }

                curMatSplitIndices.Add(tri.A);
                curMatSplitIndices.Add(tri.B);
                curMatSplitIndices.Add(tri.C);
            }

            matSplitsIndices[curMatIdx] = curMatSplitIndices;

            // pass 3: create the split data
            mMeshes = new RwMesh[geometryNode.MaterialCount];
            for (int i = 0; i < mMeshes.Length; i++)
            {
                ushort[] matSplitIndices = matSplitsIndices[i].ToArray();
                int      triangleCount;

                if (primitiveType == RwPrimitiveType.TriangleStrip)
                {
                    if (NvTriStripUtility.GenerateStrips(matSplitIndices, out PrimitiveGroup[] primitives) && primitives[0].Type == ManagedNvTriStrip.PrimitiveType.TriangleStrip)
Beispiel #2
0
        // TODO:
        //
        // 1. Figure out how the bone remap indices work
        // They seem to be tied to the used bone indices somehow
        // Maybe building up an hierarchy as the same indices appear multiple times
        // Indices that aren't in the used bone indices are set to 0xFF
        //
        // 2. Figure out the BoneRLE
        // First byte is the hierarchy index of the affected bone
        // Second byte seems to be something like how many bones it shares weights with on the same material split?
        //
        // 3. Figure out the inverse matrices
        // I can currently just copy and paste the one from the original file
        // But knowing how to calculate it would be a lot easier

        internal RwSkinNode(RwNodeFactory.RwNodeHeader header, BinaryReader reader, RwGeometryNode rwGeometryNode)
            : base(header)
        {
            int numVertices = rwGeometryNode.VertexCount;

            BoneCount               = reader.ReadByte();
            UsedBoneCount           = reader.ReadByte();
            MaxWeightCountPerVertex = reader.ReadByte();
            reader.Seek(1, SeekOrigin.Current);

            UsedBoneIndices = reader.ReadBytes(UsedBoneCount);

            VertexBoneIndices = new byte[numVertices][];
            for (int i = 0; i < numVertices; i++)
            {
                VertexBoneIndices[i] = reader.ReadBytes(4);
            }

            VertexBoneWeights = new float[numVertices][];
            for (int i = 0; i < numVertices; i++)
            {
                VertexBoneWeights[i] = reader.ReadFloatArray(4);
            }

            SkinToBoneMatrices = new Matrix4x4[BoneCount];
            for (int i = 0; i < BoneCount; i++)
            {
                Matrix4x4 mtx = Matrix4x4.Identity;

                mtx.M11 = reader.ReadSingle(); mtx.M12 = reader.ReadSingle(); mtx.M13 = reader.ReadSingle(); reader.BaseStream.Position += 4;
                mtx.M21 = reader.ReadSingle(); mtx.M22 = reader.ReadSingle(); mtx.M23 = reader.ReadSingle(); reader.BaseStream.Position += 4;
                mtx.M31 = reader.ReadSingle(); mtx.M32 = reader.ReadSingle(); mtx.M33 = reader.ReadSingle(); reader.BaseStream.Position += 4;
                mtx.M41 = reader.ReadSingle(); mtx.M42 = reader.ReadSingle(); mtx.M43 = reader.ReadSingle(); reader.BaseStream.Position += 4;

                SkinToBoneMatrices[i] = mtx;
            }

            BoneLimit = reader.ReadInt32();
            MeshCount = reader.ReadInt32();
            RleCount  = reader.ReadInt32();

            if (MeshCount < 1)
            {
                return;
            }

            MeshBoneRemapIndices = reader.ReadBytes(BoneCount);

            MeshBoneRleCount = new SkinSplitMeshRleCount[MeshCount];
            for (int i = 0; i < MeshCount; i++)
            {
                MeshBoneRleCount[i] = new SkinSplitMeshRleCount {
                    StartIndex = reader.ReadByte(), Count = reader.ReadByte()
                }
            }
            ;

            MeshBoneRle = new SkinSplitMeshBoneRle[RleCount];
            for (int i = 0; i < RleCount; i++)
            {
                MeshBoneRle[i] = new SkinSplitMeshBoneRle {
                    BoneIndex = reader.ReadByte(), SkinBoneIndexCount = reader.ReadByte()
                }
            }
            ;

            //PrintInfo();
        }
Beispiel #3
0
        /// <summary>
        /// Initialize a new <see cref="RwMeshListNode"/> using a <see cref="RwGeometryNode"/> and the primitive id for the split data.
        /// </summary>
        /// <param name="geometryNode"></param>
        /// <param name="primitiveType"></param>
        public RwMeshListNode(RwGeometryNode geometryNode, RwPrimitiveType primitiveType = RwPrimitiveType.TriangleStrip, RwNode parent = null)
            : base(RwNodeId.RwMeshListNode, parent)
        {
            // set id and prim count
            mPrimitiveType = primitiveType;
            //mPrimitiveCount = geometryNode.TriangleCount;

            // pass 1: order the triangles by ascending material id
            var sortedTriangles = geometryNode.Triangles.OrderBy(tri => tri.MatId);

            // pass 2: split the indices
            List <ushort>[] matSplitsIndices   = new List <ushort> [geometryNode.MaterialCount];
            List <ushort>   curMatSplitIndices = null;
            int             curMatIdx          = -1;

            foreach (var tri in sortedTriangles)
            {
                if (tri.MatId != curMatIdx)
                {
                    if (curMatIdx != -1)
                    {
                        matSplitsIndices[curMatIdx] = curMatSplitIndices;
                    }

                    curMatIdx          = tri.MatId;
                    curMatSplitIndices = new List <ushort>();
                }

                curMatSplitIndices.Add(tri.A);
                curMatSplitIndices.Add(tri.B);
                curMatSplitIndices.Add(tri.C);
            }

            matSplitsIndices[curMatIdx] = curMatSplitIndices;

            // pass 3: create the split data
            mMeshes = new RwMesh[geometryNode.MaterialCount];
            for (int i = 0; i < mMeshes.Length; i++)
            {
                ushort[] matSplitIndices = matSplitsIndices[i].ToArray();
                int      triangleCount;

                if (primitiveType == RwPrimitiveType.TriangleStrip)
                {
                    if (sStripifier.GenerateStrips(matSplitIndices, out var primitives) && primitives[0].Type == NvTriStripDotNet.PrimitiveType.TriangleStrip)
                    {
                        matSplitIndices     = primitives[0].Indices;
                        geometryNode.Flags |= RwGeometryFlags.CanTriStrip;
                        triangleCount       = matSplitIndices.Length - 2;
                    }
                    else
                    {
                        mPrimitiveType = RwPrimitiveType.TriangleList;
                        triangleCount  = matSplitIndices.Length / 3;
                        //throw new System.Exception("Failed to generate strips.");
                    }

                    /*
                     * NvTriStripDotNet.PrimitiveGroup[] primitives;
                     * var tristripper = new NvTriStripDotNet.NvTriStrip();
                     * if (tristripper.GenerateStrips(matSplitIndices, out primitives))
                     * {
                     *  matSplitIndices = primitives[0].indices.Cast<ushort>().ToArray();
                     * }
                     */
                }
                else
                {
                    triangleCount = matSplitIndices.Length / 3;
                }

                mPrimitiveCount += triangleCount;
                mMeshes[i]       = new RwMesh(i, matSplitIndices);
            }
        }