Beispiel #1
0
        public void Load(Stream source, TextureSet textureSet, TextureDatabase textureDatabase, bool leaveOpen = false)
        {
            Load(source, leaveOpen);

            if (textureSet != null && TextureIDs.Count <= textureSet.Textures.Count)
            {
                TextureSet = textureSet;
                for (int i = 0; i < TextureIDs.Count; i++)
                {
                    TextureSet.Textures[i].ID = TextureIDs[i];

                    var textureEntry = textureDatabase?.GetTexture(TextureIDs[i]);
                    if (textureEntry != null)
                    {
                        TextureSet.Textures[i].Name = textureEntry.Name;
                    }
                }
            }
        }
Beispiel #2
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);
        }
Beispiel #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;

                // Assume we are exporting in game's style
                var skeleton = boneDatabase.Skeletons.FirstOrDefault(x => fileName.StartsWith(x.Name, StringComparison.OrdinalIgnoreCase));

                // If we couldn't find it, default to CMN skeleton
                if (skeleton == null)
                {
                    skeleton = boneDatabase.Skeletons.FirstOrDefault(x => x.Name.Equals("CMN", StringComparison.OrdinalIgnoreCase));
                }

                // Still?? Then default to the first skeleton (this is unlikely to happen though)
                if (skeleton == null)
                {
                    skeleton = boneDatabase.Skeletons[0];
                }

                // Pretty much impossible to miss
                if (skeleton != 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 = skeleton.BoneNames1.FindIndex(x => x.Equals(bone.Name, StringComparison.OrdinalIgnoreCase));
                            }
                            else
                            {
                                index = 0x8000 | index;
                            }

                            if (index != -1)
                            {
                                // Before we do this, fix the child bones
                                foreach (var childBone in skin.Bones.Where(x => x.ParentID.Equals(bone.ID)))
                                {
                                    childBone.ParentID = index;
                                }

                                // Now replace the ID
                                bone.ID = index;
                            }
                            else
                            {
                                Debug.WriteLine($"Model.Save: Bone wasn't found in bone database or ex-data: {bone.Name}");
                            }
                        }
                    }
                }
            }

            if (textureDatabase != null && TextureSet != null)
            {
                var newIDs    = new List <int>(TextureSet.Textures.Count);
                int currentID = textureDatabase.Textures.Max(x => x.ID) + 1;
                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
                        {
                            ID   = currentID++,
                            Name = texture.Name ?? $"Texture{currentID}",
                        });
                    }

                    newIDs.Add(textureEntry.ID);
                }

                if (!newIDs.SequenceEqual(TextureIDs))
                {
                    TextureUtilities.ReAssignTextureIDs(this, newIDs);
                }
            }

            Save(destination, leaveOpen);
        }