Esempio n. 1
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();
        }
Esempio n. 2
0
        public RwSkinNode(byte[][] vertexBoneIndices, float[][] vertexBoneWeights, Matrix4x4[] skinToBoneMatrices)
            : base(RwNodeId.RwSkinNode)
        {
            BoneCount = (byte)skinToBoneMatrices.Length;

            var uniqueSkinBoneIndices = new List <byte>();

            MaxWeightCountPerVertex = 0;

            for (int i = 0; i < vertexBoneIndices.Length; i++)
            {
                for (int j = 0; j < vertexBoneIndices[i].Length; j++)
                {
                    if (vertexBoneWeights[i][j] != 0.0f)
                    {
                        if (!uniqueSkinBoneIndices.Contains(vertexBoneIndices[i][j]))
                        {
                            uniqueSkinBoneIndices.Add(vertexBoneIndices[i][j]);
                        }

                        if ((j + 1) > MaxWeightCountPerVertex)
                        {
                            MaxWeightCountPerVertex = (byte)(j + 1);
                        }
                    }
                }
            }

            UsedBoneCount      = (byte)uniqueSkinBoneIndices.Count;
            UsedBoneIndices    = uniqueSkinBoneIndices.ToArray();
            VertexBoneIndices  = vertexBoneIndices;
            VertexBoneWeights  = vertexBoneWeights;
            SkinToBoneMatrices = skinToBoneMatrices;

            BoneLimit = 64;
            MeshCount = 1;

            // these are offsets relative to the BoneIndex
            MeshBoneRemapIndices = new byte[BoneCount];
            for (int i = 0; i < MeshBoneRemapIndices.Length; i++)
            {
                MeshBoneRemapIndices[i] = 0xFF;
            }

            RleCount = UsedBoneCount;

            for (int i = 0; i < UsedBoneIndices.Length; i++)
            {
                MeshBoneRemapIndices[UsedBoneIndices[i]] = (byte)i;
            }

            MeshBoneRleCount = new[] { new SkinSplitMeshRleCount {
                                           StartIndex = 0, Count = UsedBoneCount
                                       } };

            MeshBoneRle = new SkinSplitMeshBoneRle[UsedBoneCount];
            for (int i = 0; i < MeshBoneRle.Length; i++)
            {
                MeshBoneRle[i] = new SkinSplitMeshBoneRle
                {
                    BoneIndex          = UsedBoneIndices[i],
                    SkinBoneIndexCount = 1
                };
            }
        }