aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs103
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.