diff options
author | Robert Adams | 2012-11-29 22:21:45 -0800 |
---|---|---|
committer | Robert Adams | 2012-11-29 22:21:45 -0800 |
commit | ec63e4ff29f9983b65d76232018156605762ccc0 (patch) | |
tree | b7bbe2b1fe10f05421ebb72c3f3302329bcde6ad /OpenSim/Region/Physics | |
parent | BulletSim: add copyright header where it is missing. Remove some unnecessary ... (diff) | |
download | opensim-SC-ec63e4ff29f9983b65d76232018156605762ccc0.zip opensim-SC-ec63e4ff29f9983b65d76232018156605762ccc0.tar.gz opensim-SC-ec63e4ff29f9983b65d76232018156605762ccc0.tar.bz2 opensim-SC-ec63e4ff29f9983b65d76232018156605762ccc0.tar.xz |
BulletSim: remove time scaling of computed vehicle absolute velocity since Bullet will scale the movement by the time slice. Restore LIMIT_MOTOR_UP to definitition of BOAT simce some vehicle engines use it even for land vehicles. Push vehicle parameter updates through the regular property update to solve vehicles floating off when they should be stopped.
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 98 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 8 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 15 |
3 files changed, 73 insertions, 48 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index fcee1de..fcc1224 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -127,6 +127,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
127 | private float m_verticalAttractionEfficiency = 1.0f; // damped | 127 | private float m_verticalAttractionEfficiency = 1.0f; // damped |
128 | private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. | 128 | private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. |
129 | 129 | ||
130 | // Local | ||
131 | private float m_knownTerrainHeight; | ||
132 | private float m_knownWaterLevel; | ||
133 | |||
130 | public BSDynamics(BSScene myScene, BSPrim myPrim) | 134 | public BSDynamics(BSScene myScene, BSPrim myPrim) |
131 | { | 135 | { |
132 | PhysicsScene = myScene; | 136 | PhysicsScene = myScene; |
@@ -443,9 +447,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
443 | m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | 447 | m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
444 | | VehicleFlag.HOVER_GLOBAL_HEIGHT | 448 | | VehicleFlag.HOVER_GLOBAL_HEIGHT |
445 | | VehicleFlag.LIMIT_ROLL_ONLY | 449 | | VehicleFlag.LIMIT_ROLL_ONLY |
446 | | VehicleFlag.LIMIT_MOTOR_UP | ||
447 | | VehicleFlag.HOVER_UP_ONLY); | 450 | | VehicleFlag.HOVER_UP_ONLY); |
448 | m_flags |= (VehicleFlag.NO_DEFLECTION_UP | 451 | m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
452 | | VehicleFlag.LIMIT_MOTOR_UP | ||
449 | | VehicleFlag.HOVER_WATER_ONLY); | 453 | | VehicleFlag.HOVER_WATER_ONLY); |
450 | break; | 454 | break; |
451 | case Vehicle.TYPE_AIRPLANE: | 455 | case Vehicle.TYPE_AIRPLANE: |
@@ -596,11 +600,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
596 | Refresh(); | 600 | Refresh(); |
597 | } | 601 | } |
598 | 602 | ||
603 | // Since the computation of terrain height can be a little involved, this routine | ||
604 | // is used ot fetch the height only once for each vehicle simulation step. | ||
605 | private float GetTerrainHeight(Vector3 pos) | ||
606 | { | ||
607 | if (m_knownTerrainHeight == float.MinValue) | ||
608 | m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); | ||
609 | return m_knownTerrainHeight; | ||
610 | } | ||
611 | |||
612 | // Since the computation of water level can be a little involved, this routine | ||
613 | // is used ot fetch the level only once for each vehicle simulation step. | ||
614 | private float GetWaterLevel(Vector3 pos) | ||
615 | { | ||
616 | if (m_knownWaterLevel == float.MinValue) | ||
617 | m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); | ||
618 | return m_knownWaterLevel; | ||
619 | } | ||
620 | |||
599 | // One step of the vehicle properties for the next 'pTimestep' seconds. | 621 | // One step of the vehicle properties for the next 'pTimestep' seconds. |
600 | internal void Step(float pTimestep) | 622 | internal void Step(float pTimestep) |
601 | { | 623 | { |
602 | if (!IsActive) return; | 624 | if (!IsActive) return; |
603 | 625 | ||
626 | // zap values so they will be fetched when needed | ||
627 | m_knownTerrainHeight = m_knownWaterLevel = float.MinValue; | ||
628 | |||
604 | MoveLinear(pTimestep); | 629 | MoveLinear(pTimestep); |
605 | MoveAngular(pTimestep); | 630 | MoveAngular(pTimestep); |
606 | 631 | ||
@@ -609,6 +634,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
609 | // remember the position so next step we can limit absolute movement effects | 634 | // remember the position so next step we can limit absolute movement effects |
610 | m_lastPositionVector = Prim.ForcePosition; | 635 | m_lastPositionVector = Prim.ForcePosition; |
611 | 636 | ||
637 | // Force the physics engine to decide whether values have updated. | ||
638 | // TODO: this is only necessary if pos, velocity, ... were updated. Is it quicker | ||
639 | // to check for changes here or just push the update? | ||
640 | BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr); | ||
641 | |||
612 | VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", | 642 | VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", |
613 | Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); | 643 | Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); |
614 | } | 644 | } |
@@ -629,15 +659,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
629 | Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); | 659 | Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); |
630 | 660 | ||
631 | Vector3 pos = Prim.ForcePosition; | 661 | Vector3 pos = Prim.ForcePosition; |
632 | float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); | ||
633 | 662 | ||
634 | Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep, ref pos, terrainHeight); | 663 | Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(ref pos); |
635 | 664 | ||
636 | Vector3 hoverContribution = ComputeLinearHover(pTimestep, ref pos, terrainHeight); | 665 | Vector3 hoverContribution = ComputeLinearHover(ref pos); |
637 | 666 | ||
638 | ComputeLinearBlockingEndPoint(pTimestep, ref pos); | 667 | ComputeLinearBlockingEndPoint(ref pos); |
639 | 668 | ||
640 | Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep, pos, terrainHeight); | 669 | Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pos); |
641 | 670 | ||
642 | // ================================================================== | 671 | // ================================================================== |
643 | Vector3 newVelocity = linearMotorContribution | 672 | Vector3 newVelocity = linearMotorContribution |
@@ -665,42 +694,40 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
665 | newVelocity = Vector3.Zero; | 694 | newVelocity = Vector3.Zero; |
666 | 695 | ||
667 | // ================================================================== | 696 | // ================================================================== |
668 | // Stuff new linear velocity into the vehicle | 697 | // Stuff new linear velocity into the vehicle. |
698 | // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us. | ||
669 | Prim.ForceVelocity = newVelocity; | 699 | Prim.ForceVelocity = newVelocity; |
670 | // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG | ||
671 | 700 | ||
672 | // Other linear forces are applied as forces. | 701 | // Other linear forces are applied as forces. |
673 | Vector3 totalDownForce = grav * m_vehicleMass; | 702 | Vector3 totalDownForce = grav * m_vehicleMass * pTimestep; |
674 | if (totalDownForce != Vector3.Zero) | 703 | if (totalDownForce != Vector3.Zero) |
675 | { | 704 | { |
676 | Prim.AddForce(totalDownForce, false); | 705 | Prim.AddForce(totalDownForce, false); |
677 | } | 706 | } |
678 | 707 | ||
679 | VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", | 708 | VDetailLog("{0},MoveLinear,done,newVel={1},totDown={2},linContrib={3},terrContrib={4},hoverContrib={5},limitContrib={6}", |
680 | Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, | 709 | Prim.LocalID, newVelocity, totalDownForce, |
681 | newVelocity, Prim.Velocity, totalDownForce); | 710 | linearMotorContribution, terrainHeightContribution, hoverContribution, limitMotorUpContribution |
711 | ); | ||
682 | 712 | ||
683 | } // end MoveLinear() | 713 | } // end MoveLinear() |
684 | 714 | ||
685 | public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep, ref Vector3 pos, float terrainHeight) | 715 | public Vector3 ComputeLinearTerrainHeightCorrection(ref Vector3 pos) |
686 | { | 716 | { |
687 | Vector3 ret = Vector3.Zero; | 717 | Vector3 ret = Vector3.Zero; |
688 | // If below the terrain, move us above the ground a little. | 718 | // If below the terrain, move us above the ground a little. |
689 | // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. | 719 | // TODO: Consider taking the rotated size of the object or possibly casting a ray. |
690 | // TODO: Add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. | 720 | if (pos.Z < GetTerrainHeight(pos)) |
691 | // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation; | ||
692 | // if (rotatedSize.Z < terrainHeight) | ||
693 | if (pos.Z < terrainHeight) | ||
694 | { | 721 | { |
695 | // TODO: correct position by applying force rather than forcing position. | 722 | // TODO: correct position by applying force rather than forcing position. |
696 | pos.Z = terrainHeight + 2; | 723 | pos.Z = GetTerrainHeight(pos) + 2; |
697 | Prim.ForcePosition = pos; | 724 | Prim.ForcePosition = pos; |
698 | VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); | 725 | VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); |
699 | } | 726 | } |
700 | return ret; | 727 | return ret; |
701 | } | 728 | } |
702 | 729 | ||
703 | public Vector3 ComputeLinearHover(float pTimestep, ref Vector3 pos, float terrainHeight) | 730 | public Vector3 ComputeLinearHover(ref Vector3 pos) |
704 | { | 731 | { |
705 | Vector3 ret = Vector3.Zero; | 732 | Vector3 ret = Vector3.Zero; |
706 | 733 | ||
@@ -711,11 +738,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
711 | // We should hover, get the target height | 738 | // We should hover, get the target height |
712 | if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) | 739 | if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) |
713 | { | 740 | { |
714 | m_VhoverTargetHeight = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; | 741 | m_VhoverTargetHeight = GetWaterLevel(pos) + m_VhoverHeight; |
715 | } | 742 | } |
716 | if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) | 743 | if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) |
717 | { | 744 | { |
718 | m_VhoverTargetHeight = terrainHeight + m_VhoverHeight; | 745 | m_VhoverTargetHeight = GetTerrainHeight(pos) + m_VhoverHeight; |
719 | } | 746 | } |
720 | if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) | 747 | if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) |
721 | { | 748 | { |
@@ -739,16 +766,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
739 | } | 766 | } |
740 | else | 767 | else |
741 | { | 768 | { |
742 | float verticalError = pos.Z - m_VhoverTargetHeight; | 769 | // Error is positive if below the target and negative if above. |
743 | float verticalCorrectionVelocity = pTimestep * (verticalError / m_VhoverTimescale); | 770 | float verticalError = m_VhoverTargetHeight - pos.Z; |
771 | float verticalCorrectionVelocity = verticalError / m_VhoverTimescale; | ||
744 | 772 | ||
745 | // TODO: implement m_VhoverEfficiency | 773 | // TODO: implement m_VhoverEfficiency correctly |
746 | if (verticalError > 0.01f) | 774 | if (Math.Abs(verticalError) > m_VhoverEfficiency) |
747 | { | ||
748 | // If error is positive (we're above the target height), push down | ||
749 | ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); | ||
750 | } | ||
751 | else if (verticalError < -0.01) | ||
752 | { | 775 | { |
753 | ret = new Vector3(0f, 0f, verticalCorrectionVelocity); | 776 | ret = new Vector3(0f, 0f, verticalCorrectionVelocity); |
754 | } | 777 | } |
@@ -761,7 +784,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
761 | return ret; | 784 | return ret; |
762 | } | 785 | } |
763 | 786 | ||
764 | public bool ComputeLinearBlockingEndPoint(float pTimestep, ref Vector3 pos) | 787 | public bool ComputeLinearBlockingEndPoint(ref Vector3 pos) |
765 | { | 788 | { |
766 | bool changed = false; | 789 | bool changed = false; |
767 | 790 | ||
@@ -810,13 +833,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
810 | // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering | 833 | // VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering |
811 | // when they are in mid jump. | 834 | // when they are in mid jump. |
812 | // TODO: this code is wrong. Also, what should it do for boats? | 835 | // TODO: this code is wrong. Also, what should it do for boats? |
813 | public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight) | 836 | public Vector3 ComputeLinearMotorUp(Vector3 pos) |
814 | { | 837 | { |
815 | Vector3 ret = Vector3.Zero; | 838 | Vector3 ret = Vector3.Zero; |
816 | if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) | 839 | if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) |
817 | { | 840 | { |
818 | // If the vehicle is motoring into the sky, get it going back down. | 841 | // If the vehicle is motoring into the sky, get it going back down. |
819 | float distanceAboveGround = pos.Z - terrainHeight; | 842 | // float distanceAboveGround = pos.Z - Math.Max(GetTerrainHeight(pos), GetWaterLevel(pos)); |
843 | float distanceAboveGround = pos.Z - GetTerrainHeight(pos); | ||
820 | if (distanceAboveGround > 1f) | 844 | if (distanceAboveGround > 1f) |
821 | { | 845 | { |
822 | // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); | 846 | // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); |
@@ -933,7 +957,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
933 | { | 957 | { |
934 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. | 958 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. |
935 | // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. | 959 | // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. |
936 | VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); | 960 | VDetailLog("{0},MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); |
937 | Prim.ZeroAngularMotion(true); | 961 | Prim.ZeroAngularMotion(true); |
938 | } | 962 | } |
939 | else | 963 | else |
@@ -948,7 +972,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
948 | // Unscale the force by the angular factor so it overwhelmes the Bullet additions. | 972 | // Unscale the force by the angular factor so it overwhelmes the Bullet additions. |
949 | Prim.ForceRotationalVelocity = applyAngularForce; | 973 | Prim.ForceRotationalVelocity = applyAngularForce; |
950 | 974 | ||
951 | VDetailLog("{0},MoveAngular,done,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", | 975 | VDetailLog("{0},MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", |
952 | Prim.LocalID, | 976 | Prim.LocalID, |
953 | angularMotorContribution, verticalAttractionContribution, | 977 | angularMotorContribution, verticalAttractionContribution, |
954 | bankingContribution, deflectionContribution, | 978 | bankingContribution, deflectionContribution, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index eca1452..b256887 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | |||
@@ -101,6 +101,14 @@ public class BSVMotor : BSMotor | |||
101 | { | 101 | { |
102 | TargetValue = target; | 102 | TargetValue = target; |
103 | } | 103 | } |
104 | |||
105 | // A form of stepping that does not take the time quantum into account. | ||
106 | // The caller must do the right thing later. | ||
107 | public Vector3 Step() | ||
108 | { | ||
109 | return Step(1f); | ||
110 | } | ||
111 | |||
104 | public Vector3 Step(float timeStep) | 112 | public Vector3 Step(float timeStep) |
105 | { | 113 | { |
106 | Vector3 returnCurrent = Vector3.Zero; | 114 | Vector3 returnCurrent = Vector3.Zero; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 3fb0300..54b4167 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -348,7 +348,9 @@ public sealed class BSPrim : BSPhysObject | |||
348 | if (ret) | 348 | if (ret) |
349 | { | 349 | { |
350 | // Apply upforce and overcome gravity. | 350 | // Apply upforce and overcome gravity. |
351 | AddForce(upForce - PhysicsScene.DefaultGravity, false, inTaintTime); | 351 | OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity; |
352 | DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); | ||
353 | AddForce(correctionForce, false, inTaintTime); | ||
352 | } | 354 | } |
353 | return ret; | 355 | return ret; |
354 | } | 356 | } |
@@ -839,15 +841,6 @@ public sealed class BSPrim : BSPhysObject | |||
839 | } | 841 | } |
840 | public override OMV.Vector3 RotationalVelocity { | 842 | public override OMV.Vector3 RotationalVelocity { |
841 | get { | 843 | get { |
842 | /* | ||
843 | OMV.Vector3 pv = OMV.Vector3.Zero; | ||
844 | // if close to zero, report zero | ||
845 | // This is copied from ODE but I'm not sure why it returns zero but doesn't | ||
846 | // zero the property in the physics engine. | ||
847 | if (_rotationalVelocity.ApproxEquals(pv, 0.2f)) | ||
848 | return pv; | ||
849 | */ | ||
850 | |||
851 | return _rotationalVelocity; | 844 | return _rotationalVelocity; |
852 | } | 845 | } |
853 | set { | 846 | set { |
@@ -1409,7 +1402,7 @@ public sealed class BSPrim : BSPhysObject | |||
1409 | LastEntityProperties = CurrentEntityProperties; | 1402 | LastEntityProperties = CurrentEntityProperties; |
1410 | CurrentEntityProperties = entprop; | 1403 | CurrentEntityProperties = entprop; |
1411 | 1404 | ||
1412 | OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; | 1405 | OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG |
1413 | DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", | 1406 | DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", |
1414 | LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); | 1407 | LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); |
1415 | 1408 | ||