aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs82
1 files changed, 47 insertions, 35 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index cd15850..441d2d3 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -50,14 +50,14 @@ public abstract class BSTerrainPhys : IDisposable
50 Mesh = 1 50 Mesh = 1
51 } 51 }
52 52
53 public BSScene PhysicsScene { get; private set; } 53 protected BSScene m_physicsScene { get; private set; }
54 // Base of the region in world coordinates. Coordinates inside the region are relative to this. 54 // Base of the region in world coordinates. Coordinates inside the region are relative to this.
55 public Vector3 TerrainBase { get; private set; } 55 public Vector3 TerrainBase { get; private set; }
56 public uint ID { get; private set; } 56 public uint ID { get; private set; }
57 57
58 public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id) 58 public BSTerrainPhys(BSScene physicsScene, Vector3 regionBase, uint id)
59 { 59 {
60 PhysicsScene = physicsScene; 60 m_physicsScene = physicsScene;
61 TerrainBase = regionBase; 61 TerrainBase = regionBase;
62 ID = id; 62 ID = id;
63 } 63 }
@@ -86,7 +86,7 @@ public sealed class BSTerrainManager : IDisposable
86 public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); 86 public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
87 87
88 // The scene that I am part of 88 // The scene that I am part of
89 private BSScene PhysicsScene { get; set; } 89 private BSScene m_physicsScene { get; set; }
90 90
91 // The ground plane created to keep thing from falling to infinity. 91 // The ground plane created to keep thing from falling to infinity.
92 private BulletBody m_groundPlane; 92 private BulletBody m_groundPlane;
@@ -113,7 +113,7 @@ public sealed class BSTerrainManager : IDisposable
113 113
114 public BSTerrainManager(BSScene physicsScene) 114 public BSTerrainManager(BSScene physicsScene)
115 { 115 {
116 PhysicsScene = physicsScene; 116 m_physicsScene = physicsScene;
117 m_terrains = new Dictionary<Vector3,BSTerrainPhys>(); 117 m_terrains = new Dictionary<Vector3,BSTerrainPhys>();
118 118
119 // Assume one region of default size 119 // Assume one region of default size
@@ -132,21 +132,22 @@ public sealed class BSTerrainManager : IDisposable
132 // 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.
133 public void CreateInitialGroundPlaneAndTerrain() 133 public void CreateInitialGroundPlaneAndTerrain()
134 { 134 {
135 DetailLog("{0},BSTerrainManager.CreateInitialGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, PhysicsScene.RegionName); 135 DetailLog("{0},BSTerrainManager.CreateInitialGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, m_physicsScene.RegionName);
136 // The ground plane is here to catch things that are trying to drop to negative infinity 136 // The ground plane is here to catch things that are trying to drop to negative infinity
137 BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin); 137 BulletShape groundPlaneShape = m_physicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin);
138 m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape, 138 m_groundPlane = m_physicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape,
139 BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity); 139 BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity);
140 140
141 PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_groundPlane);
142 PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_groundPlane);
143 // Ground plane does not move
144 PhysicsScene.PE.ForceActivationState(m_groundPlane, ActivationState.DISABLE_SIMULATION);
145 // Everything collides with the ground plane. 141 // Everything collides with the ground plane.
146 m_groundPlane.collisionType = CollisionType.Groundplane; 142 m_groundPlane.collisionType = CollisionType.Groundplane;
147 m_groundPlane.ApplyCollisionMask(PhysicsScene);
148 143
149 BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); 144 m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, m_groundPlane);
145 m_physicsScene.PE.UpdateSingleAabb(m_physicsScene.World, m_groundPlane);
146
147 // Ground plane does not move
148 m_physicsScene.PE.ForceActivationState(m_groundPlane, ActivationState.DISABLE_SIMULATION);
149
150 BSTerrainPhys initialTerrain = new BSTerrainHeightmap(m_physicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize);
150 lock (m_terrains) 151 lock (m_terrains)
151 { 152 {
152 // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. 153 // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain.
@@ -157,12 +158,12 @@ public sealed class BSTerrainManager : IDisposable
157 // Release all the terrain structures we might have allocated 158 // Release all the terrain structures we might have allocated
158 public void ReleaseGroundPlaneAndTerrain() 159 public void ReleaseGroundPlaneAndTerrain()
159 { 160 {
160 DetailLog("{0},BSTerrainManager.ReleaseGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, PhysicsScene.RegionName); 161 DetailLog("{0},BSTerrainManager.ReleaseGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, m_physicsScene.RegionName);
161 if (m_groundPlane.HasPhysicalBody) 162 if (m_groundPlane.HasPhysicalBody)
162 { 163 {
163 if (PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_groundPlane)) 164 if (m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, m_groundPlane))
164 { 165 {
165 PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_groundPlane); 166 m_physicsScene.PE.DestroyObject(m_physicsScene.World, m_groundPlane);
166 } 167 }
167 m_groundPlane.Clear(); 168 m_groundPlane.Clear();
168 } 169 }
@@ -188,7 +189,7 @@ public sealed class BSTerrainManager : IDisposable
188 float[] localHeightMap = heightMap; 189 float[] localHeightMap = heightMap;
189 // If there are multiple requests for changes to the same terrain between ticks, 190 // If there are multiple requests for changes to the same terrain between ticks,
190 // only do that last one. 191 // only do that last one.
191 PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate() 192 m_physicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate()
192 { 193 {
193 if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null) 194 if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null)
194 { 195 {
@@ -213,13 +214,13 @@ public sealed class BSTerrainManager : IDisposable
213 }); 214 });
214 } 215 }
215 216
216 // Another region is calling this region passing a terrain. 217 // Another region is calling this region and passing a terrain.
217 // A region that is not the mega-region root will pass its terrain to the root region so the root region 218 // A region that is not the mega-region root will pass its terrain to the root region so the root region
218 // physics engine will have all the terrains. 219 // physics engine will have all the terrains.
219 private void AddMegaRegionChildTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords) 220 private void AddMegaRegionChildTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
220 { 221 {
221 // Since we are called by another region's thread, the action must be rescheduled onto our processing thread. 222 // Since we are called by another region's thread, the action must be rescheduled onto our processing thread.
222 PhysicsScene.PostTaintObject("TerrainManager.AddMegaRegionChild" + m_worldOffset.ToString(), 0, delegate() 223 m_physicsScene.PostTaintObject("TerrainManager.AddMegaRegionChild" + minCoords.ToString(), id, delegate()
223 { 224 {
224 UpdateTerrain(id, heightMap, minCoords, maxCoords); 225 UpdateTerrain(id, heightMap, minCoords, maxCoords);
225 }); 226 });
@@ -306,7 +307,7 @@ public sealed class BSTerrainManager : IDisposable
306 newTerrainID = ++m_terrainCount; 307 newTerrainID = ++m_terrainCount;
307 308
308 DetailLog("{0},BSTerrainManager.UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", 309 DetailLog("{0},BSTerrainManager.UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}",
309 BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); 310 BSScene.DetailLogZero, newTerrainID, minCoords, maxCoords);
310 BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); 311 BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
311 m_terrains.Add(terrainRegionBase, newTerrainPhys); 312 m_terrains.Add(terrainRegionBase, newTerrainPhys);
312 313
@@ -318,26 +319,26 @@ public sealed class BSTerrainManager : IDisposable
318 // TODO: redo terrain implementation selection to allow other base types than heightMap. 319 // TODO: redo terrain implementation selection to allow other base types than heightMap.
319 private BSTerrainPhys BuildPhysicalTerrain(Vector3 terrainRegionBase, uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords) 320 private BSTerrainPhys BuildPhysicalTerrain(Vector3 terrainRegionBase, uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
320 { 321 {
321 PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}", 322 m_physicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}",
322 LogHeader, PhysicsScene.RegionName, terrainRegionBase, 323 LogHeader, m_physicsScene.RegionName, terrainRegionBase,
323 (BSTerrainPhys.TerrainImplementation)BSParam.TerrainImplementation); 324 (BSTerrainPhys.TerrainImplementation)BSParam.TerrainImplementation);
324 BSTerrainPhys newTerrainPhys = null; 325 BSTerrainPhys newTerrainPhys = null;
325 switch ((int)BSParam.TerrainImplementation) 326 switch ((int)BSParam.TerrainImplementation)
326 { 327 {
327 case (int)BSTerrainPhys.TerrainImplementation.Heightmap: 328 case (int)BSTerrainPhys.TerrainImplementation.Heightmap:
328 newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id, 329 newTerrainPhys = new BSTerrainHeightmap(m_physicsScene, terrainRegionBase, id,
329 heightMap, minCoords, maxCoords); 330 heightMap, minCoords, maxCoords);
330 break; 331 break;
331 case (int)BSTerrainPhys.TerrainImplementation.Mesh: 332 case (int)BSTerrainPhys.TerrainImplementation.Mesh:
332 newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id, 333 newTerrainPhys = new BSTerrainMesh(m_physicsScene, terrainRegionBase, id,
333 heightMap, minCoords, maxCoords); 334 heightMap, minCoords, maxCoords);
334 break; 335 break;
335 default: 336 default:
336 PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}", 337 m_physicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}",
337 LogHeader, 338 LogHeader,
338 (int)BSParam.TerrainImplementation, 339 (int)BSParam.TerrainImplementation,
339 BSParam.TerrainImplementation, 340 BSParam.TerrainImplementation,
340 PhysicsScene.RegionName, terrainRegionBase); 341 m_physicsScene.RegionName, terrainRegionBase);
341 break; 342 break;
342 } 343 }
343 return newTerrainPhys; 344 return newTerrainPhys;
@@ -354,6 +355,8 @@ public sealed class BSTerrainManager : IDisposable
354 // Return a new position that is over known terrain if the position is outside our terrain. 355 // Return a new position that is over known terrain if the position is outside our terrain.
355 public Vector3 ClampPositionIntoKnownTerrain(Vector3 pPos) 356 public Vector3 ClampPositionIntoKnownTerrain(Vector3 pPos)
356 { 357 {
358 float edgeEpsilon = 0.1f;
359
357 Vector3 ret = pPos; 360 Vector3 ret = pPos;
358 361
359 // First, base addresses are never negative so correct for that possible problem. 362 // First, base addresses are never negative so correct for that possible problem.
@@ -378,10 +381,19 @@ public sealed class BSTerrainManager : IDisposable
378 // NOTE that GetTerrainPhysicalAtXYZ will set 'terrainBaseXYZ' to the base of the unfound region. 381 // NOTE that GetTerrainPhysicalAtXYZ will set 'terrainBaseXYZ' to the base of the unfound region.
379 382
380 // Must be off the top of a region. Find an adjacent region to move into. 383 // Must be off the top of a region. Find an adjacent region to move into.
384 // The returned terrain is always 'lower'. That is, closer to <0,0>.
381 Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ); 385 Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ);
382 386
383 ret.X = Math.Min(ret.X, adjacentTerrainBase.X + (ret.X % DefaultRegionSize.X)); 387 if (adjacentTerrainBase.X < terrainBaseXYZ.X)
384 ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + (ret.X % DefaultRegionSize.Y)); 388 {
389 // moving down into a new region in the X dimension. New position will be the max in the new base.
390 ret.X = adjacentTerrainBase.X + DefaultRegionSize.X - edgeEpsilon;
391 }
392 if (adjacentTerrainBase.Y < terrainBaseXYZ.Y)
393 {
394 // moving down into a new region in the X dimension. New position will be the max in the new base.
395 ret.Y = adjacentTerrainBase.Y + DefaultRegionSize.Y - edgeEpsilon;
396 }
385 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}", 397 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}",
386 BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret); 398 BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret);
387 399
@@ -429,8 +441,8 @@ public sealed class BSTerrainManager : IDisposable
429 } 441 }
430 else 442 else
431 { 443 {
432 PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", 444 m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
433 LogHeader, PhysicsScene.RegionName, tX, tY); 445 LogHeader, m_physicsScene.RegionName, tX, tY);
434 DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}", 446 DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}",
435 BSScene.DetailLogZero, pos, terrainBaseXYZ); 447 BSScene.DetailLogZero, pos, terrainBaseXYZ);
436 } 448 }
@@ -451,8 +463,8 @@ public sealed class BSTerrainManager : IDisposable
451 } 463 }
452 else 464 else
453 { 465 {
454 PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}", 466 m_physicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}",
455 LogHeader, PhysicsScene.RegionName, pos, terrainBaseXYZ, ret); 467 LogHeader, m_physicsScene.RegionName, pos, terrainBaseXYZ, ret);
456 } 468 }
457 return ret; 469 return ret;
458 } 470 }
@@ -564,7 +576,7 @@ public sealed class BSTerrainManager : IDisposable
564 576
565 private void DetailLog(string msg, params Object[] args) 577 private void DetailLog(string msg, params Object[] args)
566 { 578 {
567 PhysicsScene.PhysicsLogging.Write(msg, args); 579 m_physicsScene.PhysicsLogging.Write(msg, args);
568 } 580 }
569} 581}
570} 582}