Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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;
            }
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        private void ReadBonesAndIks(BinaryReader reader, RawMMDModel model, PmdReadContext context)
        {
            int boneNum = reader.ReadUInt16();

            context.BoneNum = boneNum;
            var rawBones = new PmdBone[boneNum];

            for (var i = 0; i < boneNum; ++i)
            {
                rawBones[i] = ReadPmdBone(reader);
            }

            var ikBoneIds = new HashSet <int>();
            int ikNum     = reader.ReadUInt16();
            var rawIkList = new List <PmdRawIk>(ikNum);

            for (var i = 0; i < ikNum; ++i)
            {
                var rawIk = new PmdRawIk();
                rawIk.Preamble = ReadPmdIkPreamable(reader);
                ikBoneIds.Add(rawIk.Preamble.IkBoneIndex);
                rawIk.Chain = new int[rawIk.Preamble.IkChainLength];
                for (var j = 0; j < rawIk.Preamble.IkChainLength; ++j)
                {
                    rawIk.Chain[j] = reader.ReadUInt16();
                }
                rawIkList.Add(rawIk);
            }

            rawIkList.Sort((ik1, ik2) =>
            {
                var a1 = 0;
                var a2 = 0;
                if (ik1.Chain.Length > 0)
                {
                    a1 = ik1.Chain[0];
                }
                if (ik2.Chain.Length > 0)
                {
                    a2 = ik2.Chain[0];
                }
                return(a1.CompareTo(a2));
            });

            var boneList = new List <Bone>();

            int?centerBoneIndex = null;

            model.Bones = new Bone[boneNum];
            for (var i = 0; i < boneNum; ++i)
            {
                var bone = new Bone();
                boneList.Add(bone);
                var rawBone = rawBones[i];
                bone.Name = rawBone.Name;
                if ("\u30BB\u30F3\u30BF\u30FC".Equals(bone.Name)) //TODO 验证是不是这个值
                {
                    centerBoneIndex = i;
                }
                bone.Position = rawBone.Position;
                // TODO - workaround here, need fix, see [1].
                if (i != rawBone.ParentId)
                {
                    bone.ParentIndex = rawBone.ParentId;
                }
                else
                {
                    bone.ParentIndex = 0; //TODO mmdlib里是nil
                }
                bone.TransformLevel          = 0;
                bone.ChildBoneVal.ChildUseId = true;
                bone.ChildBoneVal.Index      = rawBone.ChildId;
                bone.Rotatable = true;
                var type = (PmdBoneTypes)rawBone.Type;
                bone.HasIk   = type == PmdBoneTypes.PmdBoneIk || ikBoneIds.Contains(i);
                bone.Movable = type == PmdBoneTypes.PmdBoneRotateAndTranslate || bone.HasIk;
                bone.Visible = type != PmdBoneTypes.PmdBoneIkTo && type != PmdBoneTypes.PmdBoneInvisible &&
                               type != PmdBoneTypes.PmdBoneRotateRatio;
                bone.Controllable     = true;
                bone.AppendRotate     = type == PmdBoneTypes.PmdBoneRotateEffect || type == PmdBoneTypes.PmdBoneRotateRatio;
                bone.AppendTranslate  = false;
                bone.RotAxisFixed     = type == PmdBoneTypes.PmdBoneTwist;
                bone.UseLocalAxis     = false;
                bone.PostPhysics      = false;
                bone.ReceiveTransform = false;

                if (bone.AppendRotate)
                {
                    if (type == PmdBoneTypes.PmdBoneRotateEffect)
                    {
                        bone.AppendBoneVal.Index = rawBone.IkNumber;
                        bone.AppendBoneVal.Ratio = 1.0f;
                        bone.TransformLevel      = 2;
                    }
                    else
                    {
                        bone.ChildBoneVal.ChildUseId = false;
                        bone.ChildBoneVal.Offset     = Vector3.zero;
                        bone.AppendBoneVal.Index     = rawBone.ChildId;
                        bone.AppendBoneVal.Ratio     = rawBone.IkNumber * 0.01f;
                    }
                }
                if (bone.HasIk)
                {
                    bone.TransformLevel = 1;
                }

                if (bone.RotAxisFixed)
                {
                    var childId = rawBone.ChildId;
                    if (childId > boneNum)
                    {
                        childId = 0;
                    }
                    bone.RotAxis = (rawBones[childId].Position - bone.Position).normalized;
                    if (bone.ChildBoneVal.ChildUseId)
                    {
                        bone.ChildBoneVal.ChildUseId = false;
                        bone.ChildBoneVal.Offset     = Vector3.zero;
                    }
                }

                model.Bones[i] = bone;
            }

            var loLimit = Vector3.zero;
            var hiLimit = Vector3.zero;

            loLimit.x = (float)-Math.PI;
            hiLimit.x = (float)(-0.5f / 180.0f * Math.PI);

            for (var i = 0; i < boneNum; ++i)
            {
                if (!ikBoneIds.Contains(i))
                {
                    boneList[i].IkInfoVal = new Bone.IkInfo
                    {
                        IkLinks = new Bone.IkLink[0]
                    };
                    continue;
                }
                var associatedIkCount = 0;
                for (var j = 0; j < ikNum; ++j)
                {
                    var rawIk = rawIkList[j];
                    if (i != rawIk.Preamble.IkBoneIndex)
                    {
                        continue;
                    }
                    Bone bone;
                    if (associatedIkCount == 0)
                    {
                        bone = boneList[i];
                    }
                    else
                    {
                        var originalBone = boneList[i];
                        bone = Bone.CopyOf(originalBone);
                        boneList.Add(bone);
                        bone.Name                    = "[IK]" + originalBone.Name;
                        bone.NameEn                  = "[IK]" + originalBone.NameEn;
                        bone.ParentIndex             = i;
                        bone.ChildBoneVal.ChildUseId = false;
                        bone.ChildBoneVal.Offset     = Vector3.zero;
                        bone.Visible                 = false;
                        bone.IkInfoVal.IkLinks       = new Bone.IkLink[rawIk.Preamble.IkChainLength];
                        bone.HasIk                   = true;
                    }
                    bone.IkInfoVal = new Bone.IkInfo();
                    bone.IkInfoVal.IkTargetIndex   = rawIk.Preamble.IkTargetBoneIndex;
                    bone.IkInfoVal.CcdIterateLimit = rawIk.Preamble.CcdIterateLimit;
                    bone.IkInfoVal.CcdAngleLimit   = rawIk.Preamble.CcdAngleLimit;
                    bone.IkInfoVal.IkLinks         = new Bone.IkLink[rawIk.Preamble.IkChainLength];

                    for (var k = 0; k < rawIk.Preamble.IkChainLength; ++k)
                    {
                        var link = new Bone.IkLink();
                        link.LinkIndex = rawIk.Chain[k];
                        var linkName = model.Bones[link.LinkIndex].Name;
                        if ("\u5DE6\u3072\u3056".Equals(linkName) || "\u53F3\u3072\u3056".Equals(linkName))
                        {
                            link.HasLimit = true;
                            link.LoLimit  = loLimit;
                            link.HiLimit  = hiLimit;
                        }
                        else
                        {
                            link.HasLimit = false;
                        }

                        bone.IkInfoVal.IkLinks[k] = link;
                    }

                    associatedIkCount++;
                }
            }

            model.Bones = boneList.ToArray();

            // TODO - need verification

            for (var i = 0; i < boneNum; ++i)
            {
                var stable = true;
                for (var j = 0; j < boneNum; ++j)
                {
                    var bone           = model.Bones[j];
                    var transformLevel = bone.TransformLevel;
                    var parentId       = bone.ParentIndex;
                    while (parentId < boneNum)
                    {
                        var parentTransformLevel = model.Bones[parentId].TransformLevel;
                        if (transformLevel < parentTransformLevel)
                        {
                            transformLevel = parentTransformLevel;
                            stable         = false;
                        }
                        parentId = model.Bones[parentId].ParentIndex;
                    }
                    bone.TransformLevel = transformLevel;
                }
                if (stable)
                {
                    break;
                }
            }
            context.CenterBoneIndex = centerBoneIndex;
        }