private void ReadFaces(BinaryReader reader, MmdModel 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.VertexMorph(); 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.VertexMorph)morph.MorphDatas[j]; var morphDataVertexIndex = vertexMorphData.VertexIndex; vertexMorphData.VertexIndex = ((Morph.VertexMorph)baseMorph.MorphDatas[morphDataVertexIndex]) .VertexIndex; } } } }
private static void ReadMorphs(BinaryReader reader, MmdModel 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.GroupMorph { 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.VertexMorph { 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.BoneMorph { 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.UvMorph { 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.MaterialMorph(); 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.MaterialMorph.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; } }
/// <summary> /// 读取变形 /// </summary> /// <param name="reader"></param> /// <param name="model"></param> /// <param name="pmxConfig"></param> private static void ReadMorphs(BinaryReader reader, MmdModel model, PmxConfig pmxConfig) { var morphNum = reader.ReadInt32();//OYM:表情包数量 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;//OYM:这个就相当于是一个基类吧 } morph.Type = (Morph.MorphType)reader.ReadByte(); //OYM:变形方式 var morphDataNum = reader.ReadInt32(); morph.MorphDatas = new Morph.MorphData[morphDataNum]; //OYM:获取表情变形的数据 switch (morph.Type) { case Morph.MorphType.MorphTypeGroup: //OYM:不知道干啥用的 for (var j = 0; j < morphDataNum; ++j) { var morphData = new Morph.GroupMorph { MorphIndex = MmdReaderUtil.ReadIndex(reader, pmxConfig.MorphIndexSize), MorphRate = reader.ReadSingle() }; morph.MorphDatas[j] = morphData; } break; case Morph.MorphType.MorphTypeVertex: //OYM:喜闻乐见的顶点变形 for (var j = 0; j < morphDataNum; ++j) { var morphData = new Morph.VertexMorph { VertexIndex = MmdReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize), //OYM:顶点的序号 Offset = MmdReaderUtil.ReadVector3(reader) //OYM:偏移量 }; morph.MorphDatas[j] = morphData; } break; case Morph.MorphType.MorphTypeBone: //OYM:骨骼变形 for (var j = 0; j < morphDataNum; ++j) { var morphData = new Morph.BoneMorph { BoneIndex = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize), //OYM:骨骼序号 Translation = MmdReaderUtil.ReadVector3(reader), //OYM:移动方向 Rotation = MmdReaderUtil.ReadQuaternion(reader) //OYM:旋转方向 }; morph.MorphDatas[j] = morphData; } break; //OYM:下面一堆case都是执行靠后面那个方法 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) { //OYM:获取信息就完事了 var morphData = new Morph.UvMorph { 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.MaterialMorph(); var mmIndex = MmdReaderUtil.ReadIndex(reader, pmxConfig.MaterialIndexSize); //OYM:补一个,作者居然还顺便修复了一个bug23333 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.MaterialMorph.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 //OYM:不清楚作者要干啥 } model.Morphs[i] = morph; } }