From be6edefcfb6574c1d011809315bfc464c479844c Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Fri, 15 Feb 2008 21:35:52 +0000
Subject: * ODE Stability update 4 :D * Changed the way meshing requests get
sent to the ODEPlugin * Numerous other fixes
---
OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 9 +-
OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 160 +++++++++++++++++---
OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 178 ++++++++++++-----------
3 files changed, 240 insertions(+), 107 deletions(-)
(limited to 'OpenSim/Region/Physics/OdePlugin')
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index a6acdeb..6b8d0e2 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -508,7 +508,12 @@ namespace OpenSim.Region.Physics.OdePlugin
public override PhysicsVector Velocity
{
- get { return _velocity; }
+ get {
+ if (_zeroFlag)
+ return PhysicsVector.Zero;
+ m_lastUpdateSent = false;
+ return _velocity;
+ }
set
{
m_pidControllerActive = true;
@@ -612,7 +617,7 @@ namespace OpenSim.Region.Physics.OdePlugin
_zeroPosition = d.BodyGetPosition(Body);
}
//PidStatus = true;
-
+
PhysicsVector vec = new PhysicsVector();
d.Vector3 vel = d.BodyGetLinearVel(Body);
float movementdivisor = 1f;
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 59c1f87..fae5316 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -682,6 +682,11 @@ namespace OpenSim.Region.Physics.OdePlugin
public void changePhysicsStatus(float timestap)
{
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+
if (m_isphysical == true)
{
if (Body == (IntPtr) 0)
@@ -696,6 +701,9 @@ namespace OpenSim.Region.Physics.OdePlugin
disableBody();
}
}
+
+ ode.dunlock(_parent_scene.world);
+
resetCollisionAccounting();
m_taintPhysics = m_isphysical;
}
@@ -730,7 +738,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceRemove(m_targetSpace, 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.
// Construction of new prim
@@ -742,6 +750,23 @@ namespace OpenSim.Region.Physics.OdePlugin
if (mesh != null)
{
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
{
@@ -870,37 +895,120 @@ namespace OpenSim.Region.Physics.OdePlugin
disableBody();
}
d.GeomDestroy(prim_geom);
- if (_mesh != null)
- {
- d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
- }
+ prim_geom = (IntPtr) 0;
+ // we don't need to do space calculation because the client sends a position update also.
// Construction of new prim
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);
+ // createmesh returns null when it's a shape that isn't a cube.
if (mesh != null)
{
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
{
- _parent_scene.waitForSpaceUnlock(m_targetSpace);
- SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ 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
{
- _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
- {
+ 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);
+ SetGeom(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;
@@ -908,6 +1016,16 @@ namespace OpenSim.Region.Physics.OdePlugin
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);
+ }
}
_parent_scene.geom_name_map[prim_geom] = oldname;
@@ -924,7 +1042,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
ode.dlock(_parent_scene.world);
- System.Threading.Thread.Sleep(2);
+
lock (m_forcelist)
{
//m_log.Info("[PHYSICS]: dequeing forcelist");
@@ -1048,7 +1166,11 @@ namespace OpenSim.Region.Physics.OdePlugin
public override PrimitiveBaseShape Shape
{
- set { _pbs = value; }
+ set {
+
+ _pbs = value;
+ m_taintshape = true;
+ }
}
public override PhysicsVector Velocity
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 3d70a3d..d7d9ab1 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -330,6 +330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
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.");
+ ode.drelease(world);
base.TriggerPhysicsBasedRestart();
}
catch (System.AccessViolationException)
@@ -737,87 +738,92 @@ namespace OpenSim.Region.Physics.OdePlugin
///
public void RemovePrimThreadLocked(OdePrim prim)
{
- while (ode.lockquery())
+ lock (ode)
{
- }
- ode.dlock(world);
- //System.Threading.Thread.Sleep(20);
- prim.ResetTaints();
-
-
- if (prim.IsPhysical)
- {
- prim.disableBody();
- }
- // we don't want to remove the main space
- if (prim.m_targetSpace != space && prim.IsPhysical == false)
+ if (prim.prim_geom != (IntPtr)0)
{
- // 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;
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(world);
+ //System.Threading.Thread.Sleep(20);
+ prim.ResetTaints();
+
- if (prim.m_targetSpace != (IntPtr)0)
+ if (prim.IsPhysical)
{
- if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom))
+ 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.GeomIsSpace(prim.m_targetSpace))
+ if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom))
{
- waitForSpaceUnlock(prim.m_targetSpace);
- d.SpaceRemove(prim.m_targetSpace, prim.prim_geom);
- prim.m_targetSpace = space;
+
+ if (d.GeomIsSpace(prim.m_targetSpace))
+ {
+ 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':" +
- ((OdePrim)prim).m_targetSpace.ToString());
+ d.GeomDestroy(prim.prim_geom);
+ prim.prim_geom = (IntPtr)0;
}
-
+
}
- }
- //m_log.Warn(prim.prim_geom);
- try
- {
- if (prim.prim_geom != (IntPtr)0)
+ catch (System.AccessViolationException)
{
- d.GeomDestroy(prim.prim_geom);
- prim.prim_geom = (IntPtr) 0;
+ m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed.");
}
-
- }
- catch (System.AccessViolationException)
- {
- m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed.");
- }
- _prims.Remove(prim);
+ _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 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 (d.GeomIsSpace(prim.m_targetSpace))
- //{
- //waitForSpaceUnlock(prim.m_targetSpace);
- //d.SpaceRemove(space, prim.m_targetSpace);
- // free up memory used by the space.
- //d.SpaceDestroy(prim.m_targetSpace);
- //int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position);
- //resetSpaceArrayItemToZero(xyspace[0], xyspace[1]);
- //}
- //else
- //{
- //m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
- //((OdePrim) prim).m_targetSpace.ToString());
- //}
+ //if (d.GeomIsSpace(prim.m_targetSpace))
+ //{
+ //waitForSpaceUnlock(prim.m_targetSpace);
+ //d.SpaceRemove(space, prim.m_targetSpace);
+ // free up memory used by the space.
+ //d.SpaceDestroy(prim.m_targetSpace);
+ //int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position);
+ //resetSpaceArrayItemToZero(xyspace[0], xyspace[1]);
//}
- //}
- }
+ //else
+ //{
+ //m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
+ //((OdePrim) prim).m_targetSpace.ToString());
+ //}
+ //}
+ //}
+ }
+
+
-
-
- ode.dunlock(world);
+ ode.dunlock(world);
+ }
+ }
}
///
/// 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)
{
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();
}
@@ -1249,33 +1256,32 @@ namespace OpenSim.Region.Physics.OdePlugin
while (step_time > 0.0f)
{
- foreach (OdeCharacter actor in _characters)
+ lock (ode)
{
- actor.Move(timeStep);
- actor.collidelock = true;
- }
- if (!ode.lockquery())
- {
- ode.dlock(world);
+ if (!ode.lockquery())
+ {
+ ode.dlock(world);
+ foreach (OdeCharacter actor in _characters)
+ {
+ actor.Move(timeStep);
+
+ }
+
- collision_optimized(timeStep);
+ collision_optimized(timeStep);
- d.WorldQuickStep(world, ODE_STEPSIZE);
-
- d.JointGroupEmpty(contactgroup);
- ode.dunlock(world);
+ d.WorldQuickStep(world, ODE_STEPSIZE);
- step_time -= ODE_STEPSIZE;
- i++;
- }
- else
- {
- fps = 0;
- }
+ d.JointGroupEmpty(contactgroup);
+ ode.dunlock(world);
- foreach (OdeCharacter actor in _characters)
- {
- actor.collidelock = false;
+ step_time -= ODE_STEPSIZE;
+ i++;
+ }
+ else
+ {
+ fps = 0;
+ }
}
}
--
cgit v1.1