aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorRobert Adams2012-12-01 18:03:32 -0800
committerRobert Adams2012-12-03 07:59:39 -0800
commit20c3ec7d9277997d9510f5d08df6a0523faaa31e (patch)
treea58ada0052e3a1252ba8085250bc45e403d9d093 /OpenSim
parentBulletSim: Add DumpActivationInfo2 function. Change static objects from DISAB... (diff)
downloadopensim-SC-20c3ec7d9277997d9510f5d08df6a0523faaa31e.zip
opensim-SC-20c3ec7d9277997d9510f5d08df6a0523faaa31e.tar.gz
opensim-SC-20c3ec7d9277997d9510f5d08df6a0523faaa31e.tar.bz2
opensim-SC-20c3ec7d9277997d9510f5d08df6a0523faaa31e.tar.xz
BulletSim: localize vehicle property setting so the vehicle prim is only updated at the end of the vehicle simulation step and the push of the physics property update event only happens if the properties are actually changed.
Diffstat (limited to 'OpenSim')
-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