internal override void ReadBody(EndianBinaryReader reader, StringSet stringSet)
        {
            StartIndex   = reader.ReadInt32();
            Count        = reader.ReadInt32();
            ExternalName = stringSet.ReadString(reader);
            InternalName = stringSet.ReadString(reader);

            reader.SeekCurrent(reader.AddressSpace.GetByteSize());   // Integrated skin parameter
            reader.SkipNulls(3 * sizeof(uint));

            Bones.Capacity = Count;
        }
        internal override void ReadBody(EndianBinaryReader reader, StringSet stringSet)
        {
            long nameOffset         = reader.ReadOffset();
            int  count              = reader.ReadInt32();
            long boneNamesOffset    = reader.ReadOffset();
            long boneMatricesOffset = reader.ReadOffset();

            Nodes.Capacity = count;

            Name = reader.ReadStringAtOffset(nameOffset, StringBinaryFormat.NullTerminated);

            reader.ReadAtOffset(boneNamesOffset, () =>
            {
                for (int i = 0; i < count; i++)
                {
                    Nodes.Add(new MotionNode {
                        Name = stringSet.ReadString(reader)
                    });
                }
            });

            reader.ReadAtOffset(boneMatricesOffset, () =>
            {
                for (int i = 0; i < count; i++)
                {
                    Nodes[i].Transformation = reader.ReadMatrix4x4();
                }
            });
        }
        internal override void ReadBody(EndianBinaryReader reader, StringSet stringSet)
        {
            StartIndex   = reader.ReadInt32();
            Count        = reader.ReadInt32();
            ExternalName = stringSet.ReadString(reader);
            Name         = stringSet.ReadString(reader);

            Nodes.Capacity = Count;

            for (int i = 0; i < Count; i++)
            {
                Nodes.Add(new OsageNode());
            }

            // Either means rotation info on FT, or integrated SKP on old DT/AC
            reader.ReadOffset(() =>
            {
                long current = reader.Position;
                {
                    if (reader.ReadUInt32() == 0)   // Integrated SKP, yet to support.
                    {
                        return;
                    }
                }

                reader.SeekBegin(current);

                foreach (var bone in Nodes)
                {
                    bone.ReadOsgBlockInfo(reader, stringSet);
                }
            });

            if (reader.AddressSpace == AddressSpace.Int64)
            {
                reader.SkipNulls(4 * sizeof(ulong));
            }
            else
            {
                reader.SkipNulls(5 * sizeof(uint));
            }
        }
Exemple #4
0
        internal void Read(EndianBinaryReader reader)
        {
            long boneIdsOffset       = reader.ReadOffset();
            long boneMatricesOffset  = reader.ReadOffset();
            long boneNamesOffset     = reader.ReadOffset();
            long exDataOffset        = reader.ReadOffset();
            int  boneCount           = reader.ReadInt32();
            long boneParentIdsOffset = reader.ReadOffset();

            reader.SkipNulls(3 * reader.AddressSpace.GetByteSize());

            reader.ReadAtOffset(boneIdsOffset, () =>
            {
                Bones.Capacity = boneCount;

                for (int i = 0; i < boneCount; i++)
                {
                    uint id = reader.ReadUInt32();
                    Bones.Add(new BoneInfo {
                        Id = id, IsEx = (id & 0x8000) != 0
                    });
                }
            });

            reader.ReadAtOffset(boneMatricesOffset, () =>
            {
                foreach (var bone in Bones)
                {
                    bone.InverseBindPoseMatrix = reader.ReadMatrix4x4();
                }
            });

            reader.ReadAtOffset(boneNamesOffset, () =>
            {
                foreach (var bone in Bones)
                {
                    bone.Name = reader.ReadStringOffset(StringBinaryFormat.NullTerminated);
                }
            });

            reader.ReadAtOffset(exDataOffset, () =>
            {
                int osageCount     = reader.ReadInt32();
                int osageNodeCount = reader.ReadInt32();
                reader.SkipNulls(sizeof(uint));
                long osageNodesOffset        = reader.ReadOffset();
                long osageNamesOffset        = reader.ReadOffset();
                long blocksOffset            = reader.ReadOffset();
                int stringCount              = reader.ReadInt32();
                long stringsOffset           = reader.ReadOffset();
                long osageSiblingInfosOffset = reader.ReadOffset();
                int clothCount = reader.ReadInt32();

                if (reader.AddressSpace == AddressSpace.Int64)
                {
                    reader.SkipNulls(4);
                }

                reader.SkipNulls(7 * reader.AddressSpace.GetByteSize());

                var stringSet  = new StringSet(reader, stringsOffset, stringCount);
                var osageNodes = new List <OsageNode>(osageNodeCount);

                reader.ReadAtOffset(osageNodesOffset, () =>
                {
                    for (int i = 0; i < osageNodeCount; i++)
                    {
                        var osageNode = new OsageNode();
                        osageNode.Read(reader, stringSet);
                        osageNodes.Add(osageNode);
                    }
                });

                reader.ReadAtOffset(blocksOffset, () =>
                {
                    while (true)
                    {
                        string blockSignature = reader.ReadStringOffset(StringBinaryFormat.NullTerminated);
                        long blockOffset      = reader.ReadOffset();

                        if (blockOffset == 0)
                        {
                            break;
                        }

                        reader.ReadAtOffset(blockOffset, () =>
                        {
                            if (!BlockFactory.TryGetValue(blockSignature, out var blockConstructor))
                            {
                                Debug.WriteLine("Skin.Read(): Unimplemented block ({0}) at 0x{1:X}", blockSignature, blockOffset);
                                return;
                            }

                            var block = blockConstructor();
                            block.Read(reader, stringSet);
                            Blocks.Add(block);
                        });
                    }
                });

                reader.ReadAtOffset(osageSiblingInfosOffset, () =>
                {
                    while (true)
                    {
                        string boneName = stringSet.ReadString(reader);

                        if (boneName == null)
                        {
                            break;
                        }

                        string siblingName    = stringSet.ReadString(reader);
                        float siblingDistance = reader.ReadSingle();

                        var osageNode = osageNodes.FirstOrDefault(x => x.Name.Equals(boneName));

                        if (osageNode == null)
                        {
                            continue;
                        }

                        osageNode.SiblingName        = siblingName;
                        osageNode.SiblingMaxDistance = siblingDistance;
                    }
                });

                foreach (var osageBlock in Blocks.OfType <OsageBlock>())
                {
                    for (int i = 0; i < osageBlock.Count; i++)
                    {
                        var donorOsageNode = osageNodes[osageBlock.StartIndex + i];
                        var osageNode      = osageBlock.Nodes[i];

                        osageNode.Name               = donorOsageNode.Name;
                        osageNode.Length             = donorOsageNode.Length;
                        osageNode.SiblingName        = donorOsageNode.SiblingName;
                        osageNode.SiblingMaxDistance = donorOsageNode.SiblingMaxDistance;
                    }
                }
            });

            reader.ReadAtOffset(boneParentIdsOffset, () =>
            {
                foreach (var bone in Bones)
                {
                    uint parentId = reader.ReadUInt32();

                    if (parentId != 0xFFFFFFFF)
                    {
                        bone.Parent = Bones.FirstOrDefault(x => x.Id == parentId);
                    }
                }
            });
        }