private static void ReadInfoEn(BinaryReader reader, RawMMDModel 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 ReadModelNameAndDescription(BinaryReader reader, RawMMDModel 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); }
private static void ReadVertices(BinaryReader reader, RawMMDModel 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 ReadRigidBodies(BinaryReader reader, RawMMDModel 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.ReadRawCoordinateVector3(reader), Position = MMDReaderUtil.ReadVector3(reader), Rotation = MMDReaderUtil.ReadAmpVector3(reader, Mathf.Rad2Deg), 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 static PmdMeta ReadMeta(BinaryReader reader) { PmdMeta ret; ret.Magic = MMDReaderUtil.ReadStringFixedLength(reader, 3, Encoding.ASCII); ret.Version = reader.ReadSingle(); 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 PmxVertexBasic ReadVertexBasic(BinaryReader reader) { PmxVertexBasic ret; ret.Coordinate = MMDReaderUtil.ReadVector3(reader); ret.Normal = MMDReaderUtil.ReadVector3(reader); ret.UvCoordinate = MMDReaderUtil.ReadVector2(reader); return(ret); }
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); } }
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); }
private static MMDMaterial ReadMaterial(BinaryReader reader, ModelReadConfig config, Encoding encoding, int textureIndexSize, MMDTexture[] textureList) { 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(); 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); 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 static void ReadRigidBodies(BinaryReader reader, RawMMDModel 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; } }
public override RawMMDModel Read(BinaryReader reader, ModelReadConfig config) { var model = new RawMMDModel(); 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 ReadTriangles(BinaryReader reader, RawMMDModel 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); } }
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 ReadConstraints(BinaryReader reader, RawMMDModel model) { var constraintNum = reader.ReadUInt32(); model.Joints = new Model.Joint[constraintNum]; for (var i = 0; i < constraintNum; ++i) { var constraint = new Model.Joint(); 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.ReadAmpVector3(reader, Mathf.Rad2Deg); 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.Joints[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; } }
private static void ReadJoints(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig) { var constraintNum = reader.ReadInt32(); model.Joints = new Model.Joint[constraintNum]; for (var i = 0; i < constraintNum; ++i) { var joint = new Model.Joint { Name = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding), NameEn = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding) }; var dofType = reader.ReadByte(); if (dofType == 0) { joint.AssociatedRigidBodyIndex[0] = MMDReaderUtil.ReadIndex(reader, pmxConfig.RigidBodyIndexSize); joint.AssociatedRigidBodyIndex[1] = MMDReaderUtil.ReadIndex(reader, pmxConfig.RigidBodyIndexSize); joint.Position = MMDReaderUtil.ReadVector3(reader); joint.Rotation = MMDReaderUtil.ReadAmpVector3(reader, Mathf.Rad2Deg); joint.PositionLowLimit = MMDReaderUtil.ReadVector3(reader); joint.PositionHiLimit = MMDReaderUtil.ReadVector3(reader); joint.RotationLowLimit = MMDReaderUtil.ReadVector3(reader); joint.RotationHiLimit = MMDReaderUtil.ReadVector3(reader); joint.SpringTranslate = MMDReaderUtil.ReadVector3(reader); joint.SpringRotate = MMDReaderUtil.ReadVector3(reader); } else { throw new MMDFileParseException("Only 6DOF spring joints are supported."); } model.Joints[i] = joint; } }
private static void ReadCustomTextures(BinaryReader reader, ModelReadConfig config, RawMMDModel 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(0, config.GlobalToonPath); } } }
//unused data private static void ReadEntries(BinaryReader reader, PmxConfig pmxConfig) { 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 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; } }
private static void ReadBones(BinaryReader reader, RawMMDModel model, PmxConfig pmxConfig) { var boneNum = reader.ReadInt32(); model.Bones = new Bone[boneNum]; for (var i = 0; i < boneNum; ++i) { var bone = new Bone { Name = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding), NameEn = MMDReaderUtil.ReadSizedString(reader, pmxConfig.Encoding), Position = MMDReaderUtil.ReadVector3(reader) }; var parentIndex = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); if (parentIndex < boneNum && parentIndex >= 0) { bone.ParentIndex = parentIndex; } else { bone.ParentIndex = -1; } bone.TransformLevel = reader.ReadInt32(); var flag = reader.ReadUInt16(); bone.ChildBoneVal.ChildUseId = (flag & PmxBoneFlags.PmxBoneChildUseId) != 0; bone.Rotatable = (flag & PmxBoneFlags.PmxBoneRotatable) != 0; bone.Movable = (flag & PmxBoneFlags.PmxBoneMovable) != 0; bone.Visible = (flag & PmxBoneFlags.PmxBoneVisible) != 0; bone.Controllable = (flag & PmxBoneFlags.PmxBoneControllable) != 0; bone.HasIk = (flag & PmxBoneFlags.PmxBoneHasIk) != 0; bone.AppendRotate = (flag & PmxBoneFlags.PmxBoneAcquireRotate) != 0; bone.AppendTranslate = (flag & PmxBoneFlags.PmxBoneAcquireTranslate) != 0; bone.RotAxisFixed = (flag & PmxBoneFlags.PmxBoneRotAxisFixed) != 0; bone.UseLocalAxis = (flag & PmxBoneFlags.PmxBoneUseLocalAxis) != 0; bone.PostPhysics = (flag & PmxBoneFlags.PmxBonePostPhysics) != 0; bone.ReceiveTransform = (flag & PmxBoneFlags.PmxBoneReceiveTransform) != 0; if (bone.ChildBoneVal.ChildUseId) { bone.ChildBoneVal.Index = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); } else { bone.ChildBoneVal.Offset = MMDReaderUtil.ReadVector3(reader); } if (bone.RotAxisFixed) { bone.RotAxis = MMDReaderUtil.ReadVector3(reader); } if (bone.AppendRotate || bone.AppendTranslate) { bone.AppendBoneVal.Index = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); bone.AppendBoneVal.Ratio = reader.ReadSingle(); } if (bone.UseLocalAxis) { var localX = MMDReaderUtil.ReadVector3(reader); var localZ = MMDReaderUtil.ReadVector3(reader); var localY = Vector3.Cross(localX, localZ); localZ = Vector3.Cross(localX, localY); localX.Normalize(); localY.Normalize(); localZ.Normalize(); bone.LocalAxisVal.AxisX = localX; bone.LocalAxisVal.AxisY = localY; bone.LocalAxisVal.AxisZ = localZ; } if (bone.ReceiveTransform) { bone.ExportKey = reader.ReadInt32(); } if (bone.HasIk) { ReadBoneIk(reader, bone, pmxConfig.BoneIndexSize); } model.Bones[i] = bone; } }
private static void ReadDescription(BinaryReader reader, RawMMDModel model) { model.Name = MMDReaderUtil.ReadStringFixedLength(reader, 20, Tools.JapaneseEncoding); model.Description = MMDReaderUtil.ReadStringFixedLength(reader, 256, Tools.JapaneseEncoding); }
private static void ReadParts(BinaryReader reader, RawMMDModel 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; } }
private static Vertex ReadVertex(BinaryReader reader, PmxConfig pmxConfig) { var pv = ReadVertexBasic(reader); var vertex = new Vertex { Coordinate = pv.Coordinate, Normal = pv.Normal, UvCoordinate = pv.UvCoordinate }; if (pmxConfig.ExtraUvNumber > 0) { var extraUv = new Vector4[pmxConfig.ExtraUvNumber]; for (var ei = 0; ei < pmxConfig.ExtraUvNumber; ++ei) { extraUv[ei] = MMDReaderUtil.ReadVector4(reader); } vertex.ExtraUvCoordinate = extraUv; } var op = new SkinningOperator(); var skinningType = (SkinningOperator.SkinningType)reader.ReadByte(); op.Type = skinningType; switch (skinningType) { case SkinningOperator.SkinningType.SkinningBdef1: var bdef1 = new SkinningOperator.Bdef1(); bdef1.BoneId = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); op.Param = bdef1; break; case SkinningOperator.SkinningType.SkinningBdef2: var bdef2 = new SkinningOperator.Bdef2(); bdef2.BoneId[0] = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); bdef2.BoneId[1] = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); bdef2.BoneWeight = reader.ReadSingle(); op.Param = bdef2; break; case SkinningOperator.SkinningType.SkinningBdef4: var bdef4 = new SkinningOperator.Bdef4(); for (var j = 0; j < 4; ++j) { bdef4.BoneId[j] = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); } for (var j = 0; j < 4; ++j) { bdef4.BoneWeight[j] = reader.ReadSingle(); } op.Param = bdef4; break; case SkinningOperator.SkinningType.SkinningSdef: var sdef = new SkinningOperator.Sdef(); sdef.BoneId[0] = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); sdef.BoneId[1] = MMDReaderUtil.ReadIndex(reader, pmxConfig.BoneIndexSize); sdef.BoneWeight = reader.ReadSingle(); sdef.C = MMDReaderUtil.ReadVector3(reader); sdef.R0 = MMDReaderUtil.ReadVector3(reader); sdef.R1 = MMDReaderUtil.ReadVector3(reader); op.Param = sdef; break; default: throw new MMDFileParseException("invalid skinning type: " + skinningType); } vertex.SkinningOperator = op; vertex.EdgeScale = reader.ReadSingle(); return(vertex); }