fix ODE dispose plus minor clean. On regions restart ode.dispose seems

to be called with scene still calling simulation, that should be changed,
 for now added a check for a valid world in ode simulation
avinationmerge
UbitUmarov 2012-07-09 13:25:17 +01:00
parent b74d4711bb
commit fb8e8dcbce
1 changed files with 43 additions and 15 deletions

View File

@ -268,7 +268,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public ContactData[] m_materialContactsData = new ContactData[8]; public ContactData[] m_materialContactsData = new ContactData[8];
private readonly DoubleDictionary<Vector3, IntPtr, IntPtr> RegionTerrain = new DoubleDictionary<Vector3, IntPtr, IntPtr>(); private readonly Dictionary<Vector3, IntPtr> RegionTerrain = new Dictionary<Vector3, IntPtr>();
private readonly Dictionary<IntPtr, float[]> TerrainHeightFieldHeights = new Dictionary<IntPtr, float[]>(); private readonly Dictionary<IntPtr, float[]> TerrainHeightFieldHeights = new Dictionary<IntPtr, float[]>();
private readonly Dictionary<IntPtr, GCHandle> TerrainHeightFieldHeightsHandlers = new Dictionary<IntPtr, GCHandle>(); private readonly Dictionary<IntPtr, GCHandle> TerrainHeightFieldHeightsHandlers = new Dictionary<IntPtr, GCHandle>();
@ -1892,18 +1892,22 @@ namespace OpenSim.Region.Physics.OdePlugin
lock (SimulationLock) lock (SimulationLock)
lock(OdeLock) lock(OdeLock)
{ {
if (world == IntPtr.Zero)
return 0;
// adjust number of iterations per step // adjust number of iterations per step
try
{ // try
// {
d.WorldSetQuickStepNumIterations(world, curphysiteractions); d.WorldSetQuickStepNumIterations(world, curphysiteractions);
} /* }
catch (StackOverflowException) catch (StackOverflowException)
{ {
m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim."); m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim.");
// ode.drelease(world); // ode.drelease(world);
base.TriggerPhysicsBasedRestart(); base.TriggerPhysicsBasedRestart();
} }
*/
while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever
{ {
try try
@ -2383,11 +2387,9 @@ namespace OpenSim.Region.Physics.OdePlugin
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
d.GeomSetRotation(GroundGeom, ref R); d.GeomSetRotation(GroundGeom, ref R);
d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0); d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0);
RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); RegionTerrain.Add(pOffset, GroundGeom);
// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);
TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler); TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler);
} }
} }
@ -2486,8 +2488,7 @@ namespace OpenSim.Region.Physics.OdePlugin
geom_name_map[GroundGeom] = "Terrain"; geom_name_map[GroundGeom] = "Terrain";
d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0); d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0);
RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); RegionTerrain.Add(pOffset, GroundGeom);
// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);
TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler); TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler);
} }
@ -2648,20 +2649,43 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
public override void Dispose() public override void Dispose()
{
lock (OdeLock)
{ {
m_rayCastManager.Dispose(); m_rayCastManager.Dispose();
m_rayCastManager = null; m_rayCastManager = null;
lock (OdeLock)
{
lock (_prims) lock (_prims)
{ {
ChangesQueue.Clear();
foreach (OdePrim prm in _prims) foreach (OdePrim prm in _prims)
{ {
RemovePrim(prm); prm.DoAChange(changes.Remove, null);
_collisionEventPrim.Remove(prm);
} }
_prims.Clear();
} }
OdeCharacter[] chtorem;
lock (_characters)
{
chtorem = new OdeCharacter[_characters.Count];
_characters.CopyTo(chtorem);
}
ChangesQueue.Clear();
foreach (OdeCharacter ch in chtorem)
ch.DoAChange(changes.Remove, null);
foreach (IntPtr GroundGeom in RegionTerrain.Values)
{
if (GroundGeom != IntPtr.Zero)
d.GeomDestroy(GroundGeom);
}
RegionTerrain.Clear();
if (TerrainHeightFieldHeightsHandlers.Count > 0) if (TerrainHeightFieldHeightsHandlers.Count > 0)
{ {
foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values) foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values)
@ -2671,6 +2695,9 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
TerrainHeightFieldHeightsHandlers.Clear();
TerrainHeightFieldHeights.Clear();
if (WaterGeom != IntPtr.Zero) if (WaterGeom != IntPtr.Zero)
{ {
d.GeomDestroy(WaterGeom); d.GeomDestroy(WaterGeom);
@ -2691,6 +2718,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.WorldDestroy(world); d.WorldDestroy(world);
world = IntPtr.Zero;
//d.CloseODE(); //d.CloseODE();
} }
} }