aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs254
1 files changed, 154 insertions, 100 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
index 8f2feba..e88e559 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
@@ -117,14 +117,23 @@ namespace OpenSim.Region.Physics.OdePlugin
117 117
118 118
119 // auxiliar 119 // auxiliar
120 private float m_lmEfect = 0; // current linear motor eficiency 120 private float m_lmEfect = 0f; // current linear motor eficiency
121 private float m_lmDecay = 1.0f; 121 private float m_lmDecay = 0f; // current linear decay
122
122 private float m_amEfect = 0; // current angular motor eficiency 123 private float m_amEfect = 0; // current angular motor eficiency
124 private float m_amDecay = 0f; // current linear decay
125
123 private float m_ffactor = 1.0f; 126 private float m_ffactor = 1.0f;
124 127
125 private float m_timestep = 0.02f; 128 private float m_timestep = 0.02f;
126 private float m_invtimestep = 50; 129 private float m_invtimestep = 50;
127 130
131
132 float m_ampwr;
133 float m_amdampX;
134 float m_amdampY;
135 float m_amdampZ;
136
128 public float FrictionFactor 137 public float FrictionFactor
129 { 138 {
130 get 139 get
@@ -146,6 +155,7 @@ namespace OpenSim.Region.Physics.OdePlugin
146 m_type = vd.m_type; 155 m_type = vd.m_type;
147 m_flags = vd.m_flags; 156 m_flags = vd.m_flags;
148 157
158
149 // Linear properties 159 // Linear properties
150 m_linearMotorDirection = vd.m_linearMotorDirection; 160 m_linearMotorDirection = vd.m_linearMotorDirection;
151 161
@@ -309,7 +319,10 @@ namespace OpenSim.Region.Physics.OdePlugin
309 len = m_angularMotorDirection.Length(); 319 len = m_angularMotorDirection.Length();
310 if (len > 12.566f) 320 if (len > 12.566f)
311 m_angularMotorDirection *= (12.566f / len); 321 m_angularMotorDirection *= (12.566f / len);
312 m_amEfect = 1.0f; // turn it on 322
323 m_amEfect = 1.0f / m_angularMotorTimescale; // turn it on
324 m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale;
325
313 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) 326 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
314 && !rootPrim.m_isSelected && !rootPrim.m_disabled) 327 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
315 d.BodyEnable(rootPrim.Body); 328 d.BodyEnable(rootPrim.Body);
@@ -323,8 +336,10 @@ namespace OpenSim.Region.Physics.OdePlugin
323 len = m_linearMotorDirection.Length(); 336 len = m_linearMotorDirection.Length();
324 if (len > 100.0f) 337 if (len > 100.0f)
325 m_linearMotorDirection *= (100.0f / len); 338 m_linearMotorDirection *= (100.0f / len);
339
326 m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; 340 m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale;
327 m_lmEfect = 1.0f / m_linearMotorTimescale; // turn it on 341 m_lmEfect = 1.0f / m_linearMotorTimescale; // turn it on
342
328 m_ffactor = 0.01f; 343 m_ffactor = 0.01f;
329 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) 344 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
330 && !rootPrim.m_isSelected && !rootPrim.m_disabled) 345 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
@@ -358,7 +373,10 @@ namespace OpenSim.Region.Physics.OdePlugin
358 len = m_angularMotorDirection.Length(); 373 len = m_angularMotorDirection.Length();
359 if (len > 12.566f) 374 if (len > 12.566f)
360 m_angularMotorDirection *= (12.566f / len); 375 m_angularMotorDirection *= (12.566f / len);
361 m_amEfect = 1.0f; // turn it on 376
377 m_amEfect = 1.0f / m_angularMotorTimescale; // turn it on
378 m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale;
379
362 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) 380 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
363 && !rootPrim.m_isSelected && !rootPrim.m_disabled) 381 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
364 d.BodyEnable(rootPrim.Body); 382 d.BodyEnable(rootPrim.Body);
@@ -374,8 +392,12 @@ namespace OpenSim.Region.Physics.OdePlugin
374 len = m_linearMotorDirection.Length(); 392 len = m_linearMotorDirection.Length();
375 if (len > 100.0f) 393 if (len > 100.0f)
376 m_linearMotorDirection *= (100.0f / len); 394 m_linearMotorDirection *= (100.0f / len);
377 m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; 395
378 m_lmEfect = 1.0f / m_linearMotorTimescale; // turn it on 396 m_lmEfect = 1.0f / m_linearMotorTimescale; // turn it on
397 m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale;
398
399
400
379 m_ffactor = 0.01f; 401 m_ffactor = 0.01f;
380 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) 402 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
381 && !rootPrim.m_isSelected && !rootPrim.m_disabled) 403 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
@@ -421,6 +443,7 @@ namespace OpenSim.Region.Physics.OdePlugin
421 internal void ProcessTypeChange(Vehicle pType) 443 internal void ProcessTypeChange(Vehicle pType)
422 { 444 {
423 m_lmEfect = 0; 445 m_lmEfect = 0;
446
424 m_amEfect = 0; 447 m_amEfect = 0;
425 m_ffactor = 1f; 448 m_ffactor = 1f;
426 449
@@ -607,15 +630,20 @@ namespace OpenSim.Region.Physics.OdePlugin
607// m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | 630// m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
608// VehicleFlag.HOVER_GLOBAL_HEIGHT); 631// VehicleFlag.HOVER_GLOBAL_HEIGHT);
609 break; 632 break;
633
610 } 634 }
635
611 m_lmDecay = (1.0f - 1.0f / m_linearMotorDecayTimescale); 636 m_lmDecay = (1.0f - 1.0f / m_linearMotorDecayTimescale);
637 m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale;
638
612 }//end SetDefaultsForType 639 }//end SetDefaultsForType
613 640
614 internal void Stop() 641 internal void Stop()
615 { 642 {
616 m_lmEfect = 0; 643 m_lmEfect = 0;
617 m_lmDecay = 1.0f; 644 m_lmDecay = 0f;
618 m_amEfect = 0; 645 m_amEfect = 0;
646 m_amDecay = 0;
619 m_ffactor = 1f; 647 m_ffactor = 1f;
620 } 648 }
621 649
@@ -642,6 +670,7 @@ namespace OpenSim.Region.Physics.OdePlugin
642 670
643 private const float pi = (float)Math.PI; 671 private const float pi = (float)Math.PI;
644 private const float halfpi = 0.5f * (float)Math.PI; 672 private const float halfpi = 0.5f * (float)Math.PI;
673 private const float twopi = 2.0f * pi;
645 674
646 public static Vector3 ubitRot2Euler(Quaternion rot) 675 public static Vector3 ubitRot2Euler(Quaternion rot)
647 { 676 {
@@ -744,6 +773,8 @@ namespace OpenSim.Region.Physics.OdePlugin
744 curAngVel.Z = dvtmp.Z; 773 curAngVel.Z = dvtmp.Z;
745 Vector3 curLocalAngVel = curAngVel * irotq; // current angular velocity in local 774 Vector3 curLocalAngVel = curAngVel * irotq; // current angular velocity in local
746 775
776 float ldampZ = 0;
777
747 // linear motor 778 // linear motor
748 if (m_lmEfect > 0.001 && m_linearMotorTimescale < 1000) 779 if (m_lmEfect > 0.001 && m_linearMotorTimescale < 1000)
749 { 780 {
@@ -766,9 +797,11 @@ namespace OpenSim.Region.Physics.OdePlugin
766 force.Y += tmpV.Y; 797 force.Y += tmpV.Y;
767 force.Z += tmpV.Z; 798 force.Z += tmpV.Z;
768 } 799 }
800
769 m_lmEfect *= m_lmDecay; 801 m_lmEfect *= m_lmDecay;
770 802
771 m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared(); 803 // m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared();
804 m_ffactor = 0;
772 } 805 }
773 else 806 else
774 { 807 {
@@ -776,18 +809,6 @@ namespace OpenSim.Region.Physics.OdePlugin
776 m_ffactor = 1f; 809 m_ffactor = 1f;
777 } 810 }
778 811
779 // friction
780 if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0)
781 {
782 tmpV.X = -curLocalVel.X / m_linearFrictionTimescale.X;
783 tmpV.Y = -curLocalVel.Y / m_linearFrictionTimescale.Y;
784 tmpV.Z = -curLocalVel.Z / m_linearFrictionTimescale.Z;
785 tmpV *= rotq; // to world
786 force.X += tmpV.X;
787 force.Y += tmpV.Y;
788 force.Z += tmpV.Z;
789 }
790
791 // hover 812 // hover
792 if (m_VhoverTimescale < 300 && rootPrim.prim_geom != IntPtr.Zero) 813 if (m_VhoverTimescale < 300 && rootPrim.prim_geom != IntPtr.Zero)
793 { 814 {
@@ -823,10 +844,16 @@ namespace OpenSim.Region.Physics.OdePlugin
823 else if (t > m_VhoverHeight) 844 else if (t > m_VhoverHeight)
824 perr = t - pos.Z; ; 845 perr = t - pos.Z; ;
825 846
826 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > 0) 847 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > -0.1)
827 { 848 {
828 // force.Z += (perr / m_VhoverTimescale / m_VhoverTimescale - curVel.Z * m_VhoverEfficiency) / m_timestep; 849 ldampZ = m_VhoverEfficiency * m_invtimestep;
829 force.Z += (perr / m_VhoverTimescale - curVel.Z * m_VhoverEfficiency);// * m_invtimestep); 850
851 perr *= (1.0f + ldampZ) / m_VhoverTimescale;
852
853 // force.Z += perr - curVel.Z * tmp;
854 force.Z += perr;
855 ldampZ *= -curVel.Z;
856
830 force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy); 857 force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy);
831 } 858 }
832 else // no buoyancy 859 else // no buoyancy
@@ -844,7 +871,6 @@ namespace OpenSim.Region.Physics.OdePlugin
844 float len = curVel.Length(); 871 float len = curVel.Length();
845 if (len > 0.01) // if moving 872 if (len > 0.01) // if moving
846 { 873 {
847
848 Vector3 atAxis; 874 Vector3 atAxis;
849 atAxis = Xrot(rotq); // where are we pointing to 875 atAxis = Xrot(rotq); // where are we pointing to
850 atAxis *= len; // make it same size as world velocity vector 876 atAxis *= len; // make it same size as world velocity vector
@@ -870,56 +896,19 @@ namespace OpenSim.Region.Physics.OdePlugin
870 } 896 }
871 } 897 }
872 898
873 // angular motor 899 // linear friction/damping
874 if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000) 900 if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0)
875 {
876 tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error
877 tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep
878 torque.X += tmpV.X;
879 torque.Y += tmpV.Y;
880 torque.Z += tmpV.Z;
881 m_amEfect *= (1 - 1.0f / m_angularMotorDecayTimescale);
882 }
883 else
884 m_amEfect = 0;
885
886 // angular friction
887 if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0)
888 {
889 torque.X -= curLocalAngVel.X / m_angularFrictionTimescale.X;
890 torque.Y -= curLocalAngVel.Y / m_angularFrictionTimescale.Y;
891 torque.Z -= curLocalAngVel.Z / m_angularFrictionTimescale.Z;
892 }
893
894 // angular deflection
895 if (m_angularDeflectionEfficiency > 0)
896 { 901 {
897 Vector3 dirv; 902 tmpV.X = -curLocalVel.X / m_linearFrictionTimescale.X;
898 903 tmpV.Y = -curLocalVel.Y / m_linearFrictionTimescale.Y;
899 if (curLocalVel.X > 0.01f) 904 tmpV.Z = -curLocalVel.Z / m_linearFrictionTimescale.Z;
900 dirv = curLocalVel; 905 tmpV *= rotq; // to world
901 else if (curLocalVel.X < -0.01f)
902 // use oposite
903 dirv = -curLocalVel;
904 else
905 {
906 // make it fall into small positive x case
907 dirv.X = 0.01f;
908 dirv.Y = curLocalVel.Y;
909 dirv.Z = curLocalVel.Z;
910 }
911
912 float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale;
913
914 if (Math.Abs(dirv.Z) > 0.01)
915 {
916 torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp;
917 }
918 906
919 if (Math.Abs(dirv.Y) > 0.01) 907 if(ldampZ != 0 && Math.Abs(ldampZ) > Math.Abs(tmpV.Z))
920 { 908 tmpV.Z = ldampZ;
921 torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp; 909 force.X += tmpV.X;
922 } 910 force.Y += tmpV.Y;
911 force.Z += tmpV.Z;
923 } 912 }
924 913
925 // vertical atractor 914 // vertical atractor
@@ -928,29 +917,30 @@ namespace OpenSim.Region.Physics.OdePlugin
928 float roll; 917 float roll;
929 float pitch; 918 float pitch;
930 919
931 GetRollPitch(irotq, out roll, out pitch);
932 920
933 float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale * m_invtimestep; 921
922 float ftmp = m_invtimestep / m_verticalAttractionTimescale / m_verticalAttractionTimescale;
923
934 float ftmp2; 924 float ftmp2;
935 if (m_bankingEfficiency == 0) 925 ftmp2 = 0.5f * m_verticalAttractionEfficiency * m_invtimestep;
936 ftmp2 = m_verticalAttractionEfficiency * m_invtimestep; 926 m_amdampX = ftmp2;
937 else 927
938 ftmp2 = 0; 928 m_ampwr = 1.0f - 0.8f * m_verticalAttractionEfficiency;
929
930 GetRollPitch(irotq, out roll, out pitch);
939 931
940 if (roll > halfpi) 932 if (roll > halfpi)
941 roll = pi - roll; 933 roll = pi - roll;
942 else if (roll < -halfpi) 934 else if (roll < -halfpi)
943 roll = -pi - roll; 935 roll = -pi - roll;
944 936
945 float effroll = pitch / halfpi; 937 float effroll = pitch / halfpi;
946 effroll *= effroll; 938 effroll *= effroll;
947 effroll = 1 - effroll; 939 effroll = 1 - effroll;
948 effroll *= roll; 940 effroll *= roll;
949 941
950 if (Math.Abs(effroll) > 0.01) // roll 942
951 { 943 torque.X += effroll * ftmp;
952 torque.X -= -effroll * ftmp + curLocalAngVel.X * ftmp2;
953 }
954 944
955 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0) 945 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)
956 { 946 {
@@ -958,24 +948,21 @@ namespace OpenSim.Region.Physics.OdePlugin
958 effpitch *= effpitch; 948 effpitch *= effpitch;
959 effpitch = 1 - effpitch; 949 effpitch = 1 - effpitch;
960 effpitch *= pitch; 950 effpitch *= pitch;
961 951
962 if (Math.Abs(effpitch) > 0.01) // pitch 952 torque.Y += effpitch * ftmp;
963 {
964 torque.Y -= -effpitch * ftmp + curLocalAngVel.Y * ftmp2;
965 }
966 } 953 }
967 954
968 if (m_bankingEfficiency != 0 && Math.Abs(effroll) > 0.01) 955 if (m_bankingEfficiency != 0 && Math.Abs(effroll) > 0.01)
969 { 956 {
970 957
971 float broll = effroll; 958 float broll = effroll;
972/* 959 /*
973 if (broll > halfpi) 960 if (broll > halfpi)
974 broll = pi - broll; 961 broll = pi - broll;
975 else if (broll < -halfpi) 962 else if (broll < -halfpi)
976 broll = -pi - broll; 963 broll = -pi - broll;
977*/ 964 */
978 broll *= m_bankingEfficiency; 965 broll *= m_bankingEfficiency;
979 if (m_bankingMix != 0) 966 if (m_bankingMix != 0)
980 { 967 {
981 float vfact = Math.Abs(curLocalVel.X) / 10.0f; 968 float vfact = Math.Abs(curLocalVel.X) / 10.0f;
@@ -984,24 +971,91 @@ namespace OpenSim.Region.Physics.OdePlugin
984 if (curLocalVel.X >= 0) 971 if (curLocalVel.X >= 0)
985 broll *= (1 + (vfact - 1) * m_bankingMix); 972 broll *= (1 + (vfact - 1) * m_bankingMix);
986 else 973 else
987 broll *= -(1 + (vfact - 1) * m_bankingMix); 974 broll *= -(1 + (vfact - 1) * m_bankingMix);
988 } 975 }
989 // make z rot be in world Z not local as seems to be in sl 976 // make z rot be in world Z not local as seems to be in sl
990 977
991 broll = broll / m_bankingTimescale; 978 broll = broll / m_bankingTimescale;
992 979
993 ftmp = -Math.Abs(m_bankingEfficiency) / m_bankingTimescale;
994 980
995 tmpV.X = ftmp * curAngVel.X; 981 tmpV = Zrot(irotq);
996 tmpV.Y = ftmp * curAngVel.Y; 982 tmpV *= broll;
997 tmpV.Z = broll + ftmp * curAngVel.Z;
998 tmpV *= irotq;
999 983
1000 torque.X += tmpV.X; 984 torque.X += tmpV.X;
1001 torque.Y += tmpV.Y; 985 torque.Y += tmpV.Y;
1002 torque.Z += tmpV.Z; 986 torque.Z += tmpV.Z;
987
988 m_amdampZ = Math.Abs(m_bankingEfficiency) / m_bankingTimescale;
989 m_amdampY = m_amdampZ;
990
991 }
992 else
993 {
994 m_amdampZ = 1 / m_angularFrictionTimescale.Z;
995 m_amdampY = m_amdampX;
996 }
997 }
998 else
999 {
1000 m_ampwr = 1.0f;
1001 m_amdampX = 1 / m_angularFrictionTimescale.X;
1002 m_amdampY = 1 / m_angularFrictionTimescale.Y;
1003 m_amdampZ = 1 / m_angularFrictionTimescale.Z;
1004 }
1005
1006 // angular motor
1007 if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000)
1008 {
1009 tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error
1010 tmpV *= m_amEfect; // error to correct in this timestep
1011 torque.X += tmpV.X * m_ampwr;
1012 torque.Y += tmpV.Y * m_ampwr;
1013 torque.Z += tmpV.Z;
1014
1015 m_amEfect *= m_amDecay;
1016 }
1017 else
1018 m_amEfect = 0;
1019
1020 // angular deflection
1021 if (m_angularDeflectionEfficiency > 0)
1022 {
1023 Vector3 dirv;
1024
1025 if (curLocalVel.X > 0.01f)
1026 dirv = curLocalVel;
1027 else if (curLocalVel.X < -0.01f)
1028 // use oposite
1029 dirv = -curLocalVel;
1030 else
1031 {
1032 // make it fall into small positive x case
1033 dirv.X = 0.01f;
1034 dirv.Y = curLocalVel.Y;
1035 dirv.Z = curLocalVel.Z;
1036 }
1037
1038 float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale;
1039
1040 if (Math.Abs(dirv.Z) > 0.01)
1041 {
1042 torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp;
1043 }
1044
1045 if (Math.Abs(dirv.Y) > 0.01)
1046 {
1047 torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp;
1003 } 1048 }
1004 } 1049 }
1050
1051 // angular friction
1052 if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0)
1053 {
1054 torque.X -= curLocalAngVel.X * m_amdampX;
1055 torque.Y -= curLocalAngVel.Y * m_amdampY;
1056 torque.Z -= curLocalAngVel.Z * m_amdampZ;
1057 }
1058
1005 1059
1006 d.Mass dmass; 1060 d.Mass dmass;
1007 d.BodyGetMass(Body,out dmass); 1061 d.BodyGetMass(Body,out dmass);