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.cs122
1 files changed, 73 insertions, 49 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 23fcfd3..17d9536 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -62,7 +62,8 @@ public abstract class BSTerrainPhys : IDisposable
62 ID = id; 62 ID = id;
63 } 63 }
64 public abstract void Dispose(); 64 public abstract void Dispose();
65 public abstract float GetHeightAtXYZ(Vector3 pos); 65 public abstract float GetTerrainHeightAtXYZ(Vector3 pos);
66 public abstract float GetWaterLevelAtXYZ(Vector3 pos);
66} 67}
67 68
68// ========================================================================================== 69// ==========================================================================================
@@ -75,13 +76,12 @@ public sealed class BSTerrainManager
75 public const float HEIGHT_INITIALIZATION = 24.987f; 76 public const float HEIGHT_INITIALIZATION = 24.987f;
76 public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f; 77 public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f;
77 public const float HEIGHT_GETHEIGHT_RET = 24.765f; 78 public const float HEIGHT_GETHEIGHT_RET = 24.765f;
79 public const float WATER_HEIGHT_GETHEIGHT_RET = 19.998f;
78 80
79 // If the min and max height are equal, we reduce the min by this 81 // If the min and max height are equal, we reduce the min by this
80 // amount to make sure that a bounding box is built for the terrain. 82 // amount to make sure that a bounding box is built for the terrain.
81 public const float HEIGHT_EQUAL_FUDGE = 0.2f; 83 public const float HEIGHT_EQUAL_FUDGE = 0.2f;
82 84
83 public const float TERRAIN_COLLISION_MARGIN = 0.0f;
84
85 // Until the whole simulator is changed to pass us the region size, we rely on constants. 85 // Until the whole simulator is changed to pass us the region size, we rely on constants.
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
@@ -129,7 +129,8 @@ public sealed class BSTerrainManager
129 { 129 {
130 // The ground plane is here to catch things that are trying to drop to negative infinity 130 // The ground plane is here to catch things that are trying to drop to negative infinity
131 BulletShape groundPlaneShape = new BulletShape( 131 BulletShape groundPlaneShape = new BulletShape(
132 BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN), 132 BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f,
133 PhysicsScene.Params.terrainCollisionMargin),
133 BSPhysicsShapeType.SHAPE_GROUNDPLANE); 134 BSPhysicsShapeType.SHAPE_GROUNDPLANE);
134 m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, 135 m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
135 BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, 136 BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
@@ -165,17 +166,22 @@ public sealed class BSTerrainManager
165 // Release all the terrain we have allocated 166 // Release all the terrain we have allocated
166 public void ReleaseTerrain() 167 public void ReleaseTerrain()
167 { 168 {
168 foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains) 169 lock (m_terrains)
169 { 170 {
170 kvp.Value.Dispose(); 171 foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains)
172 {
173 kvp.Value.Dispose();
174 }
175 m_terrains.Clear();
171 } 176 }
172 m_terrains.Clear();
173 } 177 }
174 178
175 // The simulator wants to set a new heightmap for the terrain. 179 // The simulator wants to set a new heightmap for the terrain.
176 public void SetTerrain(float[] heightMap) { 180 public void SetTerrain(float[] heightMap) {
177 float[] localHeightMap = heightMap; 181 float[] localHeightMap = heightMap;
178 PhysicsScene.TaintedObject("TerrainManager.SetTerrain", delegate() 182 // If there are multiple requests for changes to the same terrain between ticks,
183 // only do that last one.
184 PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate()
179 { 185 {
180 if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null) 186 if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null)
181 { 187 {
@@ -211,6 +217,7 @@ public sealed class BSTerrainManager
211 // terrain shape is created and added to the body. 217 // terrain shape is created and added to the body.
212 // This call is most often used to update the heightMap and parameters of the terrain. 218 // This call is most often used to update the heightMap and parameters of the terrain.
213 // (The above does suggest that some simplification/refactoring is in order.) 219 // (The above does suggest that some simplification/refactoring is in order.)
220 // Called during taint-time.
214 private void UpdateTerrain(uint id, float[] heightMap, 221 private void UpdateTerrain(uint id, float[] heightMap,
215 Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) 222 Vector3 minCoords, Vector3 maxCoords, bool inTaintTime)
216 { 223 {
@@ -220,7 +227,7 @@ public sealed class BSTerrainManager
220 // Find high and low points of passed heightmap. 227 // Find high and low points of passed heightmap.
221 // The min and max passed in is usually the area objects can be in (maximum 228 // The min and max passed in is usually the area objects can be in (maximum
222 // object height, for instance). The terrain wants the bounding box for the 229 // object height, for instance). The terrain wants the bounding box for the
223 // terrain so we replace passed min and max Z with the actual terrain min/max Z. 230 // terrain so replace passed min and max Z with the actual terrain min/max Z.
224 float minZ = float.MaxValue; 231 float minZ = float.MaxValue;
225 float maxZ = float.MinValue; 232 float maxZ = float.MinValue;
226 foreach (float height in heightMap) 233 foreach (float height in heightMap)
@@ -238,15 +245,15 @@ public sealed class BSTerrainManager
238 245
239 Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); 246 Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f);
240 247
241 BSTerrainPhys terrainPhys; 248 lock (m_terrains)
242 if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
243 { 249 {
244 // There is already a terrain in this spot. Free the old and build the new. 250 BSTerrainPhys terrainPhys;
245 DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", 251 if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
246 BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);
247
248 PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate()
249 { 252 {
253 // There is already a terrain in this spot. Free the old and build the new.
254 DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
255 BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);
256
250 // Remove old terrain from the collection 257 // Remove old terrain from the collection
251 m_terrains.Remove(terrainRegionBase); 258 m_terrains.Remove(terrainRegionBase);
252 // Release any physical memory it may be using. 259 // Release any physical memory it may be using.
@@ -271,35 +278,24 @@ public sealed class BSTerrainManager
271 // I hate doing this, but just bail 278 // I hate doing this, but just bail
272 return; 279 return;
273 } 280 }
274 }); 281 }
275 } 282 else
276 else 283 {
277 { 284 // We don't know about this terrain so either we are creating a new terrain or
278 // We don't know about this terrain so either we are creating a new terrain or 285 // our mega-prim child is giving us a new terrain to add to the phys world
279 // our mega-prim child is giving us a new terrain to add to the phys world
280
281 // if this is a child terrain, calculate a unique terrain id
282 uint newTerrainID = id;
283 if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
284 newTerrainID = ++m_terrainCount;
285
286 float[] heightMapX = heightMap;
287 Vector3 minCoordsX = minCoords;
288 Vector3 maxCoordsX = maxCoords;
289 286
290 DetailLog("{0},UpdateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}", 287 // if this is a child terrain, calculate a unique terrain id
291 BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); 288 uint newTerrainID = id;
289 if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
290 newTerrainID = ++m_terrainCount;
292 291
293 // Code that must happen at taint-time 292 DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}",
294 PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:NewTerrain", delegate() 293 BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
295 {
296 DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}",
297 BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y);
298 BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); 294 BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
299 m_terrains.Add(terrainRegionBase, newTerrainPhys); 295 m_terrains.Add(terrainRegionBase, newTerrainPhys);
300 296
301 m_terrainModified = true; 297 m_terrainModified = true;
302 }); 298 }
303 } 299 }
304 } 300 }
305 301
@@ -349,6 +345,7 @@ public sealed class BSTerrainManager
349 // with the same parameters as last time. 345 // with the same parameters as last time.
350 if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) 346 if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
351 return lastHeight; 347 return lastHeight;
348 m_terrainModified = false;
352 349
353 lastHeightTX = tX; 350 lastHeightTX = tX;
354 lastHeightTY = tY; 351 lastHeightTY = tY;
@@ -358,20 +355,47 @@ public sealed class BSTerrainManager
358 int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; 355 int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
359 Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); 356 Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
360 357
361 BSTerrainPhys physTerrain; 358 lock (m_terrains)
362 if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
363 { 359 {
364 ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); 360 BSTerrainPhys physTerrain;
365 DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,loc={1},base={2},height={3}", 361 if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
366 BSScene.DetailLogZero, loc, terrainBaseXYZ, ret); 362 {
363 ret = physTerrain.GetTerrainHeightAtXYZ(loc - terrainBaseXYZ);
364 }
365 else
366 {
367 PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
368 LogHeader, PhysicsScene.RegionName, tX, tY);
369 }
367 } 370 }
368 else 371 lastHeight = ret;
372 return ret;
373 }
374
375 public float GetWaterLevelAtXYZ(Vector3 pos)
376 {
377 float ret = WATER_HEIGHT_GETHEIGHT_RET;
378
379 float tX = pos.X;
380 float tY = pos.Y;
381
382 Vector3 terrainBaseXYZ = Vector3.Zero;
383 terrainBaseXYZ.X = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
384 terrainBaseXYZ.Y = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
385
386 lock (m_terrains)
369 { 387 {
370 PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", 388 BSTerrainPhys physTerrain;
371 LogHeader, PhysicsScene.RegionName, tX, tY); 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 }
372 } 398 }
373 m_terrainModified = false;
374 lastHeight = ret;
375 return ret; 399 return ret;
376 } 400 }
377 401