public void CompressMorph(ModelMaterialCollection materials, ModelVertexCollection vertices)
        {
            var typeMorphDict = new MultiDictionary <MorphType, PmxMorphData>();

            foreach (var morph in MorphList)
            {
                typeMorphDict.Add(morph.MorphType, morph);
            }

            foreach (var morphList in typeMorphDict.Values)
            {
                Compress(morphList, World.KeyFrames.MorphFrameDict);
            }

            var removeMaterialIndices = new List <int>();

            removeMaterialIndices.AddRange(materials.CompressMaterial(typeMorphDict[MorphType.MATERIAL], vertices));

            RemoveElements(typeMorphDict[MorphType.MATERIAL], removeMaterialIndices);

            removeMaterialIndices.Sort((a, b) => b - a);
            foreach (int index in removeMaterialIndices)
            {
                materials.MaterialList.RemoveAt(index);
            }
        }
        public CurtainFireModel(World world)
        {
            World = world;

            Vertices  = new ModelVertexCollection(World);
            Materials = new ModelMaterialCollection(World);
            Morphs    = new ModelMorphCollection(World);
            Bones     = new ModelBoneCollection(World);
        }
        public List <int> CompressMaterial(List <PmxMorphData> morphList, ModelVertexCollection vertices)
        {
            var groupedMaterialIndices = new List <List <int> >();

            foreach (var morph in morphList)
            {
                int[] indices = Array.ConvertAll(morph.MorphArray, m => m.Index);
                Array.Sort(indices);

                var materialDict = new MultiDictionary <int, int>();

                foreach (int index in indices)
                {
                    materialDict.Add(GetHashCode(MaterialList[index]), index);
                }

                foreach (var materialIndices in materialDict.Values)
                {
                    groupedMaterialIndices.Add(materialIndices);
                }
            }

            return(CompressGroupedMaterial(groupedMaterialIndices, vertices));

            int GetHashCode(PmxMaterialData obj)
            {
                int result = 17;

                result = result * 31 + obj.Ambient.GetHashCode();
                result = result * 31 + obj.Diffuse.GetHashCode();
                result = result * 31 + obj.Specular.GetHashCode();
                result = result * 31 + obj.Shininess.GetHashCode();
                result = result * 31 + obj.TextureId;
                result = result * 31 + obj.SphereId;

                return(result);
            }
        }
        private List <int> CompressGroupedMaterial(List <List <int> > groupedMaterialIndices, ModelVertexCollection vertices)
        {
            var vertexIndicesList    = vertices.IndexOfEachMaterialList;
            var newVertexIndicesList = new List <List <int> >();

            var removeList = new List <int>();

            foreach (var materialIndices in groupedMaterialIndices)
            {
                var vertexIndices = vertexIndicesList[materialIndices[0]];

                if (materialIndices.Count > 1)
                {
                    int addFaceCount = 0;

                    for (int i = 1; i < materialIndices.Count; i++)
                    {
                        int index = materialIndices[i];

                        addFaceCount += MaterialList[index].FaceCount;
                        vertexIndices.AddRange(vertexIndicesList[index]);
                        removeList.Add(index);
                    }

                    MaterialList[materialIndices[0]].FaceCount += addFaceCount;
                }
                newVertexIndicesList.Add(vertexIndices);
            }

            World.PmxModel.Vertices.IndexOfEachMaterialList.Clear();
            World.PmxModel.Vertices.IndexOfEachMaterialList.AddRange(newVertexIndicesList);

            var list = new List <int>();

            foreach (var vertexIndices in newVertexIndicesList)
            {
                list.AddRange(vertexIndices);
            }

            World.PmxModel.Vertices.IndexList.Clear();
            World.PmxModel.Vertices.IndexList.AddRange(list);

            return(removeList);
        }