Example #1
0
        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 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;
            }
        }
        private void AttachPhysicComponents(Transform[] boneTransforms, MMDModel model)
        {
            GameObject[] bones       = boneTransforms.Select(x => x.gameObject).ToArray();
            int          bonesCount  = bones.Length;
            Transform    parentOfAll = model.gameObject.transform;
            Dictionary <int, List <Collider> > colliderGroups = new Dictionary <int, List <Collider> >();
            int rigidbodiesCount = model.RawMMDModel.Rigidbodies.Length;

            for (int i = 0; i < rigidbodiesCount; i++)
            {
                MMDRigidBody mmdRigidBody = model.RawMMDModel.Rigidbodies[i];
                if (bonesCount <= mmdRigidBody.AssociatedBoneIndex)
                {
                    continue;
                }
                GameObject bone = bones[mmdRigidBody.AssociatedBoneIndex];
                if (Alt_OriginalBoneDictionary.ContainsKey(bone.transform))
                {
                    bone = Alt_OriginalBoneDictionary[bone.transform].gameObject;
                }

                if (mmdRigidBody.Type == MMDRigidBody.RigidBodyType.RigidTypePhysicsGhost ||
                    mmdRigidBody.Type == MMDRigidBody.RigidBodyType.RigidTypePhysicsStrict)
                {
                    continue;
                }

                if (!colliderGroups.ContainsKey(mmdRigidBody.CollisionGroup))
                {
                    colliderGroups.Add(mmdRigidBody.CollisionGroup, new List <Collider>());
                }

                GameObject colliderObject = new GameObject(mmdRigidBody.Name + ColliderNameTail);
                colliderObject.transform.parent = bone.transform;
                Vector3 bonePosition = bone.transform.position - parentOfAll.position;
                colliderObject.transform.localPosition = mmdRigidBody.Position - bonePosition;
                colliderObject.transform.localRotation = Quaternion.Euler(mmdRigidBody.Rotation);
                switch (mmdRigidBody.Shape)
                {
                case MMDRigidBody.RigidBodyShape.RigidShapeBox:
                    BoxCollider boxCollider = colliderObject.AddComponent <BoxCollider>();
                    colliderGroups[mmdRigidBody.CollisionGroup].Add(boxCollider);
                    boxCollider.size = mmdRigidBody.Dimemsions;
                    break;

                case MMDRigidBody.RigidBodyShape.RigidShapeCapsule:
                    CapsuleCollider capsuleCollider = colliderObject.AddComponent <CapsuleCollider>();
                    colliderGroups[mmdRigidBody.CollisionGroup].Add(capsuleCollider);
                    capsuleCollider.radius = mmdRigidBody.Dimemsions.x;
                    capsuleCollider.height = mmdRigidBody.Dimemsions.y;
                    break;

                case MMDRigidBody.RigidBodyShape.RigidShapeSphere:
                    SphereCollider sphereCollider = colliderObject.AddComponent <SphereCollider>();
                    colliderGroups[mmdRigidBody.CollisionGroup].Add(sphereCollider);
                    sphereCollider.radius = mmdRigidBody.Dimemsions.x;
                    break;
                }

                if (bone.GetComponent <Rigidbody>() != null)
                {
                    continue;
                }
                Rigidbody rigidbody = bone.AddComponent <Rigidbody>();
                rigidbody.useGravity  = true;
                rigidbody.mass        = mmdRigidBody.Mass;
                rigidbody.drag        = mmdRigidBody.TranslateDamp;
                rigidbody.angularDrag = mmdRigidBody.RotateDamp;
                if (mmdRigidBody.Type == MMDRigidBody.RigidBodyType.RigidTypeKinematic)
                {
                    rigidbody.isKinematic = true;
                }
            }

            //以下ジョイント
            int jointCount = model.RawMMDModel.Joints.Length;

            for (int i = 0; i < jointCount; i++)
            {
                LibMMD.Model.Joint mmdJoint = model.RawMMDModel.Joints[i];
                int jointFromBoneIndex      = model.RawMMDModel.Rigidbodies[mmdJoint.AssociatedRigidBodyIndex[0]].AssociatedBoneIndex;
                int jointToBoneIndex        = model.RawMMDModel.Rigidbodies[mmdJoint.AssociatedRigidBodyIndex[1]].AssociatedBoneIndex;
                if (bonesCount <= jointFromBoneIndex || bonesCount <= jointToBoneIndex)
                {
                    continue;
                }
                GameObject jointFromObj     = bones[jointFromBoneIndex];
                GameObject jointToObj       = bones[jointToBoneIndex];
                Rigidbody  jointToRigidbody = jointToObj.GetComponent <Rigidbody>();
                if (jointToRigidbody == null)
                {
                    continue;
                }
                Rigidbody jointFromRigidbody = jointFromObj.GetComponent <Rigidbody>();
                if (jointFromRigidbody == null)
                {
                    //この場合jointFromObjは基本的に体の一部などの始点
                    jointFromRigidbody             = jointFromObj.AddComponent <Rigidbody>();
                    jointFromRigidbody.isKinematic = true;
                }
                //すでに向こう側から接続していたら接続しない
                HingeJoint[] counterJoint = jointToObj.GetComponents <HingeJoint>();
                if (counterJoint.Any(x => x != null && jointFromRigidbody != null && x.connectedBody == jointFromRigidbody))
                {
                    continue;
                }
                //残念ながら情報を落とす
                HingeJoint joint = jointFromObj.AddComponent <HingeJoint>();
                joint.connectedBody = jointToRigidbody;
                joint.axis          = Quaternion.Euler(mmdJoint.Rotation) * jointFromObj.transform.right;
                joint.limits        = new JointLimits
                {
                    max = HalfPIDeg,
                    min = -HalfPIDeg
                };
                joint.useLimits = true;
                joint.spring    = new JointSpring
                {
                    spring = mmdJoint.SpringTranslate.magnitude
                };
                joint.useSpring = true;
            }

            foreach (List <Collider> colliderGroup in colliderGroups.Values)
            {
                int colliderCount = colliderGroup.Count;
                for (int i = 0; i < colliderCount; i++)
                {
                    for (int j = 0; j < i; j++)
                    {
                        Physics.IgnoreCollision(colliderGroup[i], colliderGroup[j]);
                    }
                }
            }
        }