public void Fix()
        {
            if (!_strict)
            {
                return;
            }
            var parentLocalMatrix = new Matrix4x4();

            _target.LocalMatrix = _target.SkinningMatrix * _target.GlobalOffsetMatrixInv;
            if (_target.HasParent)
            {
                parentLocalMatrix   = BulletPyhsicsReactor.GetPoserBoneImage(_poser, _target.Parent).LocalMatrix;
                _target.LocalMatrix = parentLocalMatrix.inverse * _target.LocalMatrix;
            }
            MathUtil.SetTransToMatrix4X4(_target.TotalTranslation + _target.LocalOffset, ref _target.LocalMatrix);
            if (_target.HasParent)
            {
                _target.LocalMatrix = parentLocalMatrix * _target.LocalMatrix;
            }
            _target.SkinningMatrix = _target.LocalMatrix * _target.GlobalOffsetMatrix;
        }
예제 #2
0
        public override void AddPoser(Poser poser)
        {
            var model = poser.Model;

            if (_rigidBodies.ContainsKey(poser))
            {
                return;
            }
            poser.ResetPosing();
            var motionStates = new List <PoserMotionState>();

            _motionStates.Add(poser, motionStates);
            var rigidBodies = new List <RigidBody>();

            _rigidBodies.Add(poser, rigidBodies);
            var constraints = new List <Generic6DofSpringConstraint>();

            _constraints.Add(poser, constraints);

            foreach (var body in model.Rigidbodies)
            {
                var bodyDimension = body.Dimemsions;

                CollisionShape btShape = null;

                var btMass         = 0.0f;
                var btLocalInertia = new Vector3(0.0f, 0.0f, 0.0f);

                switch (body.Shape)
                {
                case MmdRigidBody.RigidBodyShape.RigidShapeSphere:
                    btShape = new SphereShape(bodyDimension.x);
                    break;

                case MmdRigidBody.RigidBodyShape.RigidShapeBox:
                    btShape = new BoxShape(new Vector3(bodyDimension.x, bodyDimension.y,
                                                       bodyDimension.z));
                    break;

                case MmdRigidBody.RigidBodyShape.RigidShapeCapsule:
                    btShape = new CapsuleShape(bodyDimension.x, bodyDimension.y);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                if (body.Type != MmdRigidBody.RigidBodyType.RigidTypeKinematic)
                {
                    btMass = body.Mass;
                    btShape.CalculateLocalInertia(btMass, out btLocalInertia);
                }

                var bodyTransform = MathUtil.QuaternionToMatrix4X4(MathUtil.YxzToQuaternion(body.Rotation));
                MathUtil.SetTransToMatrix4X4(body.Position, ref bodyTransform);
                var btBodyTransform = new Matrix();
                MathUtil.UnityMatrixToBulletMatrix(bodyTransform, ref btBodyTransform);

                var btMotionState = new PoserMotionState(poser, body, btBodyTransform);
                var btInfo        =
                    new RigidBodyConstructionInfo(btMass, btMotionState, btShape, btLocalInertia)
                {
                    LinearDamping  = body.TranslateDamp,
                    AngularDamping = body.RotateDamp,
                    Restitution    = body.Restitution,
                    Friction       = body.Friction
                };

                var btRigidBody = new RigidBody(btInfo)
                {
                    ActivationState = ActivationState.DisableDeactivation
                };

                if (body.Type == MmdRigidBody.RigidBodyType.RigidTypeKinematic)
                {
                    btRigidBody.CollisionFlags = btRigidBody.CollisionFlags | CollisionFlags.KinematicObject;
                }
                _world.AddRigidBody(btRigidBody, (short)(1 << body.CollisionGroup), (short)body.CollisionMask);
#if MMD_PHYSICS_DEBUG
                CreateUnityCollisionObjectProxy(btRigidBody, body.Name);
#endif
                motionStates.Add(btMotionState);
                rigidBodies.Add(btRigidBody);
            }

            foreach (var constraint in model.Constraints)
            {
                var btBody1 = rigidBodies[constraint.AssociatedRigidBodyIndex[0]];
                var btBody2 = rigidBodies[constraint.AssociatedRigidBodyIndex[1]];

                var positionLowLimit = constraint.PositionLowLimit;
                var positionHiLimit  = constraint.PositionHiLimit;
                var rotationLoLimit  = constraint.RotationLowLimit;
                var rotationHiLimit  = constraint.RotationHiLimit;

                var constraintTransform = MathUtil.QuaternionToMatrix4X4(MathUtil.YxzToQuaternion(constraint.Rotation));
                MathUtil.SetTransToMatrix4X4(constraint.Position, ref constraintTransform);

                var btConstraintTransform = new Matrix();
                MathUtil.UnityMatrixToBulletMatrix(constraintTransform, ref btConstraintTransform);

                var btLocalizationTransform1 = btConstraintTransform * Matrix.Invert(btBody1.WorldTransform);  //TODO 验证这个和mmdlib里算出来的是否一样
                var btLocalizationTransform2 = btConstraintTransform * Matrix.Invert(btBody2.WorldTransform);

                var btConstraint = new Generic6DofSpringConstraint(btBody1, btBody2, btLocalizationTransform1,
                                                                   btLocalizationTransform2, true)
                {
                    LinearLowerLimit =
                        new Vector3(positionLowLimit.x, positionLowLimit.y, positionLowLimit.z),
                    LinearUpperLimit =
                        new Vector3(positionHiLimit.x, positionHiLimit.y, positionHiLimit.z),
                    AngularLowerLimit =
                        new Vector3(rotationLoLimit.x, rotationLoLimit.y, rotationLoLimit.z),
                    AngularUpperLimit =
                        new Vector3(rotationHiLimit.x, rotationHiLimit.y, rotationHiLimit.z)
                };

                for (var j = 0; j < 3; ++j)
                {
                    btConstraint.SetStiffness(j, constraint.SpringTranslate[j]);
                    btConstraint.EnableSpring(j, true);
                    btConstraint.SetStiffness(j + 3, constraint.SpringRotate[j]);
                    btConstraint.EnableSpring(j + 3, true);
                }

                _world.AddConstraint(btConstraint);
                constraints.Add(btConstraint);
            }
        }