aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs292
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs1
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs4
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs8
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs265
5 files changed, 424 insertions, 146 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index ecd5474..1c38246 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -79,6 +79,7 @@ namespace OpenSim.Region.Physics.OdePlugin
79 private Vector3 _acceleration; 79 private Vector3 _acceleration;
80 private Vector3 m_rotationalVelocity; 80 private Vector3 m_rotationalVelocity;
81 private Vector3 m_size; 81 private Vector3 m_size;
82 private Vector3 m_collideNormal;
82 private Quaternion m_orientation; 83 private Quaternion m_orientation;
83 private Quaternion m_orientation2D; 84 private Quaternion m_orientation2D;
84 private float m_mass = 80f; 85 private float m_mass = 80f;
@@ -96,6 +97,8 @@ namespace OpenSim.Region.Physics.OdePlugin
96 private float m_feetOffset = 0; 97 private float m_feetOffset = 0;
97 private float feetOff = 0; 98 private float feetOff = 0;
98 private float boneOff = 0; 99 private float boneOff = 0;
100 private float AvaAvaSizeXsq = 0.3f;
101 private float AvaAvaSizeYsq = 0.2f;
99 102
100 public float walkDivisor = 1.3f; 103 public float walkDivisor = 1.3f;
101 public float runDivisor = 0.8f; 104 public float runDivisor = 0.8f;
@@ -107,6 +110,7 @@ namespace OpenSim.Region.Physics.OdePlugin
107 110
108 private bool _zeroFlag = false; 111 private bool _zeroFlag = false;
109 112
113
110 private uint m_localID = 0; 114 private uint m_localID = 0;
111 public bool m_returnCollisions = false; 115 public bool m_returnCollisions = false;
112 // taints and their non-tainted counterparts 116 // taints and their non-tainted counterparts
@@ -136,7 +140,6 @@ namespace OpenSim.Region.Physics.OdePlugin
136 public IntPtr Body = IntPtr.Zero; 140 public IntPtr Body = IntPtr.Zero;
137 private OdeScene _parent_scene; 141 private OdeScene _parent_scene;
138 private IntPtr capsule = IntPtr.Zero; 142 private IntPtr capsule = IntPtr.Zero;
139 private IntPtr bbox = IntPtr.Zero;
140 public IntPtr collider = IntPtr.Zero; 143 public IntPtr collider = IntPtr.Zero;
141 144
142 public IntPtr Amotor = IntPtr.Zero; 145 public IntPtr Amotor = IntPtr.Zero;
@@ -152,9 +155,7 @@ namespace OpenSim.Region.Physics.OdePlugin
152 public UUID m_uuid; 155 public UUID m_uuid;
153 public bool bad = false; 156 public bool bad = false;
154 157
155 float mu; 158 float mu;
156
157
158 159
159 public OdeCharacter(uint localID, String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor) 160 public OdeCharacter(uint localID, String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor)
160 { 161 {
@@ -310,9 +311,9 @@ namespace OpenSim.Region.Physics.OdePlugin
310 { 311 {
311 if (value) 312 if (value)
312 { 313 {
313 m_colliderfilter += 2; 314 m_colliderfilter += 3;
314 if (m_colliderfilter > 2) 315 if (m_colliderfilter > 3)
315 m_colliderfilter = 2; 316 m_colliderfilter = 3;
316 } 317 }
317 else 318 else
318 { 319 {
@@ -327,6 +328,7 @@ namespace OpenSim.Region.Physics.OdePlugin
327 { 328 {
328 m_pidControllerActive = true; 329 m_pidControllerActive = true;
329 m_iscolliding = true; 330 m_iscolliding = true;
331 m_freemove = false;
330 } 332 }
331 } 333 }
332 } 334 }
@@ -709,6 +711,11 @@ namespace OpenSim.Region.Physics.OdePlugin
709 711
710 feetOff = bot + feetsz; 712 feetOff = bot + feetsz;
711 713
714 AvaAvaSizeXsq = 0.4f * sx;
715 AvaAvaSizeXsq *= AvaAvaSizeXsq;
716 AvaAvaSizeYsq = 0.5f * sy;
717 AvaAvaSizeYsq *= AvaAvaSizeYsq;
718
712 _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); 719 _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace);
713 720
714 collider = d.HashSpaceCreate(_parent_scene.CharsSpace); 721 collider = d.HashSpaceCreate(_parent_scene.CharsSpace);
@@ -723,9 +730,8 @@ namespace OpenSim.Region.Physics.OdePlugin
723 r = m_size.Y; 730 r = m_size.Y;
724 float l = m_size.Z - r; 731 float l = m_size.Z - r;
725 r *= 0.5f; 732 r *= 0.5f;
726 capsule = d.CreateCapsule(collider, r, l);
727 733
728 bbox = d.CreateBox(collider, m_size.X, m_size.Y, m_size.Z); 734 capsule = d.CreateCapsule(collider, r, l);
729 735
730 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass 736 m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass
731 737
@@ -750,8 +756,6 @@ namespace OpenSim.Region.Physics.OdePlugin
750 _position.Z = npositionZ; 756 _position.Z = npositionZ;
751 757
752 d.BodySetMass(Body, ref ShellMass); 758 d.BodySetMass(Body, ref ShellMass);
753
754 d.GeomSetBody(bbox, Body);
755 d.GeomSetBody(capsule, Body); 759 d.GeomSetBody(capsule, Body);
756 760
757 // The purpose of the AMotor here is to keep the avatar's physical 761 // The purpose of the AMotor here is to keep the avatar's physical
@@ -821,14 +825,6 @@ namespace OpenSim.Region.Physics.OdePlugin
821 capsule = IntPtr.Zero; 825 capsule = IntPtr.Zero;
822 } 826 }
823 827
824 if (bbox != IntPtr.Zero)
825 {
826 _parent_scene.actor_name_map.Remove(bbox);
827 _parent_scene.waitForSpaceUnlock(collider);
828 d.GeomDestroy(bbox);
829 bbox = IntPtr.Zero;
830 }
831
832 if (collider != IntPtr.Zero) 828 if (collider != IntPtr.Zero)
833 { 829 {
834 d.SpaceDestroy(collider); 830 d.SpaceDestroy(collider);
@@ -869,47 +865,107 @@ namespace OpenSim.Region.Physics.OdePlugin
869 x = tx * cos - y * sin; 865 x = tx * cos - y * sin;
870 y = tx * sin + y * cos; 866 y = tx * sin + y * cos;
871 } 867 }
872 868
873 869 public bool Collide(IntPtr me, IntPtr other, bool reverse, ref d.ContactGeom contact,
874 public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision) 870 ref d.ContactGeom altContact , ref bool useAltcontact, ref bool feetcollision)
875 { 871 {
876 feetcollision = false; 872 feetcollision = false;
877 873 useAltcontact = false;
878 Vector3 offset;
879
880 offset.X = contact.pos.X - _position.X;
881 offset.Y = contact.pos.Y - _position.Y;
882 874
883 if (me == capsule) 875 if (me == capsule)
884 { 876 {
877 Vector3 offset;
878
885 float h = contact.pos.Z - _position.Z; 879 float h = contact.pos.Z - _position.Z;
886 offset.Z = h - feetOff; 880 offset.Z = h - feetOff;
887 881
888 if (offset.Z > 0) 882 offset.X = contact.pos.X - _position.X;
883 offset.Y = contact.pos.Y - _position.Y;
884
885 d.GeomClassID gtype = d.GeomGetClass(other);
886 if (gtype == d.GeomClassID.CapsuleClass)
887 {
888 Vector3 roff = offset * Quaternion.Inverse(m_orientation2D);
889 float r = roff.X *roff.X / AvaAvaSizeXsq;
890 r += (roff.Y * roff.Y) / AvaAvaSizeYsq;
891 if (r > 1.0f)
892 return false;
893
894 float dp = 1.0f -(float)Math.Sqrt((double)r);
895 if (dp > 0.05f)
896 dp = 0.05f;
897
898 contact.depth = dp;
899
900 if (offset.Z < 0)
901 {
902 feetcollision = true;
903 if (h < boneOff)
904 {
905 m_collideNormal.X = contact.normal.X;
906 m_collideNormal.Y = contact.normal.Y;
907 m_collideNormal.Z = contact.normal.Z;
908 IsColliding = true;
909 }
910 }
889 return true; 911 return true;
912 }
913/*
914 d.AABB aabb;
915 d.GeomGetAABB(other,out aabb);
916 float othertop = aabb.MaxZ - _position.Z;
917*/
918// if (offset.Z > 0 || othertop > -feetOff || contact.normal.Z > 0.35f)
919 if (offset.Z > 0 || contact.normal.Z > 0.35f)
920 {
921 if (offset.Z <= 0)
922 {
923 feetcollision = true;
924 if (h < boneOff)
925 {
926 m_collideNormal.X = contact.normal.X;
927 m_collideNormal.Y = contact.normal.Y;
928 m_collideNormal.Z = contact.normal.Z;
929 IsColliding = true;
930 }
931 }
932 return true;
933 }
934
935 altContact = contact;
936 useAltcontact = true;
937
938 offset.Z -= 0.2f;
890 939
891 offset.Normalize(); 940 offset.Normalize();
892 941
942 if (contact.depth > 0.1f)
943 contact.depth = 0.1f;
944
893 if (reverse) 945 if (reverse)
894 { 946 {
895 contact.normal.X = offset.X; 947 altContact.normal.X = offset.X;
896 contact.normal.Y = offset.Y; 948 altContact.normal.Y = offset.Y;
897 contact.normal.Z = offset.Z; 949 altContact.normal.Z = offset.Z;
898 } 950 }
899 else 951 else
900 { 952 {
901 contact.normal.X = -offset.X; 953 altContact.normal.X = -offset.X;
902 contact.normal.Y = -offset.Y; 954 altContact.normal.Y = -offset.Y;
903 contact.normal.Z = -offset.Z; 955 altContact.normal.Z = -offset.Z;
904 } 956 }
957
905 feetcollision = true; 958 feetcollision = true;
906 if (h < boneOff) 959 if (h < boneOff)
960 {
961 m_collideNormal.X = contact.normal.X;
962 m_collideNormal.Y = contact.normal.Y;
963 m_collideNormal.Z = contact.normal.Z;
907 IsColliding = true; 964 IsColliding = true;
965 }
966 return true;
908 } 967 }
909 else 968 return false;
910 return false;
911
912 return true;
913 } 969 }
914 970
915 /// <summary> 971 /// <summary>
@@ -986,6 +1042,9 @@ namespace OpenSim.Region.Physics.OdePlugin
986 Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); 1042 Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
987 float velLengthSquared = vel.LengthSquared(); 1043 float velLengthSquared = vel.LengthSquared();
988 1044
1045
1046 Vector3 ctz = _target_velocity;
1047
989 float movementdivisor = 1f; 1048 float movementdivisor = 1f;
990 //Ubit change divisions into multiplications below 1049 //Ubit change divisions into multiplications below
991 if (!m_alwaysRun) 1050 if (!m_alwaysRun)
@@ -993,13 +1052,16 @@ namespace OpenSim.Region.Physics.OdePlugin
993 else 1052 else
994 movementdivisor = 1 / runDivisor; 1053 movementdivisor = 1 / runDivisor;
995 1054
1055 ctz.X *= movementdivisor;
1056 ctz.Y *= movementdivisor;
1057
996 //****************************************** 1058 //******************************************
997 // colide with land 1059 // colide with land
998 1060
999 d.AABB aabb; 1061 d.AABB aabb;
1000// d.GeomGetAABB(feetbox, out aabb); 1062// d.GeomGetAABB(feetbox, out aabb);
1001 d.GeomGetAABB(capsule, out aabb); 1063 d.GeomGetAABB(capsule, out aabb);
1002 float chrminZ = aabb.MinZ; ; // move up a bit 1064 float chrminZ = aabb.MinZ; // move up a bit
1003 Vector3 posch = localpos; 1065 Vector3 posch = localpos;
1004 1066
1005 float ftmp; 1067 float ftmp;
@@ -1014,15 +1076,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1014 float terrainheight = _parent_scene.GetTerrainHeightAtXY(posch.X, posch.Y); 1076 float terrainheight = _parent_scene.GetTerrainHeightAtXY(posch.X, posch.Y);
1015 if (chrminZ < terrainheight) 1077 if (chrminZ < terrainheight)
1016 { 1078 {
1079 if (ctz.Z < 0)
1080 ctz.Z = 0;
1081
1082 Vector3 n = _parent_scene.GetTerrainNormalAtXY(posch.X, posch.Y);
1017 float depth = terrainheight - chrminZ; 1083 float depth = terrainheight - chrminZ;
1084
1085 vec.Z = depth * PID_P * 50;
1086
1018 if (!flying) 1087 if (!flying)
1019 { 1088 vec.Z += -vel.Z * PID_D;
1020 vec.Z = -vel.Z * PID_D * 1.5f + depth * PID_P * 50;
1021 }
1022 else
1023 vec.Z = depth * PID_P * 50;
1024 1089
1025 if (depth < 0.1f) 1090 if (depth < 0.2f)
1026 { 1091 {
1027 m_colliderGroundfilter++; 1092 m_colliderGroundfilter++;
1028 if (m_colliderGroundfilter > 2) 1093 if (m_colliderGroundfilter > 2)
@@ -1036,50 +1101,83 @@ namespace OpenSim.Region.Physics.OdePlugin
1036 m_freemove = false; 1101 m_freemove = false;
1037 } 1102 }
1038 1103
1104 m_collideNormal.X = n.X;
1105 m_collideNormal.Y = n.Y;
1106 m_collideNormal.Z = n.Z;
1107
1039 m_iscollidingGround = true; 1108 m_iscollidingGround = true;
1040 1109
1110
1041 ContactPoint contact = new ContactPoint(); 1111 ContactPoint contact = new ContactPoint();
1042 contact.PenetrationDepth = depth; 1112 contact.PenetrationDepth = depth;
1043 contact.Position.X = localpos.X; 1113 contact.Position.X = localpos.X;
1044 contact.Position.Y = localpos.Y; 1114 contact.Position.Y = localpos.Y;
1045 contact.Position.Z = terrainheight; 1115 contact.Position.Z = terrainheight;
1046 contact.SurfaceNormal.X = 0.0f; 1116 contact.SurfaceNormal.X = -n.X;
1047 contact.SurfaceNormal.Y = 0.0f; 1117 contact.SurfaceNormal.Y = -n.Y;
1048 contact.SurfaceNormal.Z = -1f; 1118 contact.SurfaceNormal.Z = -n.Z;
1049 contact.RelativeSpeed = -vel.Z; 1119 contact.RelativeSpeed = -vel.Z;
1050 contact.CharacterFeet = true; 1120 contact.CharacterFeet = true;
1051 AddCollisionEvent(0, contact); 1121 AddCollisionEvent(0, contact);
1052 1122
1053 vec.Z *= 0.5f; 1123// vec.Z *= 0.5f;
1054 } 1124 }
1055 } 1125 }
1056 1126
1057 else 1127 else
1058 { 1128 {
1059 m_colliderGroundfilter = 0; 1129 m_colliderGroundfilter -= 5;
1060 m_iscollidingGround = false; 1130 if (m_colliderGroundfilter <= 0)
1131 {
1132 m_colliderGroundfilter = 0;
1133 m_iscollidingGround = false;
1134 }
1061 } 1135 }
1062 } 1136 }
1063 else 1137 else
1064 { 1138 {
1065 m_colliderGroundfilter = 0; 1139 m_colliderGroundfilter -= 5;
1066 m_iscollidingGround = false; 1140 if (m_colliderGroundfilter <= 0)
1141 {
1142 m_colliderGroundfilter = 0;
1143 m_iscollidingGround = false;
1144 }
1067 } 1145 }
1068 1146
1069 1147
1070 //****************************************** 1148 //******************************************
1149 if (!m_iscolliding)
1150 m_collideNormal.Z = 0;
1151
1152 bool tviszero = (ctz.X == 0.0f && ctz.Y == 0.0f && ctz.Z == 0.0f);
1153
1071 1154
1072 bool tviszero = (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f);
1073 1155
1074 // if (!tviszero || m_iscolliding || velLengthSquared <0.01)
1075 if (!tviszero) 1156 if (!tviszero)
1157 {
1076 m_freemove = false; 1158 m_freemove = false;
1077 1159
1160 // movement relative to surface if moving on it
1161 // dont disturbe vertical movement, ie jumps
1162 if (m_iscolliding && !flying && ctz.Z == 0 && m_collideNormal.Z > 0.2f && m_collideNormal.Z < 0.94f)
1163 {
1164 float p = ctz.X * m_collideNormal.X + ctz.Y * m_collideNormal.Y;
1165 ctz.X *= (float)Math.Sqrt(1 - m_collideNormal.X * m_collideNormal.X);
1166 ctz.Y *= (float)Math.Sqrt(1 - m_collideNormal.Y * m_collideNormal.Y);
1167 ctz.Z -= p;
1168 if (ctz.Z < 0)
1169 ctz.Z *= 2;
1170
1171 }
1172
1173 }
1174
1175
1078 if (!m_freemove) 1176 if (!m_freemove)
1079 { 1177 {
1080 1178
1081 // if velocity is zero, use position control; otherwise, velocity control 1179 // if velocity is zero, use position control; otherwise, velocity control
1082 if (tviszero && m_iscolliding) 1180 if (tviszero && m_iscolliding && !flying)
1083 { 1181 {
1084 // keep track of where we stopped. No more slippin' & slidin' 1182 // keep track of where we stopped. No more slippin' & slidin'
1085 if (!_zeroFlag) 1183 if (!_zeroFlag)
@@ -1094,12 +1192,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1094 // Avatar to Avatar collisions 1192 // Avatar to Avatar collisions
1095 // Prim to avatar collisions 1193 // Prim to avatar collisions
1096 1194
1097 vec.X = -vel.X * PID_D + (_zeroPosition.X - localpos.X) * (PID_P * 2); 1195 vec.X = -vel.X * PID_D * 2f + (_zeroPosition.X - localpos.X) * (PID_P * 5);
1098 vec.Y = -vel.Y * PID_D + (_zeroPosition.Y - localpos.Y) * (PID_P * 2); 1196 vec.Y = -vel.Y * PID_D * 2f + (_zeroPosition.Y - localpos.Y) * (PID_P * 5);
1197 if(vel.Z > 0)
1198 vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P;
1199 else
1200 vec.Z += (-vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P) * 0.2f;
1201/*
1099 if (flying) 1202 if (flying)
1100 { 1203 {
1101 vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P; 1204 vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P;
1102 } 1205 }
1206*/
1103 } 1207 }
1104 //PidStatus = true; 1208 //PidStatus = true;
1105 } 1209 }
@@ -1112,22 +1216,48 @@ namespace OpenSim.Region.Physics.OdePlugin
1112 { 1216 {
1113 if (!flying) 1217 if (!flying)
1114 { 1218 {
1115 if (_target_velocity.Z > 0.0f) 1219 // we are on a surface
1220 if (ctz.Z > 0f)
1221 {
1222 // moving up or JUMPING
1223 vec.Z += (ctz.Z - vel.Z) * PID_D * 2f;
1224 vec.X += (ctz.X - vel.X) * (PID_D);
1225 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1226 }
1227 else
1116 { 1228 {
1117 // We're colliding with something and we're not flying but we're moving 1229 // we are moving down on a surface
1118 // This means we're walking or running. JUMPING 1230 if (ctz.Z == 0)
1119 vec.Z += (_target_velocity.Z - vel.Z) * PID_D * 1.2f;// +(_zeroPosition.Z - localpos.Z) * PID_P; 1231 {
1232 if (vel.Z > 0)
1233 vec.Z -= vel.Z * PID_D * 2f;
1234 vec.X += (ctz.X - vel.X) * (PID_D);
1235 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1236 }
1237 // intencionally going down
1238 else
1239 {
1240 if (ctz.Z < vel.Z)
1241 vec.Z += (ctz.Z - vel.Z) * PID_D;
1242 else
1243 {
1244 }
1245
1246 if (Math.Abs(ctz.X) > Math.Abs(vel.X))
1247 vec.X += (ctz.X - vel.X) * (PID_D);
1248 if (Math.Abs(ctz.Y) > Math.Abs(vel.Y))
1249 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1250 }
1120 } 1251 }
1252
1121 // We're standing on something 1253 // We're standing on something
1122 vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D);
1123 vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D);
1124 } 1254 }
1125 else 1255 else
1126 { 1256 {
1127 // We're flying and colliding with something 1257 // We're flying and colliding with something
1128 vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D * 0.0625f); 1258 vec.X += (ctz.X - vel.X) * (PID_D * 0.0625f);
1129 vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D * 0.0625f); 1259 vec.Y += (ctz.Y - vel.Y) * (PID_D * 0.0625f);
1130 vec.Z += (_target_velocity.Z - vel.Z) * (PID_D); 1260 vec.Z += (ctz.Z - vel.Z) * (PID_D * 0.0625f);
1131 } 1261 }
1132 } 1262 }
1133 else // ie not colliding 1263 else // ie not colliding
@@ -1135,9 +1265,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1135 if (flying) //(!m_iscolliding && flying) 1265 if (flying) //(!m_iscolliding && flying)
1136 { 1266 {
1137 // we're in mid air suspended 1267 // we're in mid air suspended
1138 vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D * 1.667f); 1268 vec.X += (ctz.X - vel.X) * (PID_D);
1139 vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D * 1.667f); 1269 vec.Y += (ctz.Y - vel.Y) * (PID_D);
1140 vec.Z += (_target_velocity.Z - vel.Z) * (PID_D); 1270 vec.Z += (ctz.Z - vel.Z) * (PID_D);
1141 } 1271 }
1142 1272
1143 else 1273 else
@@ -1146,8 +1276,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1146 // m_iscolliding includes collisions with the ground. 1276 // m_iscolliding includes collisions with the ground.
1147 1277
1148 // d.Vector3 pos = d.BodyGetPosition(Body); 1278 // d.Vector3 pos = d.BodyGetPosition(Body);
1149 vec.X = (_target_velocity.X - vel.X) * PID_D * 0.833f; 1279 vec.X += (ctz.X - vel.X) * PID_D * 0.833f;
1150 vec.Y = (_target_velocity.Y - vel.Y) * PID_D * 0.833f; 1280 vec.Y += (ctz.Y - vel.Y) * PID_D * 0.833f;
1281 // hack for breaking on fall
1282 if (ctz.Z == -9999f)
1283 vec.Z += -vel.Z * PID_D - _parent_scene.gravityz * m_mass;
1151 } 1284 }
1152 } 1285 }
1153 } 1286 }
@@ -1166,9 +1299,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1166 vec.X -= breakfactor * vel.X; 1299 vec.X -= breakfactor * vel.X;
1167 vec.Y -= breakfactor * vel.Y; 1300 vec.Y -= breakfactor * vel.Y;
1168 if (flying) 1301 if (flying)
1169 vec.Z -= breakfactor * vel.Z; 1302 vec.Z -= 0.5f * breakfactor * vel.Z;
1170 else 1303 else
1171 vec.Z -= .5f* m_mass * vel.Z; 1304 vec.Z -= .16f* m_mass * vel.Z;
1172 } 1305 }
1173 1306
1174 if (flying) 1307 if (flying)
@@ -1389,10 +1522,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1389 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); 1522 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z);
1390 1523
1391 _parent_scene.actor_name_map[collider] = (PhysicsActor)this; 1524 _parent_scene.actor_name_map[collider] = (PhysicsActor)this;
1392// _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this;
1393// _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
1394// _parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
1395 _parent_scene.actor_name_map[bbox] = (PhysicsActor)this;
1396 _parent_scene.actor_name_map[capsule] = (PhysicsActor)this; 1525 _parent_scene.actor_name_map[capsule] = (PhysicsActor)this;
1397 _parent_scene.AddCharacter(this); 1526 _parent_scene.AddCharacter(this);
1398 } 1527 }
@@ -1449,7 +1578,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1449 1578
1450 1579
1451 _parent_scene.actor_name_map[collider] = (PhysicsActor)this; 1580 _parent_scene.actor_name_map[collider] = (PhysicsActor)this;
1452 _parent_scene.actor_name_map[bbox] = (PhysicsActor)this;
1453 _parent_scene.actor_name_map[capsule] = (PhysicsActor)this; 1581 _parent_scene.actor_name_map[capsule] = (PhysicsActor)this;
1454 } 1582 }
1455 m_freemove = false; 1583 m_freemove = false;
@@ -1553,9 +1681,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1553 _zeroFlag = false; 1681 _zeroFlag = false;
1554 _target_velocity = Vector3.Zero; 1682 _target_velocity = Vector3.Zero;
1555 m_freemove = true; 1683 m_freemove = true;
1556 m_colliderfilter = -2; 1684 m_colliderfilter = -1;
1557 m_colliderObjectfilter = -2; 1685 m_colliderObjectfilter = -1;
1558 m_colliderGroundfilter = -2; 1686 m_colliderGroundfilter = -1;
1559 1687
1560 m_iscolliding = false; 1688 m_iscolliding = false;
1561 m_iscollidingGround = false; 1689 m_iscollidingGround = false;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
index 5030cec..a6bdaa0 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs
@@ -100,6 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin
100 } 100 }
101 m_running = true; 101 m_running = true;
102 m_thread = new Thread(DoWork); 102 m_thread = new Thread(DoWork);
103 m_thread.Name = "OdeMeshWorker";
103 m_thread.Start(); 104 m_thread.Start();
104 } 105 }
105 106
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index 4cac0aa..2c3190f 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -251,8 +251,8 @@ namespace OpenSim.Region.Physics.OdePlugin
251 get { return m_building; } 251 get { return m_building; }
252 set 252 set
253 { 253 {
254 if (value) 254// if (value)
255 m_building = true; 255// m_building = true;
256 AddChange(changes.building, value); 256 AddChange(changes.building, value);
257 } 257 }
258 } 258 }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
index e9023c3..672212f 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
@@ -78,11 +78,11 @@ namespace OpenSim.Region.Physics.OdePlugin
78 78
79 IntPtr geom = ((OdePrim)actor).prim_geom; 79 IntPtr geom = ((OdePrim)actor).prim_geom;
80 80
81// Vector3 geopos = d.GeomGetPositionOMV(geom); 81 Vector3 geopos = d.GeomGetPositionOMV(geom);
82// Quaternion geomOri = d.GeomGetQuaternionOMV(geom); 82 Quaternion geomOri = d.GeomGetQuaternionOMV(geom);
83 83
84 Vector3 geopos = actor.Position; 84// Vector3 geopos = actor.Position;
85 Quaternion geomOri = actor.Orientation; 85// Quaternion geomOri = actor.Orientation;
86 86
87 Quaternion geomInvOri = Quaternion.Conjugate(geomOri); 87 Quaternion geomInvOri = Quaternion.Conjugate(geomOri);
88 88
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 8abf6cf..2adbe01 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -833,13 +833,7 @@ namespace OpenSim.Region.Physics.OdePlugin
833 switch (p2.PhysicsActorType) 833 switch (p2.PhysicsActorType)
834 { 834 {
835 case (int)ActorTypes.Agent: 835 case (int)ActorTypes.Agent:
836 p1.CollidingObj = true;
837 p2.CollidingObj = true;
838 break;
839
840 case (int)ActorTypes.Prim: 836 case (int)ActorTypes.Prim:
841 if (p2.Velocity.LengthSquared() > 0.0f)
842 p2.CollidingObj = true;
843 break; 837 break;
844 838
845 default: 839 default:
@@ -850,55 +844,53 @@ namespace OpenSim.Region.Physics.OdePlugin
850 } 844 }
851 845
852 case (int)ActorTypes.Prim: 846 case (int)ActorTypes.Prim:
853 switch (p2.PhysicsActorType)
854 { 847 {
855 case (int)ActorTypes.Agent: 848 switch (p2.PhysicsActorType)
856 849 {
857 dop2ava = true; 850 case (int)ActorTypes.Agent:
858 851 dop2ava = true;
859 if (p1.Velocity.LengthSquared() > 0.0f) 852 break;
860 p1.CollidingObj = true;
861 break;
862
863 case (int)ActorTypes.Prim:
864 Vector3 relV = p1.Velocity - p2.Velocity;
865 float relVlenSQ = relV.LengthSquared();
866 if (relVlenSQ > 0.0001f)
867 {
868 p1.CollidingObj = true;
869 p2.CollidingObj = true;
870 }
871 p1.getContactData(ref contactdata1);
872 p2.getContactData(ref contactdata2);
873 bounce = contactdata1.bounce * contactdata2.bounce;
874 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
875 853
876 if (relVlenSQ > 0.01f) 854 case (int)ActorTypes.Prim:
877 mu *= frictionMovementMult; 855 Vector3 relV = p1.Velocity - p2.Velocity;
856 float relVlenSQ = relV.LengthSquared();
857 if (relVlenSQ > 0.0001f)
858 {
859 p1.CollidingObj = true;
860 p2.CollidingObj = true;
861 }
862 p1.getContactData(ref contactdata1);
863 p2.getContactData(ref contactdata2);
864 bounce = contactdata1.bounce * contactdata2.bounce;
865 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
878 866
879 break; 867 if (relVlenSQ > 0.01f)
868 mu *= frictionMovementMult;
880 869
881 case (int)ActorTypes.Ground: 870 break;
882 p1.getContactData(ref contactdata1);
883 bounce = contactdata1.bounce * TerrainBounce;
884 mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction);
885 871
886 if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) 872 case (int)ActorTypes.Ground:
887 mu *= frictionMovementMult; 873 p1.getContactData(ref contactdata1);
888 p1.CollidingGround = true; 874 bounce = contactdata1.bounce * TerrainBounce;
889/* 875 mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction);
890 if (d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) 876
891 { 877 if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f)
892 if (curContact.side1 > 0) 878 mu *= frictionMovementMult;
893 IgnoreNegSides = true; 879 p1.CollidingGround = true;
894 } 880 /*
895 */ 881 if (d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass)
896 break; 882 {
883 if (curContact.side1 > 0)
884 IgnoreNegSides = true;
885 }
886 */
887 break;
897 888
898 case (int)ActorTypes.Water: 889 case (int)ActorTypes.Water:
899 default: 890 default:
900 ignore = true; 891 ignore = true;
901 break; 892 break;
893 }
902 } 894 }
903 break; 895 break;
904 896
@@ -943,26 +935,55 @@ namespace OpenSim.Region.Physics.OdePlugin
943 SharedTmpcontact.surface.mu = mu; 935 SharedTmpcontact.surface.mu = mu;
944 SharedTmpcontact.surface.bounce = bounce; 936 SharedTmpcontact.surface.bounce = bounce;
945 937
938 d.ContactGeom altContact = new d.ContactGeom();
939 bool useAltcontact = false;
940 bool noskip = true;
941
946 while (true) 942 while (true)
947 { 943 {
948// if (!(IgnoreNegSides && curContact.side1 < 0)) 944// if (!(IgnoreNegSides && curContact.side1 < 0))
949 { 945 {
950 bool noskip = true; 946 noskip = true;
947 useAltcontact = false;
948
951 if (dop1ava) 949 if (dop1ava)
952 { 950 {
953 if (!(((OdeCharacter)p1).Collide(g1, false, ref curContact, ref FeetCollision))) 951 if ((((OdeCharacter)p1).Collide(g1, g2, false, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision)))
954 952 {
953 if (p2.PhysicsActorType == (int)ActorTypes.Agent)
954 {
955 p1.CollidingObj = true;
956 p2.CollidingObj = true;
957 }
958 else if (p2.Velocity.LengthSquared() > 0.0f)
959 p2.CollidingObj = true;
960 }
961 else
955 noskip = false; 962 noskip = false;
956 } 963 }
957 else if (dop2ava) 964 else if (dop2ava)
958 { 965 {
959 if (!(((OdeCharacter)p2).Collide(g2, true, ref curContact, ref FeetCollision))) 966 if ((((OdeCharacter)p2).Collide(g2, g1, true, ref curContact, ref altContact , ref useAltcontact, ref FeetCollision)))
967 {
968 if (p1.PhysicsActorType == (int)ActorTypes.Agent)
969 {
970 p1.CollidingObj = true;
971 p2.CollidingObj = true;
972 }
973 else if (p2.Velocity.LengthSquared() > 0.0f)
974 p1.CollidingObj = true;
975 }
976 else
960 noskip = false; 977 noskip = false;
961 } 978 }
962 979
963 if (noskip) 980 if (noskip)
964 { 981 {
965 Joint = CreateContacJoint(ref curContact); 982 if(useAltcontact)
983 Joint = CreateContacJoint(ref altContact);
984 else
985 Joint = CreateContacJoint(ref curContact);
986
966 if (Joint == IntPtr.Zero) 987 if (Joint == IntPtr.Zero)
967 break; 988 break;
968 989
@@ -1095,10 +1116,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1095 // do colisions with static space 1116 // do colisions with static space
1096 d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback); 1117 d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback);
1097 1118
1098 // chars with chars
1099 d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback);
1100 // no coll with gnd 1119 // no coll with gnd
1101 } 1120 }
1121 // chars with chars
1122 d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback);
1123
1102 } 1124 }
1103 catch (AccessViolationException) 1125 catch (AccessViolationException)
1104 { 1126 {
@@ -1920,12 +1942,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1920 dy = 0; 1942 dy = 0;
1921 } 1943 }
1922 } 1944 }
1923
1924 else 1945 else
1925 { 1946 {
1926 // we still have square fixed size regions 1947 // we still have square fixed size regions
1927 // also flip x and y because of how map is done for ODE fliped axis 1948 // also flip x and y because of how map is done for ODE fliped axis
1928 // so ix,iy,dx and dy are inter exchanged 1949 // so ix,iy,dx and dy are inter exchanged
1950
1929 if (x < regsize - 1) 1951 if (x < regsize - 1)
1930 { 1952 {
1931 iy = (int)x; 1953 iy = (int)x;
@@ -1972,7 +1994,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1972 */ 1994 */
1973 h0 = ((float)heights[iy]); // 0,0 vertice 1995 h0 = ((float)heights[iy]); // 0,0 vertice
1974 1996
1975 if ((dy > dx)) 1997 if (dy>dx)
1976 { 1998 {
1977 iy += regsize; 1999 iy += regsize;
1978 h2 = (float)heights[iy]; // 0,1 vertice 2000 h2 = (float)heights[iy]; // 0,1 vertice
@@ -1990,6 +2012,133 @@ namespace OpenSim.Region.Physics.OdePlugin
1990 return h0 + h1 + h2; 2012 return h0 + h1 + h2;
1991 } 2013 }
1992 2014
2015 public Vector3 GetTerrainNormalAtXY(float x, float y)
2016 {
2017 int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
2018 int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
2019
2020 IntPtr heightFieldGeom = IntPtr.Zero;
2021 Vector3 norm = new Vector3(0, 0, 1);
2022
2023 // get region map
2024 if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom))
2025 return norm;
2026
2027 if (heightFieldGeom == IntPtr.Zero)
2028 return norm;
2029
2030 if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
2031 return norm;
2032
2033 // TerrainHeightField for ODE as offset 1m
2034 x += 1f - offsetX;
2035 y += 1f - offsetY;
2036
2037 // make position fit into array
2038 if (x < 0)
2039 x = 0;
2040 if (y < 0)
2041 y = 0;
2042
2043 // integer indexs
2044 int ix;
2045 int iy;
2046 // interpolators offset
2047 float dx;
2048 float dy;
2049
2050
2051 int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples
2052 int xstep = 1;
2053 int ystep = regsize;
2054 bool firstTri = false;
2055
2056 if (OdeUbitLib)
2057 {
2058 if (x < regsize - 1)
2059 {
2060 ix = (int)x;
2061 dx = x - (float)ix;
2062 }
2063 else // out world use external height
2064 {
2065 ix = regsize - 2;
2066 dx = 0;
2067 }
2068 if (y < regsize - 1)
2069 {
2070 iy = (int)y;
2071 dy = y - (float)iy;
2072 }
2073 else
2074 {
2075 iy = regsize - 2;
2076 dy = 0;
2077 }
2078 firstTri = dy > dx;
2079 }
2080
2081 else
2082 {
2083 xstep = regsize;
2084 ystep = 1;
2085 // we still have square fixed size regions
2086 // also flip x and y because of how map is done for ODE fliped axis
2087 // so ix,iy,dx and dy are inter exchanged
2088 if (x < regsize - 1)
2089 {
2090 iy = (int)x;
2091 dy = x - (float)iy;
2092 }
2093 else // out world use external height
2094 {
2095 iy = regsize - 2;
2096 dy = 0;
2097 }
2098 if (y < regsize - 1)
2099 {
2100 ix = (int)y;
2101 dx = y - (float)ix;
2102 }
2103 else
2104 {
2105 ix = regsize - 2;
2106 dx = 0;
2107 }
2108 firstTri = dx > dy;
2109 }
2110
2111 float h0;
2112 float h1;
2113 float h2;
2114
2115 iy *= regsize;
2116 iy += ix; // all indexes have iy + ix
2117
2118 float[] heights = TerrainHeightFieldHeights[heightFieldGeom];
2119
2120 if (firstTri)
2121 {
2122 h1 = ((float)heights[iy]); // 0,0 vertice
2123 iy += ystep;
2124 h0 = (float)heights[iy]; // 0,1
2125 h2 = (float)heights[iy+xstep]; // 1,1 vertice
2126 norm.X = h0 - h2;
2127 norm.Y = h1 - h0;
2128 }
2129 else
2130 {
2131 h2 = ((float)heights[iy]); // 0,0 vertice
2132 iy += xstep;
2133 h0 = ((float)heights[iy]); // 1,0 vertice
2134 h1 = (float)heights[iy+ystep]; // vertice 1,1
2135 norm.X = h2 - h0;
2136 norm.Y = h0 - h1;
2137 }
2138 norm.Z = 1;
2139 norm.Normalize();
2140 return norm;
2141 }
1993 2142
1994 public override void SetTerrain(float[] heightMap) 2143 public override void SetTerrain(float[] heightMap)
1995 { 2144 {