private static void ReadRigidBodies(BinaryReader reader, MmdModel model, PmxConfig pmxConfig) { var rigidBodyNum = reader.ReadInt32(); model.Rigidbodies = new MmdRigidBody[rigidBodyNum]; for (var i = 0; i < rigidBodyNum; ++i) { var rigidBody = new MmdRigidBody { Name = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding), NameEn = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding), AssociatedBoneIndex = MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize), CollisionGroup = reader.ReadByte(), CollisionMask = reader.ReadUInt16(), Shape = (MmdRigidBody.RigidBodyShape)reader.ReadByte(), Dimemsions = MmdReaderUtil.ReadVector3(reader), Position = MmdReaderUtil.ReadVector3(reader), Rotation = MmdReaderUtil.ReadVector3(reader), Mass = reader.ReadSingle(), TranslateDamp = reader.ReadSingle(), RotateDamp = reader.ReadSingle(), Restitution = reader.ReadSingle(), Friction = reader.ReadSingle(), Type = (MmdRigidBody.RigidBodyType)reader.ReadByte() }; model.Rigidbodies[i] = rigidBody; } }
private Meta ReadMetaAndCheck(MmdModel model) { var magic = MmdReaderUtil.ReadStringFixedLength(_reader, 4, Encoding.UTF8); if (!"VBP ".Equals(magic)) { throw new BonePoseFileFormatException("error magic " + magic); } var mainVersion = _reader.ReadInt16(); var subVersion = _reader.ReadInt16(); if (mainVersion != 1 || subVersion != 0) { throw new BonePoseFileFormatException("not supported version: " + mainVersion + "." + subVersion); } var ret = new Meta { BoneCount = _reader.ReadInt32(), FrameCount = _reader.ReadInt32(), StepLength = _reader.ReadSingle() }; var exceptedModelHash = _reader.ReadBytes(16); var modelHash = BonePoseFileGenerator.CalculateModelHash(model); if (!exceptedModelHash.SequenceEqual(modelHash)) { throw new BonePoseNotSuitableException("model hash not equals the value in bone pose file"); } return(ret); }
public CameraMotion ReadCameraMotion(BinaryReader reader, bool motionReadAlready = false) { if (!motionReadAlready) { Read(reader); } var ret = new CameraMotion(); var cameraMotionNum = reader.ReadInt32(); Dictionary <int, CameraKeyframe> keyframes = new Dictionary <int, CameraKeyframe>(); for (var i = 0; i < cameraMotionNum; ++i) { var nFrame = reader.ReadInt32(); var focalLength = reader.ReadSingle(); var position = MmdReaderUtil.ReadVector3(reader); var rotation = MmdReaderUtil.ReadVector3(reader); var interpolator = reader.ReadBytes(24); var fov = reader.ReadUInt32(); var orthographic = reader.ReadByte(); var keyframe = new CameraKeyframe { Fov = fov, FocalLength = focalLength, Orthographic = orthographic != 0, Position = position, Rotation = rotation, Interpolation = interpolator }; keyframes[nFrame] = keyframe; } var frameList = keyframes.Select(entry => entry).ToList().OrderBy(kv => kv.Key).ToList(); ret.KeyFrames = frameList; return(ret); }
private static void ReadInfoEn(BinaryReader reader, MmdModel model, PmdReadContext context) { var hasInfoEn = reader.ReadSByte() == 1; if (!hasInfoEn) { return; } model.NameEn = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding); model.DescriptionEn = MmdReaderUtil.ReadStringFixedLength(reader, 256, Tools.JapaneseEncoding); for (var i = 0; i < context.BoneNum; ++i) { var bone = model.Bones[i]; bone.NameEn = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding); } if (model.Morphs.Length > 0) { model.Morphs[0].NameEn = model.Morphs[0].Name; } for (var i = 1; i < model.Morphs.Length; ++i) { var morph = model.Morphs[i]; morph.NameEn = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding); } // UNDONE for (var i = 0; i < context.BoneNameListNum; ++i) { MmdReaderUtil.ReadStringFixedLength(reader, 50, Tools.JapaneseEncoding); } }
private static void ReadVertices(BinaryReader reader, MmdModel model) { var vertexNum = reader.ReadInt32(); model.Vertices = new Vertex[vertexNum]; for (var i = 0; i < vertexNum; ++i) { var vertex = new Vertex { Coordinate = MmdReaderUtil.ReadVector3(reader), Normal = MmdReaderUtil.ReadVector3(reader), UvCoordinate = MmdReaderUtil.ReadVector2(reader) }; var skinningOperator = new SkinningOperator(); var bdef2 = new SkinningOperator.Bdef2(); bdef2.BoneId = new int[2]; bdef2.BoneId[0] = reader.ReadInt16(); bdef2.BoneId[1] = reader.ReadInt16(); bdef2.BoneWeight = reader.ReadSByte() * 0.01f; skinningOperator.Param = bdef2; skinningOperator.Type = SkinningOperator.SkinningType.SkinningBdef2; vertex.SkinningOperator = skinningOperator; var noEdge = reader.ReadByte() != 0; vertex.EdgeScale = noEdge ? 0.0f : 1.0f; model.Vertices[i] = vertex; } }
private static void ReadModelNameAndDescription(BinaryReader reader, MmdModel model, PmxConfig pmxConfig) { model.Name = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding); model.NameEn = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding); model.Description = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding); model.DescriptionEn = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding); }
//unused data /// <summary> /// 作者写了一个没有用的标签 /// </summary> /// <param name="reader"></param> /// <param name="pmxConfig"></param> private static void ReadEntries(BinaryReader reader, PmxConfig pmxConfig) { //OYM:注意,这是个void方法...作者把所有的数据都丢了23333 var entryItemNum = reader.ReadInt32(); for (var i = 0; i < entryItemNum; ++i) { MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding); //entryItemName MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding); //entryItemNameEn reader.ReadByte(); //isSpecial var elementNum = reader.ReadInt32(); for (var j = 0; j < elementNum; ++j) { var isMorph = reader.ReadByte() == 1; if (isMorph) { MmdReaderUtil.ReadIndex(reader, pmxConfig.MorphIndexSize); //morphIndex } else { MmdReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); //boneIndex } } } }
private static PmdMeta ReadMeta(BinaryReader reader) { PmdMeta ret; ret.Magic = MmdReaderUtil.ReadStringFixedLength(reader, 3, Encoding.ASCII); ret.Version = reader.ReadSingle(); return(ret); }
private VmdMorph ReadVmdMorph(BinaryReader reader) { return(new VmdMorph { MorphName = MmdReaderUtil.ReadStringFixedLength(reader, 15, Tools.JapaneseEncoding), NFrame = reader.ReadInt32(), Weight = reader.ReadSingle() }); }
private static PmxVertexBasic ReadVertexBasic(BinaryReader reader) { PmxVertexBasic ret; ret.Coordinate = MmdReaderUtil.ReadVector3(reader); ret.Normal = MmdReaderUtil.ReadVector3(reader); ret.UvCoordinate = MmdReaderUtil.ReadVector2(reader); return(ret); }
private PmdFacePreamble ReadPmdFacePreamble(BinaryReader reader) { return(new PmdFacePreamble { Name = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding), VertexNum = reader.ReadInt32(), FaceType = reader.ReadSByte() }); }
private static void ReadBoneNameList(BinaryReader reader, PmdReadContext context) { int boneNameListNum = reader.ReadSByte(); context.BoneNameListNum = boneNameListNum; for (var i = 0; i < boneNameListNum; ++i) { MmdReaderUtil.ReadStringFixedLength(reader, 50, Tools.JapaneseEncoding); } }
/// <summary> /// 获取这个material各种杂七杂八的属性 /// </summary> /// <param name="reader"></param> /// <param name="config"></param> /// <param name="encoding"></param> /// <param name="textureIndexSize"></param> /// <param name="textureList"></param> /// <returns></returns> private static MmdMaterial ReadMaterial(BinaryReader reader, ModelReadConfig config, Encoding encoding, int textureIndexSize, MmdTexture[] textureList) { //OYM:别想着优化这一坨代码,人家按顺序来的 var material = new MmdMaterial(); material.Name = MmdReaderUtil.ReadSizedString(reader, encoding); material.NameEn = MmdReaderUtil.ReadSizedString(reader, encoding); material.DiffuseColor = MmdReaderUtil.ReadColor(reader, true); material.SpecularColor = MmdReaderUtil.ReadColor(reader, false); material.Shiness = reader.ReadSingle(); material.AmbientColor = MmdReaderUtil.ReadColor(reader, false); var drawFlag = reader.ReadByte(); //OYM:下面一排位运算,谁有兴趣去看一眼? material.DrawDoubleFace = (drawFlag & PmxMaterialDrawFlags.PmxMaterialDrawDoubleFace) != 0; material.DrawGroundShadow = (drawFlag & PmxMaterialDrawFlags.PmxMaterialDrawGroundShadow) != 0; material.CastSelfShadow = (drawFlag & PmxMaterialDrawFlags.PmxMaterialCastSelfShadow) != 0; material.DrawSelfShadow = (drawFlag & PmxMaterialDrawFlags.PmxMaterialDrawSelfShadow) != 0; material.DrawEdge = (drawFlag & PmxMaterialDrawFlags.PmxMaterialDrawEdge) != 0; material.EdgeColor = MmdReaderUtil.ReadColor(reader, true); material.EdgeSize = reader.ReadSingle(); var textureIndex = MmdReaderUtil.ReadIndex(reader, textureIndexSize);//OYM:后面是选择相应的着色器 if (textureIndex < textureList.Length && textureIndex >= 0) { material.Texture = textureList[textureIndex]; } var subTextureIndex = MmdReaderUtil.ReadIndex(reader, textureIndexSize); if (subTextureIndex < textureList.Length && subTextureIndex >= 0) { material.SubTexture = textureList[subTextureIndex]; } material.SubTextureType = (MmdMaterial.SubTextureTypeEnum)reader.ReadByte(); var useGlobalToon = reader.ReadByte() != 0; if (useGlobalToon) { int globalToonIndex = reader.ReadByte(); material.Toon = MmdTextureUtil.GetGlobalToon(globalToonIndex, config.GlobalToonPath); } else { var toonIndex = MmdReaderUtil.ReadIndex(reader, textureIndexSize); if (toonIndex < textureList.Length && toonIndex >= 0) { material.Toon = textureList[toonIndex]; } } material.MetaInfo = MmdReaderUtil.ReadSizedString(reader, encoding); return(material); }
private PmdBone ReadPmdBone(BinaryReader reader) { return(new PmdBone { Name = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding), ParentId = reader.ReadUInt16(), ChildId = reader.ReadUInt16(), Type = reader.ReadSByte(), IkNumber = reader.ReadUInt16(), Position = MmdReaderUtil.ReadVector3(reader) }); }
private static MmdTexture[] ReadTextureList(BinaryReader reader, PmxConfig pmxConfig) { var textureNum = reader.ReadInt32(); var textureList = new MmdTexture[textureNum]; for (var i = 0; i < textureNum; ++i) { var texturePathEncoding = pmxConfig.Utf8Encoding ? Encoding.UTF8 : Encoding.Unicode; var texturePath = MmdReaderUtil.ReadSizedString(reader, texturePathEncoding); textureList[i] = new MmdTexture(texturePath); } return(textureList); }
public override MmdModel Read(BinaryReader reader, ModelReadConfig config) { var model = new MmdModel(); var context = new PmdReadContext(); var meta = ReadMeta(reader); if (!"Pmd".Equals(meta.Magic) || Math.Abs(meta.Version - 1.0f) > 0.0001f) { throw new MmdFileParseException("File is not a PMD 1.0 file"); } ReadDescription(reader, model); ReadVertices(reader, model); ReadTriangles(reader, model); var toonTextureIds = new List <int>(); ReadParts(reader, model, toonTextureIds); ReadBonesAndIks(reader, model, context); ReadFaces(reader, model); ReadFacdDisplayListNames(reader); ReadBoneNameList(reader, context); ReadBoneDisp(reader); if (MmdReaderUtil.Eof(reader)) { goto PMD_READER_READ_LEGACY_30; } ReadInfoEn(reader, model, context); if (MmdReaderUtil.Eof(reader)) { goto PMD_READER_READ_LEGACY_30; } ReadCustomTextures(reader, config, model, toonTextureIds); if (MmdReaderUtil.Eof(reader)) { goto PMD_READER_READ_LEGACY_50; } ReadRigidBodies(reader, model, context); ReadConstraints(reader, model); goto PMD_READER_READ_SUCCEED; PMD_READER_READ_LEGACY_30: for (var i = 0; i < model.Parts.Length; ++i) { var material = model.Parts[i].Material; material.Toon = MmdTextureUtil.GetGlobalToon(toonTextureIds[i], config.GlobalToonPath); } PMD_READER_READ_LEGACY_50: PMD_READER_READ_SUCCEED: model.Normalize(); return(model); }
private static void ReadRigidBodies(BinaryReader reader, MmdModel model, PmdReadContext context) { var rigidBodyNum = reader.ReadInt32(); model.Rigidbodies = new MmdRigidBody[rigidBodyNum]; for (var i = 0; i < rigidBodyNum; ++i) { var rigidBody = new MmdRigidBody(); rigidBody.Name = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding).Trim(); var boneIndex = reader.ReadUInt16(); if (boneIndex < context.BoneNum) { rigidBody.AssociatedBoneIndex = boneIndex; } else { if (context.CenterBoneIndex == null) { rigidBody.AssociatedBoneIndex = 0; } else { rigidBody.AssociatedBoneIndex = context.CenterBoneIndex.Value; } } rigidBody.CollisionGroup = reader.ReadSByte(); rigidBody.CollisionMask = reader.ReadUInt16(); rigidBody.Shape = (MmdRigidBody.RigidBodyShape)reader.ReadByte(); rigidBody.Dimemsions = MmdReaderUtil.ReadVector3(reader); var rbPosition = MmdReaderUtil.ReadVector3(reader); rigidBody.Position = model.Bones[rigidBody.AssociatedBoneIndex].Position + rbPosition; rigidBody.Rotation = MmdReaderUtil.ReadVector3(reader); rigidBody.Mass = reader.ReadSingle(); rigidBody.TranslateDamp = reader.ReadSingle(); rigidBody.RotateDamp = reader.ReadSingle(); rigidBody.Restitution = reader.ReadSingle(); rigidBody.Friction = reader.ReadSingle(); var type = reader.ReadByte(); if (boneIndex < context.BoneNum) { rigidBody.Type = (MmdRigidBody.RigidBodyType)type; } else { rigidBody.Type = MmdRigidBody.RigidBodyType.RigidTypePhysicsGhost; } model.Rigidbodies[i] = rigidBody; } }
private VmdBone ReadVmdBone(BinaryReader reader) { return(new VmdBone { BoneName = MmdReaderUtil.ReadStringFixedLength(reader, 15, Tools.JapaneseEncoding), NFrame = reader.ReadInt32(), Translation = MmdReaderUtil.ReadVector3(reader), Rotation = MmdReaderUtil.ReadQuaternion(reader), XInterpolator = reader.ReadBytes(16), YInterpolator = reader.ReadBytes(16), ZInterpolator = reader.ReadBytes(16), RInterpolator = reader.ReadBytes(16) }); }
private static void ReadTriangles(BinaryReader reader, MmdModel model, PmxConfig pmxConfig) { var triangleIndexCount = reader.ReadInt32(); model.TriangleIndexes = new int[triangleIndexCount]; if (triangleIndexCount % 3 != 0) { throw new MmdFileParseException("triangle index count " + triangleIndexCount + " is not multiple of 3"); } for (var i = 0; i < triangleIndexCount; ++i) { model.TriangleIndexes[i] = MmdReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize); } }
/// <summary> /// 读取三角形数目 /// </summary> /// <param name="reader"></param> /// <param name="model"></param> /// <param name="pmxConfig"></param> private static void ReadTriangles(BinaryReader reader, MmdModel model, PmxConfig pmxConfig) { var triangleIndexCount = reader.ReadInt32(); model.TriangleIndexes = new int[triangleIndexCount]; if (triangleIndexCount % 3 != 0)//OYM:如果不是三的整数倍就报错(这样子就代表肯定有个三角形的数据丢失了) { throw new MmdFileParseException("triangle index count " + triangleIndexCount + " is not multiple of 3"); } for (var i = 0; i < triangleIndexCount; ++i) { model.TriangleIndexes[i] = MmdReaderUtil.ReadIndex(reader, pmxConfig.VertexIndexSize);//OYM:读取三角形,注意三角形是根据顶点的序号数目生成的 } }
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 BonePoseImage[] ReadFrame() { var boneCount = _meta.BoneCount; var ret = new BonePoseImage[boneCount]; for (var i = 0; i < boneCount; i++) { var position = MmdReaderUtil.ReadVector3(_reader); var rotationEular = MmdReaderUtil.ReadVector3(_reader); ret[i] = new BonePoseImage { Position = position, Rotation = Quaternion.Euler(rotationEular) }; } return(ret); }
private static void ReadConstraints(BinaryReader reader, MmdModel model) { var constraintNum = reader.ReadUInt32(); model.Constraints = new Constraint[constraintNum]; for (var i = 0; i < constraintNum; ++i) { var constraint = new Constraint(); constraint.Name = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding); constraint.AssociatedRigidBodyIndex[0] = reader.ReadInt32(); constraint.AssociatedRigidBodyIndex[1] = reader.ReadInt32(); constraint.Position = MmdReaderUtil.ReadVector3(reader); constraint.Rotation = MmdReaderUtil.ReadVector3(reader); constraint.PositionLowLimit = MmdReaderUtil.ReadVector3(reader); constraint.PositionHiLimit = MmdReaderUtil.ReadVector3(reader); constraint.RotationLowLimit = MmdReaderUtil.ReadVector3(reader); constraint.RotationHiLimit = MmdReaderUtil.ReadVector3(reader); constraint.SpringTranslate = MmdReaderUtil.ReadVector3(reader); constraint.SpringRotate = MmdReaderUtil.ReadVector3(reader); model.Constraints[i] = constraint; } }
private static void ReadBoneIk(BinaryReader reader, Bone bone, int boneIndexSize) { bone.IkInfoVal = new Bone.IkInfo(); bone.IkInfoVal.IkTargetIndex = MmdReaderUtil.ReadIndex(reader, boneIndexSize); bone.IkInfoVal.CcdIterateLimit = reader.ReadInt32(); bone.IkInfoVal.CcdAngleLimit = reader.ReadSingle(); var ikLinkNum = reader.ReadInt32(); bone.IkInfoVal.IkLinks = new Bone.IkLink[ikLinkNum]; for (var j = 0; j < ikLinkNum; ++j) { var link = new Bone.IkLink(); link.LinkIndex = MmdReaderUtil.ReadIndex(reader, boneIndexSize); link.HasLimit = reader.ReadByte() != 0; if (link.HasLimit) { link.LoLimit = MmdReaderUtil.ReadVector3(reader); link.HiLimit = MmdReaderUtil.ReadVector3(reader); } bone.IkInfoVal.IkLinks[j] = link; } }
/// <summary> /// 读取模型骨骼的IK /// </summary> /// <param name="reader"></param> /// <param name="bone"></param> /// <param name="boneIndexSize"></param> private static void ReadBoneIk(BinaryReader reader, Bone bone, int boneIndexSize) { bone.IkInfoVal = new Bone.IkInfo(); bone.IkInfoVal.IkTargetIndex = MmdReaderUtil.ReadIndex(reader, boneIndexSize); //OYM:IK目标 bone.IkInfoVal.CcdIterateLimit = reader.ReadInt32(); //OYM:我想起来了,这是IK解算的术语 bone.IkInfoVal.CcdAngleLimit = reader.ReadSingle(); //OYM:同上 var ikLinkNum = reader.ReadInt32(); bone.IkInfoVal.IkLinks = new Bone.IkLink[ikLinkNum]; for (var j = 0; j < ikLinkNum; ++j) { var link = new Bone.IkLink(); link.LinkIndex = MmdReaderUtil.ReadIndex(reader, boneIndexSize); //OYM:IK的link? link.HasLimit = reader.ReadByte() != 0; //OYM:有限制 if (link.HasLimit) { link.LoLimit = MmdReaderUtil.ReadVector3(reader); link.HiLimit = MmdReaderUtil.ReadVector3(reader); } bone.IkInfoVal.IkLinks[j] = link;//OYM:反正看不懂,等下找下在哪调用的看看好了 } }
private static void ReadConstraints(BinaryReader reader, MmdModel model, PmxConfig pmxConfig) { var constraintNum = reader.ReadInt32(); model.Constraints = new Constraint[constraintNum]; for (var i = 0; i < constraintNum; ++i) { var constraint = new Constraint { Name = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding), NameEn = MmdReaderUtil.ReadSizedString(reader, pmxConfig.Encoding) }; var dofType = reader.ReadByte(); if (dofType == 0) { constraint.AssociatedRigidBodyIndex[0] = MmdReaderUtil.ReadIndex(reader, pmxConfig.RigidBodyIndexSize); constraint.AssociatedRigidBodyIndex[1] = MmdReaderUtil.ReadIndex(reader, pmxConfig.RigidBodyIndexSize); constraint.Position = MmdReaderUtil.ReadVector3(reader); constraint.Rotation = MmdReaderUtil.ReadVector3(reader); constraint.PositionLowLimit = MmdReaderUtil.ReadVector3(reader); constraint.PositionHiLimit = MmdReaderUtil.ReadVector3(reader); constraint.RotationLowLimit = MmdReaderUtil.ReadVector3(reader); constraint.RotationHiLimit = MmdReaderUtil.ReadVector3(reader); constraint.SpringTranslate = MmdReaderUtil.ReadVector3(reader); constraint.SpringRotate = MmdReaderUtil.ReadVector3(reader); } else { throw new MmdFileParseException("Only 6DOF spring joints are supported."); } model.Constraints[i] = constraint; } }
private static void ReadCustomTextures(BinaryReader reader, ModelReadConfig config, MmdModel model, List <int> toonTextureIds) { var customTextures = new MmdTexture[10]; for (var i = 0; i < 10; ++i) { customTextures[i] = new MmdTexture(MmdReaderUtil.ReadStringFixedLength(reader, 100, Tools.JapaneseEncoding)); } for (var i = 0; i < model.Parts.Length; ++i) { var material = model.Parts[i].Material; if (toonTextureIds[i] < 10) { material.Toon = customTextures[toonTextureIds[i]]; } else { material.Toon = MmdTextureUtil.GetGlobalToon(-1, config.GlobalToonPath); } } }
private static void ReadDescription(BinaryReader reader, MmdModel model) { model.Name = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding); model.Description = MmdReaderUtil.ReadStringFixedLength(reader, 256, Tools.JapaneseEncoding); }
private static void ReadParts(BinaryReader reader, MmdModel model, List <int> tooTextureIds) { var partNum = reader.ReadInt32(); var partBaseShift = 0; model.Parts = new Part[partNum]; for (var i = 0; i < partNum; ++i) { var material = new MmdMaterial(); material.DiffuseColor = MmdReaderUtil.ReadColor(reader, true); material.Shiness = reader.ReadSingle(); material.SpecularColor = MmdReaderUtil.ReadColor(reader, false); material.AmbientColor = MmdReaderUtil.ReadColor(reader, false); var toonId = reader.ReadByte(); var edgeFlag = reader.ReadSByte(); var vertexNum = reader.ReadInt32(); var textureName = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding); material.DrawDoubleFace = material.DiffuseColor.a < 0.9999f; material.DrawGroundShadow = edgeFlag != 0; material.CastSelfShadow = true; material.DrawSelfShadow = true; material.DrawEdge = edgeFlag != 0; material.EdgeColor = Color.black; if (!string.IsNullOrEmpty(textureName)) { var dlmPos = textureName.IndexOf("*", StringComparison.Ordinal); if (dlmPos >= 0) { var texPath = textureName.Substring(0, dlmPos); var sphPath = textureName.Substring(dlmPos + 1); if (!string.IsNullOrEmpty(texPath)) { material.Texture = new MmdTexture(texPath); } if (!string.IsNullOrEmpty(sphPath)) { material.SubTexture = new MmdTexture(sphPath); } if (sphPath.EndsWith("a") || sphPath.EndsWith("A")) { material.SubTextureType = MmdMaterial.SubTextureTypeEnum.MatSubTexSpa; } else { material.SubTextureType = MmdMaterial.SubTextureTypeEnum.MatSubTexSph; } } else { var extDlmPos = textureName.LastIndexOf(".", StringComparison.Ordinal); if (extDlmPos >= 0) { var ext = textureName.Substring(extDlmPos + 1); ext = ext.ToLower(); if (!ext.Equals("sph") && !ext.Equals("spa")) { material.Texture = new MmdTexture(textureName); } else { material.SubTexture = new MmdTexture(textureName); ; if (ext.EndsWith("a")) { material.SubTextureType = MmdMaterial.SubTextureTypeEnum.MatSubTexSpa; } else { material.SubTextureType = MmdMaterial.SubTextureTypeEnum.MatSubTexSph; } } } else { material.Texture = new MmdTexture(textureName); } } } var part = new Part(); part.Material = material; tooTextureIds.Add(toonId); part.BaseShift = partBaseShift; part.TriangleIndexNum = vertexNum; partBaseShift += vertexNum; model.Parts[i] = part; } }
public MmdMotion Read(BinaryReader reader) { var motion = new TempMmdMotion(); var magic = MmdReaderUtil.ReadStringFixedLength(reader, 30, Tools.JapaneseEncoding); if (!"Vocaloid Motion Data 0002".Equals(magic)) { throw new MmdFileParseException("File is not a VMD file."); } motion.Name = MmdReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding); var boneMotionNum = reader.ReadInt32(); for (var i = 0; i < boneMotionNum; ++i) { var b = ReadVmdBone(reader); var keyFrame = motion.GetOrCreateBoneKeyFrame(b.BoneName, b.NFrame); keyFrame.Translation = b.Translation; keyFrame.Rotation = b.Rotation; Vector2 c0, c1; const float r = 1.0f / 127.0f; c0.x = b.XInterpolator[0] * r; c0.y = b.XInterpolator[4] * r; c1.x = b.XInterpolator[8] * r; c1.y = b.XInterpolator[12] * r; keyFrame.XInterpolator = new Interpolator(); keyFrame.XInterpolator.SetC(c0, c1); c0.x = b.YInterpolator[0] * r; c0.y = b.YInterpolator[4] * r; c1.x = b.YInterpolator[8] * r; c1.y = b.YInterpolator[12] * r; keyFrame.YInterpolator = new Interpolator(); keyFrame.YInterpolator.SetC(c0, c1); c0.x = b.ZInterpolator[0] * r; c0.y = b.ZInterpolator[4] * r; c1.x = b.ZInterpolator[8] * r; c1.y = b.ZInterpolator[12] * r; keyFrame.ZInterpolator = new Interpolator(); keyFrame.ZInterpolator.SetC(c0, c1); c0.x = b.RInterpolator[0] * r; c0.y = b.RInterpolator[4] * r; c1.x = b.RInterpolator[8] * r; c1.y = b.RInterpolator[12] * r; keyFrame.RInterpolator = new Interpolator(); keyFrame.RInterpolator.SetC(c0, c1); } var morphMotionNum = reader.ReadInt32(); for (var i = 0; i < morphMotionNum; ++i) { var vmdMorph = ReadVmdMorph(reader); var keyFrame = motion.GetOrCreateMorphKeyFrame(vmdMorph.MorphName, vmdMorph.NFrame); keyFrame.Weight = vmdMorph.Weight; keyFrame.WInterpolator = new Interpolator(); } //忽略后面的相机数据 return(motion.BuildMmdMotion()); }