aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs315
1 files changed, 89 insertions, 226 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 2ba5940..f8d7195 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -178,7 +178,9 @@ namespace OpenSim.Region.Physics.OdePlugin
178 public changes what; 178 public changes what;
179 public Object arg; 179 public Object arg;
180 } 180 }
181 181
182
183
182 public class OdeScene : PhysicsScene 184 public class OdeScene : PhysicsScene
183 { 185 {
184 private readonly ILog m_log; 186 private readonly ILog m_log;
@@ -301,6 +303,8 @@ namespace OpenSim.Region.Physics.OdePlugin
301 public IntPtr StaticSpace; // space for the static things around 303 public IntPtr StaticSpace; // space for the static things around
302 public IntPtr GroundSpace; // space for ground 304 public IntPtr GroundSpace; // space for ground
303 305
306 public IntPtr SharedRay;
307
304 // some speedup variables 308 // some speedup variables
305 private int spaceGridMaxX; 309 private int spaceGridMaxX;
306 private int spaceGridMaxY; 310 private int spaceGridMaxY;
@@ -428,6 +432,8 @@ namespace OpenSim.Region.Physics.OdePlugin
428 contactgroup = d.JointGroupCreate(0); 432 contactgroup = d.JointGroupCreate(0);
429 //contactgroup 433 //contactgroup
430 434
435 SharedRay = d.CreateRay(TopSpace, 1.0f);
436
431 d.WorldSetAutoDisableFlag(world, false); 437 d.WorldSetAutoDisableFlag(world, false);
432 } 438 }
433 } 439 }
@@ -733,35 +739,35 @@ namespace OpenSim.Region.Physics.OdePlugin
733 739
734 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 740 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
735 return; 741 return;
736/* 742 /*
737// debug 743 // debug
738 PhysicsActor dp2; 744 PhysicsActor dp2;
739 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass) 745 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
740 { 746 {
741 d.AABB aabb; 747 d.AABB aabb;
742 d.GeomGetAABB(g2, out aabb); 748 d.GeomGetAABB(g2, out aabb);
743 float x = aabb.MaxX - aabb.MinX; 749 float x = aabb.MaxX - aabb.MinX;
744 float y = aabb.MaxY - aabb.MinY; 750 float y = aabb.MaxY - aabb.MinY;
745 float z = aabb.MaxZ - aabb.MinZ; 751 float z = aabb.MaxZ - aabb.MinZ;
746 if (x > 60.0f || y > 60.0f || z > 60.0f) 752 if (x > 60.0f || y > 60.0f || z > 60.0f)
747 { 753 {
748 if (!actor_name_map.TryGetValue(g2, out dp2)) 754 if (!actor_name_map.TryGetValue(g2, out dp2))
749 m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2"); 755 m_log.WarnFormat("[PHYSICS]: failed actor mapping for geom 2");
750 else 756 else
751 m_log.WarnFormat("[PHYSICS]: land versus large prim geo {0},size {1}, AABBsize <{2},{3},{4}>, at {5} ori {6},({7})", 757 m_log.WarnFormat("[PHYSICS]: land versus large prim geo {0},size {1}, AABBsize <{2},{3},{4}>, at {5} ori {6},({7})",
752 dp2.Name, dp2.Size, x, y, z, 758 dp2.Name, dp2.Size, x, y, z,
753 dp2.Position.ToString(), 759 dp2.Position.ToString(),
754 dp2.Orientation.ToString(), 760 dp2.Orientation.ToString(),
755 dp2.Orientation.Length()); 761 dp2.Orientation.Length());
756 return; 762 return;
757 } 763 }
758 } 764 }
759// 765 //
760*/ 766 */
761 767
762 768
763 if(d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || 769 if (d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc ||
764 d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc) 770 d.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc)
765 { 771 {
766 int cflags; 772 int cflags;
767 unchecked 773 unchecked
@@ -776,7 +782,7 @@ namespace OpenSim.Region.Physics.OdePlugin
776 catch (SEHException) 782 catch (SEHException)
777 { 783 {
778 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."); 784 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.");
779// ode.drelease(world); 785 // ode.drelease(world);
780 base.TriggerPhysicsBasedRestart(); 786 base.TriggerPhysicsBasedRestart();
781 } 787 }
782 catch (Exception e) 788 catch (Exception e)
@@ -816,26 +822,25 @@ namespace OpenSim.Region.Physics.OdePlugin
816 822
817 // get first contact 823 // get first contact
818 d.ContactGeom curContact = new d.ContactGeom(); 824 d.ContactGeom curContact = new d.ContactGeom();
825
819 if (!GetCurContactGeom(0, ref curContact)) 826 if (!GetCurContactGeom(0, ref curContact))
820 return; 827 return;
821 // for now it's the one with max depth 828
822 ContactPoint maxDepthContact = new ContactPoint(
823 new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z),
824 new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z),
825 curContact.depth
826 );
827 // do volume detection case 829 // do volume detection case
828 if ( 830 if ((p1.IsVolumeDtc || p2.IsVolumeDtc))
829 (p1.IsVolumeDtc || p2.IsVolumeDtc))
830 { 831 {
832 ContactPoint maxDepthContact = new ContactPoint(
833 new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z),
834 new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z),
835 curContact.depth, false
836 );
837
831 collision_accounting_events(p1, p2, maxDepthContact); 838 collision_accounting_events(p1, p2, maxDepthContact);
832 return; 839 return;
833 } 840 }
834 841
835 // big messy collision analises 842 // big messy collision analises
836 843
837 Vector3 normoverride = Vector3.Zero; //damm c#
838
839 float mu = 0; 844 float mu = 0;
840 float bounce = 0; 845 float bounce = 0;
841 float cfm = 0.0001f; 846 float cfm = 0.0001f;
@@ -846,36 +851,15 @@ namespace OpenSim.Region.Physics.OdePlugin
846 ContactData contactdata1 = new ContactData(0, 0, false); 851 ContactData contactdata1 = new ContactData(0, 0, false);
847 ContactData contactdata2 = new ContactData(0, 0, false); 852 ContactData contactdata2 = new ContactData(0, 0, false);
848 853
849 bool dop1foot = false; 854 bool dop1ava = false;
850 bool dop2foot = false; 855 bool dop2ava = false;
851 bool ignore = false; 856 bool ignore = false;
852 bool AvanormOverride = false;
853 857
854 switch (p1.PhysicsActorType) 858 switch (p1.PhysicsActorType)
855 { 859 {
856 case (int)ActorTypes.Agent: 860 case (int)ActorTypes.Agent:
857 { 861 {
858 dop1foot = true; 862 dop1ava = true;
859
860 AvanormOverride = true;
861 Vector3 tmp = p2.Position - p1.Position;
862 normoverride = p2.Velocity - p1.Velocity;
863 mu = normoverride.LengthSquared();
864
865 if (mu > 1e-6)
866 {
867 mu = 1.0f / (float)Math.Sqrt(mu);
868 normoverride *= mu;
869 mu = Vector3.Dot(tmp, normoverride);
870 if (mu > 0)
871 normoverride *= -1;
872 }
873 else
874 {
875 tmp.Normalize();
876 normoverride = -tmp;
877 }
878
879 switch (p2.PhysicsActorType) 863 switch (p2.PhysicsActorType)
880 { 864 {
881 case (int)ActorTypes.Agent: 865 case (int)ActorTypes.Agent:
@@ -886,7 +870,6 @@ namespace OpenSim.Region.Physics.OdePlugin
886 case (int)ActorTypes.Prim: 870 case (int)ActorTypes.Prim:
887 if (p2.Velocity.LengthSquared() > 0.0f) 871 if (p2.Velocity.LengthSquared() > 0.0f)
888 p2.CollidingObj = true; 872 p2.CollidingObj = true;
889 dop1foot = true;
890 break; 873 break;
891 874
892 default: 875 default:
@@ -901,33 +884,8 @@ namespace OpenSim.Region.Physics.OdePlugin
901 { 884 {
902 case (int)ActorTypes.Agent: 885 case (int)ActorTypes.Agent:
903 886
887 dop2ava = true;
904 888
905 dop2foot = true;
906
907 AvanormOverride = true;
908
909 Vector3 tmp = p2.Position - p1.Position;
910 normoverride = p2.Velocity - p1.Velocity;
911 mu = normoverride.LengthSquared();
912 if (mu > 1e-6)
913 {
914 mu = 1.0f / (float)Math.Sqrt(mu);
915 normoverride *= mu;
916 mu = Vector3.Dot(tmp, normoverride);
917 if (mu > 0)
918 normoverride *= -1;
919 }
920 else
921 {
922 tmp.Normalize();
923 normoverride = -tmp;
924 }
925
926 bounce = 0;
927 mu = 0;
928 cfm = 0.0001f;
929
930 dop2foot = true;
931 if (p1.Velocity.LengthSquared() > 0.0f) 889 if (p1.Velocity.LengthSquared() > 0.0f)
932 p1.CollidingObj = true; 890 p1.CollidingObj = true;
933 break; 891 break;
@@ -1032,170 +990,78 @@ namespace OpenSim.Region.Physics.OdePlugin
1032 default: 990 default:
1033 break; 991 break;
1034 } 992 }
993
1035 if (ignore) 994 if (ignore)
1036 return; 995 return;
1037 996
1038 IntPtr Joint;
1039 997
1040 bool FeetCollision = false; 998 d.ContactGeom maxContact = curContact;
999// if (IgnoreNegSides && curContact.side1 < 0)
1000// maxContact.depth = float.MinValue;
1001
1002 d.ContactGeom minContact = curContact;
1003// if (IgnoreNegSides && curContact.side1 < 0)
1004// minContact.depth = float.MaxValue;
1041 1005
1042 int i = 0; 1006 IntPtr Joint;
1007 bool FeetCollision = false;
1043 int ncontacts = 0; 1008 int ncontacts = 0;
1044 while(true)
1045 {
1046 1009
1047 if (IgnoreNegSides && curContact.side1 < 0)
1048 {
1049 if (++i >= count)
1050 break;
1051 1010
1052 if (!GetCurContactGeom(i, ref curContact)) 1011 int i = 0;
1053 break;
1054 }
1055 else
1056 1012
1013 while (true)
1057 { 1014 {
1058 if(dop1foot) 1015 if (m_global_contactcount >= maxContactsbeforedeath)
1016 break;
1017
1018// if (!(IgnoreNegSides && curContact.side1 < 0))
1059 { 1019 {
1060 if (!(((OdeCharacter)p1).Collide(g1, false, ref curContact, ref FeetCollision))) 1020 bool noskip = true;
1021 if (dop1ava)
1061 { 1022 {
1062 if (++i >= count) 1023 if (!(((OdeCharacter)p1).Collide(g1,false, ref curContact, ref FeetCollision)))
1063 break; 1024
1064 else 1025 noskip = false;
1065 continue;
1066 } 1026 }
1067 } 1027 else if (dop2ava)
1068 else if(dop2foot)
1069 {
1070 if (!(((OdeCharacter)p2).Collide(g2, true, ref curContact, ref FeetCollision)))
1071 { 1028 {
1072 if (++i >= count) 1029 if (!(((OdeCharacter)p2).Collide(g2,true, ref curContact, ref FeetCollision)))
1073 break; 1030 noskip = false;
1074 else
1075 continue;
1076 } 1031 }
1077 }
1078 1032
1079/* 1033 if (noskip)
1080 if (AvanormOverride)
1081 {
1082 if (curContact.depth > 0.3f)
1083 { 1034 {
1084 if (dop1foot && (p1.Position.Z - curContact.pos.Z) > (p1.Size.Z - avCapRadius) * 0.5f) 1035 m_global_contactcount++;
1085 p1.IsColliding = true; 1036 ncontacts++;
1086 if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f)
1087 p2.IsColliding = true;
1088 curContact.normal.X = normoverride.X;
1089 curContact.normal.Y = normoverride.Y;
1090 curContact.normal.Z = normoverride.Z;
1091 }
1092 1037
1093 else 1038 Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale);
1094 { 1039 d.JointAttach(Joint, b1, b2);
1095 if (dop1foot)
1096 {
1097 float sz = p1.Size.Z;
1098 Vector3 vtmp = p1.Position;
1099 float ppos = curContact.pos.Z - vtmp.Z + (sz - avCapRadius) * 0.5f;
1100 if (ppos > 0f)
1101 {
1102 if (!p1.Flying)
1103 {
1104 d.AABB aabb;
1105 d.GeomGetAABB(g2, out aabb);
1106 float tmp = vtmp.Z - sz * .18f;
1107
1108 if (aabb.MaxZ < tmp)
1109 {
1110 vtmp.X = curContact.pos.X - vtmp.X;
1111 vtmp.Y = curContact.pos.Y - vtmp.Y;
1112 vtmp.Z = -0.2f;
1113 vtmp.Normalize();
1114 curContact.normal.X = vtmp.X;
1115 curContact.normal.Y = vtmp.Y;
1116 curContact.normal.Z = vtmp.Z;
1117 }
1118 }
1119 }
1120 else
1121 p1.IsColliding = true;
1122 1040
1123 } 1041 if (curContact.depth > maxContact.depth)
1042 maxContact = curContact;
1124 1043
1125 if (dop2foot) 1044 if (curContact.depth < minContact.depth)
1126 { 1045 minContact = curContact;
1127 float sz = p2.Size.Z;
1128 Vector3 vtmp = p2.Position;
1129 vtmp.Z -= sz * 0.5f;
1130 vtmp.Z += 0.5f;
1131 float ppos = vtmp.Z - curContact.pos.Z;
1132 if (ppos > 0f)
1133 {
1134 if (!p2.Flying)
1135 {
1136 float tmp = vtmp.Z - sz * .18f;
1137 vtmp.X = curContact.pos.X - vtmp.X;
1138 vtmp.Y = curContact.pos.Y - vtmp.Y;
1139 vtmp.Z = curContact.pos.Z - vtmp.Z;
1140 vtmp.Normalize();
1141 curContact.normal.X = vtmp.X;
1142 curContact.normal.Y = vtmp.Y;
1143 curContact.normal.Z = vtmp.Z;
1144 }
1145 }
1146// else
1147 p2.IsColliding = true;
1148
1149 }
1150 } 1046 }
1151 } 1047 }
1152*/
1153 ncontacts++;
1154 Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale);
1155 d.JointAttach(Joint, b1, b2);
1156
1157 if (++m_global_contactcount >= maxContactsbeforedeath)
1158 break;
1159 1048
1160 if (++i >= count) 1049 if (++i >= count)
1161 break; 1050 break;
1162 1051
1163 if (!GetCurContactGeom(i, ref curContact)) 1052 if (!GetCurContactGeom(i, ref curContact))
1164 break; 1053 break;
1165
1166 if (curContact.depth > maxDepthContact.PenetrationDepth)
1167 {
1168 maxDepthContact.Position.X = curContact.pos.X;
1169 maxDepthContact.Position.Y = curContact.pos.Y;
1170 maxDepthContact.Position.Z = curContact.pos.Z;
1171 maxDepthContact.SurfaceNormal.X = curContact.normal.X;
1172 maxDepthContact.SurfaceNormal.Y = curContact.normal.Y;
1173 maxDepthContact.SurfaceNormal.Z = curContact.normal.Z;
1174 maxDepthContact.PenetrationDepth = curContact.depth;
1175 }
1176 } 1054 }
1177 }
1178 1055
1179 if (ncontacts > 0) 1056 if (ncontacts > 0)
1180 { 1057 {
1181 maxDepthContact.CharacterFeet = FeetCollision; 1058 ContactPoint maxDepthContact = new ContactPoint(
1059 new Vector3(maxContact.pos.X, maxContact.pos.Y, maxContact.pos.Z),
1060 new Vector3(minContact.normal.X, minContact.normal.Y, minContact.normal.Z),
1061 maxContact.depth, FeetCollision
1062 );
1182 collision_accounting_events(p1, p2, maxDepthContact); 1063 collision_accounting_events(p1, p2, maxDepthContact);
1183 } 1064 }
1184/*
1185 if (notskipedcount > geomContactPointsStartthrottle)
1186 {
1187 // If there are more then 3 contact points, it's likely
1188 // that we've got a pile of objects, so ...
1189 // We don't want to send out hundreds of terse updates over and over again
1190 // so lets throttle them and send them again after it's somewhat sorted out.
1191 this needs checking so out for now
1192 if (b1 != IntPtr.Zero)
1193 p1.ThrottleUpdates = true;
1194 if (b2 != IntPtr.Zero)
1195 p2.ThrottleUpdates = true;
1196
1197 }
1198 */
1199 } 1065 }
1200 1066
1201 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) 1067 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact)
@@ -1286,10 +1152,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1286 // chr.CollidingGround = false; not done here 1152 // chr.CollidingGround = false; not done here
1287 chr.CollidingObj = false; 1153 chr.CollidingObj = false;
1288 // do colisions with static space 1154 // do colisions with static space
1289 d.SpaceCollide2(StaticSpace, chr.topbox, IntPtr.Zero, nearCallback); 1155 d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback);
1290 d.SpaceCollide2(StaticSpace, chr.midbox, IntPtr.Zero, nearCallback);
1291 d.SpaceCollide2(StaticSpace, chr.feetbox, IntPtr.Zero, nearCallback);
1292 d.SpaceCollide2(StaticSpace, chr.bonebox, IntPtr.Zero, nearCallback);
1293 1156
1294 // chars with chars 1157 // chars with chars
1295 d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback); 1158 d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback);
@@ -1346,7 +1209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1346 // and with chars 1209 // and with chars
1347 try 1210 try
1348 { 1211 {
1349 d.SpaceCollide2(ActiveSpace, CharsSpace,IntPtr.Zero, nearCallback); 1212 d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback);
1350 } 1213 }
1351 catch (AccessViolationException) 1214 catch (AccessViolationException)
1352 { 1215 {
@@ -1837,7 +1700,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1837 foreach (OdeCharacter actor in _characters) 1700 foreach (OdeCharacter actor in _characters)
1838 { 1701 {
1839 if (actor != null) 1702 if (actor != null)
1840 actor.Move(ODE_STEPSIZE, defects); 1703 actor.Move(defects);
1841 } 1704 }
1842 if (defects.Count != 0) 1705 if (defects.Count != 0)
1843 { 1706 {