Example #1
0
        public odfSubmesh Clone()
        {
            odfSubmesh newSubmesh = new odfSubmesh(Name, Id, _FormatType);

            newSubmesh.Unknown1    = Unknown1;
            newSubmesh.AlwaysZero1 = (byte[])AlwaysZero1.Clone();
            newSubmesh.MaterialId  = new ObjectID(MaterialId);
            newSubmesh.TextureIds  = (ObjectID[])TextureIds.Clone();
            newSubmesh.AlwaysZero2 = (byte[])AlwaysZero2.Clone();
            newSubmesh.Unknown4    = Unknown4;
            newSubmesh.Unknown5    = Unknown5;
            newSubmesh.Unknown6    = Unknown6;
            if (AlwaysZero3 != null)
            {
                newSubmesh.AlwaysZero3 = (byte[])AlwaysZero3.Clone();
            }
            newSubmesh.Unknown7   = Unknown7;
            newSubmesh.Unknown8   = (byte[])Unknown8.Clone();
            newSubmesh.VertexList = new List <odfVertex>(NumVertices);
            foreach (odfVertex vert in VertexList)
            {
                newSubmesh.VertexList.Add(vert.Clone());
            }
            newSubmesh.FaceList = new List <odfFace>(NumVertexIndices / 3);
            foreach (odfFace face in FaceList)
            {
                newSubmesh.FaceList.Add(face.Clone());
            }
            newSubmesh.AlwaysZero4 = (byte[])AlwaysZero4.Clone();
            return(newSubmesh);
        }
Example #2
0
        public override void Read(EndianBinaryReader reader, ISection section = null)
        {
            uint signature = reader.ReadUInt32();

            if (signature != 0x5062500 && signature != 0x5062501)
            {
                throw new InvalidDataException("Invalid signature (expected 0x5062500 or 0x5062501)");
            }

            int  meshCount           = reader.ReadInt32();
            int  globalBoneCount     = reader.ReadInt32();
            long meshesOffset        = reader.ReadOffset();
            long meshSkinningsOffset = reader.ReadOffset();
            long meshNamesOffset     = reader.ReadOffset();
            long meshIdsOffset       = reader.ReadOffset();
            long textureIdsOffset    = reader.ReadOffset();
            int  textureIdCount      = reader.ReadInt32();

            reader.ReadAtOffsetIf(section == null, meshesOffset, () =>
            {
                Meshes.Capacity = meshCount;
                for (int i = 0; i < meshCount; i++)
                {
                    reader.ReadOffset(() =>
                    {
                        reader.PushBaseOffset();
                        {
                            var mesh = new Mesh();
                            mesh.Read(reader);
                            Meshes.Add(mesh);
                        }
                        reader.PopBaseOffset();
                    });
                }
            });

            reader.ReadAtOffsetIf(section == null, meshSkinningsOffset, () =>
            {
                foreach (var mesh in Meshes)
                {
                    reader.ReadOffset(() =>
                    {
                        mesh.Skin = new Skin();
                        mesh.Skin.Read(reader);
                    });
                }
            });

            reader.ReadAtOffset(meshNamesOffset, () =>
            {
                foreach (var mesh in Meshes)
                {
                    mesh.Name = reader.ReadStringOffset(StringBinaryFormat.NullTerminated);
                }
            });

            reader.ReadAtOffset(meshIdsOffset, () =>
            {
                foreach (var mesh in Meshes)
                {
                    mesh.Id = reader.ReadInt32();
                }
            });

            reader.ReadAtOffset(textureIdsOffset, () =>
            {
                TextureIds.Capacity = textureIdCount;
                for (int i = 0; i < textureIdCount; i++)
                {
                    TextureIds.Add(reader.ReadInt32());
                }
            });
        }
Example #3
0
        public void Save(Stream destination, ObjectDatabase objectDatabase, TextureDatabase textureDatabase,
                         BoneDatabase boneDatabase, bool leaveOpen = false)
        {
            if (objectDatabase != null)
            {
                foreach (var mesh in Meshes)
                {
                    mesh.Id = objectDatabase.GetMesh(mesh.Name)?.Id ?? mesh.Id;
                }
            }

            if (boneDatabase != null)
            {
                string fileName = destination is FileStream fileStream
                    ? Path.GetFileName(fileStream.Name)
                    : string.Empty;

                var skeletonEntry =
                    boneDatabase.Skeletons.FirstOrDefault(x =>
                                                          fileName.StartsWith(x.Name, StringComparison.OrdinalIgnoreCase)) ??
                    boneDatabase.Skeletons.FirstOrDefault(x =>
                                                          x.Name.Equals("CMN", StringComparison.OrdinalIgnoreCase)) ??
                    boneDatabase.Skeletons[0];

                if (skeletonEntry != null)
                {
                    foreach (var skin in Meshes.Where(x => x.Skin != null).Select(x => x.Skin))
                    {
                        foreach (var bone in skin.Bones)
                        {
                            int index = skin.ExData?.BoneNames?.FindIndex(x =>
                                                                          x.Equals(bone.Name, StringComparison.OrdinalIgnoreCase)) ?? -1;

                            if (index == -1)
                            {
                                index = skeletonEntry.BoneNames1.FindIndex(x =>
                                                                           x.Equals(bone.Name, StringComparison.OrdinalIgnoreCase));
                            }
                            else
                            {
                                index = 0x8000 | index;
                            }

                            if (index == -1)
                            {
                                continue;
                            }

                            foreach (var childBone in skin.Bones.Where(x => x.ParentId == bone.Id))
                            {
                                childBone.ParentId = index;
                            }

                            bone.Id = index;
                        }
                    }
                }
            }

            if (textureDatabase != null && TextureSet != null)
            {
                int id           = textureDatabase.Textures.Max(x => x.Id) + 1;
                var idDictionary = new Dictionary <int, int>(TextureSet.Textures.Count);

                foreach (var texture in TextureSet.Textures)
                {
                    var textureEntry = !string.IsNullOrEmpty(texture.Name)
                        ? textureDatabase.GetTexture(texture.Name)
                        : textureDatabase.GetTexture(texture.Id);

                    if (textureEntry == null)
                    {
                        textureDatabase.Textures.Add(
                            textureEntry = new TextureEntry
                        {
                            Name = texture.Name,
                            Id   = id++
                        });

                        if (string.IsNullOrEmpty(textureEntry.Name))
                        {
                            textureEntry.Name = $"Unnamed {textureEntry.Id}";
                        }
                    }
                    idDictionary[texture.Id] = textureEntry.Id;

                    texture.Name = textureEntry.Name;
                    texture.Id   = textureEntry.Id;
                }

                foreach (var materialTexture in Meshes.SelectMany(x => x.Materials)
                         .SelectMany(x => x.MaterialTextures))
                {
                    if (idDictionary.TryGetValue(materialTexture.TextureId, out id))
                    {
                        materialTexture.TextureId = id;
                    }
                }

                TextureIds.Clear();
                TextureIds.AddRange(TextureSet.Textures.Select(x => x.Id));
            }

            Save(destination, leaveOpen);
        }
Example #4
0
        public override void Read(EndianBinaryReader reader, ISection section = null)
        {
            uint signature = reader.ReadUInt32();

            if (signature != 0x5062500 && signature != 0x5062501)
            {
                throw new InvalidDataException("Invalid signature (expected 0x5062500 or 0x5062501)");
            }

            int  objectCount           = reader.ReadInt32();
            int  globalBoneCount       = reader.ReadInt32();
            long objectsOffset         = reader.ReadOffset();
            long objectSkinningsOffset = reader.ReadOffset();
            long objectNamesOffset     = reader.ReadOffset();
            long objectIdsOffset       = reader.ReadOffset();
            long textureIdsOffset      = reader.ReadOffset();
            int  textureIdCount        = reader.ReadInt32();

            reader.ReadAtOffsetIf(section == null, objectsOffset, () =>
            {
                Objects.Capacity = objectCount;
                for (int i = 0; i < objectCount; i++)
                {
                    reader.ReadOffset(() =>
                    {
                        reader.PushBaseOffset();
                        {
                            var obj = new Object();
                            obj.Read(reader);
                            Objects.Add(obj);
                        }
                        reader.PopBaseOffset();
                    });
                }
            });

            reader.ReadAtOffsetIf(section == null, objectSkinningsOffset, () =>
            {
                foreach (var obj in Objects)
                {
                    reader.ReadOffset(() =>
                    {
                        obj.Skin = new Skin();
                        obj.Skin.Read(reader);
                    });
                }
            });

            reader.ReadAtOffset(objectNamesOffset, () =>
            {
                foreach (var obj in Objects)
                {
                    obj.Name = reader.ReadStringOffset(StringBinaryFormat.NullTerminated);
                }
            });

            reader.ReadAtOffset(objectIdsOffset, () =>
            {
                foreach (var obj in Objects)
                {
                    obj.Id = reader.ReadInt32();
                }
            });

            reader.ReadAtOffset(textureIdsOffset, () =>
            {
                TextureIds.Capacity = textureIdCount;
                for (int i = 0; i < textureIdCount; i++)
                {
                    TextureIds.Add(reader.ReadInt32());
                }
            });
        }