diff options
author | Teravus Ovares | 2009-02-08 03:02:43 +0000 |
---|---|---|
committer | Teravus Ovares | 2009-02-08 03:02:43 +0000 |
commit | b60931b6860760d3f2d50edebddf46c9289b7411 (patch) | |
tree | 730a446ed4e81f751062083db4e5a8863a500b90 | |
parent | * Fixes colliding with the terrain lower then 0 and higher then 256m (diff) | |
download | opensim-SC_OLD-b60931b6860760d3f2d50edebddf46c9289b7411.zip opensim-SC_OLD-b60931b6860760d3f2d50edebddf46c9289b7411.tar.gz opensim-SC_OLD-b60931b6860760d3f2d50edebddf46c9289b7411.tar.bz2 opensim-SC_OLD-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.cs | 65 |
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); |