public override void Update() { if (DisplayedObject.Entity != null) { //The reason for this complexity is that we're drawing the shape's location directly and interpolated buffers might be active. //That means we can't rely solely on the collidable's world transform or the entity's world transform alone; //we must rebuild it from the entity's world transform and the collidable's local position. //TODO: This is awfully annoying. Could use some built-in convenience methods to ease the usage. Vector3 translation = Matrix3x3.Transform(DisplayedObject.LocalPosition, DisplayedObject.Entity.BufferedStates.InterpolatedStates.OrientationMatrix); translation += DisplayedObject.Entity.BufferedStates.InterpolatedStates.Position; Matrix worldTransform = Matrix3x3.ToMatrix4X4(DisplayedObject.Entity.BufferedStates.InterpolatedStates.OrientationMatrix); worldTransform.Translation = translation; WorldTransform = MathConverter.Convert(worldTransform); } else { //Entityless EntityCollidables just go by what their current transform is. WorldTransform = MathConverter.Convert(DisplayedObject.WorldTransform.Matrix); } }
/// <summary> /// Updates the wheel's world transform for graphics. /// Called automatically by the owning wheel at the end of each frame. /// If the engine is updating asynchronously, you can call this inside of a space read buffer lock /// and update the wheel transforms safely. /// </summary> public override void UpdateWorldTransform() { #if !WINDOWS Vector3 newPosition = new Vector3(); #else Vector3 newPosition; #endif Vector3 worldAttachmentPoint; Vector3 localAttach; Vector3.Add(ref wheel.suspension.localAttachmentPoint, ref wheel.vehicle.Body.CollisionInformation.localPosition, out localAttach); worldTransform = Matrix3x3.ToMatrix4X4(wheel.vehicle.Body.BufferedStates.InterpolatedStates.OrientationMatrix); Matrix.TransformNormal(ref localAttach, ref worldTransform, out worldAttachmentPoint); worldAttachmentPoint += wheel.vehicle.Body.BufferedStates.InterpolatedStates.Position; Vector3 worldDirection; Matrix.Transform(ref wheel.suspension.localDirection, ref worldTransform, out worldDirection); float length = wheel.suspension.currentLength - graphicalRadius; newPosition.X = worldAttachmentPoint.X + worldDirection.X * length; newPosition.Y = worldAttachmentPoint.Y + worldDirection.Y * length; newPosition.Z = worldAttachmentPoint.Z + worldDirection.Z * length; Matrix spinTransform; Vector3 localSpinAxis; Vector3.Cross(ref wheel.localForwardDirection, ref wheel.suspension.localDirection, out localSpinAxis); Matrix.CreateFromAxisAngle(ref localSpinAxis, spinAngle, out spinTransform); Matrix localTurnTransform; Matrix.Multiply(ref localGraphicTransform, ref spinTransform, out localTurnTransform); Matrix.Multiply(ref localTurnTransform, ref steeringTransform, out localTurnTransform); //Matrix.Multiply(ref localTurnTransform, ref spinTransform, out localTurnTransform); Matrix.Multiply(ref localTurnTransform, ref worldTransform, out worldTransform); worldTransform.Translation += newPosition; }