aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs46
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs40
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs35
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs260
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs210
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs35
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2
8 files changed, 428 insertions, 228 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 66a6520..b5e1a52 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2671,11 +2671,11 @@ namespace OpenSim.Region.Framework.Scenes
2671 2671
2672 Vector3 axPos = linkPart.OffsetPosition; 2672 Vector3 axPos = linkPart.OffsetPosition;
2673 Quaternion parentRot = m_rootPart.RotationOffset; 2673 Quaternion parentRot = m_rootPart.RotationOffset;
2674 axPos *= Quaternion.Inverse(parentRot); 2674 axPos *= Quaternion.Conjugate(parentRot);
2675 linkPart.OffsetPosition = axPos; 2675 linkPart.OffsetPosition = axPos;
2676 2676
2677 Quaternion oldRot = linkPart.RotationOffset; 2677 Quaternion oldRot = linkPart.RotationOffset;
2678 Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; 2678 Quaternion newRot = Quaternion.Conjugate(parentRot) * oldRot;
2679 linkPart.RotationOffset = newRot; 2679 linkPart.RotationOffset = newRot;
2680 2680
2681// linkPart.ParentID = m_rootPart.LocalId; done above 2681// linkPart.ParentID = m_rootPart.LocalId; done above
@@ -2943,12 +2943,12 @@ namespace OpenSim.Region.Framework.Scenes
2943 Quaternion rootRotation = m_rootPart.RotationOffset; 2943 Quaternion rootRotation = m_rootPart.RotationOffset;
2944 2944
2945 Vector3 pos = part.OffsetPosition; 2945 Vector3 pos = part.OffsetPosition;
2946 pos *= Quaternion.Inverse(rootRotation); 2946 pos *= Quaternion.Conjugate(rootRotation);
2947 part.OffsetPosition = pos; 2947 part.OffsetPosition = pos;
2948 2948
2949 parentRot = m_rootPart.RotationOffset; 2949 parentRot = m_rootPart.RotationOffset;
2950 oldRot = part.RotationOffset; 2950 oldRot = part.RotationOffset;
2951 Quaternion newRot = Quaternion.Inverse(parentRot) * worldRot; 2951 Quaternion newRot = Quaternion.Conjugate(parentRot) * worldRot;
2952 part.RotationOffset = newRot; 2952 part.RotationOffset = newRot;
2953 2953
2954 part.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false); 2954 part.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false);
@@ -3548,13 +3548,16 @@ namespace OpenSim.Region.Framework.Scenes
3548 /// <param name="rot"></param> 3548 /// <param name="rot"></param>
3549 public void UpdateGroupRotationR(Quaternion rot) 3549 public void UpdateGroupRotationR(Quaternion rot)
3550 { 3550 {
3551 m_rootPart.UpdateRotation(rot);
3552
3553/* this is done by rootpart RotationOffset set called by UpdateRotation
3551 PhysicsActor actor = m_rootPart.PhysActor; 3554 PhysicsActor actor = m_rootPart.PhysActor;
3552 if (actor != null) 3555 if (actor != null)
3553 { 3556 {
3554 actor.Orientation = m_rootPart.RotationOffset; 3557 actor.Orientation = m_rootPart.RotationOffset;
3555 m_scene.PhysicsScene.AddPhysicsActorTaint(actor); 3558 m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
3556 } 3559 }
3557 3560*/
3558 HasGroupChanged = true; 3561 HasGroupChanged = true;
3559 ScheduleGroupForTerseUpdate(); 3562 ScheduleGroupForTerseUpdate();
3560 } 3563 }
@@ -4063,6 +4066,39 @@ namespace OpenSim.Region.Framework.Scenes
4063 return retmass; 4066 return retmass;
4064 } 4067 }
4065 4068
4069 // center of mass of full object
4070 public Vector3 GetCenterOfMass()
4071 {
4072 PhysicsActor pa = RootPart.PhysActor;
4073
4074 if(((RootPart.Flags & PrimFlags.Physics) !=0) && pa !=null)
4075 {
4076 // physics knows better about center of mass of physical prims
4077 Vector3 tmp = pa.CenterOfMass;
4078 return tmp;
4079 }
4080
4081 Vector3 Ptot = Vector3.Zero;
4082 float totmass = 0f;
4083 float m;
4084
4085 SceneObjectPart[] parts = m_parts.GetArray();
4086 for (int i = 0; i < parts.Length; i++)
4087 {
4088 m = parts[i].GetMass();
4089 Ptot += parts[i].GetPartCenterOfMass() * m;
4090 totmass += m;
4091 }
4092
4093 if (totmass == 0)
4094 totmass = 0;
4095 else
4096 totmass = 1 / totmass;
4097 Ptot *= totmass;
4098
4099 return Ptot;
4100 }
4101
4066 /// <summary> 4102 /// <summary>
4067 /// If the object is a sculpt/mesh, retrieve the mesh data for each part and reinsert it into each shape so that 4103 /// If the object is a sculpt/mesh, retrieve the mesh data for each part and reinsert it into each shape so that
4068 /// the physics engine can use it. 4104 /// the physics engine can use it.
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 37b5554..ffb86f3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1865,7 +1865,7 @@ namespace OpenSim.Region.Framework.Scenes
1865 { 1865 {
1866 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 1866 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1867 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 1867 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1868 AddToPhysics(isPhysical, isPhantom, building, true); 1868 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
1869 else 1869 else
1870 PhysActor = null; // just to be sure 1870 PhysActor = null; // just to be sure
1871 } 1871 }
@@ -2311,7 +2311,7 @@ namespace OpenSim.Region.Framework.Scenes
2311 */ 2311 */
2312 } 2312 }
2313 2313
2314 public float GetMass() 2314 public float GetMass()
2315 { 2315 {
2316 PhysicsActor pa = PhysActor; 2316 PhysicsActor pa = PhysActor;
2317 2317
@@ -2321,6 +2321,40 @@ namespace OpenSim.Region.Framework.Scenes
2321 return 0; 2321 return 0;
2322 } 2322 }
2323 2323
2324 public Vector3 GetCenterOfMass()
2325 {
2326 if (ParentGroup.RootPart == this)
2327 {
2328 if (ParentGroup.IsDeleted)
2329 return AbsolutePosition;
2330 return ParentGroup.GetCenterOfMass();
2331 }
2332
2333 PhysicsActor pa = PhysActor;
2334
2335 if (pa != null)
2336 {
2337 Vector3 tmp = pa.CenterOfMass;
2338 return tmp;
2339 }
2340 else
2341 return AbsolutePosition;
2342 }
2343
2344 public Vector3 GetPartCenterOfMass()
2345 {
2346 PhysicsActor pa = PhysActor;
2347
2348 if (pa != null)
2349 {
2350 Vector3 tmp = pa.CenterOfMass;
2351 return tmp;
2352 }
2353 else
2354 return AbsolutePosition;
2355 }
2356
2357
2324 public Vector3 GetForce() 2358 public Vector3 GetForce()
2325 { 2359 {
2326 return Force; 2360 return Force;
@@ -4804,7 +4838,7 @@ namespace OpenSim.Region.Framework.Scenes
4804 { 4838 {
4805 Velocity = velocity; 4839 Velocity = velocity;
4806 AngularVelocity = rotationalVelocity; 4840 AngularVelocity = rotationalVelocity;
4807 pa.Velocity = velocity; 4841// pa.Velocity = velocity;
4808 pa.RotationalVelocity = rotationalVelocity; 4842 pa.RotationalVelocity = rotationalVelocity;
4809 4843
4810 // if not vehicle and root part apply force and torque 4844 // if not vehicle and root part apply force and torque
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 311ba6a..1e717d9 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1088,6 +1088,41 @@ namespace OpenSim.Region.Framework.Scenes
1088 SendTerseUpdateToAllClients(); 1088 SendTerseUpdateToAllClients();
1089 } 1089 }
1090 1090
1091 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1092 {
1093 CheckLandingPoint(ref newpos);
1094 AbsolutePosition = newpos;
1095
1096 if (newvel.HasValue)
1097 {
1098 if ((Vector3)newvel == Vector3.Zero)
1099 {
1100 if (PhysicsActor != null)
1101 PhysicsActor.SetMomentum(Vector3.Zero);
1102 m_velocity = Vector3.Zero;
1103 }
1104 else
1105 {
1106 if (PhysicsActor != null)
1107 PhysicsActor.SetMomentum((Vector3)newvel);
1108 m_velocity = (Vector3)newvel;
1109
1110 if (rotateToVelXY)
1111 {
1112 Vector3 lookAt = (Vector3)newvel;
1113 lookAt.Z = 0;
1114 lookAt.Normalize();
1115 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1116 return;
1117 }
1118 }
1119 }
1120
1121 SendTerseUpdateToAllClients();
1122 }
1123
1124
1125
1091 public void StopFlying() 1126 public void StopFlying()
1092 { 1127 {
1093 ControllingClient.StopFlying(this); 1128 ControllingClient.StopFlying(this);
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 }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
index dcd02e2..d106677 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
@@ -121,6 +121,9 @@ namespace OpenSim.Region.Physics.OdePlugin
121 private float m_amEfect = 0; // current angular motor eficiency 121 private float m_amEfect = 0; // current angular motor eficiency
122 private float m_ffactor = 1.0f; 122 private float m_ffactor = 1.0f;
123 123
124 private float m_timestep = 0.02f;
125 private float m_invtimestep = 50;
126
124 public float FrictionFactor 127 public float FrictionFactor
125 { 128 {
126 get 129 get
@@ -133,14 +136,12 @@ namespace OpenSim.Region.Physics.OdePlugin
133 { 136 {
134 rootPrim = rootp; 137 rootPrim = rootp;
135 _pParentScene = rootPrim._parent_scene; 138 _pParentScene = rootPrim._parent_scene;
139 m_timestep = _pParentScene.ODE_STEPSIZE;
140 m_invtimestep = 1.0f / m_timestep;
136 } 141 }
137 142
138 public void DoSetVehicle(VehicleData vd) 143 public void DoSetVehicle(VehicleData vd)
139 { 144 {
140
141 float timestep = _pParentScene.ODE_STEPSIZE;
142 float invtimestep = 1.0f / timestep;
143
144 m_type = vd.m_type; 145 m_type = vd.m_type;
145 m_flags = vd.m_flags; 146 m_flags = vd.m_flags;
146 147
@@ -148,61 +149,60 @@ namespace OpenSim.Region.Physics.OdePlugin
148 m_linearMotorDirection = vd.m_linearMotorDirection; 149 m_linearMotorDirection = vd.m_linearMotorDirection;
149 150
150 m_linearFrictionTimescale = vd.m_linearFrictionTimescale; 151 m_linearFrictionTimescale = vd.m_linearFrictionTimescale;
151 if (m_linearFrictionTimescale.X < timestep) m_linearFrictionTimescale.X = timestep; 152 if (m_linearFrictionTimescale.X < m_timestep) m_linearFrictionTimescale.X = m_timestep;
152 if (m_linearFrictionTimescale.Y < timestep) m_linearFrictionTimescale.Y = timestep; 153 if (m_linearFrictionTimescale.Y < m_timestep) m_linearFrictionTimescale.Y = m_timestep;
153 if (m_linearFrictionTimescale.Z < timestep) m_linearFrictionTimescale.Z = timestep; 154 if (m_linearFrictionTimescale.Z < m_timestep) m_linearFrictionTimescale.Z = m_timestep;
154 155
155 m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale; 156 m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale;
156 if (m_linearMotorDecayTimescale < timestep) m_linearMotorDecayTimescale = timestep; 157 if (m_linearMotorDecayTimescale < m_timestep) m_linearMotorDecayTimescale = m_timestep;
157 m_linearMotorDecayTimescale *= invtimestep; 158 m_linearMotorDecayTimescale *= m_invtimestep;
158 159
159 m_linearMotorTimescale = vd.m_linearMotorTimescale; 160 m_linearMotorTimescale = vd.m_linearMotorTimescale;
160 if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep; 161 if (m_linearMotorTimescale < m_timestep) m_linearMotorTimescale = m_timestep;
161
162 162
163 m_linearMotorOffset = vd.m_linearMotorOffset; 163 m_linearMotorOffset = vd.m_linearMotorOffset;
164 164
165 //Angular properties 165 //Angular properties
166 m_angularMotorDirection = vd.m_angularMotorDirection; 166 m_angularMotorDirection = vd.m_angularMotorDirection;
167 m_angularMotorTimescale = vd.m_angularMotorTimescale; 167 m_angularMotorTimescale = vd.m_angularMotorTimescale;
168 if (m_angularMotorTimescale < timestep) m_angularMotorTimescale = timestep; 168 if (m_angularMotorTimescale < m_timestep) m_angularMotorTimescale = m_timestep;
169 169
170 m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale; 170 m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale;
171 if (m_angularMotorDecayTimescale < timestep) m_angularMotorDecayTimescale = timestep; 171 if (m_angularMotorDecayTimescale < m_timestep) m_angularMotorDecayTimescale = m_timestep;
172 m_angularMotorDecayTimescale *= invtimestep; 172 m_angularMotorDecayTimescale *= m_invtimestep;
173 173
174 m_angularFrictionTimescale = vd.m_angularFrictionTimescale; 174 m_angularFrictionTimescale = vd.m_angularFrictionTimescale;
175 if (m_angularFrictionTimescale.X < timestep) m_angularFrictionTimescale.X = timestep; 175 if (m_angularFrictionTimescale.X < m_timestep) m_angularFrictionTimescale.X = m_timestep;
176 if (m_angularFrictionTimescale.Y < timestep) m_angularFrictionTimescale.Y = timestep; 176 if (m_angularFrictionTimescale.Y < m_timestep) m_angularFrictionTimescale.Y = m_timestep;
177 if (m_angularFrictionTimescale.Z < timestep) m_angularFrictionTimescale.Z = timestep; 177 if (m_angularFrictionTimescale.Z < m_timestep) m_angularFrictionTimescale.Z = m_timestep;
178 178
179 //Deflection properties 179 //Deflection properties
180 m_angularDeflectionEfficiency = vd.m_angularDeflectionEfficiency; 180 m_angularDeflectionEfficiency = vd.m_angularDeflectionEfficiency;
181 m_angularDeflectionTimescale = vd.m_angularDeflectionTimescale; 181 m_angularDeflectionTimescale = vd.m_angularDeflectionTimescale;
182 if (m_angularDeflectionTimescale < timestep) m_angularDeflectionTimescale = timestep; 182 if (m_angularDeflectionTimescale < m_timestep) m_angularDeflectionTimescale = m_timestep;
183 183
184 m_linearDeflectionEfficiency = vd.m_linearDeflectionEfficiency; 184 m_linearDeflectionEfficiency = vd.m_linearDeflectionEfficiency;
185 m_linearDeflectionTimescale = vd.m_linearDeflectionTimescale; 185 m_linearDeflectionTimescale = vd.m_linearDeflectionTimescale;
186 if (m_linearDeflectionTimescale < timestep) m_linearDeflectionTimescale = timestep; 186 if (m_linearDeflectionTimescale < m_timestep) m_linearDeflectionTimescale = m_timestep;
187 187
188 //Banking properties 188 //Banking properties
189 m_bankingEfficiency = vd.m_bankingEfficiency; 189 m_bankingEfficiency = vd.m_bankingEfficiency;
190 m_bankingMix = vd.m_bankingMix; 190 m_bankingMix = vd.m_bankingMix;
191 m_bankingTimescale = vd.m_bankingTimescale; 191 m_bankingTimescale = vd.m_bankingTimescale;
192 if (m_bankingTimescale < timestep) m_bankingTimescale = timestep; 192 if (m_bankingTimescale < m_timestep) m_bankingTimescale = m_timestep;
193 193
194 //Hover and Buoyancy properties 194 //Hover and Buoyancy properties
195 m_VhoverHeight = vd.m_VhoverHeight; 195 m_VhoverHeight = vd.m_VhoverHeight;
196 m_VhoverEfficiency = vd.m_VhoverEfficiency; 196 m_VhoverEfficiency = vd.m_VhoverEfficiency;
197 m_VhoverTimescale = vd.m_VhoverTimescale; 197 m_VhoverTimescale = vd.m_VhoverTimescale;
198 if (m_VhoverTimescale < timestep) m_VhoverTimescale = timestep; 198 if (m_VhoverTimescale < m_timestep) m_VhoverTimescale = m_timestep;
199 199
200 m_VehicleBuoyancy = vd.m_VehicleBuoyancy; 200 m_VehicleBuoyancy = vd.m_VehicleBuoyancy;
201 201
202 //Attractor properties 202 //Attractor properties
203 m_verticalAttractionEfficiency = vd.m_verticalAttractionEfficiency; 203 m_verticalAttractionEfficiency = vd.m_verticalAttractionEfficiency;
204 m_verticalAttractionTimescale = vd.m_verticalAttractionTimescale; 204 m_verticalAttractionTimescale = vd.m_verticalAttractionTimescale;
205 if (m_verticalAttractionTimescale < timestep) m_verticalAttractionTimescale = timestep; 205 if (m_verticalAttractionTimescale < m_timestep) m_verticalAttractionTimescale = m_timestep;
206 206
207 // Axis 207 // Axis
208 m_referenceFrame = vd.m_referenceFrame; 208 m_referenceFrame = vd.m_referenceFrame;
@@ -215,8 +215,6 @@ namespace OpenSim.Region.Physics.OdePlugin
215 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 215 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
216 { 216 {
217 float len; 217 float len;
218 float invtimestep = 1.0f / _pParentScene.ODE_STEPSIZE;
219 float timestep = _pParentScene.ODE_STEPSIZE;
220 218
221 switch (pParam) 219 switch (pParam)
222 { 220 {
@@ -226,18 +224,16 @@ namespace OpenSim.Region.Physics.OdePlugin
226 m_angularDeflectionEfficiency = pValue; 224 m_angularDeflectionEfficiency = pValue;
227 break; 225 break;
228 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: 226 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
229 if (pValue < timestep) pValue = timestep; 227 if (pValue < m_timestep) pValue = m_timestep;
230 m_angularDeflectionTimescale = pValue; 228 m_angularDeflectionTimescale = pValue;
231 break; 229 break;
232 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: 230 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
233 if (pValue < timestep) pValue = timestep; 231 if (pValue < m_timestep) pValue = m_timestep;
234 // try to make impulses to work a bit better
235// if (pValue < 0.5f) pValue = 0.5f;
236 else if (pValue > 120) pValue = 120; 232 else if (pValue > 120) pValue = 120;
237 m_angularMotorDecayTimescale = pValue * invtimestep; 233 m_angularMotorDecayTimescale = pValue * m_invtimestep;
238 break; 234 break;
239 case Vehicle.ANGULAR_MOTOR_TIMESCALE: 235 case Vehicle.ANGULAR_MOTOR_TIMESCALE:
240 if (pValue < timestep) pValue = timestep; 236 if (pValue < m_timestep) pValue = m_timestep;
241 m_angularMotorTimescale = pValue; 237 m_angularMotorTimescale = pValue;
242 break; 238 break;
243 case Vehicle.BANKING_EFFICIENCY: 239 case Vehicle.BANKING_EFFICIENCY:
@@ -251,7 +247,7 @@ namespace OpenSim.Region.Physics.OdePlugin
251 m_bankingMix = pValue; 247 m_bankingMix = pValue;
252 break; 248 break;
253 case Vehicle.BANKING_TIMESCALE: 249 case Vehicle.BANKING_TIMESCALE:
254 if (pValue < timestep) pValue = timestep; 250 if (pValue < m_timestep) pValue = m_timestep;
255 m_bankingTimescale = pValue; 251 m_bankingTimescale = pValue;
256 break; 252 break;
257 case Vehicle.BUOYANCY: 253 case Vehicle.BUOYANCY:
@@ -268,7 +264,7 @@ namespace OpenSim.Region.Physics.OdePlugin
268 m_VhoverHeight = pValue; 264 m_VhoverHeight = pValue;
269 break; 265 break;
270 case Vehicle.HOVER_TIMESCALE: 266 case Vehicle.HOVER_TIMESCALE:
271 if (pValue < timestep) pValue = timestep; 267 if (pValue < m_timestep) pValue = m_timestep;
272 m_VhoverTimescale = pValue; 268 m_VhoverTimescale = pValue;
273 break; 269 break;
274 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: 270 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
@@ -277,18 +273,16 @@ namespace OpenSim.Region.Physics.OdePlugin
277 m_linearDeflectionEfficiency = pValue; 273 m_linearDeflectionEfficiency = pValue;
278 break; 274 break;
279 case Vehicle.LINEAR_DEFLECTION_TIMESCALE: 275 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
280 if (pValue < timestep) pValue = timestep; 276 if (pValue < m_timestep) pValue = m_timestep;
281 m_linearDeflectionTimescale = pValue; 277 m_linearDeflectionTimescale = pValue;
282 break; 278 break;
283 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: 279 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
284 if (pValue < timestep) pValue = timestep; 280 if (pValue < m_timestep) pValue = m_timestep;
285 // try to make impulses to work a bit better
286 //if (pValue < 0.5f) pValue = 0.5f;
287 else if (pValue > 120) pValue = 120; 281 else if (pValue > 120) pValue = 120;
288 m_linearMotorDecayTimescale = pValue * invtimestep; 282 m_linearMotorDecayTimescale = pValue * m_invtimestep;
289 break; 283 break;
290 case Vehicle.LINEAR_MOTOR_TIMESCALE: 284 case Vehicle.LINEAR_MOTOR_TIMESCALE:
291 if (pValue < timestep) pValue = timestep; 285 if (pValue < m_timestep) pValue = m_timestep;
292 m_linearMotorTimescale = pValue; 286 m_linearMotorTimescale = pValue;
293 break; 287 break;
294 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: 288 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
@@ -297,14 +291,14 @@ namespace OpenSim.Region.Physics.OdePlugin
297 m_verticalAttractionEfficiency = pValue; 291 m_verticalAttractionEfficiency = pValue;
298 break; 292 break;
299 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: 293 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
300 if (pValue < timestep) pValue = timestep; 294 if (pValue < m_timestep) pValue = m_timestep;
301 m_verticalAttractionTimescale = pValue; 295 m_verticalAttractionTimescale = pValue;
302 break; 296 break;
303 297
304 // These are vector properties but the engine lets you use a single float value to 298 // These are vector properties but the engine lets you use a single float value to
305 // set all of the components to the same value 299 // set all of the components to the same value
306 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 300 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
307 if (pValue < timestep) pValue = timestep; 301 if (pValue < m_timestep) pValue = m_timestep;
308 m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); 302 m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
309 break; 303 break;
310 case Vehicle.ANGULAR_MOTOR_DIRECTION: 304 case Vehicle.ANGULAR_MOTOR_DIRECTION:
@@ -318,7 +312,7 @@ namespace OpenSim.Region.Physics.OdePlugin
318 d.BodyEnable(rootPrim.Body); 312 d.BodyEnable(rootPrim.Body);
319 break; 313 break;
320 case Vehicle.LINEAR_FRICTION_TIMESCALE: 314 case Vehicle.LINEAR_FRICTION_TIMESCALE:
321 if (pValue < timestep) pValue = timestep; 315 if (pValue < m_timestep) pValue = m_timestep;
322 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); 316 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
323 break; 317 break;
324 case Vehicle.LINEAR_MOTOR_DIRECTION: 318 case Vehicle.LINEAR_MOTOR_DIRECTION:
@@ -344,14 +338,13 @@ namespace OpenSim.Region.Physics.OdePlugin
344 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) 338 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
345 { 339 {
346 float len; 340 float len;
347 float invtimestep = 1.0f / _pParentScene.ODE_STEPSIZE; 341
348 float timestep = _pParentScene.ODE_STEPSIZE;
349 switch (pParam) 342 switch (pParam)
350 { 343 {
351 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 344 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
352 if (pValue.X < timestep) pValue.X = timestep; 345 if (pValue.X < m_timestep) pValue.X = m_timestep;
353 if (pValue.Y < timestep) pValue.Y = timestep; 346 if (pValue.Y < m_timestep) pValue.Y = m_timestep;
354 if (pValue.Z < timestep) pValue.Z = timestep; 347 if (pValue.Z < m_timestep) pValue.Z = m_timestep;
355 348
356 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 349 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
357 break; 350 break;
@@ -367,9 +360,9 @@ namespace OpenSim.Region.Physics.OdePlugin
367 d.BodyEnable(rootPrim.Body); 360 d.BodyEnable(rootPrim.Body);
368 break; 361 break;
369 case Vehicle.LINEAR_FRICTION_TIMESCALE: 362 case Vehicle.LINEAR_FRICTION_TIMESCALE:
370 if (pValue.X < timestep) pValue.X = timestep; 363 if (pValue.X < m_timestep) pValue.X = m_timestep;
371 if (pValue.Y < timestep) pValue.Y = timestep; 364 if (pValue.Y < m_timestep) pValue.Y = m_timestep;
372 if (pValue.Z < timestep) pValue.Z = timestep; 365 if (pValue.Z < m_timestep) pValue.Z = m_timestep;
373 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 366 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
374 break; 367 break;
375 case Vehicle.LINEAR_MOTOR_DIRECTION: 368 case Vehicle.LINEAR_MOTOR_DIRECTION:
@@ -422,7 +415,6 @@ namespace OpenSim.Region.Physics.OdePlugin
422 415
423 internal void ProcessTypeChange(Vehicle pType) 416 internal void ProcessTypeChange(Vehicle pType)
424 { 417 {
425 float invtimestep = _pParentScene.ODE_STEPSIZE;
426 m_lmEfect = 0; 418 m_lmEfect = 0;
427 m_amEfect = 0; 419 m_amEfect = 0;
428 m_ffactor = 1f; 420 m_ffactor = 1f;
@@ -444,9 +436,9 @@ namespace OpenSim.Region.Physics.OdePlugin
444 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); 436 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
445 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); 437 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
446 m_linearMotorTimescale = 1000; 438 m_linearMotorTimescale = 1000;
447 m_linearMotorDecayTimescale = 120 * invtimestep; 439 m_linearMotorDecayTimescale = 120 * m_invtimestep;
448 m_angularMotorTimescale = 1000; 440 m_angularMotorTimescale = 1000;
449 m_angularMotorDecayTimescale = 1000 * invtimestep; 441 m_angularMotorDecayTimescale = 1000 * m_invtimestep;
450 m_VhoverHeight = 0; 442 m_VhoverHeight = 0;
451 m_VhoverEfficiency = 1; 443 m_VhoverEfficiency = 1;
452 m_VhoverTimescale = 1000; 444 m_VhoverTimescale = 1000;
@@ -468,9 +460,9 @@ namespace OpenSim.Region.Physics.OdePlugin
468 m_linearFrictionTimescale = new Vector3(30, 1, 1000); 460 m_linearFrictionTimescale = new Vector3(30, 1, 1000);
469 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); 461 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
470 m_linearMotorTimescale = 1000; 462 m_linearMotorTimescale = 1000;
471 m_linearMotorDecayTimescale = 120 * invtimestep; 463 m_linearMotorDecayTimescale = 120 * m_invtimestep;
472 m_angularMotorTimescale = 1000; 464 m_angularMotorTimescale = 1000;
473 m_angularMotorDecayTimescale = 120 * invtimestep; 465 m_angularMotorDecayTimescale = 120 * m_invtimestep;
474 m_VhoverHeight = 0; 466 m_VhoverHeight = 0;
475 m_VhoverEfficiency = 1; 467 m_VhoverEfficiency = 1;
476 m_VhoverTimescale = 10; 468 m_VhoverTimescale = 10;
@@ -491,9 +483,9 @@ namespace OpenSim.Region.Physics.OdePlugin
491 m_linearFrictionTimescale = new Vector3(100, 2, 1000); 483 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
492 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); 484 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
493 m_linearMotorTimescale = 1; 485 m_linearMotorTimescale = 1;
494 m_linearMotorDecayTimescale = 60 * invtimestep; 486 m_linearMotorDecayTimescale = 60 * m_invtimestep;
495 m_angularMotorTimescale = 1; 487 m_angularMotorTimescale = 1;
496 m_angularMotorDecayTimescale = 0.8f * invtimestep; 488 m_angularMotorDecayTimescale = 0.8f * m_invtimestep;
497 m_VhoverHeight = 0; 489 m_VhoverHeight = 0;
498 m_VhoverEfficiency = 0; 490 m_VhoverEfficiency = 0;
499 m_VhoverTimescale = 1000; 491 m_VhoverTimescale = 1000;
@@ -515,9 +507,9 @@ namespace OpenSim.Region.Physics.OdePlugin
515 m_linearFrictionTimescale = new Vector3(10, 3, 2); 507 m_linearFrictionTimescale = new Vector3(10, 3, 2);
516 m_angularFrictionTimescale = new Vector3(10, 10, 10); 508 m_angularFrictionTimescale = new Vector3(10, 10, 10);
517 m_linearMotorTimescale = 5; 509 m_linearMotorTimescale = 5;
518 m_linearMotorDecayTimescale = 60 * invtimestep; 510 m_linearMotorDecayTimescale = 60 * m_invtimestep;
519 m_angularMotorTimescale = 4; 511 m_angularMotorTimescale = 4;
520 m_angularMotorDecayTimescale = 4 * invtimestep; 512 m_angularMotorDecayTimescale = 4 * m_invtimestep;
521 m_VhoverHeight = 0; 513 m_VhoverHeight = 0;
522 m_VhoverEfficiency = 0.5f; 514 m_VhoverEfficiency = 0.5f;
523 m_VhoverTimescale = 2; 515 m_VhoverTimescale = 2;
@@ -543,9 +535,9 @@ namespace OpenSim.Region.Physics.OdePlugin
543 m_linearFrictionTimescale = new Vector3(200, 10, 5); 535 m_linearFrictionTimescale = new Vector3(200, 10, 5);
544 m_angularFrictionTimescale = new Vector3(20, 20, 20); 536 m_angularFrictionTimescale = new Vector3(20, 20, 20);
545 m_linearMotorTimescale = 2; 537 m_linearMotorTimescale = 2;
546 m_linearMotorDecayTimescale = 60 * invtimestep; 538 m_linearMotorDecayTimescale = 60 * m_invtimestep;
547 m_angularMotorTimescale = 4; 539 m_angularMotorTimescale = 4;
548 m_angularMotorDecayTimescale = 8 * invtimestep; 540 m_angularMotorDecayTimescale = 8 * m_invtimestep;
549 m_VhoverHeight = 0; 541 m_VhoverHeight = 0;
550 m_VhoverEfficiency = 0.5f; 542 m_VhoverEfficiency = 0.5f;
551 m_VhoverTimescale = 1000; 543 m_VhoverTimescale = 1000;
@@ -571,15 +563,15 @@ namespace OpenSim.Region.Physics.OdePlugin
571 m_linearFrictionTimescale = new Vector3(5, 5, 5); 563 m_linearFrictionTimescale = new Vector3(5, 5, 5);
572 m_angularFrictionTimescale = new Vector3(10, 10, 10); 564 m_angularFrictionTimescale = new Vector3(10, 10, 10);
573 m_linearMotorTimescale = 5; 565 m_linearMotorTimescale = 5;
574 m_linearMotorDecayTimescale = 60 * invtimestep; 566 m_linearMotorDecayTimescale = 60 * m_invtimestep;
575 m_angularMotorTimescale = 6; 567 m_angularMotorTimescale = 6;
576 m_angularMotorDecayTimescale = 10 * invtimestep; 568 m_angularMotorDecayTimescale = 10 * m_invtimestep;
577 m_VhoverHeight = 5; 569 m_VhoverHeight = 5;
578 m_VhoverEfficiency = 0.8f; 570 m_VhoverEfficiency = 0.8f;
579 m_VhoverTimescale = 10; 571 m_VhoverTimescale = 10;
580 m_VehicleBuoyancy = 1; 572 m_VehicleBuoyancy = 1;
581 m_linearDeflectionEfficiency = 0; 573 m_linearDeflectionEfficiency = 0;
582 m_linearDeflectionTimescale = 5 * invtimestep; 574 m_linearDeflectionTimescale = 5 * m_invtimestep;
583 m_angularDeflectionEfficiency = 0; 575 m_angularDeflectionEfficiency = 0;
584 m_angularDeflectionTimescale = 5; 576 m_angularDeflectionTimescale = 5;
585 m_verticalAttractionEfficiency = 0f; 577 m_verticalAttractionEfficiency = 0f;
@@ -701,7 +693,7 @@ namespace OpenSim.Region.Physics.OdePlugin
701 return ; 693 return ;
702 } 694 }
703 695
704 internal void Step()//float pTimestep) 696 internal void Step()
705 { 697 {
706 IntPtr Body = rootPrim.Body; 698 IntPtr Body = rootPrim.Body;
707 699
@@ -780,30 +772,37 @@ namespace OpenSim.Region.Physics.OdePlugin
780 { 772 {
781 d.Vector3 pos = d.BodyGetPosition(Body); 773 d.Vector3 pos = d.BodyGetPosition(Body);
782 774
783 // default to global 775 float t = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
784 float perr = m_VhoverHeight - pos.Z;; 776 float perr;
785 777
786 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) 778 // default to global but don't go underground
787 { 779 if (t < m_VhoverHeight)
788 perr += _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); 780 perr = m_VhoverHeight - pos.Z;
789 } 781 else
790 else if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) 782 perr = t - pos.Z; ;
791 { 783
792 perr += _pParentScene.GetWaterLevel(); 784 if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == 0)
793 }
794 else if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == 0)
795 { 785 {
796 float t = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); 786 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
797 float w = _pParentScene.GetWaterLevel(); 787 {
798 if (t > w) 788 perr += _pParentScene.GetWaterLevel();
789 }
790 else if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
791 {
799 perr += t; 792 perr += t;
793 }
800 else 794 else
801 perr += w; 795 {
796 float w = _pParentScene.GetWaterLevel();
797 if (t > w)
798 perr += t;
799 else
800 perr += w;
801 }
802 } 802 }
803
804 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > 0) 803 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > 0)
805 { 804 {
806 force.Z += (perr / m_VhoverTimescale / m_VhoverTimescale - curVel.Z * m_VhoverEfficiency) / _pParentScene.ODE_STEPSIZE; 805 force.Z += (perr / m_VhoverTimescale / m_VhoverTimescale - curVel.Z * m_VhoverEfficiency) / m_timestep;
807 force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy); 806 force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy);
808 } 807 }
809 else // no buoyancy 808 else // no buoyancy
@@ -811,7 +810,7 @@ namespace OpenSim.Region.Physics.OdePlugin
811 } 810 }
812 else 811 else
813 { 812 {
814 // default gravity and buoancy 813 // default gravity and Buoyancy
815 force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy); 814 force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy);
816 } 815 }
817 816
@@ -819,24 +818,31 @@ namespace OpenSim.Region.Physics.OdePlugin
819 if (m_linearDeflectionEfficiency > 0) 818 if (m_linearDeflectionEfficiency > 0)
820 { 819 {
821 float len = curVel.Length(); 820 float len = curVel.Length();
822 Vector3 atAxis; 821 if (len > 0.01) // if moving
823 atAxis = Xrot(rotq); // where are we pointing to
824 atAxis *= len; // make it same size as world velocity vector
825 tmpV = -atAxis; // oposite direction
826 atAxis -= curVel; // error to one direction
827 len = atAxis.LengthSquared();
828 tmpV -= curVel; // error to oposite
829 float lens = tmpV.LengthSquared();
830 if (len > 0.01 || lens > 0.01) // do nothing if close enougth
831 { 822 {
832 if (len < lens)
833 tmpV = atAxis;
834 823
835 tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep 824 Vector3 atAxis;
836 force.X += tmpV.X; 825 atAxis = Xrot(rotq); // where are we pointing to
837 force.Y += tmpV.Y; 826 atAxis *= len; // make it same size as world velocity vector
838 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) == 0) 827
839 force.Z += tmpV.Z; 828 tmpV = -atAxis; // oposite direction
829 atAxis -= curVel; // error to one direction
830 len = atAxis.LengthSquared();
831
832 tmpV -= curVel; // error to oposite
833 float lens = tmpV.LengthSquared();
834
835 if (len > 0.01 || lens > 0.01) // do nothing if close enougth
836 {
837 if (len < lens)
838 tmpV = atAxis;
839
840 tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep
841 force.X += tmpV.X;
842 force.Y += tmpV.Y;
843 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) == 0)
844 force.Z += tmpV.Z;
845 }
840 } 846 }
841 } 847 }
842 848
@@ -900,10 +906,10 @@ namespace OpenSim.Region.Physics.OdePlugin
900 906
901 GetRollPitch(irotq, out roll, out pitch); 907 GetRollPitch(irotq, out roll, out pitch);
902 908
903 float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE; 909 float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale * m_invtimestep;
904 float ftmp2; 910 float ftmp2;
905 if (m_bankingEfficiency == 0) 911 if (m_bankingEfficiency == 0)
906 ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE; 912 ftmp2 = m_verticalAttractionEfficiency * m_invtimestep;
907 else 913 else
908 ftmp2 = 0; 914 ftmp2 = 0;
909 915
@@ -985,7 +991,7 @@ namespace OpenSim.Region.Physics.OdePlugin
985 if (torque.X != 0 || torque.Y != 0 || torque.Z != 0) 991 if (torque.X != 0 || torque.Y != 0 || torque.Z != 0)
986 { 992 {
987 torque *= m_referenceFrame; // to object frame 993 torque *= m_referenceFrame; // to object frame
988 dtorque.X = torque.X; 994 dtorque.X = torque.X ;
989 dtorque.Y = torque.Y; 995 dtorque.Y = torque.Y;
990 dtorque.Z = torque.Z; 996 dtorque.Z = torque.Z;
991 997
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index 2d587ab..c9a453d 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -450,7 +450,7 @@ namespace OpenSim.Region.Physics.OdePlugin
450 get 450 get
451 { 451 {
452 d.Vector3 dtmp; 452 d.Vector3 dtmp;
453 if (IsPhysical && !childPrim && Body != IntPtr.Zero) 453 if (!childPrim && Body != IntPtr.Zero)
454 { 454 {
455 dtmp = d.BodyGetPosition(Body); 455 dtmp = d.BodyGetPosition(Body);
456 return new Vector3(dtmp.X, dtmp.Y, dtmp.Z); 456 return new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
@@ -465,12 +465,38 @@ namespace OpenSim.Region.Physics.OdePlugin
465 q.Z = dq.Z; 465 q.Z = dq.Z;
466 q.W = dq.W; 466 q.W = dq.W;
467 467
468 Vector3 vtmp = primOOBoffset * q; 468 Vector3 Ptot = primOOBoffset * q;
469 dtmp = d.GeomGetPosition(prim_geom); 469 dtmp = d.GeomGetPosition(prim_geom);
470 return new Vector3(dtmp.X + vtmp.X, dtmp.Y + vtmp.Y, dtmp.Z + vtmp.Z); 470 Ptot.X += dtmp.X;
471 Ptot.Y += dtmp.Y;
472 Ptot.Z += dtmp.Z;
473
474// if(childPrim) we only know about physical linksets
475 return Ptot;
476/*
477 float tmass = _mass;
478 Ptot *= tmass;
479
480 float m;
481
482 foreach (OdePrim prm in childrenPrim)
483 {
484 m = prm._mass;
485 Ptot += prm.CenterOfMass * m;
486 tmass += m;
487 }
488
489 if (tmass == 0)
490 tmass = 0;
491 else
492 tmass = 1.0f / tmass;
493
494 Ptot *= tmass;
495 return Ptot;
496 */
471 } 497 }
472 else 498 else
473 return Vector3.Zero; 499 return _position;
474 } 500 }
475 } 501 }
476 /* 502 /*
@@ -3490,7 +3516,6 @@ namespace OpenSim.Region.Physics.OdePlugin
3490 { 3516 {
3491 d.BodySetPosition(Body, lpos.X, lpos.Y, m_targetHoverHeight); 3517 d.BodySetPosition(Body, lpos.X, lpos.Y, m_targetHoverHeight);
3492 d.BodySetLinearVel(Body, vel.X, vel.Y, 0); 3518 d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
3493 return;
3494 } 3519 }
3495 else 3520 else
3496 { 3521 {
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index cf74f14..fa3d33e 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -1020,12 +1020,16 @@ namespace OpenSim.Region.Physics.OdePlugin
1020 1020
1021 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) 1021 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact)
1022 { 1022 {
1023 // obj1LocalID = 0;
1024 //returncollisions = false;
1025 obj2LocalID = 0; 1023 obj2LocalID = 0;
1026 //ctype = 0; 1024 bool p1events = p1.SubscribedEvents();
1027 //cStartStop = 0; 1025 bool p2events = p2.SubscribedEvents();
1028 if (!(p2.SubscribedEvents() || p1.SubscribedEvents())) 1026
1027 if (p1 is OdePrim && p1.IsVolumeDtc)
1028 p2events = false;
1029 if (p2 is OdePrim && p2.IsVolumeDtc)
1030 p1events = false;
1031
1032 if (!(p2events || p1events))
1029 return; 1033 return;
1030 1034
1031 switch ((ActorTypes)p1.PhysicsActorType) 1035 switch ((ActorTypes)p1.PhysicsActorType)
@@ -1037,7 +1041,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1037 case ActorTypes.Agent: 1041 case ActorTypes.Agent:
1038 cc2 = (OdeCharacter)p2; 1042 cc2 = (OdeCharacter)p2;
1039 obj2LocalID = cc2.m_localID; 1043 obj2LocalID = cc2.m_localID;
1040 if (p2.SubscribedEvents()) 1044 if (p2events)
1041 cc2.AddCollisionEvent(cc1.m_localID, contact); 1045 cc2.AddCollisionEvent(cc1.m_localID, contact);
1042 break; 1046 break;
1043 1047
@@ -1046,7 +1050,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1046 { 1050 {
1047 cp2 = (OdePrim)p2; 1051 cp2 = (OdePrim)p2;
1048 obj2LocalID = cp2.m_localID; 1052 obj2LocalID = cp2.m_localID;
1049 if (p2.SubscribedEvents()) 1053 if (p2events)
1050 cp2.AddCollisionEvent(cc1.m_localID, contact); 1054 cp2.AddCollisionEvent(cc1.m_localID, contact);
1051 } 1055 }
1052 break; 1056 break;
@@ -1057,7 +1061,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1057 obj2LocalID = 0; 1061 obj2LocalID = 0;
1058 break; 1062 break;
1059 } 1063 }
1060 if (p1.SubscribedEvents()) 1064 if (p1events)
1061 { 1065 {
1062 contact.SurfaceNormal = -contact.SurfaceNormal; 1066 contact.SurfaceNormal = -contact.SurfaceNormal;
1063 cc1.AddCollisionEvent(obj2LocalID, contact); 1067 cc1.AddCollisionEvent(obj2LocalID, contact);
@@ -1078,7 +1082,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1078 { 1082 {
1079 cc2 = (OdeCharacter)p2; 1083 cc2 = (OdeCharacter)p2;
1080 obj2LocalID = cc2.m_localID; 1084 obj2LocalID = cc2.m_localID;
1081 if (p2.SubscribedEvents()) 1085 if (p2events)
1082 cc2.AddCollisionEvent(cp1.m_localID, contact); 1086 cc2.AddCollisionEvent(cp1.m_localID, contact);
1083 } 1087 }
1084 break; 1088 break;
@@ -1088,7 +1092,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1088 { 1092 {
1089 cp2 = (OdePrim)p2; 1093 cp2 = (OdePrim)p2;
1090 obj2LocalID = cp2.m_localID; 1094 obj2LocalID = cp2.m_localID;
1091 if (p2.SubscribedEvents()) 1095 if (p2events)
1092 cp2.AddCollisionEvent(cp1.m_localID, contact); 1096 cp2.AddCollisionEvent(cp1.m_localID, contact);
1093 } 1097 }
1094 break; 1098 break;
@@ -1099,7 +1103,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1099 obj2LocalID = 0; 1103 obj2LocalID = 0;
1100 break; 1104 break;
1101 } 1105 }
1102 if (p1.SubscribedEvents()) 1106 if (p1events)
1103 { 1107 {
1104 contact.SurfaceNormal = -contact.SurfaceNormal; 1108 contact.SurfaceNormal = -contact.SurfaceNormal;
1105 cp1.AddCollisionEvent(obj2LocalID, contact); 1109 cp1.AddCollisionEvent(obj2LocalID, contact);
@@ -1734,7 +1738,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1734 base.TriggerPhysicsBasedRestart(); 1738 base.TriggerPhysicsBasedRestart();
1735 } 1739 }
1736 1740
1737 while (step_time >= HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever 1741 while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever
1738 { 1742 {
1739 try 1743 try
1740 { 1744 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 5a5f2e1..3fe5780 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -5237,7 +5237,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5237 public LSL_Vector llGetCenterOfMass() 5237 public LSL_Vector llGetCenterOfMass()
5238 { 5238 {
5239 m_host.AddScriptLPS(1); 5239 m_host.AddScriptLPS(1);
5240 Vector3 center = m_host.GetGeometricCenter(); 5240 Vector3 center = m_host.GetCenterOfMass();
5241 return new LSL_Vector(center.X,center.Y,center.Z); 5241 return new LSL_Vector(center.X,center.Y,center.Z);
5242 } 5242 }
5243 5243