diff options
author | Robert Adams | 2012-11-27 05:24:29 -0800 |
---|---|---|
committer | Robert Adams | 2012-11-27 10:03:44 -0800 |
commit | 59554758b155c7965dc414a16e8b35c115ad3f64 (patch) | |
tree | 6154ec184b7f783649ad756047f113d6212cf458 | |
parent | BulletSim: add 'infinite' timescale that does not reduce motor target or fric... (diff) | |
download | opensim-SC-59554758b155c7965dc414a16e8b35c115ad3f64.zip opensim-SC-59554758b155c7965dc414a16e8b35c115ad3f64.tar.gz opensim-SC-59554758b155c7965dc414a16e8b35c115ad3f64.tar.bz2 opensim-SC-59554758b155c7965dc414a16e8b35c115ad3f64.tar.xz |
BulletSim: implementation of vertical attraction motor.
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 103 |
1 files changed, 62 insertions, 41 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 6ff8a48..d94abf4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -125,6 +125,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
125 | // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. | 125 | // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. |
126 | 126 | ||
127 | //Attractor properties | 127 | //Attractor properties |
128 | private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); | ||
128 | private float m_verticalAttractionEfficiency = 1.0f; // damped | 129 | private float m_verticalAttractionEfficiency = 1.0f; // damped |
129 | private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. | 130 | private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. |
130 | 131 | ||
@@ -197,9 +198,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
197 | break; | 198 | break; |
198 | case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: | 199 | case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: |
199 | m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); | 200 | m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); |
201 | m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency; | ||
200 | break; | 202 | break; |
201 | case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: | 203 | case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: |
202 | m_verticalAttractionTimescale = Math.Max(pValue, 0.01f); | 204 | m_verticalAttractionTimescale = Math.Max(pValue, 0.01f); |
205 | m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale; | ||
203 | break; | 206 | break; |
204 | 207 | ||
205 | // These are vector properties but the engine lets you use a single float value to | 208 | // These are vector properties but the engine lets you use a single float value to |
@@ -530,12 +533,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
530 | Refresh(); | 533 | Refresh(); |
531 | 534 | ||
532 | m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, | 535 | m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, |
533 | m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f); | 536 | m_linearMotorDecayTimescale, m_linearFrictionTimescale, |
537 | 1f); | ||
534 | m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | 538 | m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
539 | |||
535 | m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, | 540 | m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, |
536 | m_angularMotorDecayTimescale, m_angularFrictionTimescale, 1f); | 541 | m_angularMotorDecayTimescale, m_angularFrictionTimescale, |
542 | 1f); | ||
537 | m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | 543 | m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
538 | 544 | ||
545 | m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, | ||
546 | BSMotor.Infinite, BSMotor.InfiniteVector, | ||
547 | m_verticalAttractionEfficiency); | ||
548 | // Z goes away and we keep X and Y | ||
549 | m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); | ||
550 | m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | ||
551 | |||
539 | // m_bankingMotor = new BSVMotor("BankingMotor", ...); | 552 | // m_bankingMotor = new BSVMotor("BankingMotor", ...); |
540 | } | 553 | } |
541 | 554 | ||
@@ -829,46 +842,63 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
829 | Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); | 842 | Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); |
830 | 843 | ||
831 | // ================================================================== | 844 | // ================================================================== |
845 | // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement | ||
846 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) | ||
847 | { | ||
848 | angularMotorContribution.X = 0f; | ||
849 | angularMotorContribution.Y = 0f; | ||
850 | VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); | ||
851 | } | ||
852 | |||
853 | // ================================================================== | ||
832 | Vector3 verticalAttractionContribution = Vector3.Zero; | 854 | Vector3 verticalAttractionContribution = Vector3.Zero; |
833 | // If vertical attaction timescale is reasonable and we applied an angular force last time... | 855 | // If vertical attaction timescale is reasonable and we applied an angular force last time... |
834 | if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) | 856 | if (m_verticalAttractionTimescale < 500) |
835 | { | 857 | { |
836 | float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; | 858 | Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; |
837 | if (Prim.IsColliding) | 859 | verticalError.Normalize(); |
838 | VAservo = pTimestep * 0.05f / m_verticalAttractionTimescale; | 860 | m_verticalAttractionMotor.SetCurrent(verticalError); |
861 | m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); | ||
862 | verticalAttractionContribution = m_verticalAttractionMotor.Step(pTimestep); | ||
863 | /* | ||
864 | // Take a vector pointing up and convert it from world to vehicle relative coords. | ||
865 | Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; | ||
866 | verticalError.Normalize(); | ||
839 | 867 | ||
840 | VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); | 868 | // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) |
869 | // is now leaning to one side (rotated around the X axis) and the Y value will | ||
870 | // go from zero (nearly straight up) to one (completely to the side) or leaning | ||
871 | // front-to-back (rotated around the Y axis) and the value of X will be between | ||
872 | // zero and one. | ||
873 | // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. | ||
841 | 874 | ||
842 | // Create a vector of the vehicle "up" in world coordinates | 875 | // If verticalError.Z is negative, the vehicle is upside down. Add additional push. |
843 | Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; | 876 | if (verticalError.Z < 0f) |
844 | // verticalError.X and .Y are the World error amounts. They are 0 when there is no | 877 | { |
845 | // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its | 878 | verticalError.X = 2f - verticalError.X; |
846 | // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall | 879 | verticalError.Y = 2f - verticalError.Y; |
847 | // and .Z will go negative. Similar for tilt and |.Y|. .X and .Y must be | 880 | } |
848 | // modulated to prevent a stable inverted body. | 881 | |
849 | 882 | // Y error means needed rotation around X axis and visa versa. | |
850 | // Error is 0 (no error) to +/- 2 (max error) | ||
851 | verticalError.X = Math.Max(-2f, Math.Min(verticalError.X, 2f)); | ||
852 | verticalError.Y = Math.Max(-2f, Math.Min(verticalError.Y, 2f)); | ||
853 | |||
854 | // scale it by VAservo (timestep and timescale) | ||
855 | verticalError = verticalError * VAservo; | ||
856 | |||
857 | // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y | ||
858 | // then .X increases, so change Body angular velocity X based on Y, and Y based on X. | ||
859 | // Z is not changed. | ||
860 | verticalAttractionContribution.X = verticalError.Y; | 883 | verticalAttractionContribution.X = verticalError.Y; |
861 | verticalAttractionContribution.Y = - verticalError.X; | 884 | verticalAttractionContribution.Y = - verticalError.X; |
862 | verticalAttractionContribution.Z = 0f; | 885 | verticalAttractionContribution.Z = 0f; |
863 | 886 | ||
864 | // scaling appears better usingsquare-law | 887 | // scale by the time scale and timestep |
865 | Vector3 angularVelocity = Prim.ForceRotationalVelocity; | 888 | Vector3 unscaledContrib = verticalAttractionContribution; |
866 | float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); | 889 | verticalAttractionContribution /= m_verticalAttractionTimescale; |
867 | verticalAttractionContribution.X += bounce * angularVelocity.X; | 890 | verticalAttractionContribution *= pTimestep; |
868 | verticalAttractionContribution.Y += bounce * angularVelocity.Y; | ||
869 | 891 | ||
870 | VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}", | 892 | // apply efficiency |
871 | Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, verticalAttractionContribution); | 893 | Vector3 preEfficiencyContrib = verticalAttractionContribution; |
894 | float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; | ||
895 | verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); | ||
896 | |||
897 | VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", | ||
898 | Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, | ||
899 | m_verticalAttractionEfficiency, efficencySquared, | ||
900 | verticalAttractionContribution); | ||
901 | */ | ||
872 | 902 | ||
873 | } | 903 | } |
874 | 904 | ||
@@ -989,15 +1019,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
989 | } | 1019 | } |
990 | 1020 | ||
991 | // ================================================================== | 1021 | // ================================================================== |
992 | // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement | ||
993 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) | ||
994 | { | ||
995 | m_lastAngularVelocity.X = 0; | ||
996 | m_lastAngularVelocity.Y = 0; | ||
997 | VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); | ||
998 | } | ||
999 | |||
1000 | // ================================================================== | ||
1001 | if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) | 1022 | if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) |
1002 | { | 1023 | { |
1003 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. | 1024 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. |