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