diff options
Diffstat (limited to '')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | 90 |
1 files changed, 54 insertions, 36 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 5dbd8ce..3428b9c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | |||
@@ -67,7 +67,7 @@ public abstract class BSTerrainPhys : IDisposable | |||
67 | } | 67 | } |
68 | 68 | ||
69 | // ========================================================================================== | 69 | // ========================================================================================== |
70 | public sealed class BSTerrainManager | 70 | public sealed class BSTerrainManager : IDisposable |
71 | { | 71 | { |
72 | static string LogHeader = "[BULLETSIM TERRAIN MANAGER]"; | 72 | static string LogHeader = "[BULLETSIM TERRAIN MANAGER]"; |
73 | 73 | ||
@@ -122,6 +122,11 @@ public sealed class BSTerrainManager | |||
122 | MegaRegionParentPhysicsScene = null; | 122 | MegaRegionParentPhysicsScene = null; |
123 | } | 123 | } |
124 | 124 | ||
125 | public void Dispose() | ||
126 | { | ||
127 | ReleaseGroundPlaneAndTerrain(); | ||
128 | } | ||
129 | |||
125 | // Create the initial instance of terrain and the underlying ground plane. | 130 | // Create the initial instance of terrain and the underlying ground plane. |
126 | // This is called from the initialization routine so we presume it is | 131 | // This is called from the initialization routine so we presume it is |
127 | // safe to call Bullet in real time. We hope no one is moving prims around yet. | 132 | // safe to call Bullet in real time. We hope no one is moving prims around yet. |
@@ -327,6 +332,13 @@ public sealed class BSTerrainManager | |||
327 | return newTerrainPhys; | 332 | return newTerrainPhys; |
328 | } | 333 | } |
329 | 334 | ||
335 | // Return 'true' of this position is somewhere in known physical terrain space | ||
336 | public bool IsWithinKnownTerrain(Vector3 pos) | ||
337 | { | ||
338 | Vector3 terrainBaseXYZ; | ||
339 | BSTerrainPhys physTerrain; | ||
340 | return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ); | ||
341 | } | ||
330 | 342 | ||
331 | // Given an X and Y, find the height of the terrain. | 343 | // Given an X and Y, find the height of the terrain. |
332 | // Since we could be handling multiple terrains for a mega-region, | 344 | // Since we could be handling multiple terrains for a mega-region, |
@@ -337,13 +349,13 @@ public sealed class BSTerrainManager | |||
337 | private float lastHeightTX = 999999f; | 349 | private float lastHeightTX = 999999f; |
338 | private float lastHeightTY = 999999f; | 350 | private float lastHeightTY = 999999f; |
339 | private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT; | 351 | private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT; |
340 | public float GetTerrainHeightAtXYZ(Vector3 loc) | 352 | public float GetTerrainHeightAtXYZ(Vector3 pos) |
341 | { | 353 | { |
342 | float tX = loc.X; | 354 | float tX = pos.X; |
343 | float tY = loc.Y; | 355 | float tY = pos.Y; |
344 | // You'd be surprized at the number of times this routine is called | 356 | // You'd be surprized at the number of times this routine is called |
345 | // with the same parameters as last time. | 357 | // with the same parameters as last time. |
346 | if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) | 358 | if (!m_terrainModified && (lastHeightTX == tX) && (lastHeightTY == tY)) |
347 | return lastHeight; | 359 | return lastHeight; |
348 | m_terrainModified = false; | 360 | m_terrainModified = false; |
349 | 361 | ||
@@ -351,23 +363,20 @@ public sealed class BSTerrainManager | |||
351 | lastHeightTY = tY; | 363 | lastHeightTY = tY; |
352 | float ret = HEIGHT_GETHEIGHT_RET; | 364 | float ret = HEIGHT_GETHEIGHT_RET; |
353 | 365 | ||
354 | int offsetX = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; | 366 | Vector3 terrainBaseXYZ; |
355 | int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; | 367 | BSTerrainPhys physTerrain; |
356 | Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); | 368 | if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) |
357 | |||
358 | lock (m_terrains) | ||
359 | { | 369 | { |
360 | BSTerrainPhys physTerrain; | 370 | ret = physTerrain.GetTerrainHeightAtXYZ(pos - terrainBaseXYZ); |
361 | if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) | 371 | } |
362 | { | 372 | else |
363 | ret = physTerrain.GetTerrainHeightAtXYZ(loc - terrainBaseXYZ); | 373 | { |
364 | } | 374 | PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", |
365 | else | 375 | LogHeader, PhysicsScene.RegionName, tX, tY); |
366 | { | 376 | DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}", |
367 | PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", | 377 | BSScene.DetailLogZero, pos, terrainBaseXYZ); |
368 | LogHeader, PhysicsScene.RegionName, tX, tY); | ||
369 | } | ||
370 | } | 378 | } |
379 | |||
371 | lastHeight = ret; | 380 | lastHeight = ret; |
372 | return ret; | 381 | return ret; |
373 | } | 382 | } |
@@ -376,27 +385,36 @@ public sealed class BSTerrainManager | |||
376 | { | 385 | { |
377 | float ret = WATER_HEIGHT_GETHEIGHT_RET; | 386 | float ret = WATER_HEIGHT_GETHEIGHT_RET; |
378 | 387 | ||
379 | float tX = pos.X; | 388 | Vector3 terrainBaseXYZ; |
380 | float tY = pos.Y; | 389 | BSTerrainPhys physTerrain; |
390 | if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ)) | ||
391 | { | ||
392 | ret = physTerrain.GetWaterLevelAtXYZ(pos); | ||
393 | } | ||
394 | else | ||
395 | { | ||
396 | PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}", | ||
397 | LogHeader, PhysicsScene.RegionName, pos, terrainBaseXYZ, ret); | ||
398 | } | ||
399 | return ret; | ||
400 | } | ||
381 | 401 | ||
382 | Vector3 terrainBaseXYZ = Vector3.Zero; | 402 | // Given an address, return 'true' of there is a description of that terrain and output |
383 | terrainBaseXYZ.X = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; | 403 | // the descriptor class and the 'base' fo the addresses therein. |
384 | terrainBaseXYZ.Y = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; | 404 | private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase) |
405 | { | ||
406 | int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; | ||
407 | int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; | ||
408 | Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); | ||
385 | 409 | ||
410 | BSTerrainPhys physTerrain = null; | ||
386 | lock (m_terrains) | 411 | lock (m_terrains) |
387 | { | 412 | { |
388 | BSTerrainPhys physTerrain; | 413 | m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain); |
389 | if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) | ||
390 | { | ||
391 | ret = physTerrain.GetWaterLevelAtXYZ(pos); | ||
392 | } | ||
393 | else | ||
394 | { | ||
395 | PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: region={1}, x={2}, y={3}", | ||
396 | LogHeader, PhysicsScene.RegionName, tX, tY); | ||
397 | } | ||
398 | } | 414 | } |
399 | return ret; | 415 | outTerrainBase = terrainBaseXYZ; |
416 | outPhysTerrain = physTerrain; | ||
417 | return (physTerrain != null); | ||
400 | } | 418 | } |
401 | 419 | ||
402 | // Although no one seems to check this, I do support combining. | 420 | // Although no one seems to check this, I do support combining. |