aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs50
1 files changed, 29 insertions, 21 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index a60946d..d4aecbc 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -343,37 +343,35 @@ public sealed class BSTerrainManager : IDisposable
343 { 343 {
344 Vector3 ret = pPos; 344 Vector3 ret = pPos;
345 345
346 // First, base addresses are never negative so correct for that possible problem.
347 if (ret.X < 0f || ret.Y < 0f)
348 {
349 ret.X = Util.Clamp<float>(ret.X, 0f, 1000000f);
350 ret.Y = Util.Clamp<float>(ret.Y, 0f, 1000000f);
351 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,zeroingNegXorY,oldPos={1},newPos={2}",
352 BSScene.DetailLogZero, pPos, ret);
353 }
354
346 // Can't do this function if we don't know about any terrain. 355 // Can't do this function if we don't know about any terrain.
347 if (m_terrains.Count == 0) 356 if (m_terrains.Count == 0)
348 return ret; 357 return ret;
349 358
350 int loopPrevention = 5; 359 int loopPrevention = 10;
351 Vector3 terrainBaseXYZ; 360 Vector3 terrainBaseXYZ;
352 BSTerrainPhys physTerrain; 361 BSTerrainPhys physTerrain;
353 while (!GetTerrainPhysicalAtXYZ(ret, out physTerrain, out terrainBaseXYZ)) 362 while (!GetTerrainPhysicalAtXYZ(ret, out physTerrain, out terrainBaseXYZ))
354 { 363 {
355 // The passed position is not within a known terrain area. 364 // The passed position is not within a known terrain area.
365 // NOTE that GetTerrainPhysicalAtXYZ will set 'terrainBaseXYZ' to the base of the unfound region.
356 366
357 // First, base addresses are never negative so correct for that possible problem. 367 // Must be off the top of a region. Find an adjacent region to move into.
358 if (ret.X < 0f || ret.Y < 0f) 368 Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ);
359 { 369
360 if (ret.X < 0f) 370 ret.X = Math.Min(ret.X, adjacentTerrainBase.X + (ret.X % DefaultRegionSize.X));
361 ret.X = 0f; 371 ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + (ret.X % DefaultRegionSize.Y));
362 if (ret.Y < 0f) 372 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}",
363 ret.Y = 0f; 373 BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret);
364 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,zeroingNegXorY,oldPos={1},newPos={2}",
365 BSScene.DetailLogZero, pPos, ret);
366 }
367 else
368 {
369 // Must be off the top of a region. Find an adjacent region to move into.
370 Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ);
371 374
372 ret.X = Math.Min(ret.X, adjacentTerrainBase.X + DefaultRegionSize.X);
373 ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + DefaultRegionSize.Y);
374 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}",
375 BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret);
376 }
377 if (loopPrevention-- < 0f) 375 if (loopPrevention-- < 0f)
378 { 376 {
379 // The 'while' is a little dangerous so this prevents looping forever if the 377 // The 'while' is a little dangerous so this prevents looping forever if the
@@ -383,6 +381,7 @@ public sealed class BSTerrainManager : IDisposable
383 break; 381 break;
384 } 382 }
385 } 383 }
384
386 return ret; 385 return ret;
387 } 386 }
388 387
@@ -479,11 +478,20 @@ public sealed class BSTerrainManager : IDisposable
479 private Vector3 FindAdjacentTerrainBase(Vector3 pTerrainBase) 478 private Vector3 FindAdjacentTerrainBase(Vector3 pTerrainBase)
480 { 479 {
481 Vector3 ret = pTerrainBase; 480 Vector3 ret = pTerrainBase;
481
482 // Can't do this function if we don't know about any terrain.
483 if (m_terrains.Count == 0)
484 return ret;
485
486 // Just some sanity
487 ret.X = Util.Clamp<float>(ret.X, 0f, 1000000f);
488 ret.Y = Util.Clamp<float>(ret.Y, 0f, 1000000f);
482 ret.Z = 0f; 489 ret.Z = 0f;
490
483 lock (m_terrains) 491 lock (m_terrains)
484 { 492 {
485 // Once down to the <0,0> region, we have to be done. 493 // Once down to the <0,0> region, we have to be done.
486 while (ret.X > 0f && ret.Y > 0f) 494 while (ret.X > 0f || ret.Y > 0f)
487 { 495 {
488 if (ret.X > 0f) 496 if (ret.X > 0f)
489 { 497 {