From 081b2ac34ec57fe0f67f0e63c9179e3a141f0ea5 Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Sun, 9 Mar 2008 15:43:01 +0000
Subject: * Cleaned up some locking on the ODEPlugin to make it more developer
friendly * Expect the occasional deadlock?
---
OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 137 ++--
OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 864 +++++++++++++-------------
2 files changed, 496 insertions(+), 505 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 36b3828..8a8a5fb 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -293,6 +293,8 @@ namespace OpenSim.Region.Physics.OdePlugin
_parent_scene.addActivePrim(this);
}
+ #region Mass Calculation
+
private float CalculateMass()
{
float volume = 0;
@@ -598,6 +600,9 @@ namespace OpenSim.Region.Physics.OdePlugin
return returnMass;
}
+ #endregion
+
+
public void setMass()
{
if (Body != (IntPtr) 0)
@@ -734,11 +739,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private void changelink(float timestep)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
-
+
if (_parent == null && m_taintparent != null)
{
if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim)
@@ -763,18 +764,14 @@ namespace OpenSim.Region.Physics.OdePlugin
m_linkJoint = (IntPtr)0;
}
- ode.dunlock(_parent_scene.world);
+
_parent = m_taintparent;
}
private void changeSelectedStatus(float timestep)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
-
+
if (m_taintselected)
{
@@ -831,7 +828,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
- ode.dunlock(_parent_scene.world);
+
resetCollisionAccounting();
m_isSelected = m_taintselected;
}
@@ -860,10 +857,8 @@ namespace OpenSim.Region.Physics.OdePlugin
}
public void changeadd(float timestep)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
+
+
int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position);
@@ -992,7 +987,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
- ode.dunlock(_parent_scene.world);
+
_parent_scene.geom_name_map[prim_geom] = this.m_primName;
_parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
@@ -1004,10 +999,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
public void Move(float timestep)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
+
if (m_isphysical)
@@ -1057,7 +1049,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceAdd(m_targetSpace, prim_geom);
}
}
- ode.dunlock(_parent_scene.world);
+
changeSelectedStatus(timestep);
@@ -1067,10 +1059,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public void rotate(float timestep)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
+
d.Quaternion myrot = new d.Quaternion();
myrot.W = _orientation.w;
@@ -1082,8 +1071,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
d.BodySetQuaternion(Body, ref myrot);
}
-
- ode.dunlock(_parent_scene.world);
resetCollisionAccounting();
m_taintrot = _orientation;
@@ -1098,46 +1085,35 @@ namespace OpenSim.Region.Physics.OdePlugin
public void changedisable(float timestep)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
+
m_disabled = true;
if (Body != (IntPtr)0)
{
d.BodyDisable(Body);
Body = (IntPtr)0;
}
- ode.dunlock(_parent_scene.world);
+
m_taintdisable = false;
}
public void changePhysicsStatus(float timestep)
{
- lock (ode)
- {
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
+
- if (m_isphysical == true)
+ if (m_isphysical == true)
+ {
+ if (Body == (IntPtr)0)
{
- if (Body == (IntPtr)0)
- {
- enableBody();
- }
+ enableBody();
}
- else
+ }
+ else
+ {
+ if (Body != (IntPtr)0)
{
- if (Body != (IntPtr)0)
- {
- disableBody();
- }
+ disableBody();
}
-
- ode.dunlock(_parent_scene.world);
}
changeSelectedStatus(timestep);
@@ -1148,10 +1124,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public void changesize(float timestamp)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
+
//if (!_parent_scene.geom_name_map.ContainsKey(prim_geom))
//{
// m_taintsize = _size;
@@ -1311,8 +1284,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_parent_scene.geom_name_map[prim_geom] = oldname;
- ode.dunlock(_parent_scene.world);
-
changeSelectedStatus(timestamp);
resetCollisionAccounting();
@@ -1321,12 +1292,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public void changeshape(float timestamp)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
-
-
+
string oldname = _parent_scene.geom_name_map[prim_geom];
// Cleanup of old prim geometry and Bodies
@@ -1471,8 +1437,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_parent_scene.geom_name_map[prim_geom] = oldname;
- ode.dunlock(_parent_scene.world);
-
changeSelectedStatus(timestamp);
resetCollisionAccounting();
@@ -1483,10 +1447,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (!m_isSelected)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
+
lock (m_forcelist)
@@ -1505,7 +1466,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_forcelist.Clear();
}
- ode.dunlock(_parent_scene.world);
m_collisionscore = 0;
m_interpenetrationcount = 0;
@@ -1517,24 +1477,17 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (!m_isSelected)
{
- lock (ode)
- {
- while (ode.lockquery())
- {
- }
- ode.dlock(_parent_scene.world);
+
- System.Threading.Thread.Sleep(20);
- if (IsPhysical)
+ System.Threading.Thread.Sleep(20);
+ if (IsPhysical)
+ {
+ if (Body != (IntPtr)0)
{
- if (Body != (IntPtr)0)
- {
- d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z);
- }
+ d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z);
}
-
- ode.dunlock(_parent_scene.world);
- }
+ }
+
//resetCollisionAccounting();
}
m_taintVelocity = PhysicsVector.Zero;
@@ -1763,12 +1716,16 @@ namespace OpenSim.Region.Physics.OdePlugin
if (l_position.X > 255.95f || l_position.X < 0f || l_position.Y > 255.95f || l_position.Y < 0f)
{
base.RaiseOutOfBounds(_position);
+
+ //if (m_crossingfailures < 5)
+ //{
+ //base.RequestPhysicsterseUpdate();
+ //}
+ //else
+ //{
+ //base.RaiseOutOfBounds(_position);
+ //}
}
- //if (m_crossingfailures < 5)
- //{
- //base.RequestPhysicsterseUpdate();
- //}
- //}
if (l_position.Z < 0)
{
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 266cb3d..5b1fd78 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -229,14 +229,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
- public void starttiming()
- {
- ms = Environment.TickCount;
- }
- public int stoptiming()
- {
- return Environment.TickCount - ms;
- }
+
// Initialize the mesh plugin
public override void Initialise(IMesher meshmerizer)
{
@@ -245,15 +238,9 @@ namespace OpenSim.Region.Physics.OdePlugin
internal void waitForSpaceUnlock(IntPtr space)
{
-
- while (d.SpaceLockQuery(space))
- {
-
- }
-
-
-
+ while (d.SpaceLockQuery(space)){ } // Wait and do nothing
}
+
///
/// Debug space message for printing the space that a prim/avatar is in.
///
@@ -264,6 +251,8 @@ namespace OpenSim.Region.Physics.OdePlugin
return calculateSpaceForGeom(pos).ToString();
}
+ #region Collision Detection
+
///
/// This is our near callback. A geometry is near a body
///
@@ -299,314 +288,359 @@ namespace OpenSim.Region.Physics.OdePlugin
//Collide all geoms in each space..
//if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
//if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
+ return;
}
- else
- {
- // Colliding Geom To Geom
- // This portion of the function 'was' blatantly ripped off from BoxStack.cs
- if (g1 == (IntPtr)0 || g2 == (IntPtr)0)
- return;
+
+
+ // Colliding Geom To Geom
+ // This portion of the function 'was' blatantly ripped off from BoxStack.cs
+ if (g1 == (IntPtr)0 || g2 == (IntPtr)0)
+ return;
- IntPtr b1 = d.GeomGetBody(g1);
- IntPtr b2 = d.GeomGetBody(g2);
+ IntPtr b1 = d.GeomGetBody(g1);
+ IntPtr b2 = d.GeomGetBody(g2);
- if (g1 == g2)
- return; // Can't collide with yourself
+ if (g1 == g2)
+ return; // Can't collide with yourself
- if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
- return;
+ if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
+ return;
+
+
+
+ d.GeomClassID id = d.GeomGetClass(g1);
+
+ String name1 = null;
+ String name2 = null;
+ if (!geom_name_map.TryGetValue(g1, out name1))
+ {
+ name1 = "null";
+ }
+ if (!geom_name_map.TryGetValue(g2, out name2))
+ {
+ name2 = "null";
+ }
+
+ //if (id == d.GeomClassId.TriMeshClass)
+ //{
+ // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2);
+ //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2);
+ //}
+
+ // Figure out how many contact points we have
+ int count = 0;
+ try
+ {
+ //m_log.Warn(g1.ToString() + "|" + g2.ToString());
+ count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
+ }
+ 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)
+ {
+ m_log.Warn("[PHYSICS]: Unable to collide test an object");
+ return;
+ }
- d.GeomClassID id = d.GeomGetClass(g1);
+ PhysicsActor p1;
+ PhysicsActor p2;
- String name1 = null;
- String name2 = null;
+ for (int i = 0; i < count; i++)
+ {
+ //m_log.Warn("[CCOUNT]: " + count);
+ IntPtr joint;
+ // If we're colliding with terrain, use 'TerrainContact' instead of contact.
+ // allows us to have different settings
- if (!geom_name_map.TryGetValue(g1, out name1))
+ if (!actor_name_map.TryGetValue(g1, out p1))
{
- name1 = "null";
+ p1 = PANull;
}
- if (!geom_name_map.TryGetValue(g2, out name2))
+ if (!actor_name_map.TryGetValue(g2, out p2))
{
- name2 = "null";
+ p2 = PANull;
}
- //if (id == d.GeomClassId.TriMeshClass)
- //{
- // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2);
- //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2);
- //}
+ // We only need to test p2 for 'jump crouch purposes'
+ p2.IsColliding = true;
- // Figure out how many contact points we have
- int count = 0;
- try
+ switch (p1.PhysicsActorType)
{
- //m_log.Warn(g1.ToString() + "|" + g2.ToString());
- count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
- }
- 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)
- {
-
- m_log.Warn("[PHYSICS]: Unable to collide test an object");
- return;
+ case (int)ActorTypes.Agent:
+ p2.CollidingObj = true;
+ break;
+ case (int)ActorTypes.Prim:
+ if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0)
+ p2.CollidingObj = true;
+ break;
+ case (int)ActorTypes.Unknown:
+ p2.CollidingGround = true;
+ break;
+ default:
+ p2.CollidingGround = true;
+ break;
}
- PhysicsActor p1;
- PhysicsActor p2;
+ // we don't want prim or avatar to explode
- for (int i = 0; i < count; i++)
- {
- //m_log.Warn("[CCOUNT]: " + count);
- IntPtr joint;
- // If we're colliding with terrain, use 'TerrainContact' instead of contact.
- // allows us to have different settings
+ #region InterPenetration Handling - Unintended physics explosions
- if (!actor_name_map.TryGetValue(g1, out p1))
+ if (contacts[i].depth >= 0.08f)
+ {
+ //This is disabled at the moment only because it needs more tweaking
+ //It will eventually be uncommented
+
+ if (contacts[i].depth >= 1.00f)
{
- p1 = PANull;
+ //m_log.Debug("[PHYSICS]: " + contacts[i].depth.ToString());
}
- if (!actor_name_map.TryGetValue(g2, out p2))
+
+ //If you interpenetrate a prim with an agent
+ if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
+ p1.PhysicsActorType == (int) ActorTypes.Prim) ||
+ (p1.PhysicsActorType == (int) ActorTypes.Agent &&
+ p2.PhysicsActorType == (int) ActorTypes.Prim))
{
- p2 = PANull;
+ # region disabled code1
+ //contacts[i].depth = contacts[i].depth * 4.15f;
+ /*
+ if (p2.PhysicsActorType == (int) ActorTypes.Agent)
+ {
+ p2.CollidingObj = true;
+ contacts[i].depth = 0.003f;
+ p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f);
+ OdeCharacter character = (OdeCharacter) p2;
+ character.SetPidStatus(true);
+ contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), contacts[i].pos.Y + (p1.Size.Y / 2), contacts[i].pos.Z + (p1.Size.Z / 2));
+
+ }
+ else
+ {
+
+ //contacts[i].depth = 0.0000000f;
+ }
+ if (p1.PhysicsActorType == (int) ActorTypes.Agent)
+ {
+
+ p1.CollidingObj = true;
+ contacts[i].depth = 0.003f;
+ p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f);
+ contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p2.Size.X / 2), contacts[i].pos.Y + (p2.Size.Y / 2), contacts[i].pos.Z + (p2.Size.Z / 2));
+ OdeCharacter character = (OdeCharacter)p1;
+ character.SetPidStatus(true);
+ }
+ else
+ {
+
+ //contacts[i].depth = 0.0000000f;
+ }
+ */
+ #endregion
}
+
- // We only need to test p2 for 'jump crouch purposes'
- p2.IsColliding = true;
-
- switch (p1.PhysicsActorType)
+ // If you interpenetrate a prim with another prim
+ if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim)
{
- case (int)ActorTypes.Agent:
- p2.CollidingObj = true;
- break;
- case (int)ActorTypes.Prim:
- if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0)
- p2.CollidingObj = true;
- break;
- case (int)ActorTypes.Unknown:
- p2.CollidingGround = true;
- break;
- default:
- p2.CollidingGround = true;
- break;
- }
+ #region disabledcode2
+ //OdePrim op1 = (OdePrim)p1;
+ //OdePrim op2 = (OdePrim)p2;
+ //op1.m_collisionscore++;
+ //op2.m_collisionscore++;
+
- // we don't want prim or avatar to explode
+ //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000)
+ //{
+ //op1.m_taintdisable = true;
+ //AddPhysicsActorTaint(p1);
+ //op2.m_taintdisable = true;
+ //AddPhysicsActorTaint(p2);
+ //}
+
+ //if (contacts[i].depth >= 0.25f)
+ //{
+ // Don't collide, one or both prim will expld.
+
- #region InterPenetration Handling - Unintended physics explosions
+ //op1.m_interpenetrationcount++;
+ //op2.m_interpenetrationcount++;
+ //interpenetrations_before_disable = 200;
+ //if (op1.m_interpenetrationcount >= interpenetrations_before_disable)
+ //{
+ //op1.m_taintdisable = true;
+ //AddPhysicsActorTaint(p1);
+ //}
+ //if (op2.m_interpenetrationcount >= interpenetrations_before_disable)
+ //{
+ // op2.m_taintdisable = true;
+ //AddPhysicsActorTaint(p2);
+ //}
- if (contacts[i].depth >= 0.08f)
+
+ //contacts[i].depth = contacts[i].depth / 8f;
+ //contacts[i].normal = new d.Vector3(0, 0, 1);
+ //}
+ //if (op1.m_disabled || op2.m_disabled)
+ //{
+ //Manually disabled objects stay disabled
+ //contacts[i].depth = 0f;
+ //}
+ #endregion
+ }
+ if (contacts[i].depth >= 1.00f)
{
- //This is disabled at the moment only because it needs more tweaking
- //It will eventually be uncommented
-
- if (contacts[i].depth >= 1.00f)
- {
- //m_log.Debug("[PHYSICS]: " + contacts[i].depth.ToString());
- }
-
- //If you interpenetrate a prim with an agent
+ //m_log.Info("[P]: " + contacts[i].depth.ToString());
if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
- p1.PhysicsActorType == (int) ActorTypes.Prim) ||
+ p1.PhysicsActorType == (int) ActorTypes.Unknown) ||
(p1.PhysicsActorType == (int) ActorTypes.Agent &&
- p2.PhysicsActorType == (int) ActorTypes.Prim))
+ p2.PhysicsActorType == (int) ActorTypes.Unknown))
{
- //contacts[i].depth = contacts[i].depth * 4.15f;
- /*
if (p2.PhysicsActorType == (int) ActorTypes.Agent)
- {
- p2.CollidingObj = true;
- contacts[i].depth = 0.003f;
- p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f);
+ {
OdeCharacter character = (OdeCharacter) p2;
+
+ //p2.CollidingObj = true;
+ contacts[i].depth = 0.00000003f;
+ p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 0.5f);
+ contacts[i].pos =
+ new d.Vector3(contacts[i].pos.X + (p1.Size.X/2),
+ contacts[i].pos.Y + (p1.Size.Y/2),
+ contacts[i].pos.Z + (p1.Size.Z/2));
character.SetPidStatus(true);
- contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), contacts[i].pos.Y + (p1.Size.Y / 2), contacts[i].pos.Z + (p1.Size.Z / 2));
-
}
else
{
-
- //contacts[i].depth = 0.0000000f;
}
if (p1.PhysicsActorType == (int) ActorTypes.Agent)
{
-
- p1.CollidingObj = true;
- contacts[i].depth = 0.003f;
- p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f);
- contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p2.Size.X / 2), contacts[i].pos.Y + (p2.Size.Y / 2), contacts[i].pos.Z + (p2.Size.Z / 2));
OdeCharacter character = (OdeCharacter)p1;
+
+ //p2.CollidingObj = true;
+ contacts[i].depth = 0.00000003f;
+ p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 0.5f);
+ contacts[i].pos =
+ new d.Vector3(contacts[i].pos.X + (p1.Size.X/2),
+ contacts[i].pos.Y + (p1.Size.Y/2),
+ contacts[i].pos.Z + (p1.Size.Z/2));
character.SetPidStatus(true);
}
else
{
-
//contacts[i].depth = 0.0000000f;
}
- */
}
-
+ }
+ }
- // If you interpenetrate a prim with another prim
- if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim)
- {
- //OdePrim op1 = (OdePrim)p1;
- //OdePrim op2 = (OdePrim)p2;
- //op1.m_collisionscore++;
- //op2.m_collisionscore++;
-
+ #endregion
- //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000)
- //{
- //op1.m_taintdisable = true;
- //AddPhysicsActorTaint(p1);
- //op2.m_taintdisable = true;
- //AddPhysicsActorTaint(p2);
- //}
-
- //if (contacts[i].depth >= 0.25f)
- //{
- // Don't collide, one or both prim will expld.
-
-
- //op1.m_interpenetrationcount++;
- //op2.m_interpenetrationcount++;
- //interpenetrations_before_disable = 200;
- //if (op1.m_interpenetrationcount >= interpenetrations_before_disable)
- //{
- //op1.m_taintdisable = true;
- //AddPhysicsActorTaint(p1);
- //}
- //if (op2.m_interpenetrationcount >= interpenetrations_before_disable)
- //{
- // op2.m_taintdisable = true;
- //AddPhysicsActorTaint(p2);
- //}
-
-
- //contacts[i].depth = contacts[i].depth / 8f;
- //contacts[i].normal = new d.Vector3(0, 0, 1);
- //}
- //if (op1.m_disabled || op2.m_disabled)
- //{
- //Manually disabled objects stay disabled
- //contacts[i].depth = 0f;
- //}
+ if (contacts[i].depth >= 0f)
+ {
+ // If we're collidng against terrain
+ if (name1 == "Terrain" || name2 == "Terrain")
+ {
+ // If we're moving
+ if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
+ (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
+ {
+ // Use the movement terrain contact
+ AvatarMovementTerrainContact.geom = contacts[i];
+ joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
}
- if (contacts[i].depth >= 1.00f)
+ else
{
- //m_log.Info("[P]: " + contacts[i].depth.ToString());
- if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
- p1.PhysicsActorType == (int) ActorTypes.Unknown) ||
- (p1.PhysicsActorType == (int) ActorTypes.Agent &&
- p2.PhysicsActorType == (int) ActorTypes.Unknown))
- {
- if (p2.PhysicsActorType == (int) ActorTypes.Agent)
- {
- OdeCharacter character = (OdeCharacter) p2;
-
- //p2.CollidingObj = true;
- contacts[i].depth = 0.00000003f;
- p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 0.5f);
- contacts[i].pos =
- new d.Vector3(contacts[i].pos.X + (p1.Size.X/2),
- contacts[i].pos.Y + (p1.Size.Y/2),
- contacts[i].pos.Z + (p1.Size.Z/2));
- character.SetPidStatus(true);
- }
- else
- {
- }
- if (p1.PhysicsActorType == (int) ActorTypes.Agent)
- {
- OdeCharacter character = (OdeCharacter)p1;
-
- //p2.CollidingObj = true;
- contacts[i].depth = 0.00000003f;
- p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 0.5f);
- contacts[i].pos =
- new d.Vector3(contacts[i].pos.X + (p1.Size.X/2),
- contacts[i].pos.Y + (p1.Size.Y/2),
- contacts[i].pos.Z + (p1.Size.Z/2));
- character.SetPidStatus(true);
- }
- else
- {
- //contacts[i].depth = 0.0000000f;
- }
- }
+ // Use the non moving terrain contact
+ TerrainContact.geom = contacts[i];
+ joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
}
}
-
- #endregion
-
- if (contacts[i].depth >= 0f)
+ else
{
- // If we're collidng against terrain
- if (name1 == "Terrain" || name2 == "Terrain")
+ // we're colliding with prim or avatar
+
+ // check if we're moving
+ if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
+ (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
{
- // If we're moving
- if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
- (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
- {
- // Use the movement terrain contact
- AvatarMovementTerrainContact.geom = contacts[i];
- joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
- }
- else
- {
- // Use the non moving terrain contact
- TerrainContact.geom = contacts[i];
- joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
- }
+ // Use the Movement prim contact
+ AvatarMovementprimContact.geom = contacts[i];
+ joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
}
else
{
- // we're colliding with prim or avatar
-
- // check if we're moving
- if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
- (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
- {
- // Use the Movement prim contact
- AvatarMovementprimContact.geom = contacts[i];
- joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
- }
- else
- {
- // Use the non movement contact
- contact.geom = contacts[i];
- joint = d.JointCreateContact(world, contactgroup, ref contact);
- }
+ // Use the non movement contact
+ contact.geom = contacts[i];
+ joint = d.JointCreateContact(world, contactgroup, ref contact);
}
- d.JointAttach(joint, b1, b2);
}
+ d.JointAttach(joint, b1, b2);
+ }
- if (count > 3)
- {
- // If there are more then 3 contact points, it's likely
- // that we've got a pile of objects
- //
- // We don't want to send out hundreds of terse updates over and over again
- // so lets throttle them and send them again after it's somewhat sorted out.
- p2.ThrottleUpdates = true;
- }
- //System.Console.WriteLine(count.ToString());
- //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2);
+ if (count > 3)
+ {
+ // If there are more then 3 contact points, it's likely
+ // that we've got a pile of objects
+ //
+ // We don't want to send out hundreds of terse updates over and over again
+ // so lets throttle them and send them again after it's somewhat sorted out.
+ p2.ThrottleUpdates = true;
}
+ //System.Console.WriteLine(count.ToString());
+ //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2);
}
+
}
- private float GetTerrainHeightAtXY(float x, float y)
+
+ public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount)
{
- return (float)_origheightmap[(int)y * Constants.RegionSize + (int)x];
-
+ /* String name1 = null;
+ String name2 = null;
+ if (!geom_name_map.TryGetValue(trimesh, out name1))
+ {
+ name1 = "null";
+ }
+ if (!geom_name_map.TryGetValue(refObject, out name2))
+ {
+ name2 = "null";
+ }
+
+ m_log.InfoFormat("TriArrayCallback: A collision was detected between {1} and {2}", 0, name1, name2);
+ */
+ return 1;
+ }
+
+ public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex)
+ {
+ String name1 = null;
+ String name2 = null;
+
+ if (!geom_name_map.TryGetValue(trimesh, out name1))
+ {
+ name1 = "null";
+ }
+
+ if (!geom_name_map.TryGetValue(refObject, out name2))
+ {
+ name2 = "null";
+ }
+
+ // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex);
+
+ d.Vector3 v0 = new d.Vector3();
+ d.Vector3 v1 = new d.Vector3();
+ d.Vector3 v2 = new d.Vector3();
+
+ d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2);
+ // m_log.DebugFormat("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z);
+
+ return 1;
}
///
@@ -715,6 +749,17 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+ #endregion
+
+ private float GetTerrainHeightAtXY(float x, float y)
+ {
+ return (float)_origheightmap[(int)y * Constants.RegionSize + (int)x];
+
+
+ }
+
+ #region Add/Remove Entities
+
public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
{
PhysicsVector pos = new PhysicsVector();
@@ -735,6 +780,80 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+ private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation,
+ IMesh mesh, PrimitiveBaseShape pbs, bool isphysical)
+ {
+ PhysicsVector pos = new PhysicsVector();
+ pos.X = position.X;
+ pos.Y = position.Y;
+ pos.Z = position.Z;
+ PhysicsVector siz = new PhysicsVector();
+ siz.X = size.X;
+ siz.Y = size.Y;
+ siz.Z = size.Z;
+ Quaternion rot = new Quaternion();
+ rot.w = rotation.w;
+ rot.x = rotation.x;
+ rot.y = rotation.y;
+ rot.z = rotation.z;
+
+
+
+ OdePrim newPrim;
+ lock (OdeLock)
+ {
+ newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode);
+
+ _prims.Add(newPrim);
+ }
+
+
+ return newPrim;
+ }
+
+ public void addActivePrim(OdePrim activatePrim)
+ {
+ // adds active prim.. (ones that should be iterated over in collisions_optimized
+
+ _activeprims.Add(activatePrim);
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation) //To be removed
+ {
+ return AddPrimShape(primName, pbs, position, size, rotation, false);
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, bool isPhysical)
+ {
+ PhysicsActor result;
+ IMesh mesh = null;
+
+ switch (pbs.ProfileShape)
+ {
+ case ProfileShape.Square:
+ /// support simple box & hollow box now; later, more shapes
+ if (needsMeshing(pbs))
+ {
+ mesh = mesher.CreateMesh(primName, pbs, size);
+ }
+
+ break;
+ }
+
+ result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
+
+
+ return result;
+ }
+
+
+ public void remActivePrim(OdePrim deactivatePrim)
+ {
+ _activeprims.Remove(deactivatePrim);
+ }
+
public override void RemovePrim(PhysicsActor prim)
{
if (prim is OdePrim)
@@ -767,10 +886,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (prim.prim_geom != (IntPtr)0)
{
- while (ode.lockquery())
- {
- }
- ode.dlock(world);
+
+
//System.Threading.Thread.Sleep(20);
prim.ResetTaints();
@@ -846,11 +963,15 @@ namespace OpenSim.Region.Physics.OdePlugin
//}
}
- ode.dunlock(world);
+
}
}
}
+ #endregion
+
+ #region Space Separation Calculation
+
///
/// Takes a space pointer and zeros out the array we're using to hold the spaces
///
@@ -1065,95 +1186,10 @@ namespace OpenSim.Region.Physics.OdePlugin
return returnint;
}
+ #endregion
- private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation,
- IMesh mesh, PrimitiveBaseShape pbs, bool isphysical)
- {
- PhysicsVector pos = new PhysicsVector();
- pos.X = position.X;
- pos.Y = position.Y;
- pos.Z = position.Z;
- PhysicsVector siz = new PhysicsVector();
- siz.X = size.X;
- siz.Y = size.Y;
- siz.Z = size.Z;
- Quaternion rot = new Quaternion();
- rot.w = rotation.w;
- rot.x = rotation.x;
- rot.y = rotation.y;
- rot.z = rotation.z;
-
-
-
- OdePrim newPrim;
- lock (OdeLock)
- {
- newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode);
-
- _prims.Add(newPrim);
- }
-
-
- return newPrim;
- }
-
- public void addActivePrim(OdePrim activatePrim)
- {
- // adds active prim.. (ones that should be iterated over in collisions_optimized
-
- _activeprims.Add(activatePrim);
- }
-
- public void remActivePrim(OdePrim deactivatePrim)
- {
- _activeprims.Remove(deactivatePrim);
- }
-
- public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount)
- {
-/* String name1 = null;
- String name2 = null;
-
- if (!geom_name_map.TryGetValue(trimesh, out name1))
- {
- name1 = "null";
- }
- if (!geom_name_map.TryGetValue(refObject, out name2))
- {
- name2 = "null";
- }
-
- m_log.InfoFormat("TriArrayCallback: A collision was detected between {1} and {2}", 0, name1, name2);
-*/
- return 1;
- }
-
- public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex)
- {
- String name1 = null;
- String name2 = null;
-
- if (!geom_name_map.TryGetValue(trimesh, out name1))
- {
- name1 = "null";
- }
-
- if (!geom_name_map.TryGetValue(refObject, out name2))
- {
- name2 = "null";
- }
-
-// m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex);
-
- d.Vector3 v0 = new d.Vector3();
- d.Vector3 v1 = new d.Vector3();
- d.Vector3 v2 = new d.Vector3();
- d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2);
-// m_log.DebugFormat("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z);
- return 1;
- }
///
/// Routine to figure out if we need to mesh this prim with our mesher
@@ -1183,36 +1219,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return false;
}
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation) //To be removed
- {
- return AddPrimShape(primName, pbs, position, size, rotation, false);
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, bool isPhysical)
- {
- PhysicsActor result;
- IMesh mesh = null;
-
- switch (pbs.ProfileShape)
- {
- case ProfileShape.Square:
- /// support simple box & hollow box now; later, more shapes
- if (needsMeshing(pbs))
- {
- mesh = mesher.CreateMesh(primName, pbs, size);
- }
-
- break;
- }
-
- result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
-
-
- return result;
- }
-
+
///
/// Called after our prim properties are set Scale, position etc.
/// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex
@@ -1224,8 +1231,11 @@ namespace OpenSim.Region.Physics.OdePlugin
if (prim is OdePrim)
{
OdePrim taintedprim = ((OdePrim) prim);
- if (!(_taintedPrim.Contains(taintedprim)))
- _taintedPrim.Add(taintedprim);
+ lock (_taintedPrim)
+ {
+ if (!(_taintedPrim.Contains(taintedprim)))
+ _taintedPrim.Add(taintedprim);
+ }
}
}
@@ -1292,12 +1302,50 @@ namespace OpenSim.Region.Physics.OdePlugin
ode.dlock(world);
try
{
- foreach (OdeCharacter actor in _characters)
+ lock (_characters)
{
- if (actor != null)
- actor.Move(timeStep);
+ foreach (OdeCharacter actor in _characters)
+ {
+ if (actor != null)
+ actor.Move(timeStep);
+ }
}
+
+ bool processedtaints = false;
+
+ lock (_taintedPrim)
+ {
+ foreach (OdePrim prim in _taintedPrim)
+ {
+ if (prim.m_taintremove)
+ {
+ RemovePrimThreadLocked(prim);
+ }
+
+ prim.ProcessTaints(timeStep);
+
+ processedtaints = true;
+ prim.m_collisionscore = 0;
+ }
+
+ if (processedtaints)
+ _taintedPrim = new List();
+
+ }
+
+ lock (_activeprims)
+ {
+ foreach (OdePrim prim in _activeprims)
+ {
+ prim.m_collisionscore = 0;
+ }
+ }
+
+
+
+
+
collision_optimized(timeStep);
d.WorldQuickStep(world, ODE_STEPSIZE);
@@ -1321,47 +1369,29 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
- foreach (OdeCharacter actor in _characters)
- {
- if (actor != null)
- actor.UpdatePositionAndVelocity();
- }
-
- if (!ode.lockquery())
- {
- bool processedtaints = false;
- foreach (OdePrim prim in _taintedPrim)
- {
- if (prim.m_taintremove)
- {
- RemovePrimThreadLocked(prim);
- }
-
- prim.ProcessTaints(timeStep);
-
- processedtaints = true;
- prim.m_collisionscore = 0;
- }
- if (processedtaints)
- _taintedPrim = new List();
- }
- foreach (OdePrim prim in _activeprims)
+ lock (_characters)
{
- prim.m_collisionscore = 0;
+ foreach (OdeCharacter actor in _characters)
+ {
+ if (actor != null)
+ actor.UpdatePositionAndVelocity();
+ }
}
-
-
- if (timeStep < 0.2f)
+ lock (_activeprims)
{
- foreach (OdePrim actor in _activeprims)
+ if (timeStep < 0.2f)
{
- if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag))
+ foreach (OdePrim actor in _activeprims)
{
- actor.UpdatePositionAndVelocity();
+ if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag))
+ {
+ actor.UpdatePositionAndVelocity();
+ }
}
}
}
+
}
return fps;
}
@@ -1375,6 +1405,8 @@ namespace OpenSim.Region.Physics.OdePlugin
// for now we won't be multithreaded
get { return (false); }
}
+
+ #region ODE Specific Terrain Fixes
public float[] ResizeTerrain512NearestNeighbour(float[] heightMap)
{
float[] returnarr = new float[262144];
@@ -1637,11 +1669,12 @@ namespace OpenSim.Region.Physics.OdePlugin
return returnarr;
}
+ #endregion
+
public override void SetTerrain(float[] heightMap)
{
// this._heightmap[i] = (double)heightMap[i];
- // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
- // also, creating a buffer zone of one extra sample all around
+ // dbm (danx0r) -- creating a buffer zone of one extra sample all around
_origheightmap = heightMap;
const uint heightmapWidth = m_regionWidth + 2;
const uint heightmapHeight = m_regionHeight + 2;
@@ -1654,6 +1687,7 @@ namespace OpenSim.Region.Physics.OdePlugin
//Double resolution
heightMap = ResizeTerrain512Interpolation(heightMap);
+
for (int x = 0; x < heightmapWidthSamples; x++)
{
for (int y = 0; y < heightmapHeightSamples; y++)
--
cgit v1.1