aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs103
1 files changed, 67 insertions, 36 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 6d5e23f..7603254 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -56,6 +56,7 @@ public sealed class BSCharacter : BSPhysObject
56 private int _physicsActorType; 56 private int _physicsActorType;
57 private bool _isPhysical; 57 private bool _isPhysical;
58 private bool _flying; 58 private bool _flying;
59 private bool _wasWalking; // 'true' if the avatar was walking/moving last frame
59 private bool _setAlwaysRun; 60 private bool _setAlwaysRun;
60 private bool _throttleUpdates; 61 private bool _throttleUpdates;
61 private bool _floatOnWater; 62 private bool _floatOnWater;
@@ -83,6 +84,7 @@ public sealed class BSCharacter : BSPhysObject
83 _position = pos; 84 _position = pos;
84 85
85 _flying = isFlying; 86 _flying = isFlying;
87 _wasWalking = true; // causes first step to initialize standing
86 _orientation = OMV.Quaternion.Identity; 88 _orientation = OMV.Quaternion.Identity;
87 _velocity = OMV.Vector3.Zero; 89 _velocity = OMV.Vector3.Zero;
88 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 90 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
@@ -198,25 +200,68 @@ public sealed class BSCharacter : BSPhysObject
198 // TODO: Decide if the step parameters should be changed depending on the avatar's 200 // TODO: Decide if the step parameters should be changed depending on the avatar's
199 // state (flying, colliding, ...). There is code in ODE to do this. 201 // state (flying, colliding, ...). There is code in ODE to do this.
200 202
201 OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); 203 // COMMENTARY: when the user is making the avatar walk, except for falling, the velocity
202 204 // specified for the avatar is the one that should be used. For falling, if the avatar
203 // If falling, we keep the world's downward vector no matter what the other axis specify. 205 // is not flying and is not colliding then it is presumed to be falling and the Z
204 if (!Flying && !IsColliding) 206 // component is not fooled with (thus allowing gravity to do its thing).
207 // When the avatar is standing, though, the user has specified a velocity of zero and
208 // the avatar should be standing. But if the avatar is pushed by something in the world
209 // (raising elevator platform, moving vehicle, ...) the avatar should be allowed to
210 // move. Thus, the velocity cannot be forced to zero. The problem is that small velocity
211 // errors can creap in and the avatar will slowly float off in some direction.
212 // So, the problem is that, when an avatar is standing, we cannot tell creaping error
213 // from real pushing.OMV.Vector3.Zero;
214 // The code below keeps setting the velocity to zero hoping the world will keep pushing.
215
216 _velocityMotor.Step(timeStep);
217
218 // If we're not supposed to be moving, make sure things are zero.
219 if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero && IsColliding)
205 { 220 {
206 stepVelocity.Z = _velocity.Z; 221 // The avatar shouldn't be moving
207 // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); 222 _velocityMotor.Zero();
223 ZeroMotion(true /* inTaintTime */);
224
225 // Standing has more friction on the ground
226 if (_currentFriction != BSParam.AvatarStandingFriction)
227 {
228 _currentFriction = BSParam.AvatarStandingFriction;
229 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
230 }
231 DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue);
232
233 _wasWalking = false;
208 } 234 }
235 else
236 {
237 OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue;
238
239 if (_currentFriction != BSParam.AvatarFriction)
240 {
241 // Probably starting up walking. Set friction to moving friction.
242 _currentFriction = BSParam.AvatarFriction;
243 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
244 }
245
246 // If falling, we keep the world's downward vector no matter what the other axis specify.
247 if (!Flying && !IsColliding)
248 {
249 stepVelocity.Z = _velocity.Z;
250 // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
251 }
209 252
210 // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. 253 // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
211 OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; 254 OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass;
212 255
213 // Should we check for move force being small and forcing velocity to zero? 256 // Should we check for move force being small and forcing velocity to zero?
214 257
215 // Add special movement force to allow avatars to walk up stepped surfaces. 258 // Add special movement force to allow avatars to walk up stepped surfaces.
216 moveForce += WalkUpStairs(); 259 moveForce += WalkUpStairs();
217 260
218 // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); 261 DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
219 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); 262 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
263 _wasWalking = true;
264 }
220 }); 265 });
221 } 266 }
222 267
@@ -559,27 +604,6 @@ public sealed class BSCharacter : BSPhysObject
559 PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); 604 PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity");
560 605
561 _velocity = value; 606 _velocity = value;
562 // Depending on whether the avatar is moving or not, change the friction
563 // to keep the avatar from slipping around
564 if (_velocity.Length() == 0)
565 {
566 if (_currentFriction != BSParam.AvatarStandingFriction)
567 {
568 _currentFriction = BSParam.AvatarStandingFriction;
569 if (PhysBody.HasPhysicalBody)
570 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
571 }
572 }
573 else
574 {
575 if (_currentFriction != BSParam.AvatarFriction)
576 {
577 _currentFriction = BSParam.AvatarFriction;
578 if (PhysBody.HasPhysicalBody)
579 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
580 }
581 }
582
583 PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity); 607 PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
584 PhysicsScene.PE.Activate(PhysBody, true); 608 PhysicsScene.PE.Activate(PhysBody, true);
585 } 609 }
@@ -853,7 +877,14 @@ public sealed class BSCharacter : BSPhysObject
853 { 877 {
854 _position = entprop.Position; 878 _position = entprop.Position;
855 _orientation = entprop.Rotation; 879 _orientation = entprop.Rotation;
856 _velocity = entprop.Velocity; 880
881 // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
882 // and will send agent updates to the clients if velocity changes by more than
883 // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many
884 // extra updates.
885 if (!entprop.Velocity.ApproxEquals(_velocity, 0.1f))
886 _velocity = entprop.Velocity;
887
857 _acceleration = entprop.Acceleration; 888 _acceleration = entprop.Acceleration;
858 _rotationalVelocity = entprop.RotationalVelocity; 889 _rotationalVelocity = entprop.RotationalVelocity;
859 890
@@ -868,7 +899,7 @@ public sealed class BSCharacter : BSPhysObject
868 CurrentEntityProperties = entprop; 899 CurrentEntityProperties = entprop;
869 900
870 // Tell the linkset about value changes 901 // Tell the linkset about value changes
871 Linkset.UpdateProperties(this, true); 902 Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
872 903
873 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 904 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
874 // base.RequestPhysicsterseUpdate(); 905 // base.RequestPhysicsterseUpdate();