* Cleaned up some locking on the ODEPlugin to make it more developer friendly

* Expect the occasional deadlock?
0.6.0-stable
Teravus Ovares 2008-03-09 15:43:01 +00:00
parent 7981c45750
commit 081b2ac34e
2 changed files with 534 additions and 543 deletions

View File

@ -293,6 +293,8 @@ namespace OpenSim.Region.Physics.OdePlugin
_parent_scene.addActivePrim(this); _parent_scene.addActivePrim(this);
} }
#region Mass Calculation
private float CalculateMass() private float CalculateMass()
{ {
float volume = 0; float volume = 0;
@ -598,6 +600,9 @@ namespace OpenSim.Region.Physics.OdePlugin
return returnMass; return returnMass;
} }
#endregion
public void setMass() public void setMass()
{ {
if (Body != (IntPtr) 0) if (Body != (IntPtr) 0)
@ -734,10 +739,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private void changelink(float timestep) private void changelink(float timestep)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
if (_parent == null && m_taintparent != null) if (_parent == null && m_taintparent != null)
{ {
@ -763,17 +764,13 @@ namespace OpenSim.Region.Physics.OdePlugin
m_linkJoint = (IntPtr)0; m_linkJoint = (IntPtr)0;
} }
ode.dunlock(_parent_scene.world);
_parent = m_taintparent; _parent = m_taintparent;
} }
private void changeSelectedStatus(float timestep) private void changeSelectedStatus(float timestep)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
if (m_taintselected) if (m_taintselected)
{ {
@ -831,7 +828,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
ode.dunlock(_parent_scene.world);
resetCollisionAccounting(); resetCollisionAccounting();
m_isSelected = m_taintselected; m_isSelected = m_taintselected;
} }
@ -860,10 +857,8 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
public void changeadd(float timestep) public void changeadd(float timestep)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_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.geom_name_map[prim_geom] = this.m_primName;
_parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
@ -1004,10 +999,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
public void Move(float timestep) public void Move(float timestep)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
if (m_isphysical) if (m_isphysical)
@ -1057,7 +1049,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceAdd(m_targetSpace, prim_geom); d.SpaceAdd(m_targetSpace, prim_geom);
} }
} }
ode.dunlock(_parent_scene.world);
changeSelectedStatus(timestep); changeSelectedStatus(timestep);
@ -1067,10 +1059,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public void rotate(float timestep) public void rotate(float timestep)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
d.Quaternion myrot = new d.Quaternion(); d.Quaternion myrot = new d.Quaternion();
myrot.W = _orientation.w; myrot.W = _orientation.w;
@ -1083,8 +1072,6 @@ namespace OpenSim.Region.Physics.OdePlugin
d.BodySetQuaternion(Body, ref myrot); d.BodySetQuaternion(Body, ref myrot);
} }
ode.dunlock(_parent_scene.world);
resetCollisionAccounting(); resetCollisionAccounting();
m_taintrot = _orientation; m_taintrot = _orientation;
} }
@ -1098,29 +1085,21 @@ namespace OpenSim.Region.Physics.OdePlugin
public void changedisable(float timestep) public void changedisable(float timestep)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
m_disabled = true; m_disabled = true;
if (Body != (IntPtr)0) if (Body != (IntPtr)0)
{ {
d.BodyDisable(Body); d.BodyDisable(Body);
Body = (IntPtr)0; Body = (IntPtr)0;
} }
ode.dunlock(_parent_scene.world);
m_taintdisable = false; m_taintdisable = false;
} }
public void changePhysicsStatus(float timestep) public void changePhysicsStatus(float timestep)
{ {
lock (ode)
{
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
if (m_isphysical == true) if (m_isphysical == true)
{ {
@ -1137,9 +1116,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
ode.dunlock(_parent_scene.world);
}
changeSelectedStatus(timestep); changeSelectedStatus(timestep);
resetCollisionAccounting(); resetCollisionAccounting();
@ -1148,10 +1124,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public void changesize(float timestamp) public void changesize(float timestamp)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
//if (!_parent_scene.geom_name_map.ContainsKey(prim_geom)) //if (!_parent_scene.geom_name_map.ContainsKey(prim_geom))
//{ //{
// m_taintsize = _size; // m_taintsize = _size;
@ -1311,8 +1284,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_parent_scene.geom_name_map[prim_geom] = oldname; _parent_scene.geom_name_map[prim_geom] = oldname;
ode.dunlock(_parent_scene.world);
changeSelectedStatus(timestamp); changeSelectedStatus(timestamp);
resetCollisionAccounting(); resetCollisionAccounting();
@ -1321,11 +1292,6 @@ namespace OpenSim.Region.Physics.OdePlugin
public void changeshape(float timestamp) public void changeshape(float timestamp)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
string oldname = _parent_scene.geom_name_map[prim_geom]; string oldname = _parent_scene.geom_name_map[prim_geom];
@ -1471,8 +1437,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_parent_scene.geom_name_map[prim_geom] = oldname; _parent_scene.geom_name_map[prim_geom] = oldname;
ode.dunlock(_parent_scene.world);
changeSelectedStatus(timestamp); changeSelectedStatus(timestamp);
resetCollisionAccounting(); resetCollisionAccounting();
@ -1483,10 +1447,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (!m_isSelected) if (!m_isSelected)
{ {
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
lock (m_forcelist) lock (m_forcelist)
@ -1505,7 +1466,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_forcelist.Clear(); m_forcelist.Clear();
} }
ode.dunlock(_parent_scene.world);
m_collisionscore = 0; m_collisionscore = 0;
m_interpenetrationcount = 0; m_interpenetrationcount = 0;
@ -1517,12 +1477,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (!m_isSelected) if (!m_isSelected)
{ {
lock (ode)
{
while (ode.lockquery())
{
}
ode.dlock(_parent_scene.world);
System.Threading.Thread.Sleep(20); System.Threading.Thread.Sleep(20);
if (IsPhysical) if (IsPhysical)
@ -1533,8 +1488,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
ode.dunlock(_parent_scene.world);
}
//resetCollisionAccounting(); //resetCollisionAccounting();
} }
m_taintVelocity = PhysicsVector.Zero; 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) if (l_position.X > 255.95f || l_position.X < 0f || l_position.Y > 255.95f || l_position.Y < 0f)
{ {
base.RaiseOutOfBounds(_position); base.RaiseOutOfBounds(_position);
}
//if (m_crossingfailures < 5) //if (m_crossingfailures < 5)
//{ //{
//base.RequestPhysicsterseUpdate(); //base.RequestPhysicsterseUpdate();
//} //}
//else
//{
//base.RaiseOutOfBounds(_position);
//} //}
}
if (l_position.Z < 0) if (l_position.Z < 0)
{ {

View File

@ -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 // Initialize the mesh plugin
public override void Initialise(IMesher meshmerizer) public override void Initialise(IMesher meshmerizer)
{ {
@ -245,15 +238,9 @@ namespace OpenSim.Region.Physics.OdePlugin
internal void waitForSpaceUnlock(IntPtr space) internal void waitForSpaceUnlock(IntPtr space)
{ {
while (d.SpaceLockQuery(space)){ } // Wait and do nothing
while (d.SpaceLockQuery(space))
{
} }
}
/// <summary> /// <summary>
/// Debug space message for printing the space that a prim/avatar is in. /// Debug space message for printing the space that a prim/avatar is in.
/// </summary> /// </summary>
@ -264,6 +251,8 @@ namespace OpenSim.Region.Physics.OdePlugin
return calculateSpaceForGeom(pos).ToString(); return calculateSpaceForGeom(pos).ToString();
} }
#region Collision Detection
/// <summary> /// <summary>
/// This is our near callback. A geometry is near a body /// This is our near callback. A geometry is near a body
/// </summary> /// </summary>
@ -299,9 +288,10 @@ namespace OpenSim.Region.Physics.OdePlugin
//Collide all geoms in each space.. //Collide all geoms in each space..
//if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
//if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
return;
} }
else
{
// Colliding Geom To Geom // Colliding Geom To Geom
// This portion of the function 'was' blatantly ripped off from BoxStack.cs // This portion of the function 'was' blatantly ripped off from BoxStack.cs
if (g1 == (IntPtr)0 || g2 == (IntPtr)0) if (g1 == (IntPtr)0 || g2 == (IntPtr)0)
@ -417,6 +407,7 @@ namespace OpenSim.Region.Physics.OdePlugin
(p1.PhysicsActorType == (int) ActorTypes.Agent && (p1.PhysicsActorType == (int) ActorTypes.Agent &&
p2.PhysicsActorType == (int) ActorTypes.Prim)) p2.PhysicsActorType == (int) ActorTypes.Prim))
{ {
# region disabled code1
//contacts[i].depth = contacts[i].depth * 4.15f; //contacts[i].depth = contacts[i].depth * 4.15f;
/* /*
if (p2.PhysicsActorType == (int) ActorTypes.Agent) if (p2.PhysicsActorType == (int) ActorTypes.Agent)
@ -450,12 +441,14 @@ namespace OpenSim.Region.Physics.OdePlugin
//contacts[i].depth = 0.0000000f; //contacts[i].depth = 0.0000000f;
} }
*/ */
#endregion
} }
// If you interpenetrate a prim with another prim // If you interpenetrate a prim with another prim
if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim) if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim)
{ {
#region disabledcode2
//OdePrim op1 = (OdePrim)p1; //OdePrim op1 = (OdePrim)p1;
//OdePrim op2 = (OdePrim)p2; //OdePrim op2 = (OdePrim)p2;
//op1.m_collisionscore++; //op1.m_collisionscore++;
@ -498,6 +491,7 @@ namespace OpenSim.Region.Physics.OdePlugin
//Manually disabled objects stay disabled //Manually disabled objects stay disabled
//contacts[i].depth = 0f; //contacts[i].depth = 0f;
//} //}
#endregion
} }
if (contacts[i].depth >= 1.00f) if (contacts[i].depth >= 1.00f)
{ {
@ -600,13 +594,53 @@ namespace OpenSim.Region.Physics.OdePlugin
//System.Console.WriteLine(count.ToString()); //System.Console.WriteLine(count.ToString());
//System.Console.WriteLine("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);
} }
} }
}
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;
} }
/// <summary> /// <summary>
@ -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) public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
{ {
PhysicsVector pos = new PhysicsVector(); 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) public override void RemovePrim(PhysicsActor prim)
{ {
if (prim is OdePrim) if (prim is OdePrim)
@ -767,10 +886,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (prim.prim_geom != (IntPtr)0) if (prim.prim_geom != (IntPtr)0)
{ {
while (ode.lockquery())
{
}
ode.dlock(world);
//System.Threading.Thread.Sleep(20); //System.Threading.Thread.Sleep(20);
prim.ResetTaints(); prim.ResetTaints();
@ -846,11 +963,15 @@ namespace OpenSim.Region.Physics.OdePlugin
//} //}
} }
ode.dunlock(world);
} }
} }
} }
#endregion
#region Space Separation Calculation
/// <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
/// </summary> /// </summary>
@ -1065,95 +1186,10 @@ namespace OpenSim.Region.Physics.OdePlugin
return returnint; 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;
}
/// <summary> /// <summary>
/// Routine to figure out if we need to mesh this prim with our mesher /// Routine to figure out if we need to mesh this prim with our mesher
@ -1183,35 +1219,6 @@ namespace OpenSim.Region.Physics.OdePlugin
return false; 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;
}
/// <summary> /// <summary>
/// Called after our prim properties are set Scale, position etc. /// Called after our prim properties are set Scale, position etc.
@ -1224,10 +1231,13 @@ namespace OpenSim.Region.Physics.OdePlugin
if (prim is OdePrim) if (prim is OdePrim)
{ {
OdePrim taintedprim = ((OdePrim) prim); OdePrim taintedprim = ((OdePrim) prim);
lock (_taintedPrim)
{
if (!(_taintedPrim.Contains(taintedprim))) if (!(_taintedPrim.Contains(taintedprim)))
_taintedPrim.Add(taintedprim); _taintedPrim.Add(taintedprim);
} }
} }
}
/// <summary> /// <summary>
/// This is our main simulate loop /// This is our main simulate loop
@ -1291,12 +1301,50 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
ode.dlock(world); ode.dlock(world);
try try
{
lock (_characters)
{ {
foreach (OdeCharacter actor in _characters) foreach (OdeCharacter actor in _characters)
{ {
if (actor != null) if (actor != null)
actor.Move(timeStep); 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<OdePrim>();
}
lock (_activeprims)
{
foreach (OdePrim prim in _activeprims)
{
prim.m_collisionscore = 0;
}
}
collision_optimized(timeStep); collision_optimized(timeStep);
@ -1321,37 +1369,17 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
lock (_characters)
{
foreach (OdeCharacter actor in _characters) foreach (OdeCharacter actor in _characters)
{ {
if (actor != null) if (actor != null)
actor.UpdatePositionAndVelocity(); actor.UpdatePositionAndVelocity();
} }
if (!ode.lockquery())
{
bool processedtaints = false;
foreach (OdePrim prim in _taintedPrim)
{
if (prim.m_taintremove)
{
RemovePrimThreadLocked(prim);
} }
prim.ProcessTaints(timeStep); lock (_activeprims)
processedtaints = true;
prim.m_collisionscore = 0;
}
if (processedtaints)
_taintedPrim = new List<OdePrim>();
}
foreach (OdePrim prim in _activeprims)
{ {
prim.m_collisionscore = 0;
}
if (timeStep < 0.2f) if (timeStep < 0.2f)
{ {
foreach (OdePrim actor in _activeprims) foreach (OdePrim actor in _activeprims)
@ -1363,6 +1391,8 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
} }
}
return fps; return fps;
} }
@ -1375,6 +1405,8 @@ namespace OpenSim.Region.Physics.OdePlugin
// for now we won't be multithreaded // for now we won't be multithreaded
get { return (false); } get { return (false); }
} }
#region ODE Specific Terrain Fixes
public float[] ResizeTerrain512NearestNeighbour(float[] heightMap) public float[] ResizeTerrain512NearestNeighbour(float[] heightMap)
{ {
float[] returnarr = new float[262144]; float[] returnarr = new float[262144];
@ -1637,11 +1669,12 @@ namespace OpenSim.Region.Physics.OdePlugin
return returnarr; return returnarr;
} }
#endregion
public override void SetTerrain(float[] heightMap) public override void SetTerrain(float[] heightMap)
{ {
// this._heightmap[i] = (double)heightMap[i]; // this._heightmap[i] = (double)heightMap[i];
// dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...) // dbm (danx0r) -- creating a buffer zone of one extra sample all around
// also, creating a buffer zone of one extra sample all around
_origheightmap = heightMap; _origheightmap = heightMap;
const uint heightmapWidth = m_regionWidth + 2; const uint heightmapWidth = m_regionWidth + 2;
const uint heightmapHeight = m_regionHeight + 2; const uint heightmapHeight = m_regionHeight + 2;
@ -1654,6 +1687,7 @@ namespace OpenSim.Region.Physics.OdePlugin
//Double resolution //Double resolution
heightMap = ResizeTerrain512Interpolation(heightMap); heightMap = ResizeTerrain512Interpolation(heightMap);
for (int x = 0; x < heightmapWidthSamples; x++) for (int x = 0; x < heightmapWidthSamples; x++)
{ {
for (int y = 0; y < heightmapHeightSamples; y++) for (int y = 0; y < heightmapHeightSamples; y++)