void IBeforeSolverUpdateable.Update(float dt) { //We can't let multiple characters manage the same pairs simultaneously. Lock it up! this.LockCharacterPairs(); try { bool hadSupport = this.SupportFinder.HasSupport; this.CollectSupportData(); //Compute the initial velocities relative to the support. var relativeVelocity = this.Body.LinearVelocity; var verticalVelocity = Vector3.Dot(this.supportData.Normal, relativeVelocity); //Don't attempt to use an object as support if we are flying away from it (and we were never standing on it to begin with). if (this.SupportFinder.HasSupport && !hadSupport && verticalVelocity < 0) { this.SupportFinder.ClearSupportData(); this.supportData = new SupportData(); } //Attempt to jump. if (this.tryToJump) //Jumping while crouching would be a bit silly. { //In the following, note that the jumping velocity changes are computed such that the separating velocity is specifically achieved, //rather than just adding some speed along an arbitrary direction. This avoids some cases where the character could otherwise increase //the jump speed, which may not be desired. if (this.SupportFinder.HasTraction) { //The character has traction, so jump straight up. float currentDownVelocity; Vector3.Dot(ref this.down, ref relativeVelocity, out currentDownVelocity); //Target velocity is JumpSpeed. float velocityChange = Math.Max(this.jumpSpeed + currentDownVelocity, 0); this.ApplyJumpVelocity(this.down * -velocityChange, ref relativeVelocity); //Prevent any old contacts from hanging around and coming back with a negative depth. foreach (var pair in this.Body.CollisionInformation.Pairs) { pair.ClearContacts(); } this.SupportFinder.ClearSupportData(); this.supportData = new SupportData(); } else { Utilities.Logger.Error("Support Does not have traction"); } } this.tryToJump = false; } finally { this.UnlockCharacterPairs(); } //Vertical support data is different because it has the capacity to stop the character from moving unless //contacts are pruned appropriately. Vector3 movement3D; this.HorizontalMotionConstraint.GetMovementDirectionIn3D(out movement3D); this.HorizontalMotionConstraint.SupportData = this.supportData; SupportData verticalSupportData; this.SupportFinder.GetTractionInDirection(ref movement3D, out verticalSupportData); this.VerticalMotionConstraint.SupportData = verticalSupportData; }
public bool GetTractionInDirection(ref Vector3 movementDirection, out SupportData supportData) { if (this.HasTraction) { int greatestIndex = -1; float greatestDot = -float.MaxValue; for (int i = 0; i < this.supports.Count; i++) { if (this.supports.Elements[i].HasTraction) { float dot; Vector3.Dot(ref movementDirection, ref this.supports.Elements[i].Contact.Normal, out dot); if (dot > greatestDot) { greatestDot = dot; greatestIndex = i; } } } if (greatestIndex != -1) { supportData.Position = this.supports.Elements[greatestIndex].Contact.Position; supportData.Normal = this.supports.Elements[greatestIndex].Contact.Normal; supportData.SupportObject = this.supports.Elements[greatestIndex].Support; supportData.HasTraction = true; float depth = -float.MaxValue; for (int i = 0; i < this.supports.Count; i++) { if (this.supports.Elements[i].HasTraction) { float dot; Vector3.Dot(ref this.supports.Elements[i].Contact.Normal, ref supportData.Normal, out dot); dot = dot * this.supports.Elements[i].Contact.PenetrationDepth; if (dot > depth) { depth = dot; } } } supportData.Depth = depth; return(true); } //Okay, try the ray cast result then. if (this.SupportRayData != null && this.SupportRayData.Value.HasTraction) { supportData.Position = this.SupportRayData.Value.HitData.Location; supportData.Normal = this.SupportRayData.Value.HitData.Normal; supportData.Depth = Vector3.Dot(this.character.Down, this.SupportRayData.Value.HitData.Normal) * (this.bottomHeight - this.SupportRayData.Value.HitData.T); supportData.SupportObject = this.SupportRayData.Value.HitObject; supportData.HasTraction = true; return(true); } //Well that's strange! supportData = new SupportData(); return(false); } else { supportData = new SupportData(); return(false); } }