diff options
author | Robert Adams | 2012-11-24 19:57:11 -0800 |
---|---|---|
committer | Robert Adams | 2012-11-25 20:04:27 -0800 |
commit | c3f30fef96674e9f43a277399c987a85cec9a7d3 (patch) | |
tree | 633d47fcc341c04ffbe4f36dce78c42daef2301c | |
parent | BulletSim: Add tables and initialization for different attributes for differe... (diff) | |
download | opensim-SC_OLD-c3f30fef96674e9f43a277399c987a85cec9a7d3.zip opensim-SC_OLD-c3f30fef96674e9f43a277399c987a85cec9a7d3.tar.gz opensim-SC_OLD-c3f30fef96674e9f43a277399c987a85cec9a7d3.tar.bz2 opensim-SC_OLD-c3f30fef96674e9f43a277399c987a85cec9a7d3.tar.xz |
BulletSim: add parameter for terrain collision margin.
Add locking around unlikely but possible race conditions on terrain list.
3 files changed, 45 insertions, 54 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 3ca756c..1450f66 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs | |||
@@ -93,7 +93,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys | |||
93 | { | 93 | { |
94 | m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, | 94 | m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, |
95 | m_mapInfo.minCoords, m_mapInfo.maxCoords, | 95 | m_mapInfo.minCoords, m_mapInfo.maxCoords, |
96 | m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN); | 96 | m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin); |
97 | 97 | ||
98 | // Create the terrain shape from the mapInfo | 98 | // Create the terrain shape from the mapInfo |
99 | m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), | 99 | m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 23fcfd3..cd623f1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | |||
@@ -80,8 +80,6 @@ public sealed class BSTerrainManager | |||
80 | // amount to make sure that a bounding box is built for the terrain. | 80 | // amount to make sure that a bounding box is built for the terrain. |
81 | public const float HEIGHT_EQUAL_FUDGE = 0.2f; | 81 | public const float HEIGHT_EQUAL_FUDGE = 0.2f; |
82 | 82 | ||
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. | 83 | // 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); | 84 | public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); |
87 | 85 | ||
@@ -129,7 +127,8 @@ public sealed class BSTerrainManager | |||
129 | { | 127 | { |
130 | // The ground plane is here to catch things that are trying to drop to negative infinity | 128 | // The ground plane is here to catch things that are trying to drop to negative infinity |
131 | BulletShape groundPlaneShape = new BulletShape( | 129 | BulletShape groundPlaneShape = new BulletShape( |
132 | BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN), | 130 | BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, |
131 | PhysicsScene.Params.terrainCollisionMargin), | ||
133 | BSPhysicsShapeType.SHAPE_GROUNDPLANE); | 132 | BSPhysicsShapeType.SHAPE_GROUNDPLANE); |
134 | m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, | 133 | m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, |
135 | BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, | 134 | BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, |
@@ -165,17 +164,22 @@ public sealed class BSTerrainManager | |||
165 | // Release all the terrain we have allocated | 164 | // Release all the terrain we have allocated |
166 | public void ReleaseTerrain() | 165 | public void ReleaseTerrain() |
167 | { | 166 | { |
168 | foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains) | 167 | lock (m_terrains) |
169 | { | 168 | { |
170 | kvp.Value.Dispose(); | 169 | foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains) |
170 | { | ||
171 | kvp.Value.Dispose(); | ||
172 | } | ||
173 | m_terrains.Clear(); | ||
171 | } | 174 | } |
172 | m_terrains.Clear(); | ||
173 | } | 175 | } |
174 | 176 | ||
175 | // The simulator wants to set a new heightmap for the terrain. | 177 | // The simulator wants to set a new heightmap for the terrain. |
176 | public void SetTerrain(float[] heightMap) { | 178 | public void SetTerrain(float[] heightMap) { |
177 | float[] localHeightMap = heightMap; | 179 | float[] localHeightMap = heightMap; |
178 | PhysicsScene.TaintedObject("TerrainManager.SetTerrain", delegate() | 180 | // If there are multiple requests for changes to the same terrain between ticks, |
181 | // only do that last one. | ||
182 | PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate() | ||
179 | { | 183 | { |
180 | if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null) | 184 | if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null) |
181 | { | 185 | { |
@@ -211,6 +215,7 @@ public sealed class BSTerrainManager | |||
211 | // terrain shape is created and added to the body. | 215 | // 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. | 216 | // 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.) | 217 | // (The above does suggest that some simplification/refactoring is in order.) |
218 | // Called during taint-time. | ||
214 | private void UpdateTerrain(uint id, float[] heightMap, | 219 | private void UpdateTerrain(uint id, float[] heightMap, |
215 | Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) | 220 | Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) |
216 | { | 221 | { |
@@ -220,7 +225,7 @@ public sealed class BSTerrainManager | |||
220 | // Find high and low points of passed heightmap. | 225 | // Find high and low points of passed heightmap. |
221 | // The min and max passed in is usually the area objects can be in (maximum | 226 | // 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 | 227 | // 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. | 228 | // terrain so replace passed min and max Z with the actual terrain min/max Z. |
224 | float minZ = float.MaxValue; | 229 | float minZ = float.MaxValue; |
225 | float maxZ = float.MinValue; | 230 | float maxZ = float.MinValue; |
226 | foreach (float height in heightMap) | 231 | foreach (float height in heightMap) |
@@ -238,15 +243,15 @@ public sealed class BSTerrainManager | |||
238 | 243 | ||
239 | Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); | 244 | Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); |
240 | 245 | ||
241 | BSTerrainPhys terrainPhys; | 246 | lock (m_terrains) |
242 | if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) | ||
243 | { | 247 | { |
244 | // There is already a terrain in this spot. Free the old and build the new. | 248 | BSTerrainPhys terrainPhys; |
245 | DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", | 249 | if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) |
246 | BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); | ||
247 | |||
248 | PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate() | ||
249 | { | 250 | { |
251 | // There is already a terrain in this spot. Free the old and build the new. | ||
252 | DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", | ||
253 | BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); | ||
254 | |||
250 | // Remove old terrain from the collection | 255 | // Remove old terrain from the collection |
251 | m_terrains.Remove(terrainRegionBase); | 256 | m_terrains.Remove(terrainRegionBase); |
252 | // Release any physical memory it may be using. | 257 | // Release any physical memory it may be using. |
@@ -271,35 +276,24 @@ public sealed class BSTerrainManager | |||
271 | // I hate doing this, but just bail | 276 | // I hate doing this, but just bail |
272 | return; | 277 | return; |
273 | } | 278 | } |
274 | }); | 279 | } |
275 | } | 280 | else |
276 | else | 281 | { |
277 | { | 282 | // 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 | 283 | // 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 | 284 | ||
290 | DetailLog("{0},UpdateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}", | 285 | // if this is a child terrain, calculate a unique terrain id |
291 | BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); | 286 | uint newTerrainID = id; |
287 | if (newTerrainID >= BSScene.CHILDTERRAIN_ID) | ||
288 | newTerrainID = ++m_terrainCount; | ||
292 | 289 | ||
293 | // Code that must happen at taint-time | 290 | DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", |
294 | PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:NewTerrain", delegate() | 291 | 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); | 292 | BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); |
299 | m_terrains.Add(terrainRegionBase, newTerrainPhys); | 293 | m_terrains.Add(terrainRegionBase, newTerrainPhys); |
300 | 294 | ||
301 | m_terrainModified = true; | 295 | m_terrainModified = true; |
302 | }); | 296 | } |
303 | } | 297 | } |
304 | } | 298 | } |
305 | 299 | ||
@@ -349,6 +343,7 @@ public sealed class BSTerrainManager | |||
349 | // with the same parameters as last time. | 343 | // with the same parameters as last time. |
350 | if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) | 344 | if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) |
351 | return lastHeight; | 345 | return lastHeight; |
346 | m_terrainModified = false; | ||
352 | 347 | ||
353 | lastHeightTX = tX; | 348 | lastHeightTX = tX; |
354 | lastHeightTY = tY; | 349 | lastHeightTY = tY; |
@@ -358,19 +353,19 @@ public sealed class BSTerrainManager | |||
358 | int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; | 353 | int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; |
359 | Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); | 354 | Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); |
360 | 355 | ||
361 | BSTerrainPhys physTerrain; | 356 | lock (m_terrains) |
362 | if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) | ||
363 | { | 357 | { |
364 | ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); | 358 | BSTerrainPhys physTerrain; |
365 | DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,loc={1},base={2},height={3}", | 359 | if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) |
366 | BSScene.DetailLogZero, loc, terrainBaseXYZ, ret); | 360 | { |
367 | } | 361 | ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); |
368 | else | 362 | } |
369 | { | 363 | else |
370 | PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", | 364 | { |
371 | LogHeader, PhysicsScene.RegionName, tX, tY); | 365 | PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", |
366 | LogHeader, PhysicsScene.RegionName, tX, tY); | ||
367 | } | ||
372 | } | 368 | } |
373 | m_terrainModified = false; | ||
374 | lastHeight = ret; | 369 | lastHeight = ret; |
375 | return ret; | 370 | return ret; |
376 | } | 371 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index dca7150..d7afdeb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs | |||
@@ -217,8 +217,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys | |||
217 | } | 217 | } |
218 | } | 218 | } |
219 | verticesCount = verticesCount / 3; | 219 | verticesCount = verticesCount / 3; |
220 | physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}", | ||
221 | BSScene.DetailLogZero, verticesCount); | ||
222 | 220 | ||
223 | for (int yy = 0; yy < sizeY; yy++) | 221 | for (int yy = 0; yy < sizeY; yy++) |
224 | { | 222 | { |
@@ -235,8 +233,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys | |||
235 | indicesCount += 6; | 233 | indicesCount += 6; |
236 | } | 234 | } |
237 | } | 235 | } |
238 | physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG | ||
239 | LogHeader, indicesCount); // DEBUG | ||
240 | ret = true; | 236 | ret = true; |
241 | } | 237 | } |
242 | catch (Exception e) | 238 | catch (Exception e) |