* ODE Stability update 4 :D

* Changed the way meshing requests get sent to the ODEPlugin
* Numerous other fixes
ThreadPoolClientBranch
Teravus Ovares 2008-02-15 21:35:52 +00:00
parent cf9c0135b1
commit be6edefcfb
6 changed files with 290 additions and 140 deletions

View File

@ -743,6 +743,21 @@ namespace OpenSim.Region.Environment.Scenes
{ {
throw; throw;
} }
catch (System.AccessViolationException e)
{
m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
}
catch (System.NullReferenceException e)
{
m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
}
catch (System.InvalidOperationException e)
{
m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
}
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);

View File

@ -1265,23 +1265,11 @@ namespace OpenSim.Region.Environment.Scenes
if (part != null) if (part != null)
{ {
part.UpdateShape(shapeBlock); part.UpdateShape(shapeBlock);
}
if (m_rootPart.PhysActor != null)
{
m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor);
m_rootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape(
m_rootPart.Name,
m_rootPart.Shape,
new PhysicsVector(m_rootPart.AbsolutePosition.X, m_rootPart.AbsolutePosition.Y,
m_rootPart.AbsolutePosition.Z),
new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z),
new Quaternion(m_rootPart.RotationOffset.W, m_rootPart.RotationOffset.X,
m_rootPart.RotationOffset.Y, m_rootPart.RotationOffset.Z),
m_rootPart.PhysActor.IsPhysical);
bool UsePhysics = ((m_rootPart.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) != 0);
m_rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
if (part.PhysActor != null)
m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
} }
} }
#endregion #endregion
@ -1299,15 +1287,24 @@ namespace OpenSim.Region.Environment.Scenes
if (part != null) if (part != null)
{ {
part.Resize(scale); part.Resize(scale);
if (part.UUID == m_rootPart.UUID) if (part.PhysActor != null)
{ {
if (m_rootPart.PhysActor != null) part.PhysActor.Size =
{ new PhysicsVector(scale.X, scale.Y, scale.Z);
m_rootPart.PhysActor.Size = m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z);
m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
}
} }
if (part.UUID != m_rootPart.UUID)
ScheduleGroupForFullUpdate();
//if (part.UUID == m_rootPart.UUID)
//{
//if (m_rootPart.PhysActor != null)
//{
//m_rootPart.PhysActor.Size =
//new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z);
//m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
//}
//}
} }
} }

View File

@ -1182,6 +1182,10 @@ namespace OpenSim.Region.Environment.Scenes
m_shape.PathTaperY = shapeBlock.PathTaperY; m_shape.PathTaperY = shapeBlock.PathTaperY;
m_shape.PathTwist = shapeBlock.PathTwist; m_shape.PathTwist = shapeBlock.PathTwist;
m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
if (PhysActor != null)
{
PhysActor.Shape = m_shape;
}
ScheduleFullUpdate(); ScheduleFullUpdate();
} }
@ -1583,6 +1587,7 @@ namespace OpenSim.Region.Environment.Scenes
public void Resize(LLVector3 scale) public void Resize(LLVector3 scale)
{ {
m_shape.Scale = scale; m_shape.Scale = scale;
ScheduleFullUpdate(); ScheduleFullUpdate();
} }

View File

@ -508,7 +508,12 @@ namespace OpenSim.Region.Physics.OdePlugin
public override PhysicsVector Velocity public override PhysicsVector Velocity
{ {
get { return _velocity; } get {
if (_zeroFlag)
return PhysicsVector.Zero;
m_lastUpdateSent = false;
return _velocity;
}
set set
{ {
m_pidControllerActive = true; m_pidControllerActive = true;

View File

@ -682,6 +682,11 @@ namespace OpenSim.Region.Physics.OdePlugin
public void changePhysicsStatus(float timestap) public void changePhysicsStatus(float timestap)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
if (m_isphysical == true) if (m_isphysical == true)
{ {
if (Body == (IntPtr) 0) if (Body == (IntPtr) 0)
@ -696,6 +701,9 @@ namespace OpenSim.Region.Physics.OdePlugin
disableBody(); disableBody();
} }
} }
ode.dunlock(_parent_scene.world);
resetCollisionAccounting(); resetCollisionAccounting();
m_taintPhysics = m_isphysical; m_taintPhysics = m_isphysical;
} }
@ -730,7 +738,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceRemove(m_targetSpace, prim_geom); d.SpaceRemove(m_targetSpace, prim_geom);
} }
d.GeomDestroy(prim_geom); d.GeomDestroy(prim_geom);
prim_geom = (IntPtr)0;
// we don't need to do space calculation because the client sends a position update also. // we don't need to do space calculation because the client sends a position update also.
// Construction of new prim // Construction of new prim
@ -742,6 +750,23 @@ namespace OpenSim.Region.Physics.OdePlugin
if (mesh != null) if (mesh != null)
{ {
setMesh(_parent_scene, mesh); setMesh(_parent_scene, mesh);
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
d.Quaternion myrot = new d.Quaternion();
myrot.W = _orientation.w;
myrot.X = _orientation.x;
myrot.Y = _orientation.y;
myrot.Z = _orientation.z;
d.GeomSetQuaternion(prim_geom, ref myrot);
//d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
if (IsPhysical && Body == (IntPtr)0)
{
// Re creates body on size.
// EnableBody also does setMass()
enableBody();
d.BodyEnable(Body);
}
} }
else else
{ {
@ -870,37 +895,120 @@ namespace OpenSim.Region.Physics.OdePlugin
disableBody(); disableBody();
} }
d.GeomDestroy(prim_geom); d.GeomDestroy(prim_geom);
if (_mesh != null) prim_geom = (IntPtr) 0;
{ // we don't need to do space calculation because the client sends a position update also.
d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
}
// Construction of new prim // Construction of new prim
if (_parent_scene.needsMeshing(_pbs)) if (_parent_scene.needsMeshing(_pbs))
{ {
// Don't need to re-enable body.. it's done in SetMesh
IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size); IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
// createmesh returns null when it's a shape that isn't a cube.
if (mesh != null) if (mesh != null)
{ {
setMesh(_parent_scene, mesh); setMesh(_parent_scene, mesh);
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
d.Quaternion myrot = new d.Quaternion();
myrot.W = _orientation.w;
myrot.X = _orientation.x;
myrot.Y = _orientation.y;
myrot.Z = _orientation.z;
d.GeomSetQuaternion(prim_geom, ref myrot);
//d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
if (IsPhysical && Body == (IntPtr)0)
{
// Re creates body on size.
// EnableBody also does setMass()
enableBody();
d.BodyEnable(Body);
}
} }
else else
{
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
{
if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
{
if (((_size.X / 2f) > 0f) && ((_size.X / 2f) < 1000))
{
_parent_scene.waitForSpaceUnlock(m_targetSpace);
SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
}
else
{
m_log.Info("[PHYSICS]: Failed to load a sphere bad size");
_parent_scene.waitForSpaceUnlock(m_targetSpace);
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
}
}
else
{
_parent_scene.waitForSpaceUnlock(m_targetSpace);
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
}
}
//else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
//{
//Cyllinder
//if (_size.X == _size.Y)
//{
// prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
//}
//else
//{
//prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
//}
//}
else
{
_parent_scene.waitForSpaceUnlock(m_targetSpace);
SetGeom(prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
}
//prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
d.Quaternion myrot = new d.Quaternion();
myrot.W = _orientation.w;
myrot.X = _orientation.x;
myrot.Y = _orientation.y;
myrot.Z = _orientation.z;
d.GeomSetQuaternion(prim_geom, ref myrot);
}
}
else
{
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
{
if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
{
_parent_scene.waitForSpaceUnlock(m_targetSpace);
SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
}
else
{
_parent_scene.waitForSpaceUnlock(m_targetSpace);
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
}
}
//else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
//{
//Cyllinder
//if (_size.X == _size.Y)
//{
//prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
//}
//else
//{
//prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
//}
//}
else
{ {
_parent_scene.waitForSpaceUnlock(m_targetSpace); _parent_scene.waitForSpaceUnlock(m_targetSpace);
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
} }
}
else
{
_parent_scene.waitForSpaceUnlock(m_targetSpace);
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
}
if (IsPhysical && Body == (IntPtr) 0)
{
//re-create new body
enableBody();
}
else
{
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
d.Quaternion myrot = new d.Quaternion(); d.Quaternion myrot = new d.Quaternion();
myrot.W = _orientation.w; myrot.W = _orientation.w;
@ -908,6 +1016,16 @@ namespace OpenSim.Region.Physics.OdePlugin
myrot.Y = _orientation.y; myrot.Y = _orientation.y;
myrot.Z = _orientation.z; myrot.Z = _orientation.z;
d.GeomSetQuaternion(prim_geom, ref myrot); d.GeomSetQuaternion(prim_geom, ref myrot);
//d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
if (IsPhysical && Body == (IntPtr)0)
{
// Re creates body on size.
// EnableBody also does setMass()
enableBody();
d.BodyEnable(Body);
}
} }
_parent_scene.geom_name_map[prim_geom] = oldname; _parent_scene.geom_name_map[prim_geom] = oldname;
@ -924,7 +1042,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
ode.dlock(_parent_scene.world); ode.dlock(_parent_scene.world);
System.Threading.Thread.Sleep(2);
lock (m_forcelist) lock (m_forcelist)
{ {
//m_log.Info("[PHYSICS]: dequeing forcelist"); //m_log.Info("[PHYSICS]: dequeing forcelist");
@ -1048,7 +1166,11 @@ namespace OpenSim.Region.Physics.OdePlugin
public override PrimitiveBaseShape Shape public override PrimitiveBaseShape Shape
{ {
set { _pbs = value; } set {
_pbs = value;
m_taintshape = true;
}
} }
public override PhysicsVector Velocity public override PhysicsVector Velocity

View File

@ -330,6 +330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
catch (SEHException) catch (SEHException)
{ {
m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
ode.drelease(world);
base.TriggerPhysicsBasedRestart(); base.TriggerPhysicsBasedRestart();
} }
catch (System.AccessViolationException) catch (System.AccessViolationException)
@ -737,87 +738,92 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="prim"></param> /// <param name="prim"></param>
public void RemovePrimThreadLocked(OdePrim prim) public void RemovePrimThreadLocked(OdePrim prim)
{ {
while (ode.lockquery()) lock (ode)
{ {
} if (prim.prim_geom != (IntPtr)0)
ode.dlock(world);
//System.Threading.Thread.Sleep(20);
prim.ResetTaints();
if (prim.IsPhysical)
{ {
prim.disableBody(); while (ode.lockquery())
}
// we don't want to remove the main space
if (prim.m_targetSpace != space && prim.IsPhysical == false)
{
// If the geometry is in the targetspace, remove it from the target space
//m_log.Warn(prim.m_targetSpace);
if (prim.prim_geom == (IntPtr)0)
prim.prim_geom = prim.prev_geom;
if (prim.m_targetSpace != (IntPtr)0)
{ {
if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom)) }
{ ode.dlock(world);
//System.Threading.Thread.Sleep(20);
prim.ResetTaints();
if (d.GeomIsSpace(prim.m_targetSpace))
if (prim.IsPhysical)
{
prim.disableBody();
}
// we don't want to remove the main space
if (prim.m_targetSpace != space && prim.IsPhysical == false)
{
// If the geometry is in the targetspace, remove it from the target space
//m_log.Warn(prim.m_targetSpace);
if (prim.m_targetSpace != (IntPtr)0)
{
if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom))
{ {
waitForSpaceUnlock(prim.m_targetSpace);
d.SpaceRemove(prim.m_targetSpace, prim.prim_geom); if (d.GeomIsSpace(prim.m_targetSpace))
prim.m_targetSpace = space; {
waitForSpaceUnlock(prim.m_targetSpace);
d.SpaceRemove(prim.m_targetSpace, prim.prim_geom);
prim.m_targetSpace = space;
}
else
{
m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
((OdePrim)prim).m_targetSpace.ToString());
}
} }
else }
//m_log.Warn(prim.prim_geom);
try
{
if (prim.prim_geom != (IntPtr)0)
{ {
m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" + d.GeomDestroy(prim.prim_geom);
((OdePrim)prim).m_targetSpace.ToString()); prim.prim_geom = (IntPtr)0;
} }
} }
} catch (System.AccessViolationException)
//m_log.Warn(prim.prim_geom);
try
{
if (prim.prim_geom != (IntPtr)0)
{ {
d.GeomDestroy(prim.prim_geom); m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed.");
prim.prim_geom = (IntPtr) 0;
} }
_prims.Remove(prim);
} //If there are no more geometries in the sub-space, we don't need it in the main space anymore
catch (System.AccessViolationException) //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0)
{ //{
m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed.");
}
_prims.Remove(prim);
//If there are no more geometries in the sub-space, we don't need it in the main space anymore
//if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0)
//{
//if (!(prim.m_targetSpace.Equals(null))) //if (!(prim.m_targetSpace.Equals(null)))
//{ //{
//if (d.GeomIsSpace(prim.m_targetSpace)) //if (d.GeomIsSpace(prim.m_targetSpace))
//{ //{
//waitForSpaceUnlock(prim.m_targetSpace); //waitForSpaceUnlock(prim.m_targetSpace);
//d.SpaceRemove(space, prim.m_targetSpace); //d.SpaceRemove(space, prim.m_targetSpace);
// free up memory used by the space. // free up memory used by the space.
//d.SpaceDestroy(prim.m_targetSpace); //d.SpaceDestroy(prim.m_targetSpace);
//int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position); //int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position);
//resetSpaceArrayItemToZero(xyspace[0], xyspace[1]); //resetSpaceArrayItemToZero(xyspace[0], xyspace[1]);
//}
//else
//{
//m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
//((OdePrim) prim).m_targetSpace.ToString());
//}
//} //}
//} //else
//{
//m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
//((OdePrim) prim).m_targetSpace.ToString());
//}
//}
//}
}
ode.dunlock(world);
} }
}
ode.dunlock(world);
} }
/// <summary> /// <summary>
/// Takes a space pointer and zeros out the array we're using to hold the spaces /// Takes a space pointer and zeros out the array we're using to hold the spaces
@ -1238,6 +1244,7 @@ namespace OpenSim.Region.Physics.OdePlugin
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);
base.TriggerPhysicsBasedRestart(); base.TriggerPhysicsBasedRestart();
} }
@ -1249,33 +1256,32 @@ namespace OpenSim.Region.Physics.OdePlugin
while (step_time > 0.0f) while (step_time > 0.0f)
{ {
foreach (OdeCharacter actor in _characters) lock (ode)
{ {
actor.Move(timeStep); if (!ode.lockquery())
actor.collidelock = true; {
} ode.dlock(world);
if (!ode.lockquery()) foreach (OdeCharacter actor in _characters)
{ {
ode.dlock(world); actor.Move(timeStep);
collision_optimized(timeStep); }
d.WorldQuickStep(world, ODE_STEPSIZE);
d.JointGroupEmpty(contactgroup); collision_optimized(timeStep);
ode.dunlock(world);
step_time -= ODE_STEPSIZE; d.WorldQuickStep(world, ODE_STEPSIZE);
i++;
}
else
{
fps = 0;
}
foreach (OdeCharacter actor in _characters) d.JointGroupEmpty(contactgroup);
{ ode.dunlock(world);
actor.collidelock = false;
step_time -= ODE_STEPSIZE;
i++;
}
else
{
fps = 0;
}
} }
} }