aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorTeravus Ovares2009-02-08 03:02:43 +0000
committerTeravus Ovares2009-02-08 03:02:43 +0000
commitb60931b6860760d3f2d50edebddf46c9289b7411 (patch)
tree730a446ed4e81f751062083db4e5a8863a500b90
parent* Fixes colliding with the terrain lower then 0 and higher then 256m (diff)
downloadopensim-SC-b60931b6860760d3f2d50edebddf46c9289b7411.zip
opensim-SC-b60931b6860760d3f2d50edebddf46c9289b7411.tar.gz
opensim-SC-b60931b6860760d3f2d50edebddf46c9289b7411.tar.bz2
opensim-SC-b60931b6860760d3f2d50edebddf46c9289b7411.tar.xz
* 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.
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs65
1 files changed, 53 insertions, 12 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 533464e..bf9d5d8 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -276,6 +276,8 @@ namespace OpenSim.Region.Physics.OdePlugin
276 public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); 276 public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f);
277 public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); 277 public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f);
278 278
279 private volatile int m_global_contactcount = 0;
280
279 /// <summary> 281 /// <summary>
280 /// Initiailizes the scene 282 /// Initiailizes the scene
281 /// Sets many properties that ODE requires to be stable 283 /// Sets many properties that ODE requires to be stable
@@ -832,6 +834,10 @@ namespace OpenSim.Region.Physics.OdePlugin
832 if (!skipThisContact && checkDupe(contacts[i], p2.PhysicsActorType)) 834 if (!skipThisContact && checkDupe(contacts[i], p2.PhysicsActorType))
833 skipThisContact = true; 835 skipThisContact = true;
834 836
837 int maxContactsbeforedeath = 4000;
838 joint = IntPtr.Zero;
839
840
835 if (!skipThisContact) 841 if (!skipThisContact)
836 { 842 {
837 // If we're colliding against terrain 843 // If we're colliding against terrain
@@ -844,23 +850,31 @@ namespace OpenSim.Region.Physics.OdePlugin
844 // Use the movement terrain contact 850 // Use the movement terrain contact
845 AvatarMovementTerrainContact.geom = contacts[i]; 851 AvatarMovementTerrainContact.geom = contacts[i];
846 _perloopContact.Add(contacts[i]); 852 _perloopContact.Add(contacts[i]);
847 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); 853 if (m_global_contactcount < maxContactsbeforedeath)
854 {
855 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
856 m_global_contactcount++;
857 }
848 } 858 }
849 else 859 else
850 { 860 {
851 // Use the non moving terrain contact 861 // Use the non moving terrain contact
852 TerrainContact.geom = contacts[i]; 862 TerrainContact.geom = contacts[i];
853 _perloopContact.Add(contacts[i]); 863 _perloopContact.Add(contacts[i]);
854 joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); 864 if (m_global_contactcount < maxContactsbeforedeath)
865 {
866 joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
867 m_global_contactcount++;
868 }
855 } 869 }
856 //if (p2.PhysicsActorType == (int)ActorTypes.Prim) 870 //if (p2.PhysicsActorType == (int)ActorTypes.Prim)
857 //{ 871 //{
858 //m_log.Debug("[PHYSICS]: prim contacting with ground"); 872 //m_log.Debug("[PHYSICS]: prim contacting with ground");
859 //} 873 //}
860 } 874 }
861 else if (name1 == "Water" || name2 == "Water") 875 else if (name1 == "Water" || name2 == "Water")
862 { 876 {
863 if ((p2.PhysicsActorType == (int)ActorTypes.Prim)) 877 if ((p2.PhysicsActorType == (int) ActorTypes.Prim))
864 { 878 {
865 } 879 }
866 else 880 else
@@ -877,29 +891,49 @@ namespace OpenSim.Region.Physics.OdePlugin
877 } 891 }
878 WaterContact.geom = contacts[i]; 892 WaterContact.geom = contacts[i];
879 _perloopContact.Add(contacts[i]); 893 _perloopContact.Add(contacts[i]);
880 joint = d.JointCreateContact(world, contactgroup, ref WaterContact); 894 if (m_global_contactcount < maxContactsbeforedeath)
881 895 {
896 joint = d.JointCreateContact(world, contactgroup, ref WaterContact);
897 m_global_contactcount++;
898 }
882 //m_log.Info("[PHYSICS]: Prim Water Contact" + contacts[i].depth); 899 //m_log.Info("[PHYSICS]: Prim Water Contact" + contacts[i].depth);
883 } 900 }
884 else 901 else
885 { // we're colliding with prim or avatar 902 {
903 // we're colliding with prim or avatar
886 // check if we're moving 904 // check if we're moving
887 if ((p2.PhysicsActorType == (int)ActorTypes.Agent) && 905 if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
888 (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) 906 (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
889 { 907 {
890 // Use the Movement prim contact 908 // Use the Movement prim contact
891 AvatarMovementprimContact.geom = contacts[i]; 909 AvatarMovementprimContact.geom = contacts[i];
892 _perloopContact.Add(contacts[i]); 910 _perloopContact.Add(contacts[i]);
893 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); 911 if (m_global_contactcount < maxContactsbeforedeath)
912 {
913 joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
914 m_global_contactcount++;
915 }
894 } 916 }
895 else 917 else
896 { // Use the non movement contact 918 {
919 // Use the non movement contact
897 contact.geom = contacts[i]; 920 contact.geom = contacts[i];
898 _perloopContact.Add(contacts[i]); 921 _perloopContact.Add(contacts[i]);
899 joint = d.JointCreateContact(world, contactgroup, ref contact); 922
923 if (m_global_contactcount < maxContactsbeforedeath)
924 {
925 joint = d.JointCreateContact(world, contactgroup, ref contact);
926 m_global_contactcount++;
927 }
900 } 928 }
901 } 929 }
902 d.JointAttach(joint, b1, b2); 930
931 if (m_global_contactcount < maxContactsbeforedeath && joint != IntPtr.Zero) // stack collide!
932 {
933 d.JointAttach(joint, b1, b2);
934 m_global_contactcount++;
935 }
936
903 } 937 }
904 collision_accounting_events(p1, p2, max_collision_depth); 938 collision_accounting_events(p1, p2, max_collision_depth);
905 if (count > geomContactPointsStartthrottle) 939 if (count > geomContactPointsStartthrottle)
@@ -2543,6 +2577,13 @@ namespace OpenSim.Region.Physics.OdePlugin
2543 } 2577 }
2544 } 2578 }
2545 2579
2580 //if (m_global_contactcount > 5)
2581 //{
2582 // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount);
2583 //}
2584
2585 m_global_contactcount = 0;
2586
2546 d.WorldQuickStep(world, ODE_STEPSIZE); 2587 d.WorldQuickStep(world, ODE_STEPSIZE);
2547 d.JointGroupEmpty(contactgroup); 2588 d.JointGroupEmpty(contactgroup);
2548 //ode.dunlock(world); 2589 //ode.dunlock(world);