Exemple #1
0
        void ICCDPositionUpdateable.UpdatePositionContinuously(float dt)
        {
            float minimumToi = 1;

            for (int i = 0; i < collisionInformation.pairs.Count; ++i)
            {
                if (collisionInformation.pairs.Elements[i].timeOfImpact < minimumToi)
                {
                    minimumToi = collisionInformation.pairs.Elements[i].timeOfImpact;
                }
            }

            //The orientation was already updated by the PreUpdatePosition.
            //However, to be here, this object is not a discretely updated object.
            //That means we still need to update the linear motion.

            Vector3 increment;

            Vector3.Multiply(ref linearVelocity, dt * minimumToi, out increment);
            Vector3.Add(ref position, ref increment, out position);

            collisionInformation.UpdateWorldTransform(ref position, ref orientation);

            if (PositionUpdated != null)
            {
                PositionUpdated(this);
            }

            linearMomentum.Validate();
            linearVelocity.Validate();
            angularMomentum.Validate();
            angularVelocity.Validate();
            position.Validate();
            orientation.Validate();
        }
Exemple #2
0
 ///<summary>
 /// Constructs a new compound shape entry using the volume of the shape as a weight.
 ///</summary>
 ///<param name="shape">Shape to use.</param>
 ///<param name="position">Local position of the shape.</param>
 ///<param name="weight">Weight of the entry.  This defines how much the entry contributes to its owner
 /// for the purposes of center of mass and inertia computation.</param>
 public CompoundShapeEntry(EntityShape shape, Vector3 position, float weight)
 {
     position.Validate();
     LocalTransform = new RigidTransform(position);
     Shape          = shape;
     Weight         = weight;
 }
Exemple #3
0
 ///<summary>
 /// Constructs a new compound shape entry using the volume of the shape as a weight.
 ///</summary>
 ///<param name="shape">Shape to use.</param>
 ///<param name="position">Local position of the shape.</param>
 ///<param name="weight">Weight of the entry.  This defines how much the entry contributes to its owner
 /// for the purposes of center of mass and inertia computation.</param>
 public CompoundShapeEntry(EntityShape shape, Vector3 position, float weight)
 {
     position.Validate();
     LocalTransform = new RigidTransform(position);
     Shape = shape;
     Weight = weight;
 }
Exemple #4
0
 ///<summary>
 /// Constructs a new compound shape entry using the volume of the shape as a weight.
 ///</summary>
 ///<param name="shape">Shape to use.</param>
 ///<param name="position">Local position of the shape.</param>
 public CompoundShapeEntry(EntityShape shape, Vector3 position)
 {
     position.Validate();
     LocalTransform = new RigidTransform(position);
     Shape          = shape;
     Weight         = shape.ComputeVolume();
 }
Exemple #5
0
        //These methods are very direct and quick.  They don't activate the object or anything.
        /// <summary>
        /// Applies a linear velocity change to the entity using the given impulse.
        /// This method does not wake up the object or perform any other nonessential operation;
        /// it is meant to be used for performance-sensitive constraint solving.
        /// Consider equivalently adding to the LinearMomentum property for convenience instead.
        /// </summary>
        /// <param name="impulse">Impulse to apply.</param>
        public void ApplyLinearImpulse(ref Vector3 impulse)
        {
#if WINDOWS_PHONE
            //Some XNA math methods support SIMD on the phone.
            //This would most likely be inlined on the PC anyway, but the XBOX360 is a questionmark.
            //Just inline those platforms manually.
            Vector3.Add(ref linearMomentum, ref impulse, out linearMomentum);
            Vector3.Multiply(ref linearMomentum, inverseMass, out linearVelocity);
#else
            linearMomentum.X += impulse.X;
            linearMomentum.Y += impulse.Y;
            linearMomentum.Z += impulse.Z;
            linearVelocity.X  = linearMomentum.X * inverseMass;
            linearVelocity.Y  = linearMomentum.Y * inverseMass;
            linearVelocity.Z  = linearMomentum.Z * inverseMass;
#endif
            linearVelocity.Validate();
            linearMomentum.Validate();
        }
Exemple #6
0
        /// <summary>
        /// Applies an angular velocity change to the entity using the given impulse.
        /// This method does not wake up the object or perform any other nonessential operation;
        /// it is meant to be used for performance-sensitive constraint solving.
        /// Consider equivalently adding to the AngularMomentum property for convenience instead.
        /// </summary>
        /// <param name="impulse">Impulse to apply.</param>
        public void ApplyAngularImpulse(ref Vector3 impulse)
        {
            //There's some room here for SIMD-friendliness.  However, since the phone doesn't accelerate non-XNA types, the matrix3x3 operations don't gain much.
            angularMomentum.X += impulse.X;
            angularMomentum.Y += impulse.Y;
            angularMomentum.Z += impulse.Z;
            if (MotionSettings.ConserveAngularMomentum)
            {
                angularVelocity.X = angularMomentum.X * inertiaTensorInverse.M11 + angularMomentum.Y * inertiaTensorInverse.M21 + angularMomentum.Z * inertiaTensorInverse.M31;
                angularVelocity.Y = angularMomentum.X * inertiaTensorInverse.M12 + angularMomentum.Y * inertiaTensorInverse.M22 + angularMomentum.Z * inertiaTensorInverse.M32;
                angularVelocity.Z = angularMomentum.X * inertiaTensorInverse.M13 + angularMomentum.Y * inertiaTensorInverse.M23 + angularMomentum.Z * inertiaTensorInverse.M33;
            }
            else
            {
                angularVelocity.X += impulse.X * inertiaTensorInverse.M11 + impulse.Y * inertiaTensorInverse.M21 + impulse.Z * inertiaTensorInverse.M31;
                angularVelocity.Y += impulse.X * inertiaTensorInverse.M12 + impulse.Y * inertiaTensorInverse.M22 + impulse.Z * inertiaTensorInverse.M32;
                angularVelocity.Z += impulse.X * inertiaTensorInverse.M13 + impulse.Y * inertiaTensorInverse.M23 + impulse.Z * inertiaTensorInverse.M33;
            }

            angularVelocity.Validate();
            angularMomentum.Validate();
        }
Exemple #7
0
        ///<summary>
        /// Computes the center of a compound using its child data.
        /// Children are weighted using their volumes for contribution to the center of 'mass.'
        ///</summary>
        ///<param name="childData">Child data to use to compute the center.</param>
        ///<returns>Center of the children.</returns>
        public static Vector3 ComputeCenter(IList <CompoundShapeEntry> childData)
        {
            var   center      = new Vector3();
            float totalWeight = 0;

            for (int i = 0; i < childData.Count; i++)
            {
                float weight = childData[i].Weight;
                totalWeight += weight;
                center      += childData[i].LocalTransform.Position * weight;
            }
            if (totalWeight <= 0)
            {
                throw new NotFiniteNumberException("Cannot compute center; the total weight of a compound shape must be positive.");
            }
            Vector3.Divide(ref center, totalWeight, out center);
            center.Validate();
            return(center);
        }
Exemple #8
0
        /// <summary>
        /// Computes the center of the shape.  This can be considered its
        /// center of mass, based on the weightings of entries in the shape.
        /// For properly calibrated compound shapes, this will return a zero vector,
        /// since the shape recenters itself on construction.
        /// </summary>
        /// <returns>Center of the shape.</returns>
        public override Vector3 ComputeCenter()
        {
            float totalWeight = 0;
            var   center      = new Vector3();

            for (int i = 0; i < shapes.Count; i++)
            {
                totalWeight += shapes.Elements[i].Weight;
                Vector3 centerContribution;
                Vector3.Multiply(ref shapes.Elements[i].LocalTransform.Position, shapes.Elements[i].Weight, out centerContribution);
                Vector3.Add(ref center, ref centerContribution, out center);
            }
            if (totalWeight <= 0)
            {
                throw new NotFiniteNumberException("Cannot compute center; the total weight of a compound shape must be positive.");
            }
            Vector3.Divide(ref center, totalWeight, out center);
            center.Validate();
            return(center);
        }
Exemple #9
0
 protected void SetPosition(Vector3 position)
 {
     position.Validate();
     this.Position = position;
     ResetViewMatrix();
 }
Exemple #10
0
        /// <summary>
        /// Computes the center of the shape.  This can be considered its 
        /// center of mass, based on the weightings of entries in the shape.
        /// For properly calibrated compound shapes, this will return a zero vector,
        /// since the shape recenters itself on construction.
        /// </summary>
        /// <returns>Center of the shape.</returns>
        public override Vector3 ComputeCenter()
        {
            float totalWeight = 0;
            var center = new Vector3();
            for (int i = 0; i < shapes.Count; i++)
            {
                totalWeight += shapes.Elements[i].Weight;
                Vector3 centerContribution;
                Vector3.Multiply(ref shapes.Elements[i].LocalTransform.Position, shapes.Elements[i].Weight, out centerContribution);
                Vector3.Add(ref center, ref centerContribution, out center);

            }
            if (totalWeight <= 0)
                throw new NotFiniteNumberException("Cannot compute center; the total weight of a compound shape must be positive.");
            Vector3.Divide(ref center, totalWeight, out center);
            center.Validate();
            return center;
        }
Exemple #11
0
        ///<summary>
        /// Computes the center of a compound using its child data.
        /// Children are weighted using their volumes for contribution to the center of 'mass.'
        ///</summary>
        ///<param name="childData">Child data to use to compute the center.</param>
        ///<returns>Center of the children.</returns>
        public static Vector3 ComputeCenter(IList<CompoundShapeEntry> childData)
        {
            var center = new Vector3();
            float totalWeight = 0;
            for (int i = 0; i < childData.Count; i++)
            {
                float weight = childData[i].Weight;
                totalWeight += weight;
                center += childData[i].LocalTransform.Position * weight;
            }
            if (totalWeight <= 0)
                throw new NotFiniteNumberException("Cannot compute center; the total weight of a compound shape must be positive.");
            Vector3.Divide(ref center, totalWeight, out center);
            center.Validate();
            return center;

        }
Exemple #12
0
 ///<summary>
 /// Constructs a new compound shape entry using the volume of the shape as a weight.
 ///</summary>
 ///<param name="shape">Shape to use.</param>
 ///<param name="position">Local position of the shape.</param>
 public CompoundShapeEntry(EntityShape shape, Vector3 position)
 {
     position.Validate();
     LocalTransform = new RigidTransform(position);
     Shape = shape;
     Weight = shape.ComputeVolume();
 }
 public void Validate()
 {
     Position.Validate(nameof(Position));
 }
 public void Validate()
 {
     Position.Validate(nameof(Position));
     Normal.ValidateNormal(nameof(Normal));
     Tangent.ValidateTangent(nameof(Tangent));
 }
 public void Validate()
 {
     Position.Validate(nameof(Position));
     Normal.ValidateNormal(nameof(Normal));
 }
Exemple #16
0
 protected void SetPosition(Vector3 position)
 {
     position.Validate();
     this.Position = position;
     ResetViewMatrix();
 }