diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 103 |
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(); |