aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRobert Adams2013-03-28 10:56:21 -0700
committerRobert Adams2013-03-28 10:59:18 -0700
commit6a9630d2bdc27ed702936f4c44e6978f728a9ef0 (patch)
tree0f5a4a00d4108d3e1015fb9a36a0bbb456545668
parentBulletSim: tweaks to terrain boundry computation. No functional changes. (diff)
downloadopensim-SC_OLD-6a9630d2bdc27ed702936f4c44e6978f728a9ef0.zip
opensim-SC_OLD-6a9630d2bdc27ed702936f4c44e6978f728a9ef0.tar.gz
opensim-SC_OLD-6a9630d2bdc27ed702936f4c44e6978f728a9ef0.tar.bz2
opensim-SC_OLD-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.
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs3
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs38
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs10
5 files changed, 35 insertions, 22 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index e208d3a..90c2d9c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -479,7 +479,7 @@ public sealed class BSCharacter : BSPhysObject
479 // The character is out of the known/simulated area. 479 // The character is out of the known/simulated area.
480 // Force the avatar position to be within known. ScenePresence will use the position 480 // Force the avatar position to be within known. ScenePresence will use the position
481 // plus the velocity to decide if the avatar is moving out of the region. 481 // plus the velocity to decide if the avatar is moving out of the region.
482 RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition); 482 RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition);
483 DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition); 483 DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition);
484 return true; 484 return true;
485 } 485 }
@@ -898,7 +898,7 @@ public sealed class BSCharacter : BSPhysObject
898 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 898 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
899 if (PositionSanityCheck(true)) 899 if (PositionSanityCheck(true))
900 { 900 {
901 DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); 901 DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position);
902 entprop.Position = _position; 902 entprop.Position = _position;
903 } 903 }
904 904
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs
index 92d62ff..ee77d6e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs
@@ -180,11 +180,14 @@ public static class BSMaterials
180 // Use reflection to set the value in the attribute structure. 180 // Use reflection to set the value in the attribute structure.
181 private static void SetAttributeValue(int matType, string attribName, float val) 181 private static void SetAttributeValue(int matType, string attribName, float val)
182 { 182 {
183 // Get the current attribute values for this material
183 MaterialAttributes thisAttrib = Attributes[matType]; 184 MaterialAttributes thisAttrib = Attributes[matType];
185 // Find the field for the passed attribute name (eg, find field named 'friction')
184 FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower()); 186 FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName.ToLower());
185 if (fieldInfo != null) 187 if (fieldInfo != null)
186 { 188 {
187 fieldInfo.SetValue(thisAttrib, val); 189 fieldInfo.SetValue(thisAttrib, val);
190 // Copy new attributes back to array -- since MaterialAttributes is 'struct', passed by value, not reference.
188 Attributes[matType] = thisAttrib; 191 Attributes[matType] = thisAttrib;
189 } 192 }
190 } 193 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index f3454c8..385ed9e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -482,7 +482,7 @@ public static class BSParam
482 (s) => { return TerrainImplementation; }, 482 (s) => { return TerrainImplementation; },
483 (s,v) => { TerrainImplementation = v; } ), 483 (s,v) => { TerrainImplementation = v; } ),
484 new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , 484 new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" ,
485 3, 485 2,
486 (s) => { return TerrainMeshMagnification; }, 486 (s) => { return TerrainMeshMagnification; },
487 (s,v) => { TerrainMeshMagnification = v; } ), 487 (s,v) => { TerrainMeshMagnification = v; } ),
488 new ParameterDefn<float>("TerrainFriction", "Factor to reduce movement against terrain surface" , 488 new ParameterDefn<float>("TerrainFriction", "Factor to reduce movement against terrain surface" ,
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);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
index a9cd8a1..2ce1513 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
@@ -98,20 +98,20 @@ public sealed class BSTerrainMesh : BSTerrainPhys
98 if (!meshCreationSuccess) 98 if (!meshCreationSuccess)
99 { 99 {
100 // DISASTER!! 100 // DISASTER!!
101 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); 101 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap,id={1}", BSScene.DetailLogZero, ID);
102 PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); 102 PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase);
103 // Something is very messed up and a crash is in our future. 103 // Something is very messed up and a crash is in our future.
104 return; 104 return;
105 } 105 }
106 106
107 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", 107 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,id={1},indices={2},indSz={3},vertices={4},vertSz={5}",
108 ID, indicesCount, indices.Length, verticesCount, vertices.Length); 108 BSScene.DetailLogZero, ID, indicesCount, indices.Length, verticesCount, vertices.Length);
109 109
110 m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices); 110 m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices);
111 if (!m_terrainShape.HasPhysicalShape) 111 if (!m_terrainShape.HasPhysicalShape)
112 { 112 {
113 // DISASTER!! 113 // DISASTER!!
114 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); 114 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape,id={1}", BSScene.DetailLogZero, ID);
115 PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); 115 PhysicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase);
116 // Something is very messed up and a crash is in our future. 116 // Something is very messed up and a crash is in our future.
117 return; 117 return;
@@ -151,7 +151,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
151 151
152 if (BSParam.UseSingleSidedMeshes) 152 if (BSParam.UseSingleSidedMeshes)
153 { 153 {
154 PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial", id); 154 PhysicsScene.DetailLog("{0},BSTerrainMesh.settingCustomMaterial,id={1}", BSScene.DetailLogZero, id);
155 PhysicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK); 155 PhysicsScene.PE.AddToCollisionFlags(m_terrainBody, CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
156 } 156 }
157 157