// The velocity 'clipping' algorithm that is ran any time a plane is detected throughout // the PM_SlideMove() func execution. // It is responsible for: // Handling velocity orientation along stable planes // Handling velocity clipping along unstable 'wall' planes public static void PM_SlideClipVelocity( ref Vector3 _velocity, bool _stability, Vector3 _plane, bool _groundstability, Vector3 _groundplane, Vector3 _up) { float _m = _velocity.magnitude; if (_m <= 0F) // preventing NaN generation { return; } else { if (VectorHeader.Dot(_velocity / _m, _plane) < 0F) // only clip if we're piercing into the infinite plane { if (_stability) // if stable, just orient and maintain magnitude { // anyways just orient along the newly discovered stable plane //VectorHeader.CrossProjection(ref _velocity, _up, _groundplane); VectorHeader.ClipVector(ref _velocity, _plane); } else { if (_groundstability) // clip along the surface of the ground { // clip normally VectorHeader.ClipVector(ref _velocity, _plane); // orient velocity to ground plane VectorHeader.CrossProjection(ref _velocity, _up, _groundplane); // i'd originally used this but when orienting velocities above certain planes, // issues would arise where velocities would be clipped and projected in the opposite // direction of where the character should be moving, so I'm resorting to orienting // in this particular scenario.... // VectorHeader.ClipVector(ref _vel, _groundplane); } else // wall clip { VectorHeader.ClipVector(ref _velocity, _plane); } } } else { return; } } }
public override void Simulate(ActorArgs _args) { ActorHeader.Actor Actor = _args.Actor; ActorHeader.GroundHit Ground = Actor.Ground; ActorHeader.GroundHit LastGround = Actor.LastGround; Vector3 Velocity = Actor._velocity; Vector3 Wish = _args.ViewWishDir; bool Grounded = Actor.SnapEnabled && Ground.stable; if (Grounded && !LastGround.stable) // Landing { VectorHeader.ClipVector(ref Velocity, Ground.normal); } // Orient Wish Velocity to grounding plane if (Grounded && OrientVelocityToGroundPlane) { VectorHeader.CrossProjection(ref Wish, new Vector3(0, 1, 0), Ground.normal); } else { // Clip Wish Velocity along upward plane if we're not orienting/stable as we may be able to fight gravity if not done VectorHeader.ClipVector(ref Wish, new Vector3(0, 1, 0)); Wish.Normalize(); } //if (Grounded) // Subtract max speed based on stability // BehaviourHeader.DetermineWishVelocity(ref Velocity, Wish, MaximumGroundMoveSpeed, GroundAcceleration * GlobalTime.FDT); //else // BehaviourHeader.DetermineWishVelocity(ref Velocity, Wish, MaximumAirMoveSpeed, AirAcceleration * GlobalTime.FDT); if (Grounded) { BehaviourHeader.ApplyAcceleration(ref Velocity, Wish, MaximumGroundMoveSpeed, GroundAcceleration); } else { BehaviourHeader.ApplyAcceleration(ref Velocity, Wish, MaximumAirMoveSpeed, AirAcceleration); } Actor.SetVelocity(Velocity); return; }