aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs161
1 files changed, 128 insertions, 33 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 15a40fe..9749429 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -127,10 +127,6 @@ 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
134 public BSDynamics(BSScene myScene, BSPrim myPrim) 130 public BSDynamics(BSScene myScene, BSPrim myPrim)
135 { 131 {
136 PhysicsScene = myScene; 132 PhysicsScene = myScene;
@@ -560,9 +556,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
560 { 556 {
561 if (IsActive) 557 if (IsActive)
562 { 558 {
559 // Remember the mass so we don't have to fetch it every step
563 m_vehicleMass = Prim.Linkset.LinksetMass; 560 m_vehicleMass = Prim.Linkset.LinksetMass;
564 561
565 // Friction effects are handled by this vehicle code 562 // Friction affects are handled by this vehicle code
566 float friction = 0f; 563 float friction = 0f;
567 BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction); 564 BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction);
568 565
@@ -600,31 +597,130 @@ namespace OpenSim.Region.Physics.BulletSPlugin
600 Refresh(); 597 Refresh();
601 } 598 }
602 599
600 #region Known vehicle value functions
601 private int m_knownChanged;
602 private float? m_knownTerrainHeight;
603 private float? m_knownWaterLevel;
604
605 private Vector3? m_knownPosition;
606 private Vector3? m_knownVelocity;
607 private Quaternion? m_knownOrientation;
608 private Vector3? m_knownRotationalVelocity;
609
610 private const int m_knownChangedPosition = 1 << 0;
611 private const int m_knownChangedVelocity = 1 << 1;
612 private const int m_knownChangedOrientation = 1 << 2;
613 private const int m_knownChangedRotationalVelocity = 1 << 3;
614
615 private void ForgetKnownVehicleProperties()
616 {
617 m_knownTerrainHeight = null;
618 m_knownWaterLevel = null;
619 m_knownPosition = null;
620 m_knownVelocity = null;
621 m_knownOrientation = null;
622 m_knownRotationalVelocity = null;
623 m_knownChanged = 0;
624 }
625 private void PushKnownChanged()
626 {
627 if (m_knownChanged != 0)
628 {
629 if ((m_knownChanged & m_knownChangedPosition) != 0) Prim.ForcePosition = VehiclePosition;
630 if ((m_knownChanged & m_knownChangedOrientation) != 0) Prim.ForceOrientation = VehicleOrientation;
631 if ((m_knownChanged & m_knownChangedVelocity) != 0) Prim.ForceVelocity = VehicleVelocity;
632 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) Prim.ForceRotationalVelocity = VehicleRotationalVelocity;
633 // If we set one of the values (ie, the physics engine doesn't do it) we must make sure there
634 // is an UpdateProperties event to send the changes up to the simulator.
635 BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr);
636 }
637 }
638
603 // Since the computation of terrain height can be a little involved, this routine 639 // 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. 640 // is used ot fetch the height only once for each vehicle simulation step.
605 private float GetTerrainHeight(Vector3 pos) 641 private float GetTerrainHeight(Vector3 pos)
606 { 642 {
607 if (m_knownTerrainHeight == float.MinValue) 643 if (m_knownTerrainHeight == null)
608 m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); 644 m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
609 return m_knownTerrainHeight; 645 return (float)m_knownTerrainHeight;
610 } 646 }
611 647
612 // Since the computation of water level can be a little involved, this routine 648 // 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. 649 // is used ot fetch the level only once for each vehicle simulation step.
614 private float GetWaterLevel(Vector3 pos) 650 private float GetWaterLevel(Vector3 pos)
615 { 651 {
616 if (m_knownWaterLevel == float.MinValue) 652 if (m_knownWaterLevel == null)
617 m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); 653 m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos);
618 return m_knownWaterLevel; 654 return (float)m_knownWaterLevel;
655 }
656
657 private Vector3 VehiclePosition
658 {
659 get
660 {
661 if (m_knownPosition == null)
662 m_knownPosition = Prim.ForcePosition;
663 return (Vector3)m_knownPosition;
664 }
665 set
666 {
667 m_knownPosition = value;
668 m_knownChanged |= m_knownChangedPosition;
669 }
670 }
671
672 private Quaternion VehicleOrientation
673 {
674 get
675 {
676 if (m_knownOrientation == null)
677 m_knownOrientation = Prim.ForceOrientation;
678 return (Quaternion)m_knownOrientation;
679 }
680 set
681 {
682 m_knownOrientation = value;
683 m_knownChanged |= m_knownChangedOrientation;
684 }
685 }
686
687 private Vector3 VehicleVelocity
688 {
689 get
690 {
691 if (m_knownVelocity == null)
692 m_knownVelocity = Prim.ForceVelocity;
693 return (Vector3)m_knownVelocity;
694 }
695 set
696 {
697 m_knownVelocity = value;
698 m_knownChanged |= m_knownChangedVelocity;
699 }
700 }
701
702 private Vector3 VehicleRotationalVelocity
703 {
704 get
705 {
706 if (m_knownRotationalVelocity == null)
707 m_knownRotationalVelocity = Prim.ForceRotationalVelocity;
708 return (Vector3)m_knownRotationalVelocity;
709 }
710 set
711 {
712 m_knownRotationalVelocity = value;
713 m_knownChanged |= m_knownChangedRotationalVelocity;
714 }
619 } 715 }
716 #endregion // Known vehicle value functions
620 717
621 // One step of the vehicle properties for the next 'pTimestep' seconds. 718 // One step of the vehicle properties for the next 'pTimestep' seconds.
622 internal void Step(float pTimestep) 719 internal void Step(float pTimestep)
623 { 720 {
624 if (!IsActive) return; 721 if (!IsActive) return;
625 722
626 // Zap values so they will be fetched if needed 723 ForgetKnownVehicleProperties();
627 m_knownTerrainHeight = m_knownWaterLevel = float.MinValue;
628 724
629 MoveLinear(pTimestep); 725 MoveLinear(pTimestep);
630 MoveAngular(pTimestep); 726 MoveAngular(pTimestep);
@@ -632,15 +728,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
632 LimitRotation(pTimestep); 728 LimitRotation(pTimestep);
633 729
634 // remember the position so next step we can limit absolute movement effects 730 // remember the position so next step we can limit absolute movement effects
635 m_lastPositionVector = Prim.ForcePosition; 731 m_lastPositionVector = VehiclePosition;
636 732
637 // Force the physics engine to decide whether values were updated. 733 // If we forced the changing of some vehicle parameters, update the values and
638 // TODO: this is only necessary if pos, velocity, etc were updated. Is it quicker 734 // for the physics engine to note the changes so an UpdateProperties event will happen.
639 // to check for changes here or just push the update? 735 PushKnownChanged();
640 BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr);
641 736
642 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 737 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
643 Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); 738 Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity);
644 } 739 }
645 740
646 // Apply the effect of the linear motor and other linear motions (like hover and float). 741 // Apply the effect of the linear motor and other linear motions (like hover and float).
@@ -650,7 +745,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
650 745
651 // The movement computed in the linear motor is relative to the vehicle 746 // The movement computed in the linear motor is relative to the vehicle
652 // coordinates. Rotate the movement to world coordinates. 747 // coordinates. Rotate the movement to world coordinates.
653 linearMotorContribution *= Prim.ForceOrientation; 748 linearMotorContribution *= VehicleOrientation;
654 749
655 // ================================================================== 750 // ==================================================================
656 // Gravity and Buoyancy 751 // Gravity and Buoyancy
@@ -658,7 +753,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
658 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; 753 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
659 Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); 754 Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy);
660 755
661 Vector3 pos = Prim.ForcePosition; 756 Vector3 pos = VehiclePosition;
662 757
663 Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(ref pos); 758 Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(ref pos);
664 759
@@ -696,7 +791,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
696 // ================================================================== 791 // ==================================================================
697 // Stuff new linear velocity into the vehicle. 792 // 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. 793 // Since the velocity is just being set, it is not scaled by pTimeStep. Bullet will do that for us.
699 Prim.ForceVelocity = newVelocity; 794 VehicleVelocity = newVelocity;
700 795
701 // Other linear forces are applied as forces. 796 // Other linear forces are applied as forces.
702 Vector3 totalDownForce = grav * m_vehicleMass * pTimestep; 797 Vector3 totalDownForce = grav * m_vehicleMass * pTimestep;
@@ -721,7 +816,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
721 { 816 {
722 // TODO: correct position by applying force rather than forcing position. 817 // TODO: correct position by applying force rather than forcing position.
723 pos.Z = GetTerrainHeight(pos) + 2; 818 pos.Z = GetTerrainHeight(pos) + 2;
724 Prim.ForcePosition = pos; 819 VehiclePosition = pos;
725 VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos); 820 VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(pos), pos);
726 } 821 }
727 return ret; 822 return ret;
@@ -761,7 +856,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
761 if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f) 856 if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f)
762 { 857 {
763 pos.Z = m_VhoverTargetHeight; 858 pos.Z = m_VhoverTargetHeight;
764 Prim.ForcePosition = pos; 859 VehiclePosition = pos;
765 } 860 }
766 } 861 }
767 else 862 else
@@ -818,7 +913,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
818 } 913 }
819 if (changed) 914 if (changed)
820 { 915 {
821 Prim.ForcePosition = pos; 916 VehiclePosition = pos;
822 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", 917 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
823 Prim.LocalID, m_BlockingEndPoint, posChange, pos); 918 Prim.LocalID, m_BlockingEndPoint, posChange, pos);
824 } 919 }
@@ -958,6 +1053,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
958 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 1053 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
959 // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle. 1054 // TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle.
960 VDetailLog("{0},MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); 1055 VDetailLog("{0},MoveAngular,done,zero,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
1056 VehicleRotationalVelocity = Vector3.Zero;
961 Prim.ZeroAngularMotion(true); 1057 Prim.ZeroAngularMotion(true);
962 } 1058 }
963 else 1059 else
@@ -967,10 +1063,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
967 // Since we are stuffing the angular velocity directly into the object, the computed 1063 // Since we are stuffing the angular velocity directly into the object, the computed
968 // velocity needs to be scaled by the timestep. 1064 // velocity needs to be scaled by the timestep.
969 // Also remove any motion that is on the object so added motion is only from vehicle. 1065 // Also remove any motion that is on the object so added motion is only from vehicle.
970 Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) 1066 Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - VehicleRotationalVelocity);
971 - Prim.ForceRotationalVelocity);
972 // Unscale the force by the angular factor so it overwhelmes the Bullet additions. 1067 // Unscale the force by the angular factor so it overwhelmes the Bullet additions.
973 Prim.ForceRotationalVelocity = applyAngularForce; 1068 VehicleRotationalVelocity = applyAngularForce;
974 1069
975 VDetailLog("{0},MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}", 1070 VDetailLog("{0},MoveAngular,done,nonZero,angMotor={1},vertAttr={2},bank={3},deflect={4},newAngForce={5},lastAngular={6}",
976 Prim.LocalID, 1071 Prim.LocalID,
@@ -988,14 +1083,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
988 // If vertical attaction timescale is reasonable and we applied an angular force last time... 1083 // If vertical attaction timescale is reasonable and we applied an angular force last time...
989 if (m_verticalAttractionTimescale < 500) 1084 if (m_verticalAttractionTimescale < 500)
990 { 1085 {
991 Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; 1086 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
992 verticalError.Normalize(); 1087 verticalError.Normalize();
993 m_verticalAttractionMotor.SetCurrent(verticalError); 1088 m_verticalAttractionMotor.SetCurrent(verticalError);
994 m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); 1089 m_verticalAttractionMotor.SetTarget(Vector3.UnitZ);
995 ret = m_verticalAttractionMotor.Step(pTimestep); 1090 ret = m_verticalAttractionMotor.Step(pTimestep);
996 /* 1091 /*
997 // Take a vector pointing up and convert it from world to vehicle relative coords. 1092 // Take a vector pointing up and convert it from world to vehicle relative coords.
998 Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; 1093 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
999 verticalError.Normalize(); 1094 verticalError.Normalize();
1000 1095
1001 // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) 1096 // If vertical attraction correction is needed, the vector that was pointing up (UnitZ)
@@ -1048,7 +1143,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1048 new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); 1143 new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0);
1049 // Adding the current vehicle orientation and reference frame displaces the orientation to the frame. 1144 // Adding the current vehicle orientation and reference frame displaces the orientation to the frame.
1050 // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point. 1145 // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point.
1051 Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); 1146 Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(VehicleOrientation, m_referenceFrame);
1052 1147
1053 // Scale by efficiency and timescale 1148 // Scale by efficiency and timescale
1054 ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; 1149 ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep;
@@ -1067,7 +1162,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1067 1162
1068 if (m_bankingEfficiency != 0) 1163 if (m_bankingEfficiency != 0)
1069 { 1164 {
1070 Vector3 dir = Vector3.One * Prim.ForceOrientation; 1165 Vector3 dir = Vector3.One * VehicleOrientation;
1071 float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); 1166 float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1);
1072 //Changes which way it banks in and out of turns 1167 //Changes which way it banks in and out of turns
1073 1168
@@ -1111,7 +1206,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1111 bankingRot.X = 3; 1206 bankingRot.X = 3;
1112 else if (bankingRot.X < -3) 1207 else if (bankingRot.X < -3)
1113 bankingRot.X = -3; 1208 bankingRot.X = -3;
1114 bankingRot *= Prim.ForceOrientation; 1209 bankingRot *= VehicleOrientation;
1115 ret += bankingRot; 1210 ret += bankingRot;
1116 } 1211 }
1117 m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; 1212 m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency;
@@ -1128,7 +1223,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1128 // Should this be in MoveAngular()? 1223 // Should this be in MoveAngular()?
1129 internal void LimitRotation(float timestep) 1224 internal void LimitRotation(float timestep)
1130 { 1225 {
1131 Quaternion rotq = Prim.ForceOrientation; 1226 Quaternion rotq = VehicleOrientation;
1132 Quaternion m_rot = rotq; 1227 Quaternion m_rot = rotq;
1133 if (m_RollreferenceFrame != Quaternion.Identity) 1228 if (m_RollreferenceFrame != Quaternion.Identity)
1134 { 1229 {
@@ -1156,7 +1251,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1156 } 1251 }
1157 if (rotq != m_rot) 1252 if (rotq != m_rot)
1158 { 1253 {
1159 Prim.ForceOrientation = m_rot; 1254 VehicleOrientation = m_rot;
1160 VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); 1255 VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot);
1161 } 1256 }
1162 1257