/// <summary>
        /// Se crea una capsula a partir de un radio, altura, posicion, masa y si se dedea o no calcular
        /// la inercia. Esto es importante ya que sin inercia no se generan rotaciones que no se
        /// controlen en forma particular.
        /// </summary>
        /// <param name="radius">Radio de la Capsula</param>
        /// <param name="height">Altura de la Capsula</param>
        /// <param name="position">Posicion de la Capsula</param>
        /// <param name="mass">Masa de la Capsula</param>
        /// <param name="needInertia">Booleano para el momento de inercia de la Capsula</param>
        /// <returns>Rigid Body de una Capsula</returns>
        public static RigidBody CreateCapsule(float radius, float height, TGCVector3 position, float mass, bool needInertia)
        {
            //Creamos el shape de la Capsula a partir de un radio y una altura.
            var capsuleShape = new CapsuleShape(radius, height);

            //Armamos las transformaciones que luego formaran parte del cuerpo rigido de la capsula.
            var capsuleTransform = TGCMatrix.Identity;

            capsuleTransform.Origin = position;
            var capsuleMotionState = new DefaultMotionState(capsuleTransform.ToBsMatrix);
            RigidBodyConstructionInfo capsuleRigidBodyInfo;

            //Calculamos o no el momento de inercia dependiendo de que comportamiento
            //queremos que tenga la capsula.
            if (!needInertia)
            {
                capsuleRigidBodyInfo = new RigidBodyConstructionInfo(mass, capsuleMotionState, capsuleShape);
            }
            else
            {
                var capsuleInertia = capsuleShape.CalculateLocalInertia(mass);
                capsuleRigidBodyInfo = new RigidBodyConstructionInfo(mass, capsuleMotionState, capsuleShape, capsuleInertia);
            }

            var localCapsuleRigidBody = new RigidBody(capsuleRigidBodyInfo);

            localCapsuleRigidBody.LinearFactor = TGCVector3.One.ToBsVector;
            //Dado que hay muchos parametros a configurar el RigidBody lo ideal es que
            //cada caso se configure segun lo que se necesite.

            return(localCapsuleRigidBody);
        }
        /// <summary>
        ///  Se crea una capsula a partir de un radio, una altura y una posicion.
        ///  Los valores de la masa y el calculo de inercia asociado estan fijos para que no haya comportamiento erratico.
        /// </summary>
        /// <param name="radius"></param>
        /// <param name="height"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        public static RigidBody CreateCapsule(float radius, float height, TGCVector3 position)
        {
            //Creamos el shape de la Capsula a partir de un radio y una altura.
            var caspsuleShape = new CapsuleShape(radius, height);

            //Armamos las transformaciones que luego formaran parte del cuerpo rigido de la capsula.
            var capsuleTransform = TGCMatrix.Identity;

            capsuleTransform.Origin = position;
            var capsuleMotionState = new DefaultMotionState(Matrix.Translation(position.ToBsVector));

            // Utilizamos una masa muy grande (1000 Kg) para calcular el momento de inercia de forma que la capsula no
            // genere una rotacion y termine volcando.
            var capsuleInertia = caspsuleShape.CalculateLocalInertia(100000);

            // Aqui usamos una masa bastante baja (1 Kg) para que cuando se arme el cuerpo rigido y se intente aplicar
            // un impulso se facil de mover la capsula.
            var capsuleRigidBodyInfo = new RigidBodyConstructionInfo(1, capsuleMotionState, caspsuleShape, capsuleInertia);

            var localCapsuleRigidBody = new RigidBody(capsuleRigidBodyInfo);

            localCapsuleRigidBody.LinearFactor = TGCVector3.One.ToBsVector;
            localCapsuleRigidBody.SetDamping(0.5f, 0f);
            localCapsuleRigidBody.Restitution = 0f;
            localCapsuleRigidBody.Friction    = 1;

            return(localCapsuleRigidBody);
        }
Esempio n. 3
0
        protected override void RebuildRigidBody()
        {
            lock (PhysicsSimulation.Locker)
            {
                World?.Physics.World.RemoveRigidBody(RigidBody);

                _capsuleShape?.Dispose();
                RigidBody?.Dispose();

                _capsuleShape = new CapsuleShape(_capsuleRadius, _capsuleHeight / 2);
                var mass             = GetMass();
                var intertia         = _capsuleShape.CalculateLocalInertia(mass);
                var constructionInfo = new RigidBodyConstructionInfo(mass, _motionState, _capsuleShape, intertia);
                RigidBody = new RigidBody(constructionInfo)
                {
                    AngularFactor   = new BulletSharp.Math.Vector3(0, 0, 0),
                    CollisionFlags  = CollisionFlags.CharacterObject,
                    ActivationState = ActivationState.DisableDeactivation,
                    UserObject      = this
                };
                RigidBody.UpdateInertiaTensor();

                World?.Physics.World.AddRigidBody(RigidBody);
            }
        }
        private static RigidBody CreateRigidBody(TGCVector3 position, float mass, CapsuleShape capsule)
        {
            var inertia   = capsule.CalculateLocalInertia(mass);
            var transform = TGCMatrix.Translation(position);

            var motionState   = new DefaultMotionState(transform.ToBsMatrix);
            var rigidBodyInfo = new RigidBodyConstructionInfo(mass, motionState, capsule, inertia);

            return(new RigidBody(rigidBodyInfo)
            {
                AngularFactor = Vector3.UnitY
            });
        }
Esempio n. 5
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);
            }
        }