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