aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs29
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs5
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs100
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs6
4 files changed, 117 insertions, 23 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index f442ca2..e208d3a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -205,7 +205,7 @@ public sealed class BSCharacter : BSPhysObject
205 // errors can creap in and the avatar will slowly float off in some direction. 205 // errors can creap in and the avatar will slowly float off in some direction.
206 // So, the problem is that, when an avatar is standing, we cannot tell creaping error 206 // So, the problem is that, when an avatar is standing, we cannot tell creaping error
207 // from real pushing. 207 // from real pushing.
208 // The code below keeps setting the velocity to zero hoping the world will keep pushing. 208 // The code below uses whether the collider is static or moving to decide whether to zero motion.
209 209
210 _velocityMotor.Step(timeStep); 210 _velocityMotor.Step(timeStep);
211 211
@@ -244,6 +244,7 @@ public sealed class BSCharacter : BSPhysObject
244 } 244 }
245 else 245 else
246 { 246 {
247 // Supposed to be moving.
247 OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; 248 OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue;
248 249
249 if (Friction != BSParam.AvatarFriction) 250 if (Friction != BSParam.AvatarFriction)
@@ -276,8 +277,8 @@ public sealed class BSCharacter : BSPhysObject
276 }); 277 });
277 } 278 }
278 279
279 // Decide of the character is colliding with a low object and compute a force to pop the 280 // Decide if the character is colliding with a low object and compute a force to pop the
280 // avatar up so it has a chance of walking up and over the low object. 281 // avatar up so it can walk up and over the low objects.
281 private OMV.Vector3 WalkUpStairs() 282 private OMV.Vector3 WalkUpStairs()
282 { 283 {
283 OMV.Vector3 ret = OMV.Vector3.Zero; 284 OMV.Vector3 ret = OMV.Vector3.Zero;
@@ -476,17 +477,19 @@ public sealed class BSCharacter : BSPhysObject
476 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) 477 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
477 { 478 {
478 // The character is out of the known/simulated area. 479 // The character is out of the known/simulated area.
479 // Upper levels of code will handle the transition to other areas so, for 480 // Force the avatar position to be within known. ScenePresence will use the position
480 // the time, we just ignore the position. 481 // plus the velocity to decide if the avatar is moving out of the region.
481 return ret; 482 RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition);
483 DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition);
484 return true;
482 } 485 }
483 486
484 // If below the ground, move the avatar up 487 // If below the ground, move the avatar up
485 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); 488 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
486 if (Position.Z < terrainHeight) 489 if (Position.Z < terrainHeight)
487 { 490 {
488 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 491 DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, _position, terrainHeight);
489 _position.Z = terrainHeight + 2.0f; 492 _position.Z = terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters;
490 ret = true; 493 ret = true;
491 } 494 }
492 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) 495 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
@@ -806,14 +809,7 @@ public sealed class BSCharacter : BSPhysObject
806 private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 809 private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
807 if (force.IsFinite()) 810 if (force.IsFinite())
808 { 811 {
809 float magnitude = force.Length(); 812 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
810 if (magnitude > BSParam.MaxAddForceMagnitude)
811 {
812 // Force has a limit
813 force = force / magnitude * BSParam.MaxAddForceMagnitude;
814 }
815
816 OMV.Vector3 addForce = force;
817 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); 813 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
818 814
819 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() 815 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
@@ -902,6 +898,7 @@ public sealed class BSCharacter : BSPhysObject
902 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 898 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
903 if (PositionSanityCheck(true)) 899 if (PositionSanityCheck(true))
904 { 900 {
901 DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position);
905 entprop.Position = _position; 902 entprop.Position = _position;
906 } 903 }
907 904
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index fa58109..2af8468 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -107,6 +107,7 @@ public static class BSParam
107 public static float AvatarCapsuleDepth { get; private set; } 107 public static float AvatarCapsuleDepth { get; private set; }
108 public static float AvatarCapsuleHeight { get; private set; } 108 public static float AvatarCapsuleHeight { get; private set; }
109 public static float AvatarContactProcessingThreshold { get; private set; } 109 public static float AvatarContactProcessingThreshold { get; private set; }
110 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
110 public static float AvatarStepHeight { get; private set; } 111 public static float AvatarStepHeight { get; private set; }
111 public static float AvatarStepApproachFactor { get; private set; } 112 public static float AvatarStepApproachFactor { get; private set; }
112 public static float AvatarStepForceFactor { get; private set; } 113 public static float AvatarStepForceFactor { get; private set; }
@@ -497,6 +498,10 @@ public static class BSParam
497 0.1f, 498 0.1f,
498 (s) => { return AvatarContactProcessingThreshold; }, 499 (s) => { return AvatarContactProcessingThreshold; },
499 (s,v) => { AvatarContactProcessingThreshold = v; } ), 500 (s,v) => { AvatarContactProcessingThreshold = v; } ),
501 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
502 1.0f,
503 (s) => { return AvatarBelowGroundUpCorrectionMeters; },
504 (s,v) => { AvatarBelowGroundUpCorrectionMeters = v; } ),
500 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction", 505 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction",
501 0.3f, 506 0.3f,
502 (s) => { return AvatarStepHeight; }, 507 (s) => { return AvatarStepHeight; },
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 2e9db39..e8040d8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -337,6 +337,54 @@ public sealed class BSTerrainManager : IDisposable
337 return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ); 337 return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ);
338 } 338 }
339 339
340 // Return a new position that is over known terrain if the position is outside our terrain.
341 public Vector3 ClampPositionIntoKnownTerrain(Vector3 pPos)
342 {
343 Vector3 ret = pPos;
344
345 // Can't do this function if we don't know about any terrain.
346 if (m_terrains.Count == 0)
347 return ret;
348
349 int loopPrevention = 5;
350 Vector3 terrainBaseXYZ;
351 BSTerrainPhys physTerrain;
352 while (!GetTerrainPhysicalAtXYZ(ret, out physTerrain, out terrainBaseXYZ))
353 {
354 // The passed position is not within a known terrain area.
355
356 // First, base addresses are never negative so correct for that possible problem.
357 if (ret.X < 0f || ret.Y < 0f)
358 {
359 if (ret.X < 0f)
360 ret.X = 0f;
361 if (ret.Y < 0f)
362 ret.Y = 0f;
363 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,zeroingNegXorY,oldPos={1},newPos={2}",
364 BSScene.DetailLogZero, pPos, ret);
365 }
366 else
367 {
368 // Must be off the top of a region. Find an adjacent region to move into.
369 Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ);
370
371 ret.X = Math.Min(ret.X, adjacentTerrainBase.X + DefaultRegionSize.X);
372 ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + DefaultRegionSize.Y);
373 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}",
374 BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret);
375 }
376 if (loopPrevention-- < 0f)
377 {
378 // The 'while' is a little dangerous so this prevents looping forever if the
379 // mapping of the terrains ever gets messed up (like nothing at <0,0>) or
380 // the list of terrains is in transition.
381 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,suppressingFindAdjacentRegionLoop", BSScene.DetailLogZero);
382 break;
383 }
384 }
385 return ret;
386 }
387
340 // Given an X and Y, find the height of the terrain. 388 // Given an X and Y, find the height of the terrain.
341 // Since we could be handling multiple terrains for a mega-region, 389 // Since we could be handling multiple terrains for a mega-region,
342 // the base of the region is calcuated assuming all regions are 390 // the base of the region is calcuated assuming all regions are
@@ -400,18 +448,60 @@ public sealed class BSTerrainManager : IDisposable
400 // the descriptor class and the 'base' fo the addresses therein. 448 // the descriptor class and the 'base' fo the addresses therein.
401 private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase) 449 private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase)
402 { 450 {
403 int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; 451 bool ret = false;
404 int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; 452
405 Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); 453 Vector3 terrainBaseXYZ = Vector3.Zero;
454 if (pos.X < 0f || pos.Y < 0f)
455 {
456 // We don't handle negative addresses so just make up a base that will not be found.
457 terrainBaseXYZ = new Vector3(-DefaultRegionSize.X, -DefaultRegionSize.Y, 0f);
458 }
459 else
460 {
461 int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
462 int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
463 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
464 }
406 465
407 BSTerrainPhys physTerrain = null; 466 BSTerrainPhys physTerrain = null;
408 lock (m_terrains) 467 lock (m_terrains)
409 { 468 {
410 m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain); 469 ret = m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain);
411 } 470 }
412 outTerrainBase = terrainBaseXYZ; 471 outTerrainBase = terrainBaseXYZ;
413 outPhysTerrain = physTerrain; 472 outPhysTerrain = physTerrain;
414 return (physTerrain != null); 473 return ret;
474 }
475
476 // Given a terrain base, return a terrain base for a terrain that is closer to <0,0> than
477 // this one. Usually used to return an out of bounds object to a known place.
478 private Vector3 FindAdjacentTerrainBase(Vector3 pTerrainBase)
479 {
480 Vector3 ret = pTerrainBase;
481 ret.Z = 0f;
482 lock (m_terrains)
483 {
484 // Once down to the <0,0> region, we have to be done.
485 while (ret.X > 0f && ret.Y > 0f)
486 {
487 if (ret.X > 0f)
488 {
489 ret.X = Math.Max(0f, ret.X - DefaultRegionSize.X);
490 DetailLog("{0},BSTerrainManager.FindAdjacentTerrainBase,reducingX,terrainBase={1}", BSScene.DetailLogZero, ret);
491 if (m_terrains.ContainsKey(ret))
492 break;
493 }
494 if (ret.Y > 0f)
495 {
496 ret.Y = Math.Max(0f, ret.Y - DefaultRegionSize.Y);
497 DetailLog("{0},BSTerrainManager.FindAdjacentTerrainBase,reducingY,terrainBase={1}", BSScene.DetailLogZero, ret);
498 if (m_terrains.ContainsKey(ret))
499 break;
500 }
501 }
502 }
503
504 return ret;
415 } 505 }
416 506
417 // Although no one seems to check this, I do support combining. 507 // Although no one seems to check this, I do support combining.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
index d7e800d..57a5ff2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
@@ -215,7 +215,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
215 215
216 float magX = (float)sizeX / extentX; 216 float magX = (float)sizeX / extentX;
217 float magY = (float)sizeY / extentY; 217 float magY = (float)sizeY / extentY;
218 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", 218 if (physicsScene != null)
219 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}",
219 BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); 220 BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY);
220 float minHeight = float.MaxValue; 221 float minHeight = float.MaxValue;
221 // Note that sizeX+1 vertices are created since there is land between this and the next region. 222 // Note that sizeX+1 vertices are created since there is land between this and the next region.
@@ -257,7 +258,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
257 } 258 }
258 catch (Exception e) 259 catch (Exception e)
259 { 260 {
260 physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", 261 if (physicsScene != null)
262 physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}",
261 LogHeader, physicsScene.RegionName, extentBase, e); 263 LogHeader, physicsScene.RegionName, extentBase, e);
262 } 264 }
263 265