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); }
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()); } }); }
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); }
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()); } }); }