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.cs314
1 files changed, 219 insertions, 95 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index c34c05a..e434412 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;
128 private bool enableAngularDeflection;
129 private bool enableAngularBanking;
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 = false;
145 enableAngularBanking = false;
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,20 +645,24 @@ 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;
652 private Vector3 m_knownRotationalImpulse;
625 private Vector3 m_knownForwardVelocity; // vehicle relative forward speed 653 private Vector3 m_knownForwardVelocity; // vehicle relative forward speed
626 654
627 private const int m_knownChangedPosition = 1 << 0; 655 private const int m_knownChangedPosition = 1 << 0;
628 private const int m_knownChangedVelocity = 1 << 1; 656 private const int m_knownChangedVelocity = 1 << 1;
629 private const int m_knownChangedForce = 1 << 2; 657 private const int m_knownChangedForce = 1 << 2;
630 private const int m_knownChangedOrientation = 1 << 3; 658 private const int m_knownChangedForceImpulse = 1 << 3;
631 private const int m_knownChangedRotationalVelocity = 1 << 4; 659 private const int m_knownChangedOrientation = 1 << 4;
632 private const int m_knownChangedRotationalForce = 1 << 5; 660 private const int m_knownChangedRotationalVelocity = 1 << 5;
633 private const int m_knownChangedTerrainHeight = 1 << 6; 661 private const int m_knownChangedRotationalForce = 1 << 6;
634 private const int m_knownChangedWaterLevel = 1 << 7; 662 private const int m_knownChangedRotationalImpulse = 1 << 7;
635 private const int m_knownChangedForwardVelocity = 1 << 8; 663 private const int m_knownChangedTerrainHeight = 1 << 8;
664 private const int m_knownChangedWaterLevel = 1 << 9;
665 private const int m_knownChangedForwardVelocity = 1 <<10;
636 666
637 private void ForgetKnownVehicleProperties() 667 private void ForgetKnownVehicleProperties()
638 { 668 {
@@ -653,21 +683,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin
653 if ((m_knownChanged & m_knownChangedVelocity) != 0) 683 if ((m_knownChanged & m_knownChangedVelocity) != 0)
654 { 684 {
655 Prim.ForceVelocity = m_knownVelocity; 685 Prim.ForceVelocity = m_knownVelocity;
656 PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity); 686 // Fake out Bullet by making it think the velocity is the same as last time.
687 // Bullet does a bunch of smoothing for changing parameters.
688 // Since the vehicle is demanding this setting, we override Bullet's smoothing
689 // by telling Bullet the value was the same last time.
690 PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity);
657 } 691 }
658 692
659 if ((m_knownChanged & m_knownChangedForce) != 0) 693 if ((m_knownChanged & m_knownChangedForce) != 0)
660 Prim.AddForce((Vector3)m_knownForce, false, true); 694 Prim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/);
695
696 if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
697 Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
661 698
662 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) 699 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
663 { 700 {
664 Prim.ForceRotationalVelocity = m_knownRotationalVelocity; 701 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); 702 PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
667 } 703 }
668 704
705 if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0)
706 Prim.ApplyTorqueImpulse((Vector3)m_knownRotationalImpulse, true /*inTaintTime*/);
707
669 if ((m_knownChanged & m_knownChangedRotationalForce) != 0) 708 if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
670 Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); 709 {
710 Prim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/);
711 }
671 712
672 // If we set one of the values (ie, the physics engine didn't do it) we must force 713 // 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. 714 // an UpdateProperties event to send the changes up to the simulator.
@@ -757,15 +798,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
757 } 798 }
758 } 799 }
759 800
760 private void VehicleAddForce(Vector3 aForce) 801 private void VehicleAddForce(Vector3 pForce)
761 { 802 {
762 if ((m_knownHas & m_knownChangedForce) == 0) 803 if ((m_knownHas & m_knownChangedForce) == 0)
763 { 804 {
764 m_knownForce = Vector3.Zero; 805 m_knownForce = Vector3.Zero;
806 m_knownHas |= m_knownChangedForce;
765 } 807 }
766 m_knownForce += aForce; 808 m_knownForce += pForce;
767 m_knownChanged |= m_knownChangedForce; 809 m_knownChanged |= m_knownChangedForce;
768 m_knownHas |= m_knownChangedForce; 810 }
811
812 private void VehicleAddForceImpulse(Vector3 pImpulse)
813 {
814 if ((m_knownHas & m_knownChangedForceImpulse) == 0)
815 {
816 m_knownForceImpulse = Vector3.Zero;
817 m_knownHas |= m_knownChangedForceImpulse;
818 }
819 m_knownForceImpulse += pImpulse;
820 m_knownChanged |= m_knownChangedForceImpulse;
769 } 821 }
770 822
771 private Vector3 VehicleRotationalVelocity 823 private Vector3 VehicleRotationalVelocity
@@ -796,6 +848,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin
796 m_knownChanged |= m_knownChangedRotationalForce; 848 m_knownChanged |= m_knownChangedRotationalForce;
797 m_knownHas |= m_knownChangedRotationalForce; 849 m_knownHas |= m_knownChangedRotationalForce;
798 } 850 }
851 private void VehicleAddRotationalImpulse(Vector3 pImpulse)
852 {
853 if ((m_knownHas & m_knownChangedRotationalImpulse) == 0)
854 {
855 m_knownRotationalImpulse = Vector3.Zero;
856 m_knownHas |= m_knownChangedRotationalImpulse;
857 }
858 m_knownRotationalImpulse += pImpulse;
859 m_knownChanged |= m_knownChangedRotationalImpulse;
860 }
861
799 // Vehicle relative forward velocity 862 // Vehicle relative forward velocity
800 private Vector3 VehicleForwardVelocity 863 private Vector3 VehicleForwardVelocity
801 { 864 {
@@ -844,86 +907,92 @@ namespace OpenSim.Region.Physics.BulletSPlugin
844 if (PhysicsScene.VehiclePhysicalLoggingEnabled) 907 if (PhysicsScene.VehiclePhysicalLoggingEnabled)
845 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); 908 PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
846 909
847 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 910 VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}",
848 Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); 911 Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
849 } 912 }
850 913
851 // Apply the effect of the linear motor and other linear motions (like hover and float). 914 // Apply the effect of the linear motor and other linear motions (like hover and float).
852 private void MoveLinear(float pTimestep) 915 private void MoveLinear(float pTimestep)
853 { 916 {
854 Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); 917 ComputeLinearVelocity(pTimestep);
855
856 // The movement computed in the linear motor is relative to the vehicle
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 918
867 Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep); 919 ComputeLinearTerrainHeightCorrection(pTimestep);
868 920
869 Vector3 hoverContribution = ComputeLinearHover(pTimestep); 921 ComputeLinearHover(pTimestep);
870 922
871 ComputeLinearBlockingEndPoint(pTimestep); 923 ComputeLinearBlockingEndPoint(pTimestep);
872 924
873 Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep); 925 ComputeLinearMotorUp(pTimestep);
874
875 // ==================================================================
876 Vector3 newVelocity = linearMotorContribution
877 + terrainHeightContribution
878 + hoverContribution
879 + limitMotorUpContribution;
880 926
881 Vector3 newForce = buoyancyContribution; 927 ApplyGravity(pTimestep);
882 928
883 // If not changing some axis, reduce out velocity 929 // If not changing some axis, reduce out velocity
884 if ((m_flags & (VehicleFlag.NO_X)) != 0) 930 if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0)
885 newVelocity.X = 0; 931 {
886 if ((m_flags & (VehicleFlag.NO_Y)) != 0) 932 Vector3 vel = VehicleVelocity;
887 newVelocity.Y = 0; 933 if ((m_flags & (VehicleFlag.NO_X)) != 0)
888 if ((m_flags & (VehicleFlag.NO_Z)) != 0) 934 vel.X = 0;
889 newVelocity.Z = 0; 935 if ((m_flags & (VehicleFlag.NO_Y)) != 0)
936 vel.Y = 0;
937 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
938 vel.Z = 0;
939 VehicleVelocity = vel;
940 }
890 941
891 // ================================================================== 942 // ==================================================================
892 // Clamp high or low velocities 943 // Clamp high or low velocities
893 float newVelocityLengthSq = newVelocity.LengthSquared(); 944 float newVelocityLengthSq = VehicleVelocity.LengthSquared();
894 if (newVelocityLengthSq > 1000f) 945 if (newVelocityLengthSq > 1000f)
895 { 946 {
896 newVelocity /= newVelocity.Length(); 947 VehicleVelocity /= VehicleVelocity.Length();
897 newVelocity *= 1000f; 948 VehicleVelocity *= 1000f;
898 } 949 }
899 else if (newVelocityLengthSq < 0.001f) 950 else if (newVelocityLengthSq < 0.001f)
900 newVelocity = Vector3.Zero; 951 VehicleVelocity = Vector3.Zero;
901 952
902 // ================================================================== 953 VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", Prim.LocalID, Prim.IsColliding, VehicleVelocity );
903 // Stuff new linear velocity into the vehicle. 954
904 // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. 955 } // end MoveLinear()
905 VehicleVelocity = newVelocity;
906 956
907 // Other linear forces are applied as forces. 957 public void ComputeLinearVelocity(float pTimestep)
908 Vector3 totalDownForce = newForce * m_vehicleMass; 958 {
909 if (!totalDownForce.ApproxEquals(Vector3.Zero, 0.01f)) 959 Vector3 linearMotorStep = m_linearMotor.Step(pTimestep);
960
961 // The movement computed in the linear motor is relative to the vehicle
962 // coordinates. Rotate the movement to world coordinates.
963 Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation;
964
965 // If we're a ground vehicle, don't loose any Z action (like gravity acceleration).
966 float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z
967 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
968 {
969 if (!Prim.IsColliding)
970 {
971 // If a ground vehicle and not on the ground, I want gravity effect
972 mixFactor = 0.2f;
973 }
974 }
975 else
910 { 976 {
911 VehicleAddForce(totalDownForce); 977 // I'm not a ground vehicle but don't totally loose the effect of the environment
978 mixFactor = 0.8f;
912 } 979 }
980 linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z;
913 981
914 VDetailLog("{0}, MoveLinear,done,newVel={1},totDown={2},IsColliding={3}", 982 // What we want to contribute to the vehicle's existing velocity
915 Prim.LocalID, newVelocity, totalDownForce, Prim.IsColliding); 983 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 984
922 } // end MoveLinear() 985 // Act against the inertia of the vehicle
986 linearMotorForce *= m_vehicleMass;
923 987
924 public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep) 988 VehicleAddForceImpulse(linearMotorForce * pTimestep);
989
990 VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}",
991 Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce);
992 }
993
994 public void ComputeLinearTerrainHeightCorrection(float pTimestep)
925 { 995 {
926 Vector3 ret = Vector3.Zero;
927 // If below the terrain, move us above the ground a little. 996 // 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. 997 // TODO: Consider taking the rotated size of the object or possibly casting a ray.
929 if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition)) 998 if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition))
@@ -935,13 +1004,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
935 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", 1004 VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
936 Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition); 1005 Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
937 } 1006 }
938 return ret;
939 } 1007 }
940 1008
941 public Vector3 ComputeLinearHover(float pTimestep) 1009 public void ComputeLinearHover(float pTimestep)
942 { 1010 {
943 Vector3 ret = Vector3.Zero;
944
945 // m_VhoverEfficiency: 0=bouncy, 1=totally damped 1011 // m_VhoverEfficiency: 0=bouncy, 1=totally damped
946 // m_VhoverTimescale: time to achieve height 1012 // m_VhoverTimescale: time to achieve height
947 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 1013 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
@@ -974,23 +1040,42 @@ namespace OpenSim.Region.Physics.BulletSPlugin
974 Vector3 pos = VehiclePosition; 1040 Vector3 pos = VehiclePosition;
975 pos.Z = m_VhoverTargetHeight; 1041 pos.Z = m_VhoverTargetHeight;
976 VehiclePosition = pos; 1042 VehiclePosition = pos;
1043
1044 VDetailLog("{0}, MoveLinear,hover,pos={1},lockHoverHeight", Prim.LocalID, pos);
977 } 1045 }
978 } 1046 }
979 else 1047 else
980 { 1048 {
981 // Error is positive if below the target and negative if above. 1049 // Error is positive if below the target and negative if above.
982 float verticalError = m_VhoverTargetHeight - VehiclePosition.Z; 1050 Vector3 hpos = VehiclePosition;
1051 float verticalError = m_VhoverTargetHeight - hpos.Z;
1052 float verticalCorrection = verticalError / m_VhoverTimescale;
1053 verticalCorrection *= m_VhoverEfficiency;
1054
1055 hpos.Z += verticalCorrection;
1056 VehiclePosition = hpos;
1057
1058 // Since we are hovering, we need to do the opposite of falling -- get rid of world Z
1059 Vector3 vel = VehicleVelocity;
1060 vel.Z = 0f;
1061 VehicleVelocity = vel;
1062
1063 /*
983 float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; 1064 float verticalCorrectionVelocity = verticalError / m_VhoverTimescale;
1065 Vector3 verticalCorrection = new Vector3(0f, 0f, verticalCorrectionVelocity);
1066 verticalCorrection *= m_vehicleMass;
984 1067
985 // TODO: implement m_VhoverEfficiency correctly 1068 // TODO: implement m_VhoverEfficiency correctly
986 ret = new Vector3(0f, 0f, verticalCorrectionVelocity); 1069 VehicleAddForceImpulse(verticalCorrection);
1070 */
1071
1072 VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corr={7}",
1073 Prim.LocalID, VehiclePosition, m_VhoverEfficiency,
1074 m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight,
1075 verticalError, verticalCorrection);
987 } 1076 }
988 1077
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 } 1078 }
992
993 return ret;
994 } 1079 }
995 1080
996 public bool ComputeLinearBlockingEndPoint(float pTimestep) 1081 public bool ComputeLinearBlockingEndPoint(float pTimestep)
@@ -1045,30 +1130,67 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1045 // TODO: this code is wrong. Also, what should it do for boats (height from water)? 1130 // 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 1131 // This is just using the ground and a general collision check. Should really be using
1047 // a downward raycast to find what is below. 1132 // a downward raycast to find what is below.
1048 public Vector3 ComputeLinearMotorUp(float pTimestep) 1133 public void ComputeLinearMotorUp(float pTimestep)
1049 { 1134 {
1050 Vector3 ret = Vector3.Zero; 1135 Vector3 ret = Vector3.Zero;
1051 float distanceAboveGround = 0f;
1052 1136
1053 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 1137 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
1054 { 1138 {
1139 // This code tries to decide if the object is not on the ground and then pushing down
1140 /*
1055 float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); 1141 float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition);
1056 distanceAboveGround = VehiclePosition.Z - targetHeight; 1142 distanceAboveGround = VehiclePosition.Z - targetHeight;
1057 // Not colliding if the vehicle is off the ground 1143 // Not colliding if the vehicle is off the ground
1058 if (!Prim.IsColliding) 1144 if (!Prim.IsColliding)
1059 { 1145 {
1060 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); 1146 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
1061 ret = new Vector3(0, 0, -distanceAboveGround); 1147 VehicleVelocity += new Vector3(0, 0, -distanceAboveGround);
1062 } 1148 }
1063 // TODO: this calculation is wrong. From the description at 1149 // TODO: this calculation is wrong. From the description at
1064 // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce 1150 // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
1065 // has a decay factor. This says this force should 1151 // has a decay factor. This says this force should
1066 // be computed with a motor. 1152 // be computed with a motor.
1067 // TODO: add interaction with banking. 1153 // TODO: add interaction with banking.
1068 } 1154 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); 1155 Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret);
1071 return ret; 1156 */
1157
1158 // Another approach is to measure if we're going up. If going up and not colliding,
1159 // the vehicle is in the air. Fix that by pushing down.
1160 if (!Prim.IsColliding && VehicleVelocity.Z > 0.1)
1161 {
1162 // Get rid of any of the velocity vector that is pushing us up.
1163 VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z);
1164
1165 // If we're pointed up into the air, we should nose down
1166 Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
1167 // The rotation around the Y axis is pitch up or down
1168 if (pointingDirection.Y > 0.01f)
1169 {
1170 float angularCorrectionForce = -(float)Math.Asin(pointingDirection.Y);
1171 Vector3 angularCorrectionVector = new Vector3(0f, angularCorrectionForce, 0f);
1172 // Rotate into world coordinates and apply to vehicle
1173 angularCorrectionVector *= VehicleOrientation;
1174 VehicleAddAngularForce(angularCorrectionVector);
1175 VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}",
1176 Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector);
1177 }
1178 else
1179 {
1180 VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}",
1181 Prim.LocalID, VehicleVelocity, pointingDirection);
1182 }
1183 }
1184 }
1185 }
1186
1187 private void ApplyGravity(float pTimeStep)
1188 {
1189 Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
1190 VehicleAddForce(appliedGravity);
1191
1192 VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}",
1193 Prim.LocalID, m_VehicleGravity, appliedGravity);
1072 } 1194 }
1073 1195
1074 // ======================================================================= 1196 // =======================================================================
@@ -1088,6 +1210,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1088 // for preventing ground vehicles with large linear deflection, like bumper cars, 1210 // for preventing ground vehicles with large linear deflection, like bumper cars,
1089 // from climbing their linear deflection into the sky. 1211 // 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 1212 // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
1213 // TODO: This is here because this is where ODE put it but documentation says it
1214 // is a linear effect. Where should this check go?
1091 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 1215 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
1092 { 1216 {
1093 angularMotorContribution.X = 0f; 1217 angularMotorContribution.X = 0f;
@@ -1179,7 +1303,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1179 Vector3 ret = Vector3.Zero; 1303 Vector3 ret = Vector3.Zero;
1180 1304
1181 // If vertical attaction timescale is reasonable 1305 // If vertical attaction timescale is reasonable
1182 if (m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1306 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1183 { 1307 {
1184 // Take a vector pointing up and convert it from world to vehicle relative coords. 1308 // Take a vector pointing up and convert it from world to vehicle relative coords.
1185 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; 1309 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
@@ -1230,7 +1354,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1230 // this creates an over-correction and then wabbling as the target is overshot. 1354 // this creates an over-correction and then wabbling as the target is overshot.
1231 // TODO: rethink how the different correction computations inter-relate. 1355 // TODO: rethink how the different correction computations inter-relate.
1232 1356
1233 if (m_angularDeflectionEfficiency != 0 && VehicleVelocity != Vector3.Zero) 1357 if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
1234 { 1358 {
1235 // The direction the vehicle is moving 1359 // The direction the vehicle is moving
1236 Vector3 movingDirection = VehicleVelocity; 1360 Vector3 movingDirection = VehicleVelocity;
@@ -1303,7 +1427,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1303 { 1427 {
1304 Vector3 ret = Vector3.Zero; 1428 Vector3 ret = Vector3.Zero;
1305 1429
1306 if (m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1430 if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1307 { 1431 {
1308 // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. 1432 // 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 1433 // As the vehicle rolls to the right or left, the Y value will increase from