aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs260
1 files changed, 160 insertions, 100 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index 8b5b989..326fe97 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -103,12 +103,13 @@ namespace OpenSim.Region.Physics.OdePlugin
103 103
104 private float m_buoyancy = 0f; 104 private float m_buoyancy = 0f;
105 105
106 private bool m_freemove = false;
106 // private CollisionLocker ode; 107 // private CollisionLocker ode;
107 108
108 private string m_name = String.Empty; 109 private string m_name = String.Empty;
109 // other filter control 110 // other filter control
110 int m_colliderfilter = 0; 111 int m_colliderfilter = 0;
111 // int m_colliderGroundfilter = 0; 112 int m_colliderGroundfilter = 0;
112 int m_colliderObjectfilter = 0; 113 int m_colliderObjectfilter = 0;
113 114
114 // Default we're a Character 115 // Default we're a Character
@@ -280,7 +281,6 @@ namespace OpenSim.Region.Physics.OdePlugin
280 m_iscolliding = false; 281 m_iscolliding = false;
281 else 282 else
282 { 283 {
283// SetPidStatus(false);
284 m_pidControllerActive = true; 284 m_pidControllerActive = true;
285 m_iscolliding = true; 285 m_iscolliding = true;
286 } 286 }
@@ -379,24 +379,21 @@ namespace OpenSim.Region.Physics.OdePlugin
379 get { return _position; } 379 get { return _position; }
380 set 380 set
381 { 381 {
382 if (Body == IntPtr.Zero || Shell == IntPtr.Zero) 382 if (value.IsFinite())
383 { 383 {
384 if (value.IsFinite()) 384 if (value.Z > 9999999f)
385 { 385 {
386 if (value.Z > 9999999f) 386 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
387 {
388 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
389 }
390 if (value.Z < -100f)
391 {
392 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
393 }
394 AddChange(changes.Position, value);
395 } 387 }
396 else 388 if (value.Z < -100f)
397 { 389 {
398 m_log.Warn("[PHYSICS]: Got a NaN Position from Scene on a Character"); 390 value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
399 } 391 }
392 AddChange(changes.Position, value);
393 }
394 else
395 {
396 m_log.Warn("[PHYSICS]: Got a NaN Position from Scene on a Character");
400 } 397 }
401 } 398 }
402 } 399 }
@@ -616,7 +613,7 @@ namespace OpenSim.Region.Physics.OdePlugin
616 { 613 {
617 if (pushforce) 614 if (pushforce)
618 { 615 {
619 AddChange(changes.Force, force * m_density / _parent_scene.ODE_STEPSIZE / 28f); 616 AddChange(changes.Force, force * m_density / (_parent_scene.ODE_STEPSIZE * 28f));
620 } 617 }
621 else 618 else
622 { 619 {
@@ -687,6 +684,7 @@ namespace OpenSim.Region.Physics.OdePlugin
687 684
688 _zeroFlag = false; 685 _zeroFlag = false;
689 m_pidControllerActive = true; 686 m_pidControllerActive = true;
687 m_freemove = false;
690 688
691 d.BodySetAutoDisableFlag(Body, false); 689 d.BodySetAutoDisableFlag(Body, false);
692 d.BodySetPosition(Body, npositionX, npositionY, npositionZ); 690 d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
@@ -828,11 +826,17 @@ namespace OpenSim.Region.Physics.OdePlugin
828 localpos.Y = _parent_scene.WorldExtents.Y - 0.1f; 826 localpos.Y = _parent_scene.WorldExtents.Y - 0.1f;
829 } 827 }
830 if (fixbody) 828 if (fixbody)
829 {
830 m_freemove = false;
831 d.BodySetPosition(Body, localpos.X, localpos.Y, localpos.Z); 831 d.BodySetPosition(Body, localpos.X, localpos.Y, localpos.Z);
832 }
833
834 float breakfactor;
832 835
833 Vector3 vec = Vector3.Zero; 836 Vector3 vec = Vector3.Zero;
834 dtmp = d.BodyGetLinearVel(Body); 837 dtmp = d.BodyGetLinearVel(Body);
835 Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); 838 Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
839 float velLengthSquared = vel.LengthSquared();
836 840
837 float movementdivisor = 1f; 841 float movementdivisor = 1f;
838 //Ubit change divisions into multiplications below 842 //Ubit change divisions into multiplications below
@@ -871,104 +875,148 @@ namespace OpenSim.Region.Physics.OdePlugin
871 875
872 if (depth < 0.1f) 876 if (depth < 0.1f)
873 { 877 {
874 m_iscolliding = true; 878 m_colliderGroundfilter++;
875 m_colliderfilter = 2; 879 if (m_colliderGroundfilter > 2)
876 m_iscollidingGround = true; 880 {
877 881 m_iscolliding = true;
878 ContactPoint contact = new ContactPoint(); 882 m_colliderfilter = 2;
879 contact.PenetrationDepth = depth; 883
880 contact.Position.X = localpos.X; 884 if (m_colliderGroundfilter > 10)
881 contact.Position.Y = localpos.Y; 885 {
882 contact.Position.Z = chrminZ; 886 m_colliderGroundfilter = 10;
883 contact.SurfaceNormal.X = 0f; 887 m_freemove = false;
884 contact.SurfaceNormal.Y = 0f; 888 }
885 contact.SurfaceNormal.Z = -1f; 889
886 AddCollisionEvent(0, contact); 890 m_iscollidingGround = true;
887 891
888 vec.Z *= 0.5f; 892 ContactPoint contact = new ContactPoint();
893 contact.PenetrationDepth = depth;
894 contact.Position.X = localpos.X;
895 contact.Position.Y = localpos.Y;
896 contact.Position.Z = chrminZ;
897 contact.SurfaceNormal.X = 0f;
898 contact.SurfaceNormal.Y = 0f;
899 contact.SurfaceNormal.Z = -1f;
900 AddCollisionEvent(0, contact);
901
902 vec.Z *= 0.5f;
903 }
889 } 904 }
890 905
891 else 906 else
907 {
908 m_colliderGroundfilter = 0;
892 m_iscollidingGround = false; 909 m_iscollidingGround = false;
910 }
893 } 911 }
894 else 912 else
913 {
914 m_colliderGroundfilter = 0;
895 m_iscollidingGround = false; 915 m_iscollidingGround = false;
916 }
896 917
897 //****************************************** 918 //******************************************
898 919
899 // if velocity is zero, use position control; otherwise, velocity control 920 bool tviszero = (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f);
900 if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f 921
901 && m_iscolliding) 922 // if (!tviszero || m_iscolliding || velLengthSquared <0.01)
923 if (!tviszero)
924 m_freemove = false;
925
926 if (!m_freemove)
902 { 927 {
903 // keep track of where we stopped. No more slippin' & slidin' 928
904 if (!_zeroFlag) 929 // if velocity is zero, use position control; otherwise, velocity control
905 { 930 if (tviszero && m_iscolliding)
906 _zeroFlag = true;
907 _zeroPosition = localpos;
908 }
909 if (m_pidControllerActive)
910 { 931 {
911 // We only want to deactivate the PID Controller if we think we want to have our surrogate 932 // keep track of where we stopped. No more slippin' & slidin'
912 // react to the physics scene by moving it's position. 933 if (!_zeroFlag)
913 // Avatar to Avatar collisions
914 // Prim to avatar collisions
915
916 vec.X = -vel.X * PID_D + (_zeroPosition.X - localpos.X) * (PID_P * 2);
917 vec.Y = -vel.Y * PID_D + (_zeroPosition.Y - localpos.Y) * (PID_P * 2);
918 if (flying)
919 { 934 {
920 vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P; 935 _zeroFlag = true;
936 _zeroPosition = localpos;
921 } 937 }
922 } 938 if (m_pidControllerActive)
923 //PidStatus = true;
924 }
925 else
926 {
927 m_pidControllerActive = true;
928 _zeroFlag = false;
929
930 if (m_iscolliding)
931 {
932 if (!flying)
933 { 939 {
934 if (_target_velocity.Z > 0.0f) 940 // We only want to deactivate the PID Controller if we think we want to have our surrogate
941 // react to the physics scene by moving it's position.
942 // Avatar to Avatar collisions
943 // Prim to avatar collisions
944
945 vec.X = -vel.X * PID_D + (_zeroPosition.X - localpos.X) * (PID_P * 2);
946 vec.Y = -vel.Y * PID_D + (_zeroPosition.Y - localpos.Y) * (PID_P * 2);
947 if (flying)
935 { 948 {
936 // We're colliding with something and we're not flying but we're moving 949 vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P;
937 // This means we're walking or running. JUMPING
938 vec.Z += (_target_velocity.Z - vel.Z) * PID_D * 1.2f;// +(_zeroPosition.Z - localpos.Z) * PID_P;
939 } 950 }
940 // We're standing on something
941 vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D);
942 vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D);
943 }
944 else
945 {
946 // We're flying and colliding with something
947 vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D * 0.0625f);
948 vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D * 0.0625f);
949 vec.Z += (_target_velocity.Z - vel.Z) * (PID_D);
950 } 951 }
952 //PidStatus = true;
951 } 953 }
952 else // ie not colliding 954 else
953 { 955 {
954 if (flying) //(!m_iscolliding && flying) 956 m_pidControllerActive = true;
957 _zeroFlag = false;
958
959 if (m_iscolliding)
955 { 960 {
956 // we're in mid air suspended 961 if (!flying)
957 vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D * 1.667f); 962 {
958 vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D * 1.667f); 963 if (_target_velocity.Z > 0.0f)
959 vec.Z += (_target_velocity.Z - vel.Z) * (PID_D); 964 {
965 // We're colliding with something and we're not flying but we're moving
966 // This means we're walking or running. JUMPING
967 vec.Z += (_target_velocity.Z - vel.Z) * PID_D * 1.2f;// +(_zeroPosition.Z - localpos.Z) * PID_P;
968 }
969 // We're standing on something
970 vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D);
971 vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D);
972 }
973 else
974 {
975 // We're flying and colliding with something
976 vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D * 0.0625f);
977 vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D * 0.0625f);
978 vec.Z += (_target_velocity.Z - vel.Z) * (PID_D);
979 }
960 } 980 }
961 981 else // ie not colliding
962 else
963 { 982 {
964 // we're not colliding and we're not flying so that means we're falling! 983 if (flying) //(!m_iscolliding && flying)
965 // m_iscolliding includes collisions with the ground. 984 {
985 // we're in mid air suspended
986 vec.X = ((_target_velocity.X * movementdivisor) - vel.X) * (PID_D * 1.667f);
987 vec.Y = ((_target_velocity.Y * movementdivisor) - vel.Y) * (PID_D * 1.667f);
988 vec.Z += (_target_velocity.Z - vel.Z) * (PID_D);
989 }
966 990
967 // d.Vector3 pos = d.BodyGetPosition(Body); 991 else
968 vec.X = (_target_velocity.X - vel.X) * PID_D * 0.833f; 992 {
969 vec.Y = (_target_velocity.Y - vel.Y) * PID_D * 0.833f; 993 // we're not colliding and we're not flying so that means we're falling!
994 // m_iscolliding includes collisions with the ground.
995
996 // d.Vector3 pos = d.BodyGetPosition(Body);
997 vec.X = (_target_velocity.X - vel.X) * PID_D * 0.833f;
998 vec.Y = (_target_velocity.Y - vel.Y) * PID_D * 0.833f;
999 }
970 } 1000 }
971 } 1001 }
1002
1003 if (velLengthSquared > 2500.0f) // 50m/s apply breaks
1004 {
1005 breakfactor = 0.16f * m_mass;
1006 vec.X -= breakfactor * vel.X;
1007 vec.Y -= breakfactor * vel.Y;
1008 vec.Z -= breakfactor * vel.Z;
1009 }
1010 }
1011 else
1012 {
1013 breakfactor = m_mass;
1014 vec.X -= breakfactor * vel.X;
1015 vec.Y -= breakfactor * vel.Y;
1016 if (flying)
1017 vec.Z -= breakfactor * vel.Z;
1018 else
1019 vec.Z -= .5f* m_mass * vel.Z;
972 } 1020 }
973 1021
974 if (flying) 1022 if (flying)
@@ -985,14 +1033,6 @@ namespace OpenSim.Region.Physics.OdePlugin
985 // end add Kitto Flora 1033 // end add Kitto Flora
986 } 1034 }
987 1035
988 if (vel.X * vel.X + vel.Y * vel.Y + vel.Z * vel.Z > 2500.0f) // 50m/s apply breaks
989 {
990 float breakfactor = 0.16f * m_mass; // will give aprox 60m/s terminal velocity at free fall
991 vec.X -= breakfactor * vel.X;
992 vec.Y -= breakfactor * vel.Y;
993 vec.Z -= breakfactor * vel.Z;
994 }
995
996 if (vec.IsFinite()) 1036 if (vec.IsFinite())
997 { 1037 {
998 if (vec.X != 0 || vec.Y !=0 || vec.Z !=0) 1038 if (vec.X != 0 || vec.Y !=0 || vec.Z !=0)
@@ -1210,6 +1250,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1210 if (Body != IntPtr.Zero) 1250 if (Body != IntPtr.Zero)
1211 d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z); 1251 d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z);
1212 _position = newPos; 1252 _position = newPos;
1253 m_pidControllerActive = true;
1213 } 1254 }
1214 1255
1215 private void changeOrientation(Quaternion newOri) 1256 private void changeOrientation(Quaternion newOri)
@@ -1256,11 +1297,30 @@ namespace OpenSim.Region.Physics.OdePlugin
1256 1297
1257 private void changeBuilding(bool arg) 1298 private void changeBuilding(bool arg)
1258 { 1299 {
1259 } 1300 }
1301
1302 private void setFreeMove()
1303 {
1304 m_pidControllerActive = true;
1305 _zeroFlag = false;
1306 _target_velocity = Vector3.Zero;
1307 m_freemove = true;
1308 m_colliderfilter = -2;
1309 m_colliderObjectfilter = -2;
1310 m_colliderGroundfilter = -2;
1311
1312 m_iscolliding = false;
1313 m_iscollidingGround = false;
1314 m_iscollidingObj = false;
1315
1316 CollisionEventsThisFrame = new CollisionEventUpdate();
1317 m_eventsubscription = 0;
1318 }
1260 1319
1261 private void changeForce(Vector3 newForce) 1320 private void changeForce(Vector3 newForce)
1262 { 1321 {
1263 m_pidControllerActive = false; 1322 setFreeMove();
1323
1264 if (Body != IntPtr.Zero) 1324 if (Body != IntPtr.Zero)
1265 { 1325 {
1266 if (newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0) 1326 if (newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0)
@@ -1272,8 +1332,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1272 private void changeMomentum(Vector3 newmomentum) 1332 private void changeMomentum(Vector3 newmomentum)
1273 { 1333 {
1274 _velocity = newmomentum; 1334 _velocity = newmomentum;
1275 _target_velocity = newmomentum; 1335 setFreeMove();
1276 m_pidControllerActive = true; 1336
1277 if (Body != IntPtr.Zero) 1337 if (Body != IntPtr.Zero)
1278 d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); 1338 d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z);
1279 } 1339 }