* Limit the total number of joints created per frame to the maximum possible without causing a stack collision.
* This fixes crashing on large sets of physical prims because of stack collisions (assuming you follow the directions on linux for starting ode with ulimit). After the maximum joints are created, objects will start to fall through the ground and be disabled. Not the best solution, but it's better then a crash caused by a stack collision with the process exceeding the maximum available memory/recursions per thread. * Make a clean region, make a stack of 5000 prim, 20 layers high. Make them physical, *SLOW*, but no crash.0.6.3-post-fixes
parent
08a9a85376
commit
b60931b686
|
@ -276,6 +276,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f);
|
||||
public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f);
|
||||
|
||||
private volatile int m_global_contactcount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Initiailizes the scene
|
||||
/// Sets many properties that ODE requires to be stable
|
||||
|
@ -832,6 +834,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
if (!skipThisContact && checkDupe(contacts[i], p2.PhysicsActorType))
|
||||
skipThisContact = true;
|
||||
|
||||
int maxContactsbeforedeath = 4000;
|
||||
joint = IntPtr.Zero;
|
||||
|
||||
|
||||
if (!skipThisContact)
|
||||
{
|
||||
// If we're colliding against terrain
|
||||
|
@ -844,23 +850,31 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
// Use the movement terrain contact
|
||||
AvatarMovementTerrainContact.geom = contacts[i];
|
||||
_perloopContact.Add(contacts[i]);
|
||||
joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
|
||||
if (m_global_contactcount < maxContactsbeforedeath)
|
||||
{
|
||||
joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
|
||||
m_global_contactcount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the non moving terrain contact
|
||||
TerrainContact.geom = contacts[i];
|
||||
_perloopContact.Add(contacts[i]);
|
||||
joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
|
||||
if (m_global_contactcount < maxContactsbeforedeath)
|
||||
{
|
||||
joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
|
||||
m_global_contactcount++;
|
||||
}
|
||||
}
|
||||
//if (p2.PhysicsActorType == (int)ActorTypes.Prim)
|
||||
//{
|
||||
//m_log.Debug("[PHYSICS]: prim contacting with ground");
|
||||
//m_log.Debug("[PHYSICS]: prim contacting with ground");
|
||||
//}
|
||||
}
|
||||
else if (name1 == "Water" || name2 == "Water")
|
||||
{
|
||||
if ((p2.PhysicsActorType == (int)ActorTypes.Prim))
|
||||
if ((p2.PhysicsActorType == (int) ActorTypes.Prim))
|
||||
{
|
||||
}
|
||||
else
|
||||
|
@ -877,29 +891,49 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
WaterContact.geom = contacts[i];
|
||||
_perloopContact.Add(contacts[i]);
|
||||
joint = d.JointCreateContact(world, contactgroup, ref WaterContact);
|
||||
|
||||
if (m_global_contactcount < maxContactsbeforedeath)
|
||||
{
|
||||
joint = d.JointCreateContact(world, contactgroup, ref WaterContact);
|
||||
m_global_contactcount++;
|
||||
}
|
||||
//m_log.Info("[PHYSICS]: Prim Water Contact" + contacts[i].depth);
|
||||
}
|
||||
else
|
||||
{ // we're colliding with prim or avatar
|
||||
{
|
||||
// we're colliding with prim or avatar
|
||||
// check if we're moving
|
||||
if ((p2.PhysicsActorType == (int)ActorTypes.Agent) &&
|
||||
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];
|
||||
_perloopContact.Add(contacts[i]);
|
||||
joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
|
||||
if (m_global_contactcount < maxContactsbeforedeath)
|
||||
{
|
||||
joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
|
||||
m_global_contactcount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Use the non movement contact
|
||||
{
|
||||
// Use the non movement contact
|
||||
contact.geom = contacts[i];
|
||||
_perloopContact.Add(contacts[i]);
|
||||
joint = d.JointCreateContact(world, contactgroup, ref contact);
|
||||
|
||||
if (m_global_contactcount < maxContactsbeforedeath)
|
||||
{
|
||||
joint = d.JointCreateContact(world, contactgroup, ref contact);
|
||||
m_global_contactcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
d.JointAttach(joint, b1, b2);
|
||||
|
||||
if (m_global_contactcount < maxContactsbeforedeath && joint != IntPtr.Zero) // stack collide!
|
||||
{
|
||||
d.JointAttach(joint, b1, b2);
|
||||
m_global_contactcount++;
|
||||
}
|
||||
|
||||
}
|
||||
collision_accounting_events(p1, p2, max_collision_depth);
|
||||
if (count > geomContactPointsStartthrottle)
|
||||
|
@ -2543,6 +2577,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
}
|
||||
|
||||
//if (m_global_contactcount > 5)
|
||||
//{
|
||||
// m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount);
|
||||
//}
|
||||
|
||||
m_global_contactcount = 0;
|
||||
|
||||
d.WorldQuickStep(world, ODE_STEPSIZE);
|
||||
d.JointGroupEmpty(contactgroup);
|
||||
//ode.dunlock(world);
|
||||
|
|
Loading…
Reference in New Issue