diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 99 |
1 files changed, 71 insertions, 28 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index c215e3a..939d38a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -58,8 +58,6 @@ public sealed class BSCharacter : BSPhysObject | |||
58 | private bool _flying; | 58 | private bool _flying; |
59 | private bool _setAlwaysRun; | 59 | private bool _setAlwaysRun; |
60 | private bool _throttleUpdates; | 60 | private bool _throttleUpdates; |
61 | private bool _isColliding; | ||
62 | private bool _collidingObj; | ||
63 | private bool _floatOnWater; | 61 | private bool _floatOnWater; |
64 | private OMV.Vector3 _rotationalVelocity; | 62 | private OMV.Vector3 _rotationalVelocity; |
65 | private bool _kinematic; | 63 | private bool _kinematic; |
@@ -186,10 +184,6 @@ public sealed class BSCharacter : BSPhysObject | |||
186 | // standing as well as moving. Destruction of the avatar will destroy the pre-step action. | 184 | // standing as well as moving. Destruction of the avatar will destroy the pre-step action. |
187 | private void SetupMovementMotor() | 185 | private void SetupMovementMotor() |
188 | { | 186 | { |
189 | |||
190 | // Someday, use a PID motor for asymmetric speed up and slow down | ||
191 | // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); | ||
192 | |||
193 | // Infinite decay and timescale values so motor only changes current to target values. | 187 | // Infinite decay and timescale values so motor only changes current to target values. |
194 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", | 188 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", |
195 | 0.2f, // time scale | 189 | 0.2f, // time scale |
@@ -216,25 +210,68 @@ public sealed class BSCharacter : BSPhysObject | |||
216 | // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. | 210 | // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force. |
217 | OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; | 211 | OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; |
218 | 212 | ||
219 | /* | 213 | // Should we check for move force being small and forcing velocity to zero? |
220 | // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user | 214 | |
221 | float moveForceMagnitudeSquared = moveForce.LengthSquared(); | 215 | // Add special movement force to allow avatars to walk up stepped surfaces. |
222 | if (moveForceMagnitudeSquared < 0.0001) | 216 | moveForce += WalkUpStairs(); |
223 | { | 217 | |
224 | DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}", | 218 | DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); |
225 | LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce); | ||
226 | ForceVelocity = OMV.Vector3.Zero; | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | AddForce(moveForce, false, true); | ||
231 | } | ||
232 | */ | ||
233 | // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); | ||
234 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); | 219 | PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); |
235 | }); | 220 | }); |
236 | } | 221 | } |
237 | 222 | ||
223 | // Decide of the character is colliding with a low object and compute a force to pop the | ||
224 | // avatar up so it has a chance of walking up and over the low object. | ||
225 | private OMV.Vector3 WalkUpStairs() | ||
226 | { | ||
227 | OMV.Vector3 ret = OMV.Vector3.Zero; | ||
228 | |||
229 | // This test is done if moving forward, not flying and is colliding with something. | ||
230 | // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}", | ||
231 | // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count); | ||
232 | if (IsColliding && !Flying && TargetSpeed > 0.1f /* && ForwardSpeed < 0.1f */) | ||
233 | { | ||
234 | // The range near the character's feet where we will consider stairs | ||
235 | float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f; | ||
236 | float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight; | ||
237 | |||
238 | // Look for a collision point that is near the character's feet and is oriented the same as the charactor is | ||
239 | foreach (KeyValuePair<uint, ContactPoint> kvp in CollisionsLastTick.m_objCollisionList) | ||
240 | { | ||
241 | // Don't care about collisions with the terrain | ||
242 | if (kvp.Key > PhysicsScene.TerrainManager.HighestTerrainID) | ||
243 | { | ||
244 | OMV.Vector3 touchPosition = kvp.Value.Position; | ||
245 | // DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}", | ||
246 | // LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition); | ||
247 | if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax) | ||
248 | { | ||
249 | // This contact is within the 'near the feet' range. | ||
250 | // The normal should be our contact point to the object so it is pointing away | ||
251 | // thus the difference between our facing orientation and the normal should be small. | ||
252 | OMV.Vector3 directionFacing = OMV.Vector3.UnitX * RawOrientation; | ||
253 | OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal); | ||
254 | float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal)); | ||
255 | if (diff < BSParam.AvatarStepApproachFactor) | ||
256 | { | ||
257 | // Found the stairs contact point. Push up a little to raise the character. | ||
258 | float upForce = (touchPosition.Z - nearFeetHeightMin) * Mass * BSParam.AvatarStepForceFactor; | ||
259 | ret = new OMV.Vector3(0f, 0f, upForce); | ||
260 | |||
261 | // Also move the avatar up for the new height | ||
262 | OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f); | ||
263 | ForcePosition = RawPosition + displacement; | ||
264 | } | ||
265 | DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}", | ||
266 | LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret); | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | |||
272 | return ret; | ||
273 | } | ||
274 | |||
238 | public override void RequestPhysicsterseUpdate() | 275 | public override void RequestPhysicsterseUpdate() |
239 | { | 276 | { |
240 | base.RequestPhysicsterseUpdate(); | 277 | base.RequestPhysicsterseUpdate(); |
@@ -344,13 +381,11 @@ public sealed class BSCharacter : BSPhysObject | |||
344 | } | 381 | } |
345 | set { | 382 | set { |
346 | _position = value; | 383 | _position = value; |
347 | PositionSanityCheck(); | ||
348 | 384 | ||
349 | PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() | 385 | PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() |
350 | { | 386 | { |
351 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 387 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
352 | if (PhysBody.HasPhysicalBody) | 388 | ForcePosition = _position; |
353 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
354 | }); | 389 | }); |
355 | } | 390 | } |
356 | } | 391 | } |
@@ -361,8 +396,11 @@ public sealed class BSCharacter : BSPhysObject | |||
361 | } | 396 | } |
362 | set { | 397 | set { |
363 | _position = value; | 398 | _position = value; |
364 | PositionSanityCheck(); | 399 | if (PhysBody.HasPhysicalBody) |
365 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | 400 | { |
401 | PositionSanityCheck(); | ||
402 | PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); | ||
403 | } | ||
366 | } | 404 | } |
367 | } | 405 | } |
368 | 406 | ||
@@ -375,7 +413,7 @@ public sealed class BSCharacter : BSPhysObject | |||
375 | bool ret = false; | 413 | bool ret = false; |
376 | 414 | ||
377 | // TODO: check for out of bounds | 415 | // TODO: check for out of bounds |
378 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) | 416 | if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) |
379 | { | 417 | { |
380 | // The character is out of the known/simulated area. | 418 | // The character is out of the known/simulated area. |
381 | // Upper levels of code will handle the transition to other areas so, for | 419 | // Upper levels of code will handle the transition to other areas so, for |
@@ -384,7 +422,7 @@ public sealed class BSCharacter : BSPhysObject | |||
384 | } | 422 | } |
385 | 423 | ||
386 | // If below the ground, move the avatar up | 424 | // If below the ground, move the avatar up |
387 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); | 425 | float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); |
388 | if (Position.Z < terrainHeight) | 426 | if (Position.Z < terrainHeight) |
389 | { | 427 | { |
390 | DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); | 428 | DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); |
@@ -487,6 +525,11 @@ public sealed class BSCharacter : BSPhysObject | |||
487 | }); | 525 | }); |
488 | } | 526 | } |
489 | } | 527 | } |
528 | public override OMV.Vector3 RawVelocity | ||
529 | { | ||
530 | get { return _velocity; } | ||
531 | set { _velocity = value; } | ||
532 | } | ||
490 | // Directly setting velocity means this is what the user really wants now. | 533 | // Directly setting velocity means this is what the user really wants now. |
491 | public override OMV.Vector3 Velocity { | 534 | public override OMV.Vector3 Velocity { |
492 | get { return _velocity; } | 535 | get { return _velocity; } |