diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 696c4bde07..cd279e31c5 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -56,6 +56,7 @@ public sealed class BSCharacter : BSPhysObject private int _physicsActorType; private bool _isPhysical; private bool _flying; + private bool _wasWalking; // 'true' if the avatar was walking/moving last frame private bool _setAlwaysRun; private bool _throttleUpdates; private bool _floatOnWater; @@ -83,6 +84,7 @@ public sealed class BSCharacter : BSPhysObject _position = pos; _flying = isFlying; + _wasWalking = true; // causes first step to initialize standing _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); @@ -199,25 +201,51 @@ public sealed class BSCharacter : BSPhysObject // state (flying, colliding, ...). There is code in ODE to do this. _velocityMotor.Step(timeStep); - OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; - // If falling, we keep the world's downward vector no matter what the other axis specify. - if (!Flying && !IsColliding) + // If we're not supposed to be moving, make sure things are zero. + if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f)) { - stepVelocity.Z = _velocity.Z; - // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); + if (_wasWalking) + { + _velocityMotor.Zero(); + _velocity = OMV.Vector3.Zero; + PhysicsScene.PE.SetLinearVelocity(PhysBody, OMV.Vector3.Zero); + _currentFriction = BSParam.AvatarStandingFriction; + PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); + // DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); + } + _wasWalking = false; } + else + { + OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; - // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. - OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; + if (_currentFriction != BSParam.AvatarFriction) + { + // Probably starting up walking. Set friction to moving friction. + _currentFriction = BSParam.AvatarFriction; + PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); + } - // Should we check for move force being small and forcing velocity to zero? + // If falling, we keep the world's downward vector no matter what the other axis specify. + if (!Flying && !IsColliding) + { + stepVelocity.Z = _velocity.Z; + // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); + } - // Add special movement force to allow avatars to walk up stepped surfaces. - moveForce += WalkUpStairs(); + // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. + OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; - // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); - PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); + // Should we check for move force being small and forcing velocity to zero? + + // Add special movement force to allow avatars to walk up stepped surfaces. + moveForce += WalkUpStairs(); + + // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); + PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); + _wasWalking = true; + } }); } @@ -560,27 +588,6 @@ public sealed class BSCharacter : BSPhysObject PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); _velocity = value; - // Depending on whether the avatar is moving or not, change the friction - // to keep the avatar from slipping around - if (_velocity.Length() == 0) - { - if (_currentFriction != BSParam.AvatarStandingFriction) - { - _currentFriction = BSParam.AvatarStandingFriction; - if (PhysBody.HasPhysicalBody) - PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); - } - } - else - { - if (_currentFriction != BSParam.AvatarFriction) - { - _currentFriction = BSParam.AvatarFriction; - if (PhysBody.HasPhysicalBody) - PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); - } - } - PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); PhysicsScene.PE.Activate(PhysBody, true); } @@ -855,7 +862,7 @@ public sealed class BSCharacter : BSPhysObject _position = entprop.Position; _orientation = entprop.Rotation; - // Smooth velocity. OpenSimulator is very sensitive to changes in velocity of the avatar + // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar // and will send agent updates to the clients if velocity changes by more than // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many // extra updates.