diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 314 |
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 |