diff options
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | 50 |
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 | { |