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(); }
///<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; }
///<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(); }
//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(); }
/// <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(); }
///<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); }
/// <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); }
protected void SetPosition(Vector3 position) { position.Validate(); this.Position = position; ResetViewMatrix(); }
/// <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; }
///<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; }
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)); }