diff options
-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 | ||