BulletSim: fix problem of avatar sliding very slowly occasionally after stopping walking. Consolidate movement tests into the one prestep motion action

user_profiles
Robert Adams 2013-01-20 19:13:18 -08:00
parent 2cb1d5240e
commit 3c4868f613
1 changed files with 41 additions and 34 deletions

View File

@ -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.