diff options
author | Robert Adams | 2013-03-28 10:56:21 -0700 |
---|---|---|
committer | Robert Adams | 2013-03-28 10:59:18 -0700 |
commit | 6a9630d2bdc27ed702936f4c44e6978f728a9ef0 (patch) | |
tree | 0f5a4a00d4108d3e1015fb9a36a0bbb456545668 /OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | |
parent | BulletSim: tweaks to terrain boundry computation. No functional changes. (diff) | |
download | opensim-SC-6a9630d2bdc27ed702936f4c44e6978f728a9ef0.zip opensim-SC-6a9630d2bdc27ed702936f4c44e6978f728a9ef0.tar.gz opensim-SC-6a9630d2bdc27ed702936f4c44e6978f728a9ef0.tar.bz2 opensim-SC-6a9630d2bdc27ed702936f4c44e6978f728a9ef0.tar.xz |
BulletSim: fix race condition when creating very large mega-regions.
The symptom was exceptions while creating physical terrain.
Reduce default terrain mesh magnification to 2 from 3 because the
higher resolution uses a lot of memory and doesn't solve the terrain
smoothness for vehicles.
Added comments here and there and improved some debugging log messages.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index d4aecbc..b2fb835 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | |||
@@ -132,6 +132,7 @@ 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 | // 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 |
136 | BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin); | 137 | BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin); |
137 | m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape, | 138 | m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape, |
@@ -145,14 +146,18 @@ public sealed class BSTerrainManager : IDisposable | |||
145 | m_groundPlane.collisionType = CollisionType.Groundplane; | 146 | m_groundPlane.collisionType = CollisionType.Groundplane; |
146 | m_groundPlane.ApplyCollisionMask(PhysicsScene); | 147 | m_groundPlane.ApplyCollisionMask(PhysicsScene); |
147 | 148 | ||
148 | // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. | ||
149 | BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); | 149 | BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); |
150 | m_terrains.Add(Vector3.Zero, initialTerrain); | 150 | lock (m_terrains) |
151 | { | ||
152 | // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. | ||
153 | m_terrains.Add(Vector3.Zero, initialTerrain); | ||
154 | } | ||
151 | } | 155 | } |
152 | 156 | ||
153 | // Release all the terrain structures we might have allocated | 157 | // Release all the terrain structures we might have allocated |
154 | public void ReleaseGroundPlaneAndTerrain() | 158 | public void ReleaseGroundPlaneAndTerrain() |
155 | { | 159 | { |
160 | DetailLog("{0},BSTerrainManager.ReleaseGroundPlaneAndTerrain,region={1}", BSScene.DetailLogZero, PhysicsScene.RegionName); | ||
156 | if (m_groundPlane.HasPhysicalBody) | 161 | if (m_groundPlane.HasPhysicalBody) |
157 | { | 162 | { |
158 | if (PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_groundPlane)) | 163 | if (PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_groundPlane)) |
@@ -193,11 +198,16 @@ public sealed class BSTerrainManager : IDisposable | |||
193 | // the terrain is added to our parent | 198 | // the terrain is added to our parent |
194 | if (MegaRegionParentPhysicsScene is BSScene) | 199 | if (MegaRegionParentPhysicsScene is BSScene) |
195 | { | 200 | { |
196 | DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", | 201 | DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}", BSScene.DetailLogZero, m_worldOffset, m_worldMax); |
197 | BSScene.DetailLogZero, m_worldOffset, m_worldMax); | 202 | // This looks really odd but this region is passing its terrain to its mega-region root region |
198 | ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain( | 203 | // and the creation of the terrain must happen on the root region's taint thread and not |
199 | BSScene.CHILDTERRAIN_ID, localHeightMap, | 204 | // my taint thread. |
200 | m_worldOffset, m_worldOffset + DefaultRegionSize, true); | 205 | ((BSScene)MegaRegionParentPhysicsScene).PostTaintObject("TerrainManager.SetTerrain.Mega-" + m_worldOffset.ToString(), 0, delegate() |
206 | { | ||
207 | ((BSScene)MegaRegionParentPhysicsScene).TerrainManager.UpdateTerrain( | ||
208 | BSScene.CHILDTERRAIN_ID, localHeightMap, | ||
209 | m_worldOffset, m_worldOffset + DefaultRegionSize, true /* inTaintTime */); | ||
210 | }); | ||
201 | } | 211 | } |
202 | } | 212 | } |
203 | else | 213 | else |
@@ -206,16 +216,16 @@ public sealed class BSTerrainManager : IDisposable | |||
206 | DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); | 216 | DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero); |
207 | 217 | ||
208 | UpdateTerrain(BSScene.TERRAIN_ID, localHeightMap, | 218 | UpdateTerrain(BSScene.TERRAIN_ID, localHeightMap, |
209 | m_worldOffset, m_worldOffset + DefaultRegionSize, true); | 219 | m_worldOffset, m_worldOffset + DefaultRegionSize, true /* inTaintTime */); |
210 | } | 220 | } |
211 | }); | 221 | }); |
212 | } | 222 | } |
213 | 223 | ||
214 | // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain | 224 | // If called for terrain has has not been previously allocated, a new terrain will be built |
215 | // based on the passed information. The 'id' should be either the terrain id or | 225 | // based on the passed information. The 'id' should be either the terrain id or |
216 | // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used. | 226 | // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used. |
217 | // The latter feature is for creating child terrains for mega-regions. | 227 | // The latter feature is for creating child terrains for mega-regions. |
218 | // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new | 228 | // If there is an existing terrain body, a new |
219 | // terrain shape is created and added to the body. | 229 | // terrain shape is created and added to the body. |
220 | // This call is most often used to update the heightMap and parameters of the terrain. | 230 | // This call is most often used to update the heightMap and parameters of the terrain. |
221 | // (The above does suggest that some simplification/refactoring is in order.) | 231 | // (The above does suggest that some simplification/refactoring is in order.) |
@@ -223,8 +233,8 @@ public sealed class BSTerrainManager : IDisposable | |||
223 | private void UpdateTerrain(uint id, float[] heightMap, | 233 | private void UpdateTerrain(uint id, float[] heightMap, |
224 | Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) | 234 | Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) |
225 | { | 235 | { |
226 | DetailLog("{0},BSTerrainManager.UpdateTerrain,call,minC={1},maxC={2},inTaintTime={3}", | 236 | DetailLog("{0},BSTerrainManager.UpdateTerrain,call,id={1},minC={2},maxC={3},inTaintTime={4}", |
227 | BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime); | 237 | BSScene.DetailLogZero, id, minCoords, maxCoords, inTaintTime); |
228 | 238 | ||
229 | // Find high and low points of passed heightmap. | 239 | // Find high and low points of passed heightmap. |
230 | // The min and max passed in is usually the area objects can be in (maximum | 240 | // The min and max passed in is usually the area objects can be in (maximum |
@@ -253,7 +263,7 @@ public sealed class BSTerrainManager : IDisposable | |||
253 | if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) | 263 | if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) |
254 | { | 264 | { |
255 | // There is already a terrain in this spot. Free the old and build the new. | 265 | // There is already a terrain in this spot. Free the old and build the new. |
256 | DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", | 266 | DetailLog("{0},BSTErrainManager.UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", |
257 | BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); | 267 | BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); |
258 | 268 | ||
259 | // Remove old terrain from the collection | 269 | // Remove old terrain from the collection |
@@ -292,7 +302,7 @@ public sealed class BSTerrainManager : IDisposable | |||
292 | if (newTerrainID >= BSScene.CHILDTERRAIN_ID) | 302 | if (newTerrainID >= BSScene.CHILDTERRAIN_ID) |
293 | newTerrainID = ++m_terrainCount; | 303 | newTerrainID = ++m_terrainCount; |
294 | 304 | ||
295 | DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", | 305 | DetailLog("{0},BSTerrainManager.UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", |
296 | BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); | 306 | BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); |
297 | BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); | 307 | BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); |
298 | m_terrains.Add(terrainRegionBase, newTerrainPhys); | 308 | m_terrains.Add(terrainRegionBase, newTerrainPhys); |