aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
authorRobert Adams2012-11-29 22:21:45 -0800
committerRobert Adams2012-11-29 22:21:45 -0800
commitec63e4ff29f9983b65d76232018156605762ccc0 (patch)
treeb7bbe2b1fe10f05421ebb72c3f3302329bcde6ad /OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
parentBulletSim: add copyright header where it is missing. Remove some unnecessary ... (diff)
downloadopensim-SC_OLD-ec63e4ff29f9983b65d76232018156605762ccc0.zip
opensim-SC_OLD-ec63e4ff29f9983b65d76232018156605762ccc0.tar.gz
opensim-SC_OLD-ec63e4ff29f9983b65d76232018156605762ccc0.tar.bz2
opensim-SC_OLD-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/BulletSPlugin/BSDynamics.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs98
1 files changed, 61 insertions, 37 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,