diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | 254 |
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); |