diff options
author | Robert Adams | 2013-01-09 22:45:01 -0800 |
---|---|---|
committer | Robert Adams | 2013-01-11 16:47:20 -0800 |
commit | 93adc4cb6689b156db4db315d44b5ba0ddcd65ac (patch) | |
tree | 0068e2e8bb2721f6f33e622ebb6f7535eb843518 /OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |
parent | Fix exception reporting in SceneObjectPart so it logs what the exception is r... (diff) | |
download | opensim-SC-93adc4cb6689b156db4db315d44b5ba0ddcd65ac.zip opensim-SC-93adc4cb6689b156db4db315d44b5ba0ddcd65ac.tar.gz opensim-SC-93adc4cb6689b156db4db315d44b5ba0ddcd65ac.tar.bz2 opensim-SC-93adc4cb6689b156db4db315d44b5ba0ddcd65ac.tar.xz |
BulletSim: Add IsSelected attribute to physical objects. Have vehicles check to see if physical before trying to step. Replace vehicle gravity application. Previously relying on Bullet to apply gravity but since vehicles over-ride the velocity calculation, gravity never had a chance to accelerate the body down. Added AddForceImpulse as well as AddForce for those who need to apply immediate velocity updates. Use the impulse to apply the linear motion.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 126 |
1 files changed, 96 insertions, 30 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 2e44ab6..80fdfb9 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"); |
@@ -149,14 +148,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
149 | enableAngularVerticalAttraction = false; | 148 | enableAngularVerticalAttraction = false; |
150 | enableAngularDeflection = false; | 149 | enableAngularDeflection = false; |
151 | enableAngularBanking = false; | 150 | enableAngularBanking = false; |
152 | VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode"); | 151 | VDetailLog("{0},BSDynamics.SetupVehicleDebugging,settingDebugMode", Prim.LocalID); |
153 | } | 152 | } |
154 | } | 153 | } |
155 | 154 | ||
156 | // Return 'true' if this vehicle is doing vehicle things | 155 | // Return 'true' if this vehicle is doing vehicle things |
157 | public bool IsActive | 156 | public bool IsActive |
158 | { | 157 | { |
159 | get { return Type != Vehicle.TYPE_NONE && Prim.IsPhysical; } | 158 | get { return (Type != Vehicle.TYPE_NONE && !Prim.IsStatic); } |
160 | } | 159 | } |
161 | 160 | ||
162 | #region Vehicle parameter setting | 161 | #region Vehicle parameter setting |
@@ -190,6 +189,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
190 | break; | 189 | break; |
191 | case Vehicle.BUOYANCY: | 190 | case Vehicle.BUOYANCY: |
192 | m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); | 191 | m_VehicleBuoyancy = ClampInRange(-1f, pValue, 1f); |
192 | m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); | ||
193 | break; | 193 | break; |
194 | case Vehicle.HOVER_EFFICIENCY: | 194 | case Vehicle.HOVER_EFFICIENCY: |
195 | m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); | 195 | m_VhoverEfficiency = ClampInRange(0f, pValue, 1f); |
@@ -562,12 +562,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
562 | 1f); | 562 | 1f); |
563 | m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | 563 | m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
564 | 564 | ||
565 | /* Not implemented | ||
565 | m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, | 566 | m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, |
566 | BSMotor.Infinite, BSMotor.InfiniteVector, | 567 | BSMotor.Infinite, BSMotor.InfiniteVector, |
567 | m_verticalAttractionEfficiency); | 568 | m_verticalAttractionEfficiency); |
568 | // Z goes away and we keep X and Y | 569 | // Z goes away and we keep X and Y |
569 | m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); | 570 | m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); |
570 | m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | 571 | m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
572 | */ | ||
571 | } | 573 | } |
572 | #endregion // Vehicle parameter setting | 574 | #endregion // Vehicle parameter setting |
573 | 575 | ||
@@ -599,11 +601,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
599 | 601 | ||
600 | // Set the gravity for the vehicle depending on the buoyancy | 602 | // Set the gravity for the vehicle depending on the buoyancy |
601 | // TODO: what should be done if prim and vehicle buoyancy differ? | 603 | // TODO: what should be done if prim and vehicle buoyancy differ? |
602 | Vector3 grav = Prim.ComputeGravity(m_VehicleBuoyancy); | 604 | m_VehicleGravity = Prim.ComputeGravity(m_VehicleBuoyancy); |
603 | PhysicsScene.PE.SetGravity(Prim.PhysBody, grav); | 605 | // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. |
606 | PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero); | ||
604 | 607 | ||
605 | VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", | 608 | VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}", |
606 | Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, grav); | 609 | Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity); |
607 | } | 610 | } |
608 | else | 611 | else |
609 | { | 612 | { |
@@ -643,6 +646,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
643 | private Vector3 m_knownPosition; | 646 | private Vector3 m_knownPosition; |
644 | private Vector3 m_knownVelocity; | 647 | private Vector3 m_knownVelocity; |
645 | private Vector3 m_knownForce; | 648 | private Vector3 m_knownForce; |
649 | private Vector3 m_knownForceImpulse; | ||
646 | private Quaternion m_knownOrientation; | 650 | private Quaternion m_knownOrientation; |
647 | private Vector3 m_knownRotationalVelocity; | 651 | private Vector3 m_knownRotationalVelocity; |
648 | private Vector3 m_knownRotationalForce; | 652 | private Vector3 m_knownRotationalForce; |
@@ -651,12 +655,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
651 | private const int m_knownChangedPosition = 1 << 0; | 655 | private const int m_knownChangedPosition = 1 << 0; |
652 | private const int m_knownChangedVelocity = 1 << 1; | 656 | private const int m_knownChangedVelocity = 1 << 1; |
653 | private const int m_knownChangedForce = 1 << 2; | 657 | private const int m_knownChangedForce = 1 << 2; |
654 | private const int m_knownChangedOrientation = 1 << 3; | 658 | private const int m_knownChangedForceImpulse = 1 << 3; |
655 | private const int m_knownChangedRotationalVelocity = 1 << 4; | 659 | private const int m_knownChangedOrientation = 1 << 4; |
656 | private const int m_knownChangedRotationalForce = 1 << 5; | 660 | private const int m_knownChangedRotationalVelocity = 1 << 5; |
657 | private const int m_knownChangedTerrainHeight = 1 << 6; | 661 | private const int m_knownChangedRotationalForce = 1 << 6; |
658 | private const int m_knownChangedWaterLevel = 1 << 7; | 662 | private const int m_knownChangedTerrainHeight = 1 << 7; |
659 | private const int m_knownChangedForwardVelocity = 1 << 8; | 663 | private const int m_knownChangedWaterLevel = 1 << 8; |
664 | private const int m_knownChangedForwardVelocity = 1 << 9; | ||
660 | 665 | ||
661 | private void ForgetKnownVehicleProperties() | 666 | private void ForgetKnownVehicleProperties() |
662 | { | 667 | { |
@@ -677,21 +682,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
677 | if ((m_knownChanged & m_knownChangedVelocity) != 0) | 682 | if ((m_knownChanged & m_knownChangedVelocity) != 0) |
678 | { | 683 | { |
679 | Prim.ForceVelocity = m_knownVelocity; | 684 | Prim.ForceVelocity = m_knownVelocity; |
680 | PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity); | 685 | // Fake out Bullet by making it think the velocity is the same as last time. |
686 | // Bullet does a bunch of smoothing for changing parameters. | ||
687 | // Since the vehicle is demanding this setting, we override Bullet's smoothing | ||
688 | // by telling Bullet the value was the same last time. | ||
689 | PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity); | ||
681 | } | 690 | } |
682 | 691 | ||
683 | if ((m_knownChanged & m_knownChangedForce) != 0) | 692 | if ((m_knownChanged & m_knownChangedForce) != 0) |
684 | Prim.AddForce((Vector3)m_knownForce, false, true); | 693 | Prim.AddForce((Vector3)m_knownForce, false, true); |
685 | 694 | ||
695 | if ((m_knownChanged & m_knownChangedForceImpulse) != 0) | ||
696 | Prim.AddForceImpulse((Vector3)m_knownForceImpulse, false, true); | ||
697 | |||
686 | if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) | 698 | if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) |
687 | { | 699 | { |
688 | Prim.ForceRotationalVelocity = m_knownRotationalVelocity; | 700 | Prim.ForceRotationalVelocity = m_knownRotationalVelocity; |
689 | // Fake out Bullet by making it think the velocity is the same as last time. | ||
690 | PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); | 701 | PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); |
691 | } | 702 | } |
692 | 703 | ||
693 | if ((m_knownChanged & m_knownChangedRotationalForce) != 0) | 704 | if ((m_knownChanged & m_knownChangedRotationalForce) != 0) |
705 | { | ||
694 | Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); | 706 | Prim.AddAngularForce((Vector3)m_knownRotationalForce, false, true); |
707 | } | ||
695 | 708 | ||
696 | // If we set one of the values (ie, the physics engine didn't do it) we must force | 709 | // If we set one of the values (ie, the physics engine didn't do it) we must force |
697 | // an UpdateProperties event to send the changes up to the simulator. | 710 | // an UpdateProperties event to send the changes up to the simulator. |
@@ -781,15 +794,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
781 | } | 794 | } |
782 | } | 795 | } |
783 | 796 | ||
784 | private void VehicleAddForce(Vector3 aForce) | 797 | private void VehicleAddForce(Vector3 pForce) |
785 | { | 798 | { |
786 | if ((m_knownHas & m_knownChangedForce) == 0) | 799 | if ((m_knownHas & m_knownChangedForce) == 0) |
787 | { | 800 | { |
788 | m_knownForce = Vector3.Zero; | 801 | m_knownForce = Vector3.Zero; |
802 | m_knownHas |= m_knownChangedForce; | ||
789 | } | 803 | } |
790 | m_knownForce += aForce; | 804 | m_knownForce += pForce; |
791 | m_knownChanged |= m_knownChangedForce; | 805 | m_knownChanged |= m_knownChangedForce; |
792 | m_knownHas |= m_knownChangedForce; | 806 | } |
807 | |||
808 | private void VehicleAddForceImpulse(Vector3 pImpulse) | ||
809 | { | ||
810 | if ((m_knownHas & m_knownChangedForceImpulse) == 0) | ||
811 | { | ||
812 | m_knownForceImpulse = Vector3.Zero; | ||
813 | m_knownHas |= m_knownChangedForceImpulse; | ||
814 | } | ||
815 | m_knownForceImpulse += pImpulse; | ||
816 | m_knownChanged |= m_knownChangedForceImpulse; | ||
793 | } | 817 | } |
794 | 818 | ||
795 | private Vector3 VehicleRotationalVelocity | 819 | private Vector3 VehicleRotationalVelocity |
@@ -868,20 +892,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
868 | if (PhysicsScene.VehiclePhysicalLoggingEnabled) | 892 | if (PhysicsScene.VehiclePhysicalLoggingEnabled) |
869 | PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); | 893 | PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody); |
870 | 894 | ||
871 | VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", | 895 | VDetailLog("{0},BSDynamics.Step,done,pos={1}, force={2},velocity={3},angvel={4}", |
872 | Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity); | 896 | Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity); |
873 | } | 897 | } |
874 | 898 | ||
875 | // Apply the effect of the linear motor and other linear motions (like hover and float). | 899 | // Apply the effect of the linear motor and other linear motions (like hover and float). |
876 | private void MoveLinear(float pTimestep) | 900 | private void MoveLinear(float pTimestep) |
877 | { | 901 | { |
878 | Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); | 902 | ComputeLinearVelocity(pTimestep); |
879 | |||
880 | // The movement computed in the linear motor is relative to the vehicle | ||
881 | // coordinates. Rotate the movement to world coordinates. | ||
882 | linearMotorContribution *= VehicleOrientation; | ||
883 | |||
884 | VehicleVelocity = linearMotorContribution; | ||
885 | 903 | ||
886 | ComputeLinearTerrainHeightCorrection(pTimestep); | 904 | ComputeLinearTerrainHeightCorrection(pTimestep); |
887 | 905 | ||
@@ -891,6 +909,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
891 | 909 | ||
892 | ComputeLinearMotorUp(pTimestep); | 910 | ComputeLinearMotorUp(pTimestep); |
893 | 911 | ||
912 | ApplyGravity(pTimestep); | ||
913 | |||
894 | // If not changing some axis, reduce out velocity | 914 | // If not changing some axis, reduce out velocity |
895 | if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0) | 915 | if ((m_flags & (VehicleFlag.NO_X | VehicleFlag.NO_Y | VehicleFlag.NO_Z)) != 0) |
896 | { | 916 | { |
@@ -919,6 +939,43 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
919 | 939 | ||
920 | } // end MoveLinear() | 940 | } // end MoveLinear() |
921 | 941 | ||
942 | public void ComputeLinearVelocity(float pTimestep) | ||
943 | { | ||
944 | Vector3 linearMotorStep = m_linearMotor.Step(pTimestep); | ||
945 | |||
946 | // The movement computed in the linear motor is relative to the vehicle | ||
947 | // coordinates. Rotate the movement to world coordinates. | ||
948 | Vector3 linearMotorVelocity = linearMotorStep * VehicleOrientation; | ||
949 | |||
950 | // If we're a ground vehicle, don't loose any Z action (like gravity acceleration). | ||
951 | float mixFactor = 1f; // 1 means use all linear motor Z value, 0 means use all existing Z | ||
952 | if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) | ||
953 | { | ||
954 | if (!Prim.IsColliding) | ||
955 | { | ||
956 | // If a ground vehicle and not on the ground, I want gravity effect | ||
957 | mixFactor = 0.2f; | ||
958 | } | ||
959 | } | ||
960 | else | ||
961 | { | ||
962 | // I'm not a ground vehicle but don't totally loose the effect of the environment | ||
963 | mixFactor = 0.8f; | ||
964 | } | ||
965 | linearMotorVelocity.Z = mixFactor * linearMotorVelocity.Z + (1f - mixFactor) * VehicleVelocity.Z; | ||
966 | |||
967 | // What we want to contribute to the vehicle's existing velocity | ||
968 | Vector3 linearMotorForce = linearMotorVelocity - VehicleVelocity; | ||
969 | |||
970 | // Act against the inertia of the vehicle | ||
971 | linearMotorForce *= m_vehicleMass; | ||
972 | |||
973 | VehicleAddForceImpulse(linearMotorForce); | ||
974 | |||
975 | VDetailLog("{0}, MoveLinear,velocity,vehVel={1},step={2},stepVel={3},mix={4},force={5}", | ||
976 | Prim.LocalID, VehicleVelocity, linearMotorStep, linearMotorVelocity, mixFactor, linearMotorForce); | ||
977 | } | ||
978 | |||
922 | public void ComputeLinearTerrainHeightCorrection(float pTimestep) | 979 | public void ComputeLinearTerrainHeightCorrection(float pTimestep) |
923 | { | 980 | { |
924 | // If below the terrain, move us above the ground a little. | 981 | // If below the terrain, move us above the ground a little. |
@@ -979,7 +1036,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
979 | float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; | 1036 | float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; |
980 | 1037 | ||
981 | // TODO: implement m_VhoverEfficiency correctly | 1038 | // TODO: implement m_VhoverEfficiency correctly |
982 | VehicleVelocity += new Vector3(0f, 0f, verticalCorrectionVelocity); | 1039 | VehicleAddForceImpulse(new Vector3(0f, 0f, verticalCorrectionVelocity)); |
983 | 1040 | ||
984 | VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}", | 1041 | VDetailLog("{0}, MoveLinear,hover,pos={1},eff={2},hoverTS={3},height={4},target={5},err={6},corrVel={7}", |
985 | Prim.LocalID, VehiclePosition, m_VhoverEfficiency, | 1042 | Prim.LocalID, VehiclePosition, m_VhoverEfficiency, |
@@ -1096,6 +1153,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1096 | } | 1153 | } |
1097 | } | 1154 | } |
1098 | 1155 | ||
1156 | private void ApplyGravity(float pTimeStep) | ||
1157 | { | ||
1158 | Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; | ||
1159 | VehicleAddForce(appliedGravity); | ||
1160 | |||
1161 | VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}", | ||
1162 | Prim.LocalID, m_VehicleGravity, appliedGravity); | ||
1163 | } | ||
1164 | |||
1099 | // ======================================================================= | 1165 | // ======================================================================= |
1100 | // ======================================================================= | 1166 | // ======================================================================= |
1101 | // Apply the effect of the angular motor. | 1167 | // Apply the effect of the angular motor. |