diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 490 |
1 files changed, 311 insertions, 179 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 0fd1f73..7b98f9d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -45,7 +45,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
45 | private static string LogHeader = "[BULLETSIM VEHICLE]"; | 45 | private static string LogHeader = "[BULLETSIM VEHICLE]"; |
46 | 46 | ||
47 | // the prim this dynamic controller belongs to | 47 | // the prim this dynamic controller belongs to |
48 | private BSPrim ControllingPrim { get; set; } | 48 | private BSPrimLinkable ControllingPrim { get; set; } |
49 | 49 | ||
50 | private bool m_haveRegisteredForSceneEvents; | 50 | private bool m_haveRegisteredForSceneEvents; |
51 | 51 | ||
@@ -125,33 +125,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
125 | static readonly float PIOverFour = ((float)Math.PI) / 4f; | 125 | static readonly float PIOverFour = ((float)Math.PI) / 4f; |
126 | static readonly float PIOverTwo = ((float)Math.PI) / 2f; | 126 | static readonly float PIOverTwo = ((float)Math.PI) / 2f; |
127 | 127 | ||
128 | // For debugging, flags to turn on and off individual corrections. | ||
129 | public bool enableAngularVerticalAttraction; | ||
130 | public bool enableAngularDeflection; | ||
131 | public bool enableAngularBanking; | ||
132 | |||
133 | public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName) | 128 | public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName) |
134 | : base(myScene, myPrim, actorName) | 129 | : base(myScene, myPrim, actorName) |
135 | { | 130 | { |
136 | ControllingPrim = myPrim; | ||
137 | Type = Vehicle.TYPE_NONE; | 131 | Type = Vehicle.TYPE_NONE; |
138 | m_haveRegisteredForSceneEvents = false; | 132 | m_haveRegisteredForSceneEvents = false; |
139 | SetupVehicleDebugging(); | ||
140 | } | ||
141 | 133 | ||
142 | // Stopgap debugging enablement. Allows source level debugging but still checking | 134 | ControllingPrim = myPrim as BSPrimLinkable; |
143 | // in changes by making enablement of debugging flags from INI file. | 135 | if (ControllingPrim == null) |
144 | public void SetupVehicleDebugging() | ||
145 | { | ||
146 | enableAngularVerticalAttraction = true; | ||
147 | enableAngularDeflection = false; | ||
148 | enableAngularBanking = true; | ||
149 | if (BSParam.VehicleDebuggingEnabled) | ||
150 | { | 136 | { |
151 | enableAngularVerticalAttraction = true; | 137 | // THIS CANNOT HAPPEN!! |
152 | enableAngularDeflection = false; | ||
153 | enableAngularBanking = false; | ||
154 | } | 138 | } |
139 | VDetailLog("{0},Creation", ControllingPrim.LocalID); | ||
155 | } | 140 | } |
156 | 141 | ||
157 | // Return 'true' if this vehicle is doing vehicle things | 142 | // Return 'true' if this vehicle is doing vehicle things |
@@ -173,7 +158,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
173 | switch (pParam) | 158 | switch (pParam) |
174 | { | 159 | { |
175 | case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: | 160 | case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: |
176 | m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f); | 161 | m_angularDeflectionEfficiency = ClampInRange(0f, pValue, 1f); |
177 | break; | 162 | break; |
178 | case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: | 163 | case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: |
179 | m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); | 164 | m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); |
@@ -209,7 +194,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
209 | m_VhoverTimescale = Math.Max(pValue, 0.01f); | 194 | m_VhoverTimescale = Math.Max(pValue, 0.01f); |
210 | break; | 195 | break; |
211 | case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: | 196 | case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: |
212 | m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f); | 197 | m_linearDeflectionEfficiency = ClampInRange(0f, pValue, 1f); |
213 | break; | 198 | break; |
214 | case Vehicle.LINEAR_DEFLECTION_TIMESCALE: | 199 | case Vehicle.LINEAR_DEFLECTION_TIMESCALE: |
215 | m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); | 200 | m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); |
@@ -235,7 +220,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
235 | // set all of the components to the same value | 220 | // set all of the components to the same value |
236 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: | 221 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: |
237 | m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); | 222 | m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); |
238 | m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; | ||
239 | break; | 223 | break; |
240 | case Vehicle.ANGULAR_MOTOR_DIRECTION: | 224 | case Vehicle.ANGULAR_MOTOR_DIRECTION: |
241 | m_angularMotorDirection = new Vector3(pValue, pValue, pValue); | 225 | m_angularMotorDirection = new Vector3(pValue, pValue, pValue); |
@@ -244,7 +228,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
244 | break; | 228 | break; |
245 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 229 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
246 | m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); | 230 | m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); |
247 | m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; | ||
248 | break; | 231 | break; |
249 | case Vehicle.LINEAR_MOTOR_DIRECTION: | 232 | case Vehicle.LINEAR_MOTOR_DIRECTION: |
250 | m_linearMotorDirection = new Vector3(pValue, pValue, pValue); | 233 | m_linearMotorDirection = new Vector3(pValue, pValue, pValue); |
@@ -265,7 +248,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
265 | { | 248 | { |
266 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: | 249 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: |
267 | m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); | 250 | m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); |
268 | m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; | ||
269 | break; | 251 | break; |
270 | case Vehicle.ANGULAR_MOTOR_DIRECTION: | 252 | case Vehicle.ANGULAR_MOTOR_DIRECTION: |
271 | // Limit requested angular speed to 2 rps= 4 pi rads/sec | 253 | // Limit requested angular speed to 2 rps= 4 pi rads/sec |
@@ -278,7 +260,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
278 | break; | 260 | break; |
279 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 261 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
280 | m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); | 262 | m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); |
281 | m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; | ||
282 | break; | 263 | break; |
283 | case Vehicle.LINEAR_MOTOR_DIRECTION: | 264 | case Vehicle.LINEAR_MOTOR_DIRECTION: |
284 | m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); | 265 | m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); |
@@ -559,25 +540,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
559 | break; | 540 | break; |
560 | } | 541 | } |
561 | 542 | ||
562 | // Update any physical parameters based on this type. | 543 | m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f); |
563 | Refresh(); | 544 | // m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
564 | |||
565 | m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, | ||
566 | m_linearMotorDecayTimescale, m_linearFrictionTimescale, | ||
567 | 1f); | ||
568 | m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | ||
569 | 545 | ||
570 | m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, | 546 | m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f); |
571 | m_angularMotorDecayTimescale, m_angularFrictionTimescale, | 547 | // m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
572 | 1f); | ||
573 | m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | ||
574 | 548 | ||
575 | /* Not implemented | 549 | /* Not implemented |
576 | m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, | 550 | m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, |
577 | BSMotor.Infinite, BSMotor.InfiniteVector, | 551 | BSMotor.Infinite, BSMotor.InfiniteVector, |
578 | m_verticalAttractionEfficiency); | 552 | m_verticalAttractionEfficiency); |
579 | // Z goes away and we keep X and Y | 553 | // Z goes away and we keep X and Y |
580 | m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); | ||
581 | m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | 554 | m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) |
582 | */ | 555 | */ |
583 | 556 | ||
@@ -589,6 +562,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
589 | { | 562 | { |
590 | RegisterForSceneEvents(); | 563 | RegisterForSceneEvents(); |
591 | } | 564 | } |
565 | |||
566 | // Update any physical parameters based on this type. | ||
567 | Refresh(); | ||
592 | } | 568 | } |
593 | #endregion // Vehicle parameter setting | 569 | #endregion // Vehicle parameter setting |
594 | 570 | ||
@@ -596,6 +572,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
596 | public override void Refresh() | 572 | public override void Refresh() |
597 | { | 573 | { |
598 | // If asking for a refresh, reset the physical parameters before the next simulation step. | 574 | // If asking for a refresh, reset the physical parameters before the next simulation step. |
575 | // Called whether active or not since the active state may be updated before the next step. | ||
599 | m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate() | 576 | m_physicsScene.PostTaintObject("BSDynamics.Refresh", ControllingPrim.LocalID, delegate() |
600 | { | 577 | { |
601 | SetPhysicalParameters(); | 578 | SetPhysicalParameters(); |
@@ -612,8 +589,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
612 | m_vehicleMass = ControllingPrim.TotalMass; | 589 | m_vehicleMass = ControllingPrim.TotalMass; |
613 | 590 | ||
614 | // Friction affects are handled by this vehicle code | 591 | // Friction affects are handled by this vehicle code |
615 | m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction); | 592 | // m_physicsScene.PE.SetFriction(ControllingPrim.PhysBody, BSParam.VehicleFriction); |
616 | m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution); | 593 | // m_physicsScene.PE.SetRestitution(ControllingPrim.PhysBody, BSParam.VehicleRestitution); |
594 | ControllingPrim.Linkset.SetPhysicalFriction(BSParam.VehicleFriction); | ||
595 | ControllingPrim.Linkset.SetPhysicalRestitution(BSParam.VehicleRestitution); | ||
617 | 596 | ||
618 | // Moderate angular movement introduced by Bullet. | 597 | // Moderate angular movement introduced by Bullet. |
619 | // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. | 598 | // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. |
@@ -623,17 +602,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
623 | m_physicsScene.PE.SetAngularFactorV(ControllingPrim.PhysBody, BSParam.VehicleAngularFactor); | 602 | m_physicsScene.PE.SetAngularFactorV(ControllingPrim.PhysBody, BSParam.VehicleAngularFactor); |
624 | 603 | ||
625 | // Vehicles report collision events so we know when it's on the ground | 604 | // Vehicles report collision events so we know when it's on the ground |
626 | m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); | 605 | // m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); |
606 | ControllingPrim.Linkset.AddToPhysicalCollisionFlags(CollisionFlags.BS_VEHICLE_COLLISIONS); | ||
627 | 607 | ||
628 | ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape, m_vehicleMass); | 608 | // Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass); |
629 | m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia); | 609 | // ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor; |
630 | m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody); | 610 | // m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia); |
611 | // m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody); | ||
612 | ControllingPrim.Linkset.ComputeAndSetLocalInertia(BSParam.VehicleInertiaFactor, m_vehicleMass); | ||
631 | 613 | ||
632 | // Set the gravity for the vehicle depending on the buoyancy | 614 | // Set the gravity for the vehicle depending on the buoyancy |
633 | // TODO: what should be done if prim and vehicle buoyancy differ? | 615 | // TODO: what should be done if prim and vehicle buoyancy differ? |
634 | m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy); | 616 | m_VehicleGravity = ControllingPrim.ComputeGravity(m_VehicleBuoyancy); |
635 | // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. | 617 | // The actual vehicle gravity is set to zero in Bullet so we can do all the application of same. |
636 | m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero); | 618 | // m_physicsScene.PE.SetGravity(ControllingPrim.PhysBody, Vector3.Zero); |
619 | ControllingPrim.Linkset.SetPhysicalGravity(Vector3.Zero); | ||
637 | 620 | ||
638 | VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}", | 621 | VDetailLog("{0},BSDynamics.SetPhysicalParameters,mass={1},inert={2},vehGrav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}", |
639 | ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity, | 622 | ControllingPrim.LocalID, m_vehicleMass, ControllingPrim.Inertia, m_VehicleGravity, |
@@ -645,11 +628,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
645 | { | 628 | { |
646 | if (ControllingPrim.PhysBody.HasPhysicalBody) | 629 | if (ControllingPrim.PhysBody.HasPhysicalBody) |
647 | m_physicsScene.PE.RemoveFromCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); | 630 | m_physicsScene.PE.RemoveFromCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); |
631 | // ControllingPrim.Linkset.RemoveFromPhysicalCollisionFlags(CollisionFlags.BS_VEHICLE_COLLISIONS); | ||
648 | } | 632 | } |
649 | } | 633 | } |
650 | 634 | ||
651 | // BSActor.RemoveBodyDependencies | 635 | // BSActor.RemoveBodyDependencies |
652 | public override void RemoveBodyDependencies() | 636 | public override void RemoveDependencies() |
653 | { | 637 | { |
654 | Refresh(); | 638 | Refresh(); |
655 | } | 639 | } |
@@ -657,6 +641,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
657 | // BSActor.Release() | 641 | // BSActor.Release() |
658 | public override void Dispose() | 642 | public override void Dispose() |
659 | { | 643 | { |
644 | VDetailLog("{0},Dispose", ControllingPrim.LocalID); | ||
660 | UnregisterForSceneEvents(); | 645 | UnregisterForSceneEvents(); |
661 | Type = Vehicle.TYPE_NONE; | 646 | Type = Vehicle.TYPE_NONE; |
662 | Enabled = false; | 647 | Enabled = false; |
@@ -714,7 +699,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
714 | private Vector3 m_knownRotationalVelocity; | 699 | private Vector3 m_knownRotationalVelocity; |
715 | private Vector3 m_knownRotationalForce; | 700 | private Vector3 m_knownRotationalForce; |
716 | private Vector3 m_knownRotationalImpulse; | 701 | private Vector3 m_knownRotationalImpulse; |
717 | private Vector3 m_knownForwardVelocity; // vehicle relative forward speed | ||
718 | 702 | ||
719 | private const int m_knownChangedPosition = 1 << 0; | 703 | private const int m_knownChangedPosition = 1 << 0; |
720 | private const int m_knownChangedVelocity = 1 << 1; | 704 | private const int m_knownChangedVelocity = 1 << 1; |
@@ -726,7 +710,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
726 | private const int m_knownChangedRotationalImpulse = 1 << 7; | 710 | private const int m_knownChangedRotationalImpulse = 1 << 7; |
727 | private const int m_knownChangedTerrainHeight = 1 << 8; | 711 | private const int m_knownChangedTerrainHeight = 1 << 8; |
728 | private const int m_knownChangedWaterLevel = 1 << 9; | 712 | private const int m_knownChangedWaterLevel = 1 << 9; |
729 | private const int m_knownChangedForwardVelocity = 1 <<10; | ||
730 | 713 | ||
731 | public void ForgetKnownVehicleProperties() | 714 | public void ForgetKnownVehicleProperties() |
732 | { | 715 | { |
@@ -783,13 +766,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
783 | 766 | ||
784 | // Since the computation of terrain height can be a little involved, this routine | 767 | // Since the computation of terrain height can be a little involved, this routine |
785 | // is used to fetch the height only once for each vehicle simulation step. | 768 | // is used to fetch the height only once for each vehicle simulation step. |
786 | Vector3 lastRememberedHeightPos; | 769 | Vector3 lastRememberedHeightPos = new Vector3(-1, -1, -1); |
787 | private float GetTerrainHeight(Vector3 pos) | 770 | private float GetTerrainHeight(Vector3 pos) |
788 | { | 771 | { |
789 | if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos) | 772 | if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos) |
790 | { | 773 | { |
791 | lastRememberedHeightPos = pos; | 774 | lastRememberedHeightPos = pos; |
792 | m_knownTerrainHeight = ControllingPrim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); | 775 | m_knownTerrainHeight = ControllingPrim.PhysScene.TerrainManager.GetTerrainHeightAtXYZ(pos); |
793 | m_knownHas |= m_knownChangedTerrainHeight; | 776 | m_knownHas |= m_knownChangedTerrainHeight; |
794 | } | 777 | } |
795 | return m_knownTerrainHeight; | 778 | return m_knownTerrainHeight; |
@@ -797,14 +780,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
797 | 780 | ||
798 | // Since the computation of water level can be a little involved, this routine | 781 | // Since the computation of water level can be a little involved, this routine |
799 | // is used ot fetch the level only once for each vehicle simulation step. | 782 | // is used ot fetch the level only once for each vehicle simulation step. |
783 | Vector3 lastRememberedWaterHeightPos = new Vector3(-1, -1, -1); | ||
800 | private float GetWaterLevel(Vector3 pos) | 784 | private float GetWaterLevel(Vector3 pos) |
801 | { | 785 | { |
802 | if ((m_knownHas & m_knownChangedWaterLevel) == 0) | 786 | if ((m_knownHas & m_knownChangedWaterLevel) == 0 || pos != lastRememberedWaterHeightPos) |
803 | { | 787 | { |
804 | m_knownWaterLevel = ControllingPrim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); | 788 | lastRememberedWaterHeightPos = pos; |
789 | m_knownWaterLevel = ControllingPrim.PhysScene.TerrainManager.GetWaterLevelAtXYZ(pos); | ||
805 | m_knownHas |= m_knownChangedWaterLevel; | 790 | m_knownHas |= m_knownChangedWaterLevel; |
806 | } | 791 | } |
807 | return (float)m_knownWaterLevel; | 792 | return m_knownWaterLevel; |
808 | } | 793 | } |
809 | 794 | ||
810 | private Vector3 VehiclePosition | 795 | private Vector3 VehiclePosition |
@@ -930,14 +915,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
930 | { | 915 | { |
931 | get | 916 | get |
932 | { | 917 | { |
933 | if ((m_knownHas & m_knownChangedForwardVelocity) == 0) | 918 | return VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); |
934 | { | ||
935 | m_knownForwardVelocity = VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); | ||
936 | m_knownHas |= m_knownChangedForwardVelocity; | ||
937 | } | ||
938 | return m_knownForwardVelocity; | ||
939 | } | 919 | } |
940 | } | 920 | } |
921 | |||
941 | private float VehicleForwardSpeed | 922 | private float VehicleForwardSpeed |
942 | { | 923 | { |
943 | get | 924 | get |
@@ -988,6 +969,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
988 | { | 969 | { |
989 | ComputeLinearVelocity(pTimestep); | 970 | ComputeLinearVelocity(pTimestep); |
990 | 971 | ||
972 | ComputeLinearDeflection(pTimestep); | ||
973 | |||
991 | ComputeLinearTerrainHeightCorrection(pTimestep); | 974 | ComputeLinearTerrainHeightCorrection(pTimestep); |
992 | 975 | ||
993 | ComputeLinearHover(pTimestep); | 976 | ComputeLinearHover(pTimestep); |
@@ -1003,11 +986,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1003 | { | 986 | { |
1004 | Vector3 vel = VehicleVelocity; | 987 | Vector3 vel = VehicleVelocity; |
1005 | if ((m_flags & (VehicleFlag.NO_X)) != 0) | 988 | if ((m_flags & (VehicleFlag.NO_X)) != 0) |
989 | { | ||
1006 | vel.X = 0; | 990 | vel.X = 0; |
991 | } | ||
1007 | if ((m_flags & (VehicleFlag.NO_Y)) != 0) | 992 | if ((m_flags & (VehicleFlag.NO_Y)) != 0) |
993 | { | ||
1008 | vel.Y = 0; | 994 | vel.Y = 0; |
995 | } | ||
1009 | if ((m_flags & (VehicleFlag.NO_Z)) != 0) | 996 | if ((m_flags & (VehicleFlag.NO_Z)) != 0) |
997 | { | ||
1010 | vel.Z = 0; | 998 | vel.Z = 0; |
999 | } | ||
1011 | VehicleVelocity = vel; | 1000 | VehicleVelocity = vel; |
1012 | } | 1001 | } |
1013 | 1002 | ||
@@ -1019,13 +1008,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1019 | Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG | 1008 | Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG |
1020 | VehicleVelocity /= VehicleVelocity.Length(); | 1009 | VehicleVelocity /= VehicleVelocity.Length(); |
1021 | VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; | 1010 | VehicleVelocity *= BSParam.VehicleMaxLinearVelocity; |
1022 | VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}", | 1011 | VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}", |
1023 | ControllingPrim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity); | 1012 | ControllingPrim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySquared, VehicleVelocity); |
1024 | } | 1013 | } |
1025 | else if (newVelocityLengthSq < 0.001f) | 1014 | else if (newVelocityLengthSq < 0.001f) |
1026 | VehicleVelocity = Vector3.Zero; | 1015 | VehicleVelocity = Vector3.Zero; |
1027 | 1016 | ||
1028 | VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.IsColliding, VehicleVelocity ); | 1017 | VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, VehicleVelocity ); |
1029 | 1018 | ||
1030 | } // end MoveLinear() | 1019 | } // end MoveLinear() |
1031 | 1020 | ||
@@ -1033,9 +1022,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1033 | { | 1022 | { |
1034 | // Step the motor from the current value. Get the correction needed this step. | 1023 | // Step the motor from the current value. Get the correction needed this step. |
1035 | Vector3 origVelW = VehicleVelocity; // DEBUG | 1024 | Vector3 origVelW = VehicleVelocity; // DEBUG |
1036 | Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); | 1025 | Vector3 currentVelV = VehicleForwardVelocity; |
1037 | Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV); | 1026 | Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV); |
1038 | 1027 | ||
1028 | // Friction reduces vehicle motion based on absolute speed. Slow vehicle down by friction. | ||
1029 | Vector3 frictionFactorV = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep); | ||
1030 | linearMotorCorrectionV -= (currentVelV * frictionFactorV); | ||
1031 | |||
1039 | // Motor is vehicle coordinates. Rotate it to world coordinates | 1032 | // Motor is vehicle coordinates. Rotate it to world coordinates |
1040 | Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; | 1033 | Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation; |
1041 | 1034 | ||
@@ -1049,8 +1042,49 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1049 | // Add this correction to the velocity to make it faster/slower. | 1042 | // Add this correction to the velocity to make it faster/slower. |
1050 | VehicleVelocity += linearMotorVelocityW; | 1043 | VehicleVelocity += linearMotorVelocityW; |
1051 | 1044 | ||
1052 | VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}", | 1045 | VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},tgt={3},correctV={4},correctW={5},newVelW={6},fricFact={7}", |
1053 | ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity); | 1046 | ControllingPrim.LocalID, origVelW, currentVelV, m_linearMotor.TargetValue, linearMotorCorrectionV, |
1047 | linearMotorVelocityW, VehicleVelocity, frictionFactorV); | ||
1048 | } | ||
1049 | |||
1050 | //Given a Deflection Effiency and a Velocity, Returns a Velocity that is Partially Deflected onto the X Axis | ||
1051 | //Clamped so that a DeflectionTimescale of less then 1 does not increase force over original velocity | ||
1052 | private void ComputeLinearDeflection(float pTimestep) | ||
1053 | { | ||
1054 | Vector3 linearDeflectionV = Vector3.Zero; | ||
1055 | Vector3 velocityV = VehicleForwardVelocity; | ||
1056 | |||
1057 | if (BSParam.VehicleEnableLinearDeflection) | ||
1058 | { | ||
1059 | // Velocity in Y and Z dimensions is movement to the side or turning. | ||
1060 | // Compute deflection factor from the to the side and rotational velocity | ||
1061 | linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y); | ||
1062 | linearDeflectionV.Z = SortedClampInRange(0, (velocityV.Z * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Z); | ||
1063 | |||
1064 | // Velocity to the side and around is corrected and moved into the forward direction | ||
1065 | linearDeflectionV.X += Math.Abs(linearDeflectionV.Y); | ||
1066 | linearDeflectionV.X += Math.Abs(linearDeflectionV.Z); | ||
1067 | |||
1068 | // Scale the deflection to the fractional simulation time | ||
1069 | linearDeflectionV *= pTimestep; | ||
1070 | |||
1071 | // Subtract the sideways and rotational velocity deflection factors while adding the correction forward | ||
1072 | linearDeflectionV *= new Vector3(1, -1, -1); | ||
1073 | |||
1074 | // Correction is vehicle relative. Convert to world coordinates. | ||
1075 | Vector3 linearDeflectionW = linearDeflectionV * VehicleOrientation; | ||
1076 | |||
1077 | // Optionally, if not colliding, don't effect world downward velocity. Let falling things fall. | ||
1078 | if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.HasSomeCollision) | ||
1079 | { | ||
1080 | linearDeflectionW.Z = 0f; | ||
1081 | } | ||
1082 | |||
1083 | VehicleVelocity += linearDeflectionW; | ||
1084 | |||
1085 | VDetailLog("{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}", | ||
1086 | ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV); | ||
1087 | } | ||
1054 | } | 1088 | } |
1055 | 1089 | ||
1056 | public void ComputeLinearTerrainHeightCorrection(float pTimestep) | 1090 | public void ComputeLinearTerrainHeightCorrection(float pTimestep) |
@@ -1087,14 +1121,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1087 | { | 1121 | { |
1088 | m_VhoverTargetHeight = m_VhoverHeight; | 1122 | m_VhoverTargetHeight = m_VhoverHeight; |
1089 | } | 1123 | } |
1090 | |||
1091 | if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) | 1124 | if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) |
1092 | { | 1125 | { |
1093 | // If body is already heigher, use its height as target height | 1126 | // If body is already heigher, use its height as target height |
1094 | if (VehiclePosition.Z > m_VhoverTargetHeight) | 1127 | if (VehiclePosition.Z > m_VhoverTargetHeight) |
1128 | { | ||
1095 | m_VhoverTargetHeight = VehiclePosition.Z; | 1129 | m_VhoverTargetHeight = VehiclePosition.Z; |
1130 | |||
1131 | // A 'misfeature' of this flag is that if the vehicle is above it's hover height, | ||
1132 | // the vehicle's buoyancy goes away. This is an SL bug that got used by so many | ||
1133 | // scripts that it could not be changed. | ||
1134 | // So, if above the height, reapply gravity if buoyancy had it turned off. | ||
1135 | if (m_VehicleBuoyancy != 0) | ||
1136 | { | ||
1137 | Vector3 appliedGravity = ControllingPrim.ComputeGravity(ControllingPrim.Buoyancy) * m_vehicleMass; | ||
1138 | VehicleAddForce(appliedGravity); | ||
1139 | } | ||
1140 | } | ||
1096 | } | 1141 | } |
1097 | 1142 | ||
1098 | if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) | 1143 | if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) |
1099 | { | 1144 | { |
1100 | if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f) | 1145 | if (Math.Abs(VehiclePosition.Z - m_VhoverTargetHeight) > 0.2f) |
@@ -1136,7 +1181,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1136 | m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, | 1181 | m_VhoverTimescale, m_VhoverHeight, m_VhoverTargetHeight, |
1137 | verticalError, verticalCorrection); | 1182 | verticalError, verticalCorrection); |
1138 | } | 1183 | } |
1139 | |||
1140 | } | 1184 | } |
1141 | } | 1185 | } |
1142 | 1186 | ||
@@ -1188,7 +1232,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1188 | // used with conjunction with banking: the strength of the banking will decay when the | 1232 | // used with conjunction with banking: the strength of the banking will decay when the |
1189 | // vehicle no longer experiences collisions. The decay timescale is the same as | 1233 | // vehicle no longer experiences collisions. The decay timescale is the same as |
1190 | // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering | 1234 | // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering |
1191 | // when they are in mid jump. | 1235 | // when they are in mid jump. |
1192 | // TODO: this code is wrong. Also, what should it do for boats (height from water)? | 1236 | // TODO: this code is wrong. Also, what should it do for boats (height from water)? |
1193 | // This is just using the ground and a general collision check. Should really be using | 1237 | // This is just using the ground and a general collision check. Should really be using |
1194 | // a downward raycast to find what is below. | 1238 | // a downward raycast to find what is below. |
@@ -1201,7 +1245,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1201 | float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); | 1245 | float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition); |
1202 | distanceAboveGround = VehiclePosition.Z - targetHeight; | 1246 | distanceAboveGround = VehiclePosition.Z - targetHeight; |
1203 | // Not colliding if the vehicle is off the ground | 1247 | // Not colliding if the vehicle is off the ground |
1204 | if (!Prim.IsColliding) | 1248 | if (!Prim.HasSomeCollision) |
1205 | { | 1249 | { |
1206 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); | 1250 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); |
1207 | VehicleVelocity += new Vector3(0, 0, -distanceAboveGround); | 1251 | VehicleVelocity += new Vector3(0, 0, -distanceAboveGround); |
@@ -1212,12 +1256,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1212 | // be computed with a motor. | 1256 | // be computed with a motor. |
1213 | // TODO: add interaction with banking. | 1257 | // TODO: add interaction with banking. |
1214 | VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", | 1258 | VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}", |
1215 | Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret); | 1259 | Prim.LocalID, distanceAboveGround, Prim.HasSomeCollision, ret); |
1216 | */ | 1260 | */ |
1217 | 1261 | ||
1218 | // Another approach is to measure if we're going up. If going up and not colliding, | 1262 | // Another approach is to measure if we're going up. If going up and not colliding, |
1219 | // the vehicle is in the air. Fix that by pushing down. | 1263 | // the vehicle is in the air. Fix that by pushing down. |
1220 | if (!ControllingPrim.IsColliding && VehicleVelocity.Z > 0.1) | 1264 | if (!ControllingPrim.HasSomeCollision && VehicleVelocity.Z > 0.1) |
1221 | { | 1265 | { |
1222 | // Get rid of any of the velocity vector that is pushing us up. | 1266 | // Get rid of any of the velocity vector that is pushing us up. |
1223 | float upVelocity = VehicleVelocity.Z; | 1267 | float upVelocity = VehicleVelocity.Z; |
@@ -1239,7 +1283,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1239 | } | 1283 | } |
1240 | */ | 1284 | */ |
1241 | VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}", | 1285 | VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}", |
1242 | ControllingPrim.LocalID, ControllingPrim.IsColliding, upVelocity, VehicleVelocity); | 1286 | ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, upVelocity, VehicleVelocity); |
1243 | } | 1287 | } |
1244 | } | 1288 | } |
1245 | } | 1289 | } |
@@ -1249,14 +1293,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1249 | Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; | 1293 | Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass; |
1250 | 1294 | ||
1251 | // Hack to reduce downward force if the vehicle is probably sitting on the ground | 1295 | // Hack to reduce downward force if the vehicle is probably sitting on the ground |
1252 | if (ControllingPrim.IsColliding && IsGroundVehicle) | 1296 | if (ControllingPrim.HasSomeCollision && IsGroundVehicle) |
1253 | appliedGravity *= BSParam.VehicleGroundGravityFudge; | 1297 | appliedGravity *= BSParam.VehicleGroundGravityFudge; |
1254 | 1298 | ||
1255 | VehicleAddForce(appliedGravity); | 1299 | VehicleAddForce(appliedGravity); |
1256 | 1300 | ||
1257 | VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={3}", | 1301 | VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={5}", |
1258 | ControllingPrim.LocalID, m_VehicleGravity, | 1302 | ControllingPrim.LocalID, m_VehicleGravity, |
1259 | ControllingPrim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity); | 1303 | ControllingPrim.HasSomeCollision, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity); |
1260 | } | 1304 | } |
1261 | 1305 | ||
1262 | // ======================================================================= | 1306 | // ======================================================================= |
@@ -1323,6 +1367,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1323 | private void ComputeAngularTurning(float pTimestep) | 1367 | private void ComputeAngularTurning(float pTimestep) |
1324 | { | 1368 | { |
1325 | // The user wants this many radians per second angular change? | 1369 | // The user wants this many radians per second angular change? |
1370 | Vector3 origVehicleRotationalVelocity = VehicleRotationalVelocity; // DEBUG DEBUG | ||
1326 | Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation); | 1371 | Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation); |
1327 | Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV); | 1372 | Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV); |
1328 | 1373 | ||
@@ -1330,18 +1375,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1330 | // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : | 1375 | // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : |
1331 | // This flag prevents linear deflection parallel to world z-axis. This is useful | 1376 | // This flag prevents linear deflection parallel to world z-axis. This is useful |
1332 | // for preventing ground vehicles with large linear deflection, like bumper cars, | 1377 | // for preventing ground vehicles with large linear deflection, like bumper cars, |
1333 | // from climbing their linear deflection into the sky. | 1378 | // from climbing their linear deflection into the sky. |
1334 | // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement | 1379 | // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement |
1335 | // TODO: This is here because this is where ODE put it but documentation says it | 1380 | // TODO: This is here because this is where ODE put it but documentation says it |
1336 | // is a linear effect. Where should this check go? | 1381 | // is a linear effect. Where should this check go? |
1337 | //if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) | 1382 | //if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) |
1338 | // { | 1383 | // { |
1339 | // angularMotorContributionV.X = 0f; | 1384 | // angularMotorContributionV.X = 0f; |
1340 | // angularMotorContributionV.Y = 0f; | 1385 | // angularMotorContributionV.Y = 0f; |
1341 | // } | 1386 | // } |
1387 | |||
1388 | // Reduce any velocity by friction. | ||
1389 | Vector3 frictionFactorW = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep); | ||
1390 | angularMotorContributionV -= (currentAngularV * frictionFactorW); | ||
1391 | |||
1392 | Vector3 angularMotorContributionW = angularMotorContributionV * VehicleOrientation; | ||
1393 | VehicleRotationalVelocity += angularMotorContributionW; | ||
1342 | 1394 | ||
1343 | VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation; | 1395 | VDetailLog("{0}, MoveAngular,angularTurning,curAngVelV={1},origVehRotVel={2},vehRotVel={3},frictFact={4}, angContribV={5},angContribW={6}", |
1344 | VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", ControllingPrim.LocalID, angularMotorContributionV); | 1396 | ControllingPrim.LocalID, currentAngularV, origVehicleRotationalVelocity, VehicleRotationalVelocity, frictionFactorW, angularMotorContributionV, angularMotorContributionW); |
1345 | } | 1397 | } |
1346 | 1398 | ||
1347 | // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: | 1399 | // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: |
@@ -1356,86 +1408,136 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1356 | { | 1408 | { |
1357 | 1409 | ||
1358 | // If vertical attaction timescale is reasonable | 1410 | // If vertical attaction timescale is reasonable |
1359 | if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1411 | if (BSParam.VehicleEnableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1360 | { | 1412 | { |
1361 | // Possible solution derived from a discussion at: | 1413 | Vector3 vehicleUpAxis = Vector3.UnitZ * VehicleOrientation; |
1362 | // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no | 1414 | switch (BSParam.VehicleAngularVerticalAttractionAlgorithm) |
1363 | |||
1364 | // Create a rotation that is only the vehicle's rotation around Z | ||
1365 | Vector3 currentEuler = Vector3.Zero; | ||
1366 | VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z); | ||
1367 | Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z); | ||
1368 | |||
1369 | // Create the axis that is perpendicular to the up vector and the rotated up vector. | ||
1370 | Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation); | ||
1371 | // Compute the angle between those to vectors. | ||
1372 | double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation))); | ||
1373 | // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical | ||
1374 | |||
1375 | // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied. | ||
1376 | // TODO: add 'efficiency'. | ||
1377 | differenceAngle /= m_verticalAttractionTimescale; | ||
1378 | |||
1379 | // Create the quaterian representing the correction angle | ||
1380 | Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle); | ||
1381 | |||
1382 | // Turn that quaternion into Euler values to make it into velocities to apply. | ||
1383 | Vector3 vertContributionV = Vector3.Zero; | ||
1384 | correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z); | ||
1385 | vertContributionV *= -1f; | ||
1386 | |||
1387 | VehicleRotationalVelocity += vertContributionV; | ||
1388 | |||
1389 | VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}", | ||
1390 | ControllingPrim.LocalID, | ||
1391 | differenceAxis, | ||
1392 | differenceAngle, | ||
1393 | correctionRotation, | ||
1394 | vertContributionV); | ||
1395 | |||
1396 | // =================================================================== | ||
1397 | /* | ||
1398 | Vector3 vertContributionV = Vector3.Zero; | ||
1399 | Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG | ||
1400 | |||
1401 | // Take a vector pointing up and convert it from world to vehicle relative coords. | ||
1402 | Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation); | ||
1403 | |||
1404 | // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) | ||
1405 | // is now: | ||
1406 | // leaning to one side: rotated around the X axis with the Y value going | ||
1407 | // from zero (nearly straight up) to one (completely to the side)) or | ||
1408 | // leaning front-to-back: rotated around the Y axis with the value of X being between | ||
1409 | // zero and one. | ||
1410 | // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. | ||
1411 | |||
1412 | // Y error means needed rotation around X axis and visa versa. | ||
1413 | // Since the error goes from zero to one, the asin is the corresponding angle. | ||
1414 | vertContributionV.X = (float)Math.Asin(verticalError.Y); | ||
1415 | // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) | ||
1416 | vertContributionV.Y = -(float)Math.Asin(verticalError.X); | ||
1417 | |||
1418 | // If verticalError.Z is negative, the vehicle is upside down. Add additional push. | ||
1419 | if (verticalError.Z < 0f) | ||
1420 | { | 1415 | { |
1421 | vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour; | 1416 | case 0: |
1422 | // vertContribution.Y -= PIOverFour; | 1417 | { |
1418 | //Another formula to try got from : | ||
1419 | //http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html | ||
1420 | |||
1421 | // Flipping what was originally a timescale into a speed variable and then multiplying it by 2 | ||
1422 | // since only computing half the distance between the angles. | ||
1423 | float verticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f; | ||
1424 | |||
1425 | // Make a prediction of where the up axis will be when this is applied rather then where it is now as | ||
1426 | // this makes for a smoother adjustment and less fighting between the various forces. | ||
1427 | Vector3 predictedUp = vehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f); | ||
1428 | |||
1429 | // This is only half the distance to the target so it will take 2 seconds to complete the turn. | ||
1430 | Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ); | ||
1431 | |||
1432 | // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared | ||
1433 | Vector3 vertContributionV = torqueVector * verticalAttractionSpeed * verticalAttractionSpeed; | ||
1434 | |||
1435 | VehicleRotationalVelocity += vertContributionV; | ||
1436 | |||
1437 | VDetailLog("{0}, MoveAngular,verticalAttraction,vertAttrSpeed={1},upAxis={2},PredictedUp={3},torqueVector={4},contrib={5}", | ||
1438 | ControllingPrim.LocalID, | ||
1439 | verticalAttractionSpeed, | ||
1440 | vehicleUpAxis, | ||
1441 | predictedUp, | ||
1442 | torqueVector, | ||
1443 | vertContributionV); | ||
1444 | break; | ||
1445 | } | ||
1446 | case 1: | ||
1447 | { | ||
1448 | // Possible solution derived from a discussion at: | ||
1449 | // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no | ||
1450 | |||
1451 | // Create a rotation that is only the vehicle's rotation around Z | ||
1452 | Vector3 currentEulerW = Vector3.Zero; | ||
1453 | VehicleOrientation.GetEulerAngles(out currentEulerW.X, out currentEulerW.Y, out currentEulerW.Z); | ||
1454 | Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEulerW.Z); | ||
1455 | |||
1456 | // Create the axis that is perpendicular to the up vector and the rotated up vector. | ||
1457 | Vector3 differenceAxisW = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation); | ||
1458 | // Compute the angle between those to vectors. | ||
1459 | double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation))); | ||
1460 | // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical | ||
1461 | |||
1462 | // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied. | ||
1463 | // TODO: add 'efficiency'. | ||
1464 | // differenceAngle /= m_verticalAttractionTimescale; | ||
1465 | |||
1466 | // Create the quaterian representing the correction angle | ||
1467 | Quaternion correctionRotationW = Quaternion.CreateFromAxisAngle(differenceAxisW, (float)differenceAngle); | ||
1468 | |||
1469 | // Turn that quaternion into Euler values to make it into velocities to apply. | ||
1470 | Vector3 vertContributionW = Vector3.Zero; | ||
1471 | correctionRotationW.GetEulerAngles(out vertContributionW.X, out vertContributionW.Y, out vertContributionW.Z); | ||
1472 | vertContributionW *= -1f; | ||
1473 | vertContributionW /= m_verticalAttractionTimescale; | ||
1474 | |||
1475 | VehicleRotationalVelocity += vertContributionW; | ||
1476 | |||
1477 | VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}", | ||
1478 | ControllingPrim.LocalID, | ||
1479 | vehicleUpAxis, | ||
1480 | differenceAxisW, | ||
1481 | differenceAngle, | ||
1482 | correctionRotationW, | ||
1483 | vertContributionW); | ||
1484 | break; | ||
1485 | } | ||
1486 | case 2: | ||
1487 | { | ||
1488 | Vector3 vertContributionV = Vector3.Zero; | ||
1489 | Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG | ||
1490 | |||
1491 | // Take a vector pointing up and convert it from world to vehicle relative coords. | ||
1492 | Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation); | ||
1493 | |||
1494 | // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) | ||
1495 | // is now: | ||
1496 | // leaning to one side: rotated around the X axis with the Y value going | ||
1497 | // from zero (nearly straight up) to one (completely to the side)) or | ||
1498 | // leaning front-to-back: rotated around the Y axis with the value of X being between | ||
1499 | // zero and one. | ||
1500 | // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. | ||
1501 | |||
1502 | // Y error means needed rotation around X axis and visa versa. | ||
1503 | // Since the error goes from zero to one, the asin is the corresponding angle. | ||
1504 | vertContributionV.X = (float)Math.Asin(verticalError.Y); | ||
1505 | // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) | ||
1506 | vertContributionV.Y = -(float)Math.Asin(verticalError.X); | ||
1507 | |||
1508 | // If verticalError.Z is negative, the vehicle is upside down. Add additional push. | ||
1509 | if (verticalError.Z < 0f) | ||
1510 | { | ||
1511 | vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour; | ||
1512 | // vertContribution.Y -= PIOverFour; | ||
1513 | } | ||
1514 | |||
1515 | // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. | ||
1516 | // Correction happens over a number of seconds. | ||
1517 | Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG | ||
1518 | |||
1519 | // The correction happens over the user's time period | ||
1520 | vertContributionV /= m_verticalAttractionTimescale; | ||
1521 | |||
1522 | // Rotate the vehicle rotation to the world coordinates. | ||
1523 | VehicleRotationalVelocity += (vertContributionV * VehicleOrientation); | ||
1524 | |||
1525 | VDetailLog("{0}, MoveAngular,verticalAttraction,,upAxis={1},origRotVW={2},vertError={3},unscaledV={4},eff={5},ts={6},vertContribV={7}", | ||
1526 | ControllingPrim.LocalID, | ||
1527 | vehicleUpAxis, | ||
1528 | origRotVelW, | ||
1529 | verticalError, | ||
1530 | unscaledContribVerticalErrorV, | ||
1531 | m_verticalAttractionEfficiency, | ||
1532 | m_verticalAttractionTimescale, | ||
1533 | vertContributionV); | ||
1534 | break; | ||
1535 | } | ||
1536 | default: | ||
1537 | { | ||
1538 | break; | ||
1539 | } | ||
1423 | } | 1540 | } |
1424 | |||
1425 | // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. | ||
1426 | // Correction happens over a number of seconds. | ||
1427 | Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG | ||
1428 | |||
1429 | // The correction happens over the user's time period | ||
1430 | vertContributionV /= m_verticalAttractionTimescale; | ||
1431 | |||
1432 | // Rotate the vehicle rotation to the world coordinates. | ||
1433 | VehicleRotationalVelocity += (vertContributionV * VehicleOrientation); | ||
1434 | |||
1435 | VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", | ||
1436 | Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, | ||
1437 | m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); | ||
1438 | */ | ||
1439 | } | 1541 | } |
1440 | } | 1542 | } |
1441 | 1543 | ||
@@ -1445,13 +1547,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1445 | // in that direction. | 1547 | // in that direction. |
1446 | // TODO: implement reference frame. | 1548 | // TODO: implement reference frame. |
1447 | public void ComputeAngularDeflection() | 1549 | public void ComputeAngularDeflection() |
1448 | { | 1550 | { |
1449 | // Since angularMotorUp and angularDeflection are computed independently, they will calculate | ||
1450 | // approximately the same X or Y correction. When added together (when contributions are combined) | ||
1451 | // this creates an over-correction and then wabbling as the target is overshot. | ||
1452 | // TODO: rethink how the different correction computations inter-relate. | ||
1453 | 1551 | ||
1454 | if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) | 1552 | if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) |
1455 | { | 1553 | { |
1456 | Vector3 deflectContributionV = Vector3.Zero; | 1554 | Vector3 deflectContributionV = Vector3.Zero; |
1457 | 1555 | ||
@@ -1464,10 +1562,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1464 | 1562 | ||
1465 | // The direction the vehicle is pointing | 1563 | // The direction the vehicle is pointing |
1466 | Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; | 1564 | Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; |
1467 | pointingDirection.Normalize(); | 1565 | //Predict where the Vehicle will be pointing after AngularVelocity change is applied. This will keep |
1566 | // from overshooting and allow this correction to merge with the Vertical Attraction peacefully. | ||
1567 | Vector3 predictedPointingDirection = pointingDirection * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f); | ||
1568 | predictedPointingDirection.Normalize(); | ||
1468 | 1569 | ||
1469 | // The difference between what is and what should be. | 1570 | // The difference between what is and what should be. |
1470 | Vector3 deflectionError = movingDirection - pointingDirection; | 1571 | // Vector3 deflectionError = movingDirection - predictedPointingDirection; |
1572 | Vector3 deflectionError = Vector3.Cross(movingDirection, predictedPointingDirection); | ||
1471 | 1573 | ||
1472 | // Don't try to correct very large errors (not our job) | 1574 | // Don't try to correct very large errors (not our job) |
1473 | // if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = PIOverTwo * Math.Sign(deflectionError.X); | 1575 | // if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = PIOverTwo * Math.Sign(deflectionError.X); |
@@ -1480,15 +1582,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1480 | // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); | 1582 | // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); |
1481 | 1583 | ||
1482 | // Scale the correction by recovery timescale and efficiency | 1584 | // Scale the correction by recovery timescale and efficiency |
1483 | deflectContributionV = (-deflectionError) * m_angularDeflectionEfficiency; | 1585 | // Not modeling a spring so clamp the scale to no more then the arc |
1484 | deflectContributionV /= m_angularDeflectionTimescale; | 1586 | deflectContributionV = (-deflectionError) * ClampInRange(0, m_angularDeflectionEfficiency/m_angularDeflectionTimescale,1f); |
1485 | 1587 | //deflectContributionV /= m_angularDeflectionTimescale; | |
1486 | VehicleRotationalVelocity += deflectContributionV * VehicleOrientation; | ||
1487 | 1588 | ||
1589 | // VehicleRotationalVelocity += deflectContributionV * VehicleOrientation; | ||
1590 | VehicleRotationalVelocity += deflectContributionV; | ||
1488 | VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", | 1591 | VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", |
1489 | ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV); | 1592 | ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV); |
1490 | VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", | 1593 | VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3},PredictedPointingDir={4}", |
1491 | ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); | 1594 | ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale, predictedPointingDirection); |
1492 | } | 1595 | } |
1493 | } | 1596 | } |
1494 | 1597 | ||
@@ -1500,13 +1603,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1500 | // produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude | 1603 | // produce a angular velocity around the yaw-axis, causing the vehicle to turn. The magnitude |
1501 | // of the yaw effect will be proportional to the | 1604 | // of the yaw effect will be proportional to the |
1502 | // VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's | 1605 | // VEHICLE_BANKING_EFFICIENCY, the angle of the roll rotation, and sometimes the vehicle's |
1503 | // velocity along its preferred axis of motion. | 1606 | // velocity along its preferred axis of motion. |
1504 | // The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any | 1607 | // The VEHICLE_BANKING_EFFICIENCY can vary between -1 and +1. When it is positive then any |
1505 | // positive rotation (by the right-hand rule) about the roll-axis will effect a | 1608 | // positive rotation (by the right-hand rule) about the roll-axis will effect a |
1506 | // (negative) torque around the yaw-axis, making it turn to the right--that is the | 1609 | // (negative) torque around the yaw-axis, making it turn to the right--that is the |
1507 | // vehicle will lean into the turn, which is how real airplanes and motorcycle's work. | 1610 | // vehicle will lean into the turn, which is how real airplanes and motorcycle's work. |
1508 | // Negating the banking coefficient will make it so that the vehicle leans to the | 1611 | // Negating the banking coefficient will make it so that the vehicle leans to the |
1509 | // outside of the turn (not very "physical" but might allow interesting vehicles so why not?). | 1612 | // outside of the turn (not very "physical" but might allow interesting vehicles so why not?). |
1510 | // The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making | 1613 | // The VEHICLE_BANKING_MIX is a fake (i.e. non-physical) parameter that is useful for making |
1511 | // banking vehicles do what you want rather than what the laws of physics allow. | 1614 | // banking vehicles do what you want rather than what the laws of physics allow. |
1512 | // For example, consider a real motorcycle...it must be moving forward in order for | 1615 | // For example, consider a real motorcycle...it must be moving forward in order for |
@@ -1518,14 +1621,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1518 | // totally static (0.0) and totally dynamic (1.0). By "static" we mean that the | 1621 | // totally static (0.0) and totally dynamic (1.0). By "static" we mean that the |
1519 | // banking effect depends only on the vehicle's rotation about its roll-axis compared | 1622 | // banking effect depends only on the vehicle's rotation about its roll-axis compared |
1520 | // to "dynamic" where the banking is also proportional to its velocity along its | 1623 | // to "dynamic" where the banking is also proportional to its velocity along its |
1521 | // roll-axis. Finding the best value of the "mixture" will probably require trial and error. | 1624 | // roll-axis. Finding the best value of the "mixture" will probably require trial and error. |
1522 | // The time it takes for the banking behavior to defeat a preexisting angular velocity about the | 1625 | // The time it takes for the banking behavior to defeat a preexisting angular velocity about the |
1523 | // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to | 1626 | // world z-axis is determined by the VEHICLE_BANKING_TIMESCALE. So if you want the vehicle to |
1524 | // bank quickly then give it a banking timescale of about a second or less, otherwise you can | 1627 | // bank quickly then give it a banking timescale of about a second or less, otherwise you can |
1525 | // make a sluggish vehicle by giving it a timescale of several seconds. | 1628 | // make a sluggish vehicle by giving it a timescale of several seconds. |
1526 | public void ComputeAngularBanking() | 1629 | public void ComputeAngularBanking() |
1527 | { | 1630 | { |
1528 | if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) | 1631 | if (BSParam.VehicleEnableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) |
1529 | { | 1632 | { |
1530 | Vector3 bankingContributionV = Vector3.Zero; | 1633 | Vector3 bankingContributionV = Vector3.Zero; |
1531 | 1634 | ||
@@ -1551,7 +1654,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1551 | 1654 | ||
1552 | //VehicleRotationalVelocity += bankingContributionV * VehicleOrientation; | 1655 | //VehicleRotationalVelocity += bankingContributionV * VehicleOrientation; |
1553 | VehicleRotationalVelocity += bankingContributionV; | 1656 | VehicleRotationalVelocity += bankingContributionV; |
1554 | 1657 | ||
1555 | 1658 | ||
1556 | VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", | 1659 | VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", |
1557 | ControllingPrim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV); | 1660 | ControllingPrim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV); |
@@ -1598,6 +1701,35 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1598 | 1701 | ||
1599 | } | 1702 | } |
1600 | 1703 | ||
1704 | // Given a friction vector (reduction in seconds) and a timestep, return the factor to reduce | ||
1705 | // some value by to apply this friction. | ||
1706 | private Vector3 ComputeFrictionFactor(Vector3 friction, float pTimestep) | ||
1707 | { | ||
1708 | Vector3 frictionFactor = Vector3.Zero; | ||
1709 | if (friction != BSMotor.InfiniteVector) | ||
1710 | { | ||
1711 | // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; | ||
1712 | // Individual friction components can be 'infinite' so compute each separately. | ||
1713 | frictionFactor.X = (friction.X == BSMotor.Infinite) ? 0f : (1f / friction.X); | ||
1714 | frictionFactor.Y = (friction.Y == BSMotor.Infinite) ? 0f : (1f / friction.Y); | ||
1715 | frictionFactor.Z = (friction.Z == BSMotor.Infinite) ? 0f : (1f / friction.Z); | ||
1716 | frictionFactor *= pTimestep; | ||
1717 | } | ||
1718 | return frictionFactor; | ||
1719 | } | ||
1720 | |||
1721 | private float SortedClampInRange(float clampa, float val, float clampb) | ||
1722 | { | ||
1723 | if (clampa > clampb) | ||
1724 | { | ||
1725 | float temp = clampa; | ||
1726 | clampa = clampb; | ||
1727 | clampb = temp; | ||
1728 | } | ||
1729 | return ClampInRange(clampa, val, clampb); | ||
1730 | |||
1731 | } | ||
1732 | |||
1601 | private float ClampInRange(float low, float val, float high) | 1733 | private float ClampInRange(float low, float val, float high) |
1602 | { | 1734 | { |
1603 | return Math.Max(low, Math.Min(val, high)); | 1735 | return Math.Max(low, Math.Min(val, high)); |
@@ -1607,8 +1739,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1607 | // Invoke the detailed logger and output something if it's enabled. | 1739 | // Invoke the detailed logger and output something if it's enabled. |
1608 | private void VDetailLog(string msg, params Object[] args) | 1740 | private void VDetailLog(string msg, params Object[] args) |
1609 | { | 1741 | { |
1610 | if (ControllingPrim.PhysicsScene.VehicleLoggingEnabled) | 1742 | if (ControllingPrim.PhysScene.VehicleLoggingEnabled) |
1611 | ControllingPrim.PhysicsScene.DetailLog(msg, args); | 1743 | ControllingPrim.PhysScene.DetailLog(msg, args); |
1612 | } | 1744 | } |
1613 | } | 1745 | } |
1614 | } | 1746 | } |