private void ReadFaces(BinaryReader reader, RawMMDModel model) { var faceNum = reader.ReadUInt16(); int?baseMorphIndex = null; model.Morphs = new Morph[faceNum]; for (var i = 0; i < faceNum; ++i) { var morph = new Morph(); var fp = ReadPmdFacePreamble(reader); morph.Name = fp.Name; morph.Category = (Morph.MorphCategory)fp.FaceType; if (morph.Category == Morph.MorphCategory.MorphCatSystem) { baseMorphIndex = i; } morph.Type = Morph.MorphType.MorphTypeVertex; morph.MorphDatas = new Morph.MorphData[fp.VertexNum]; for (var j = 0; j < fp.VertexNum; ++j) { var vertexMorphData = new Morph.VertexMorphData(); vertexMorphData.VertexIndex = reader.ReadInt32(); vertexMorphData.Offset = MMDReaderUtil.ReadVector3(reader); morph.MorphDatas[j] = vertexMorphData; } model.Morphs[i] = morph; } if (baseMorphIndex != null) { var baseMorph = model.Morphs[baseMorphIndex.Value]; for (var i = 0; i < faceNum; ++i) { if (i == baseMorphIndex) { continue; } var morph = model.Morphs[i]; for (var j = 0; j < morph.MorphDatas.Length; ++j) { var vertexMorphData = (Morph.VertexMorphData)morph.MorphDatas[j]; var morphDataVertexIndex = vertexMorphData.VertexIndex; vertexMorphData.VertexIndex = ((Morph.VertexMorphData)baseMorph.MorphDatas[morphDataVertexIndex]) .VertexIndex; } } } }
private static void ReadMorphs(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig) { var morphNum = reader.ReadInt32(); int?baseMorphIndex = null; model.Morphs = new Morph[morphNum]; for (var i = 0; i < morphNum; ++i) { var morph = new Morph { Name = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding), NameEn = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding), Category = (Morph.MorphCategory)reader.ReadByte() }; if (morph.Category == Morph.MorphCategory.MorphCatSystem) { baseMorphIndex = i; } morph.Type = (Morph.MorphType)reader.ReadByte(); var morphDataNum = reader.ReadInt32(); morph.MorphDatas = new Morph.MorphData[morphDataNum]; switch (morph.Type) { case Morph.MorphType.MorphTypeGroup: for (var j = 0; j < morphDataNum; ++j) { var morphData = new Morph.GroupMorphData { MorphIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.MorphIndexSize), MorphRate = reader.ReadSingle() }; morph.MorphDatas[j] = morphData; } break; case Morph.MorphType.MorphTypeVertex: for (var j = 0; j < morphDataNum; ++j) { var morphData = new Morph.VertexMorphData { VertexIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize), Offset = MMDReaderUtil.ReadVector3(reader) }; morph.MorphDatas[j] = morphData; } break; case Morph.MorphType.MorphTypeBone: for (var j = 0; j < morphDataNum; ++j) { var morphData = new Morph.BoneMorphData { BoneIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize), Translation = MMDReaderUtil.ReadVector3(reader), Rotation = MMDReaderUtil.ReadQuaternion(reader) }; morph.MorphDatas[j] = morphData; } break; case Morph.MorphType.MorphTypeUv: case Morph.MorphType.MorphTypeExtUv1: case Morph.MorphType.MorphTypeExtUv2: case Morph.MorphType.MorphTypeExtUv3: case Morph.MorphType.MorphTypeExtUv4: for (var j = 0; j < morphDataNum; ++j) { var morphData = new Morph.UvMorphData { VertexIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize), Offset = MMDReaderUtil.ReadVector4(reader) }; morph.MorphDatas[j] = morphData; } break; case Morph.MorphType.MorphTypeMaterial: for (var j = 0; j < morphDataNum; j++) { var morphData = new Morph.MaterialMorphData(); var mmIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.MaterialIndexSize); if (mmIndex < model.Parts.Length && mmIndex > 0) //TODO mmdlib的代码里是和bone数比较。确认这个逻辑 { morphData.MaterialIndex = mmIndex; morphData.Global = false; } else { morphData.MaterialIndex = 0; morphData.Global = true; } morphData.Method = (Morph.MaterialMorphData.MaterialMorphMethod)reader.ReadByte(); morphData.Diffuse = MMDReaderUtil.ReadColor(reader, true); morphData.Specular = MMDReaderUtil.ReadColor(reader, false); morphData.Shiness = reader.ReadSingle(); morphData.Ambient = MMDReaderUtil.ReadColor(reader, false); morphData.EdgeColor = MMDReaderUtil.ReadColor(reader, true); morphData.EdgeSize = reader.ReadSingle(); morphData.Texture = MMDReaderUtil.ReadVector4(reader); morphData.SubTexture = MMDReaderUtil.ReadVector4(reader); morphData.ToonTexture = MMDReaderUtil.ReadVector4(reader); morph.MorphDatas[j] = morphData; } break; default: throw new MMDFileParseException("invalid morph type " + morph.Type); } if (baseMorphIndex != null) { //TODO rectify system-reserved category } model.Morphs[i] = morph; } }