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