aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs282
1 files changed, 187 insertions, 95 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index c34c05a..bcebaec 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -108,10 +108,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
108 private float m_VhoverEfficiency = 0f; 108 private float m_VhoverEfficiency = 0f;
109 private float m_VhoverTimescale = 0f; 109 private float m_VhoverTimescale = 0f;
110 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height 110 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
111 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. 111 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
112 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) 112 private float m_VehicleBuoyancy = 0f;
113 // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. 113 private Vector3 m_VehicleGravity = Vector3.Zero; // Gravity computed when buoyancy set
114 // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
115 114
116 //Attractor properties 115 //Attractor properties
117 private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); 116 private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction");
@@ -124,17 +123,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin
124 static readonly float PIOverFour = ((float)Math.PI) / 4f; 123 static readonly float PIOverFour = ((float)Math.PI) / 4f;
125 static readonly float PIOverTwo = ((float)Math.PI) / 2f; 124 static readonly float PIOverTwo = ((float)Math.PI) / 2f;
126 125
126 // For debugging, flags to turn on and off individual corrections.
127 private bool enableAngularVerticalAttraction = true;
128 private bool enableAngularDeflection = true;
129 private bool enableAngularBanking = true;
130
127 public BSDynamics(BSScene myScene, BSPrim myPrim) 131 public BSDynamics(BSScene myScene, BSPrim myPrim)
128 { 132 {
129 PhysicsScene = myScene; 133 PhysicsScene = myScene;
130 Prim = myPrim; 134 Prim = myPrim;
131 Type = Vehicle.TYPE_NONE; 135 Type = Vehicle.TYPE_NONE;
136 SetupVehicleDebugging();
137 }
138
139 // Stopgap debugging enablement. Allows source level debugging but still checking
140 // in changes by making enablement of debugging flags from INI file.
141 public void SetupVehicleDebugging()
142 {
143 enableAngularVerticalAttraction = true;
144 enableAngularDeflection = true;
145 enableAngularBanking = true;
146 if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse)
147 {
148 enableAngularVerticalAttraction = false;
149 enableAngularDeflection = false;
150 enableAngularBanking = false;
151 }
132 } 152 }
133 153
134 // Return 'true' if this vehicle is doing vehicle things 154 // Return 'true' if this vehicle is doing vehicle things
135 public bool IsActive 155 public bool IsActive
136 { 156 {
137 get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } 157 get { return (Type != Vehicle.TYPE_NONE && !Prim.IsStatic); }
138 } 158 }
139 159
140 #region Vehicle parameter setting 160 #region Vehicle parameter setting
@@ -168,6 +188,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
168 break; 188 break;
169 case Vehicle.BUOYANCY: 189 case Vehicle.BUOYANCY:
170 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); 190 m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f);
191 m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy);
171 break; 192 break;
172 case Vehicle.HOVER_EFFICIENCY: 193 case Vehicle.HOVER_EFFICIENCY:
173 m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); 194 m_VhoverEfficiency = ClampInRange(0f, pValue, 1f);
@@ -540,12 +561,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
540 1f); 561 1f);
541 m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 562 m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
542 563
564 /* Not implemented
543 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, 565 m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale,
544 BSMotor.Infinite, BSMotor.InfiniteVector, 566 BSMotor.Infinite, BSMotor.InfiniteVector,
545 m_verticalAttractionEfficiency); 567 m_verticalAttractionEfficiency);
546 // Z goes away and we keep X and Y 568 // Z goes away and we keep X and Y
547 m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); 569 m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
548 m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) 570 m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
571 */
549 } 572 }
550 #endregion // Vehicle parameter setting 573 #endregion // Vehicle parameter setting
551 574
@@ -571,15 +594,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
571 // Vehicles report collision events so we know when it's on the ground 594 // Vehicles report collision events so we know when it's on the ground
572 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 595 PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
573 596
574 Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass); 597 Prim.Inertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass);
575 PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia); 598 PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, Prim.Inertia);
576 PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody); 599 PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody);
577 600
578 Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy); 601 // Set the gravity for the vehicle depending on the buoyancy
579 PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); 602 // TODO: what should be done if prim and vehicle buoyancy differ?
603 m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy);
604 // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
605 PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero);
580 606
581 VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}", 607 VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}",
582 Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping); 608 Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity);
583 } 609 }
584 else 610 else
585 { 611 {
@@ -619,6 +645,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
619 private Vector3 m_knownPosition; 645 private Vector3 m_knownPosition;
620 private Vector3 m_knownVelocity; 646 private Vector3 m_knownVelocity;
621 private Vector3 m_knownForce; 647 private Vector3 m_knownForce;
648 private Vector3 m_knownForceImpulse;
622 private Quaternion m_knownOrientation; 649 private Quaternion m_knownOrientation;
623 private Vector3 m_knownRotationalVelocity; 650 private Vector3 m_knownRotationalVelocity;
624 private Vector3 m_knownRotationalForce; 651 private Vector3 m_knownRotationalForce;
@@ -627,12 +654,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
627 private const int m_knownChangedPosition = 1 << 0; 654 private const int m_knownChangedPosition = 1 << 0;
628 private const int m_knownChangedVelocity = 1 << 1; 655 private const int m_knownChangedVelocity = 1 << 1;
629 private const int m_knownChangedForce = 1 << 2; 656 private const int m_knownChangedForce = 1 << 2;
630 private const int m_knownChangedOrientation = 1 << 3; 657 private const int m_knownChangedForceImpulse = 1 << 3;
631 private const int m_knownChangedRotationalVelocity = 1 << 4; 658 private const int m_knownChangedOrientation = 1 << 4;
632 private const int m_knownChangedRotationalForce = 1 << 5; 659 private const int m_knownChangedRotationalVelocity = 1 << 5;
633 private const int m_knownChangedTerrainHeight = 1 << 6; 660 private const int m_knownChangedRotationalForce = 1 << 6;
634 private const int m_knownChangedWaterLevel = 1 << 7; 661 private const int m_knownChangedTerrainHeight = 1 << 7;
635 private const int m_knownChangedForwardVelocity = 1 << 8; 662 private const int m_knownChangedWaterLevel = 1 << 8;
663 private const int m_knownChangedForwardVelocity = 1 << 9;
636 664
637 private void ForgetKnownVehicleProperties() 665 private void ForgetKnownVehicleProperties()
638 { 666 {
@@ -653,21 +681,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin
653 if ((m_knownChanged & m_knownChangedVelocity) != 0) 681 if ((m_knownChanged & m_knownChangedVelocity) != 0)
654 { 682 {
655 Prim.ForceVelocity = m_knownVelocity; 683 Prim.ForceVelocity = m_knownVelocity;
656 PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity); 684 // Fake out Bullet by making it think the velocity is the same as last time.
685 // Bullet does a bunch of smoothing for changing parameters.
686 // Since the vehicle is demanding this setting, we override Bullet's smoothing
687 // by telling Bullet the value was the same last time.
688 PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity);
657 } 689 }
658 690
659 if ((m_knownChanged & m_knownChangedForce) != 0) 691 if ((m_knownChanged & m_knownChangedForce) != 0)
660 Prim.AddForce((Vector3)m_knownForce, false, true); 692 Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/);
693
694 if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
695 Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
661 696
662 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) 697 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
663 { 698 {
664 Prim.ForceRotationalVelocity = m_knownRotationalVelocity; 699 Prim.ForceRotationalVelocity = m_knownRotationalVelocity;
665 // Fake out Bullet by making it think the velocity is the same as last time.
666 PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); 700 PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
667 } 701 }
668 702
669 if ((m_knownChanged & m_knownChangedRotationalForce) != 0) 703 if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
670 Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); 704 {
705 Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/);
706 }
671 707
672 // If we set one of the values (ie, the physics engine didn't do it) we must force 708 // If we set one of the values (ie, the physics engine didn't do it) we must force
673 // an UpdateProperties event to send the changes up to the simulator. 709 // an UpdateProperties event to send the changes up to the simulator.
@@ -757,15 +793,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
757 } 793 }
758 } 794 }
759 795
760 private void VehicleAddForce(Vector3 aForce) 796 private void VehicleAddForce(Vector3 pForce)
761 { 797 {
762 if ((m_knownHas & m_knownChangedForce) == 0) 798 if ((m_knownHas & m_knownChangedForce) == 0)
763 { 799 {
764 m_knownForce = Vector3.Zero; 800 m_knownForce = Vector3.Zero;
801 m_knownHas |= m_knownChangedForce;
765 } 802 }
766 m_knownForce += aForce; 803 m_knownForce += pForce;
767 m_knownChanged |= m_knownChangedForce; 804 m_knownChanged |= m_knownChangedForce;
768 m_knownHas |= m_knownChangedForce; 805 }
806
807 private void VehicleAddForceImpulse(Vector3 pImpulse)
808 {
809 if ((m_knownHas & m_knownChangedForceImpulse) == 0)
810 {
811 m_knownForceImpulse = Vector3.Zero;
812 m_knownHas |= m_knownChangedForceImpulse;
813 }
814 m_knownForceImpulse += pImpulse;
815 m_knownChanged |= m_knownChangedForceImpulse;
769 } 816 }
770 817
771 private Vector3 VehicleRotationalVelocity 818 private Vector3 VehicleRotationalVelocity
@@ -844,86 +891,92 @@ namespace OpenSim.Region.Physics.BulletSPlugin
844 if (PhysicsScene.VehiclePhysicalLoggingEnabled) 891 if (PhysicsScene.VehiclePhysicalLoggingEnabled)
845 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); 892 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
846 893
847 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 894 VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
848 Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); 895 Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
849 } 896 }
850 897
851 // Apply the effect of the linear motor and other linear motions (like hover and float). 898 // Apply the effect of the linear motor and other linear motions (like hover and float).
852 private void MoveLinear(float pTimestep) 899 private void MoveLinear(float pTimestep)
853 { 900 {
854 Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); 901 ComputeLinearVelocity(pTimestep);
855 902
856 // The movement computed in the linear motor is relative to the vehicle 903 ComputeLinearTerrainHeightCorrection(pTimestep);
857 // coordinates. Rotate the movement to world coordinates.
858 linearMotorContribution *= VehicleOrientation;
859 // All the contributions after this are world relative (mostly Z modifications)
860
861 // ==================================================================
862 // Buoyancy: force to overcome gravity.
863 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
864 // So, if zero, don't change anything (let gravity happen). If one, negate the effect of gravity.
865 Vector3 buoyancyContribution = Prim.PhysicsScene.DefaultGravity * m_VehicleBuoyancy;
866
867 Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep);
868 904
869 Vector3 hoverContribution = ComputeLinearHover(pTimestep); 905 ComputeLinearHover(pTimestep);
870 906
871 ComputeLinearBlockingEndPoint(pTimestep); 907 ComputeLinearBlockingEndPoint(pTimestep);
872 908
873 Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); 909 ComputeLinearMotorUp(pTimestep);
874 910
875 // ================================================================== 911 ApplyGravity(pTimestep);
876 Vector3 newVelocity = linearMotorContribution
877 + terrainHeightContribution
878 + hoverContribution
879 + limitMotorUpContribution;
880
881 Vector3 newForce = buoyancyContribution;
882 912
883 // If not changing some axis, reduce out velocity 913 // If not changing some axis, reduce out velocity
884 if ((m_flags & (VehicleFlag.NO_X)) != 0) 914 if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0)
885 newVelocity.X = 0; 915 {
886 if ((m_flags & (VehicleFlag.NO_Y)) != 0) 916 Vector3 vel = VehicleVelocity;
887 newVelocity.Y = 0; 917 if ((m_flags & (VehicleFlag.NO_X)) != 0)
888 if ((m_flags & (VehicleFlag.NO_Z)) != 0) 918 vel.X = 0;
889 newVelocity.Z = 0; 919 if ((m_flags & (VehicleFlag.NO_Y)) != 0)
920 vel.Y = 0;
921 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
922 vel.Z = 0;
923 VehicleVelocity = vel;
924 }
890 925
891 // ================================================================== 926 // ==================================================================
892 // Clamp high or low velocities 927 // Clamp high or low velocities
893 float newVelocityLengthSq = newVelocity.LengthSquared(); 928 float newVelocityLengthSq = VehicleVelocity.LengthSquared();
894 if (newVelocityLengthSq > 1000f) 929 if (newVelocityLengthSq > 1000f)
895 { 930 {
896 newVelocity /= newVelocity.Length(); 931 VehicleVelocity /= VehicleVelocity.Length();
897 newVelocity *= 1000f; 932 VehicleVelocity *= 1000f;
898 } 933 }
899 else if (newVelocityLengthSq < 0.001f) 934 else if (newVelocityLengthSq < 0.001f)
900 newVelocity = Vector3.Zero; 935 VehicleVelocity = Vector3.Zero;
901 936
902 // ================================================================== 937 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity );
903 // Stuff new linear velocity into the vehicle. 938
904 // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. 939 } // end MoveLinear()
905 VehicleVelocity = newVelocity; 940
941 public void ComputeLinearVelocity(float pTimestep)
942 {
943 Vector3 linearMotorStep = m_linearMotor.Step(pTimestep);
944
945 // The movement computed in the linear motor is relative to the vehicle
946 // coordinates. Rotate the movement to world coordinates.
947 Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation;
906 948
907 // Other linear forces are applied as forces. 949 // If we're a ground vehicle, don't loose any Z action (like gravity acceleration).
908 Vector3 totalDownForce = newForce * m_vehicleMass; 950 float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z
909 if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) 951 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
910 { 952 {
911 VehicleAddForce(totalDownForce); 953 if (!Prim.IsColliding)
954 {
955 // If a ground vehicle and not on the ground, I want gravity effect
956 mixFactor = 0.2f;
957 }
912 } 958 }
959 else
960 {
961 // I'm not a ground vehicle but don't totally loose the effect of the environment
962 mixFactor = 0.8f;
963 }
964 linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z;
913 965
914 VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", 966 // What we want to contribute to the vehicle's existing velocity
915 Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); 967 Vector3 linearMotorForce = linearMotorVelocity - VehicleVelocity;
916 VDetailLog("{0}, MoveLinear,done,linContrib={1},terrContrib={2},hoverContrib={3},limitContrib={4},buoyContrib={5}",
917 Prim.LocalID,
918 linearMotorContribution, terrainHeightContribution, hoverContribution,
919 limitMotorUpContribution, buoyancyContribution
920 );
921 968
922 } // end MoveLinear() 969 // Act against the inertia of the vehicle
970 linearMotorForce *= m_vehicleMass;
923 971
924 public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) 972 VehicleAddForceImpulse(linearMotorForce * pTimestep);
973
974 VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}",
975 Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce);
976 }
977
978 public void ComputeLinearTerrainHeightCorrection(float pTimestep)
925 { 979 {
926 Vector3 ret = Vector3.Zero;
927 // If below the terrain, move us above the ground a little. 980 // If below the terrain, move us above the ground a little.
928 // TODO: Consider taking the rotated size of the object or possibly casting a ray. 981 // TODO: Consider taking the rotated size of the object or possibly casting a ray.
929 if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) 982 if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition))
@@ -935,13 +988,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
935 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", 988 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
936 Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); 989 Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
937 } 990 }
938 return ret;
939 } 991 }
940 992
941 public Vector3 ComputeLinearHover(float pTimestep) 993 public void ComputeLinearHover(float pTimestep)
942 { 994 {
943 Vector3 ret = Vector3.Zero;
944
945 // m_VhoverEfficiency: 0=bouncy, 1=totally damped 995 // m_VhoverEfficiency: 0=bouncy, 1=totally damped
946 // m_VhoverTimescale: time to achieve height 996 // m_VhoverTimescale: time to achieve height
947 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 997 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
@@ -974,23 +1024,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
974 Vector3 pos = VehiclePosition; 1024 Vector3 pos = VehiclePosition;
975 pos.Z = m_VhoverTargetHeight; 1025 pos.Z = m_VhoverTargetHeight;
976 VehiclePosition = pos; 1026 VehiclePosition = pos;
1027
1028 VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos);
977 } 1029 }
978 } 1030 }
979 else 1031 else
980 { 1032 {
981 // Error is positive if below the target and negative if above. 1033 // Error is positive if below the target and negative if above.
982 float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; 1034 float verticalError = m_VhoverTargetHeight - VehiclePosition.Z;
983 float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; 1035 float verticalCorrectionVelocity = verticalError / m_VhoverTimescale * pTimestep;
984 1036
985 // TODO: implement m_VhoverEfficiency correctly 1037 // TODO: implement m_VhoverEfficiency correctly
986 ret = new Vector3(0f, 0f, verticalCorrectionVelocity); 1038 VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity));
1039
1040 VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}",
1041 Prim.LocalID, VehiclePosition, m_VhoverEfficiency,
1042 m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
1043 verticalError, verticalCorrectionVelocity);
987 } 1044 }
988 1045
989 VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},ret={6}",
990 Prim.LocalID, VehiclePosition, m_VhoverEfficiency, m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, ret);
991 } 1046 }
992
993 return ret;
994 } 1047 }
995 1048
996 public bool ComputeLinearBlockingEndPoint(float pTimestep) 1049 public bool ComputeLinearBlockingEndPoint(float pTimestep)
@@ -1045,30 +1098,67 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1045 // TODO: this code is wrong. Also, what should it do for boats (height from water)? 1098 // TODO: this code is wrong. Also, what should it do for boats (height from water)?
1046 // This is just using the ground and a general collision check. Should really be using 1099 // This is just using the ground and a general collision check. Should really be using
1047 // a downward raycast to find what is below. 1100 // a downward raycast to find what is below.
1048 public Vector3 ComputeLinearMotorUp(float pTimestep) 1101 public void ComputeLinearMotorUp(float pTimestep)
1049 { 1102 {
1050 Vector3 ret = Vector3.Zero; 1103 Vector3 ret = Vector3.Zero;
1051 float distanceAboveGround = 0f;
1052 1104
1053 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 1105 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
1054 { 1106 {
1107 // This code tries to decide if the object is not on the ground and then pushing down
1108 /*
1055 float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); 1109 float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition);
1056 distanceAboveGround = VehiclePosition.Z - targetHeight; 1110 distanceAboveGround = VehiclePosition.Z - targetHeight;
1057 // Not colliding if the vehicle is off the ground 1111 // Not colliding if the vehicle is off the ground
1058 if (!Prim.IsColliding) 1112 if (!Prim.IsColliding)
1059 { 1113 {
1060 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); 1114 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
1061 ret = new Vector3(0, 0, -distanceAboveGround); 1115 VehicleVelocity += new Vector3(0, 0, -distanceAboveGround);
1062 } 1116 }
1063 // TODO: this calculation is wrong. From the description at 1117 // TODO: this calculation is wrong. From the description at
1064 // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce 1118 // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
1065 // has a decay factor. This says this force should 1119 // has a decay factor. This says this force should
1066 // be computed with a motor. 1120 // be computed with a motor.
1067 // TODO: add interaction with banking. 1121 // TODO: add interaction with banking.
1068 } 1122 VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}",
1069 VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}",
1070 Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); 1123 Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret);
1071 return ret; 1124 */
1125
1126 // Another approach is to measure if we're going up. If going up and not colliding,
1127 // the vehicle is in the air. Fix that by pushing down.
1128 if (!Prim.IsColliding && VehicleVelocity.Z > 0.1)
1129 {
1130 // Get rid of any of the velocity vector that is pushing us up.
1131 VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z);
1132
1133 // If we're pointed up into the air, we should nose down
1134 Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
1135 // The rotation around the Y axis is pitch up or down
1136 if (pointingDirection.Y > 0.01f)
1137 {
1138 float angularCorrectionForce = -(float)Math.Asin(pointingDirection.Y);
1139 Vector3 angularCorrectionVector = new Vector3(0f, angularCorrectionForce, 0f);
1140 // Rotate into world coordinates and apply to vehicle
1141 angularCorrectionVector *= VehicleOrientation;
1142 VehicleAddAngularForce(angularCorrectionVector);
1143 VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}",
1144 Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector);
1145 }
1146 else
1147 {
1148 VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}",
1149 Prim.LocalID, VehicleVelocity, pointingDirection);
1150 }
1151 }
1152 }
1153 }
1154
1155 private void ApplyGravity(float pTimeStep)
1156 {
1157 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
1158 VehicleAddForce(appliedGravity);
1159
1160 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}",
1161 Prim.LocalID, m_VehicleGravity, appliedGravity);
1072 } 1162 }
1073 1163
1074 // ======================================================================= 1164 // =======================================================================
@@ -1088,6 +1178,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1088 // for preventing ground vehicles with large linear deflection, like bumper cars, 1178 // for preventing ground vehicles with large linear deflection, like bumper cars,
1089 // from climbing their linear deflection into the sky. 1179 // from climbing their linear deflection into the sky.
1090 // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement 1180 // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
1181 // TODO: This is here because this is where ODE put it but documentation says it
1182 // is a linear effect. Where should this check go?
1091 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 1183 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
1092 { 1184 {
1093 angularMotorContribution.X = 0f; 1185 angularMotorContribution.X = 0f;
@@ -1179,7 +1271,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1179 Vector3 ret = Vector3.Zero; 1271 Vector3 ret = Vector3.Zero;
1180 1272
1181 // If vertical attaction timescale is reasonable 1273 // If vertical attaction timescale is reasonable
1182 if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1274 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1183 { 1275 {
1184 // Take a vector pointing up and convert it from world to vehicle relative coords. 1276 // Take a vector pointing up and convert it from world to vehicle relative coords.
1185 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; 1277 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
@@ -1230,7 +1322,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1230 // this creates an over-correction and then wabbling as the target is overshot. 1322 // this creates an over-correction and then wabbling as the target is overshot.
1231 // TODO: rethink how the different correction computations inter-relate. 1323 // TODO: rethink how the different correction computations inter-relate.
1232 1324
1233 if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) 1325 if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
1234 { 1326 {
1235 // The direction the vehicle is moving 1327 // The direction the vehicle is moving
1236 Vector3 movingDirection = VehicleVelocity; 1328 Vector3 movingDirection = VehicleVelocity;
@@ -1303,7 +1395,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1303 { 1395 {
1304 Vector3 ret = Vector3.Zero; 1396 Vector3 ret = Vector3.Zero;
1305 1397
1306 if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1398 if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1307 { 1399 {
1308 // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. 1400 // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented.
1309 // As the vehicle rolls to the right or left, the Y value will increase from 1401 // As the vehicle rolls to the right or left, the Y value will increase from