aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs97
1 files changed, 71 insertions, 26 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index fe48166..939d38a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -184,10 +184,6 @@ public sealed class BSCharacter : BSPhysObject
184 // 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.
185 private void SetupMovementMotor() 185 private void SetupMovementMotor()
186 { 186 {
187
188 // Someday, use a PID motor for asymmetric speed up and slow down
189 // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f);
190
191 // 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.
192 _velocityMotor = new BSVMotor("BSCharacter.Velocity", 188 _velocityMotor = new BSVMotor("BSCharacter.Velocity",
193 0.2f, // time scale 189 0.2f, // time scale
@@ -214,25 +210,68 @@ public sealed class BSCharacter : BSPhysObject
214 // '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.
215 OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass; 211 OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass;
216 212
217 /* 213 // Should we check for move force being small and forcing velocity to zero?
218 // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user 214
219 float moveForceMagnitudeSquared = moveForce.LengthSquared(); 215 // Add special movement force to allow avatars to walk up stepped surfaces.
220 if (moveForceMagnitudeSquared < 0.0001) 216 moveForce += WalkUpStairs();
221 { 217
222 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);
223 LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce);
224 ForceVelocity = OMV.Vector3.Zero;
225 }
226 else
227 {
228 AddForce(moveForce, false, true);
229 }
230 */
231 // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
232 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); 219 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
233 }); 220 });
234 } 221 }
235 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
236 public override void RequestPhysicsterseUpdate() 275 public override void RequestPhysicsterseUpdate()
237 { 276 {
238 base.RequestPhysicsterseUpdate(); 277 base.RequestPhysicsterseUpdate();
@@ -342,13 +381,11 @@ public sealed class BSCharacter : BSPhysObject
342 } 381 }
343 set { 382 set {
344 _position = value; 383 _position = value;
345 PositionSanityCheck();
346 384
347 PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() 385 PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate()
348 { 386 {
349 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);
350 if (PhysBody.HasPhysicalBody) 388 ForcePosition = _position;
351 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
352 }); 389 });
353 } 390 }
354 } 391 }
@@ -359,8 +396,11 @@ public sealed class BSCharacter : BSPhysObject
359 } 396 }
360 set { 397 set {
361 _position = value; 398 _position = value;
362 PositionSanityCheck(); 399 if (PhysBody.HasPhysicalBody)
363 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); 400 {
401 PositionSanityCheck();
402 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
403 }
364 } 404 }
365 } 405 }
366 406
@@ -373,7 +413,7 @@ public sealed class BSCharacter : BSPhysObject
373 bool ret = false; 413 bool ret = false;
374 414
375 // TODO: check for out of bounds 415 // TODO: check for out of bounds
376 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) 416 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
377 { 417 {
378 // The character is out of the known/simulated area. 418 // The character is out of the known/simulated area.
379 // 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
@@ -382,7 +422,7 @@ public sealed class BSCharacter : BSPhysObject
382 } 422 }
383 423
384 // If below the ground, move the avatar up 424 // If below the ground, move the avatar up
385 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); 425 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
386 if (Position.Z < terrainHeight) 426 if (Position.Z < terrainHeight)
387 { 427 {
388 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);
@@ -485,6 +525,11 @@ public sealed class BSCharacter : BSPhysObject
485 }); 525 });
486 } 526 }
487 } 527 }
528 public override OMV.Vector3 RawVelocity
529 {
530 get { return _velocity; }
531 set { _velocity = value; }
532 }
488 // 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.
489 public override OMV.Vector3 Velocity { 534 public override OMV.Vector3 Velocity {
490 get { return _velocity; } 535 get { return _velocity; }