aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
diff options
context:
space:
mode:
authorRobert Adams2011-08-18 14:32:09 -0700
committerMic Bowman2011-08-18 14:32:09 -0700
commitfef73a1a1011126d4df2da2279caae9cef7984d1 (patch)
treeaf54473f37f419648b98c4b8ddc815ff7aea98a3 /OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
parentBulletSim: fix problem with not convex hulling large objects by creating unit... (diff)
downloadopensim-SC-fef73a1a1011126d4df2da2279caae9cef7984d1.zip
opensim-SC-fef73a1a1011126d4df2da2279caae9cef7984d1.tar.gz
opensim-SC-fef73a1a1011126d4df2da2279caae9cef7984d1.tar.bz2
opensim-SC-fef73a1a1011126d4df2da2279caae9cef7984d1.tar.xz
BulletSim: add runtime setting of physics parameters. Update default values.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSScene.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs223
1 files changed, 211 insertions, 12 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index de86d59..518be09 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -58,11 +58,13 @@ using OpenSim.Region.Framework;
58// 58//
59namespace OpenSim.Region.Physics.BulletSPlugin 59namespace OpenSim.Region.Physics.BulletSPlugin
60{ 60{
61public class BSScene : PhysicsScene 61public class BSScene : PhysicsScene, IPhysicsParameters
62{ 62{
63 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 63 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
64 private static readonly string LogHeader = "[BULLETS SCENE]"; 64 private static readonly string LogHeader = "[BULLETS SCENE]";
65 65
66 public string BulletSimVersion = "?";
67
66 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); 68 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
67 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>(); 69 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
68 private List<BSPrim> m_vehicles = new List<BSPrim>(); 70 private List<BSPrim> m_vehicles = new List<BSPrim>();
@@ -127,7 +129,7 @@ public class BSScene : PhysicsScene
127 ConfigurationParameters[] m_params; 129 ConfigurationParameters[] m_params;
128 GCHandle m_paramsHandle; 130 GCHandle m_paramsHandle;
129 131
130 private BulletSimAPI.DebugLogCallback debugLogCallbackHandle; 132 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
131 133
132 public BSScene(string identifier) 134 public BSScene(string identifier)
133 { 135 {
@@ -149,12 +151,17 @@ public class BSScene : PhysicsScene
149 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; 151 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
150 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); 152 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
151 153
154 // Get the version of the DLL
155 // TODO: this doesn't work yet. Something wrong with marshaling the returned string.
156 // BulletSimVersion = BulletSimAPI.GetVersion();
157 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
158
152 // if Debug, enable logging from the unmanaged code 159 // if Debug, enable logging from the unmanaged code
153 if (m_log.IsDebugEnabled) 160 if (m_log.IsDebugEnabled)
154 { 161 {
155 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); 162 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
156 debugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); 163 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
157 BulletSimAPI.SetDebugLogCallback(debugLogCallbackHandle); 164 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
158 } 165 }
159 166
160 _taintedObjects = new List<TaintCallback>(); 167 _taintedObjects = new List<TaintCallback>();
@@ -188,7 +195,7 @@ public class BSScene : PhysicsScene
188 m_maxUpdatesPerFrame = 2048; 195 m_maxUpdatesPerFrame = 2048;
189 m_maximumObjectMass = 10000.01f; 196 m_maximumObjectMass = 10000.01f;
190 197
191 parms.defaultFriction = 0.70f; 198 parms.defaultFriction = 0.5f;
192 parms.defaultDensity = 10.000006836f; // Aluminum g/cm3 199 parms.defaultDensity = 10.000006836f; // Aluminum g/cm3
193 parms.defaultRestitution = 0f; 200 parms.defaultRestitution = 0f;
194 parms.collisionMargin = 0.0f; 201 parms.collisionMargin = 0.0f;
@@ -202,10 +209,10 @@ public class BSScene : PhysicsScene
202 parms.ccdMotionThreshold = 0.5f; // set to zero to disable 209 parms.ccdMotionThreshold = 0.5f; // set to zero to disable
203 parms.ccdSweptSphereRadius = 0.2f; 210 parms.ccdSweptSphereRadius = 0.2f;
204 211
205 parms.terrainFriction = 0.85f; 212 parms.terrainFriction = 0.5f;
206 parms.terrainHitFriction = 0.8f; 213 parms.terrainHitFraction = 0.8f;
207 parms.terrainRestitution = 0.2f; 214 parms.terrainRestitution = 0f;
208 parms.avatarFriction = 0.85f; 215 parms.avatarFriction = 0.0f;
209 parms.avatarDensity = 60f; 216 parms.avatarDensity = 60f;
210 parms.avatarCapsuleRadius = 0.37f; 217 parms.avatarCapsuleRadius = 0.37f;
211 parms.avatarCapsuleHeight = 1.5f; // 2.140599f 218 parms.avatarCapsuleHeight = 1.5f; // 2.140599f
@@ -213,7 +220,8 @@ public class BSScene : PhysicsScene
213 if (config != null) 220 if (config != null)
214 { 221 {
215 // If there are specifications in the ini file, use those values 222 // If there are specifications in the ini file, use those values
216 // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO ALSO UPDATE OpenSimDefaults.ini 223 // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO UPDATE OpenSimDefaults.ini
224 // ALSO REMEMBER TO UPDATE THE RUNTIME SETTING OF THE PARAMETERS.
217 IConfig pConfig = config.Configs["BulletSim"]; 225 IConfig pConfig = config.Configs["BulletSim"];
218 if (pConfig != null) 226 if (pConfig != null)
219 { 227 {
@@ -243,7 +251,7 @@ public class BSScene : PhysicsScene
243 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius); 251 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius);
244 252
245 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction); 253 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction);
246 parms.terrainHitFriction = pConfig.GetFloat("TerrainHitFriction", parms.terrainHitFriction); 254 parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction);
247 parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution); 255 parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution);
248 parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction); 256 parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction);
249 parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity); 257 parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity);
@@ -386,7 +394,7 @@ public class BSScene : PhysicsScene
386 } 394 }
387 } 395 }
388 396
389 // FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. 397 // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
390 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; 398 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
391 } 399 }
392 400
@@ -651,5 +659,196 @@ public class BSScene : PhysicsScene
651 } 659 }
652 } 660 }
653 #endregion Vehicles 661 #endregion Vehicles
662
663 #region Runtime settable parameters
664 public static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[]
665 {
666 new PhysParameterEntry("MeshLOD", "Level of detail to render meshes (Power of two. Default 32)"),
667 new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"),
668 new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"),
669 new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"),
670
671 new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"),
672 new PhysParameterEntry("DefaultDensity", "Density for new objects" ),
673 new PhysParameterEntry("DefaultRestitution", "Bouncyness of an object" ),
674 // new PhysParameterEntry("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!!)" ),
675 new PhysParameterEntry("Gravity", "Vertical force of gravity (negative means down)" ),
676
677 new PhysParameterEntry("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)" ),
678 new PhysParameterEntry("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)" ),
679 new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ),
680 new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ),
681 new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ),
682 // new PhysParameterEntry("CcdMotionThreshold", "" ),
683 // new PhysParameterEntry("CcdSweptSphereRadius", "" ),
684
685 new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ),
686 new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ),
687 new PhysParameterEntry("TerrainRestitution", "Bouncyness" ),
688 new PhysParameterEntry("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation." ),
689 new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ),
690 new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ),
691 new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ),
692 new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" )
693 };
694
695 #region IPhysicsParameters
696 // Get the list of parameters this physics engine supports
697 public PhysParameterEntry[] GetParameterList()
698 {
699 return SettableParameters;
700 }
701
702 // Set parameter on a specific or all instances.
703 // Return 'false' if not able to set the parameter.
704 // Setting the value in the m_params block will change the value the physics engine
705 // will use the next time since it's pinned and shared memory.
706 // Some of the values require calling into the physics engine to get the new
707 // value activated ('terrainFriction' for instance).
708 public bool SetPhysicsParameter(string parm, float val, uint localID)
709 {
710 bool ret = true;
711 string lparm = parm.ToLower();
712 switch (lparm)
713 {
714 case "meshlod": m_meshLOD = (int)val; break;
715 case "maxsubstep": m_maxSubSteps = (int)val; break;
716 case "fixedtimestep": m_fixedTimeStep = val; break;
717 case "maxobjectmass": m_maximumObjectMass = val; break;
718
719 case "defaultfriction": m_params[0].defaultFriction = val; break;
720 case "defaultdensity": m_params[0].defaultDensity = val; break;
721 case "defaultrestitution": m_params[0].defaultRestitution = val; break;
722 case "collisionmargin": m_params[0].collisionMargin = val; break;
723 case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break;
724
725 case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break;
726 case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
727 case "deactivationtime": UpdateParameterPrims(ref m_params[0].deactivationTime, lparm, localID, val); break;
728 case "linearsleepingthreshold": UpdateParameterPrims(ref m_params[0].linearSleepingThreshold, lparm, localID, val); break;
729 case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
730 case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break;
731 case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break;
732
733 // set a terrain physical feature and cause terrain to be recalculated
734 case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break;
735 case "terrainhitfraction": m_params[0].terrainHitFraction = val; TaintedUpdateParameter("terrain", 0, val); break;
736 case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break;
737 // set an avatar physical feature and cause avatar(s) to be recalculated
738 case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break;
739 case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break;
740 case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break;
741 case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break;
742 case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break;
743
744 default: ret = false; break;
745 }
746 return ret;
747 }
748
749 // check to see if we are updating a parameter for a particular or all of the prims
750 private void UpdateParameterPrims(ref float loc, string parm, uint localID, float val)
751 {
752 List<uint> operateOn;
753 lock (m_prims) operateOn = new List<uint>(m_prims.Keys);
754 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
755 }
756
757 // check to see if we are updating a parameter for a particular or all of the avatars
758 private void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
759 {
760 List<uint> operateOn;
761 lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys);
762 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
763 }
764
765 // update all the localIDs specified
766 // If the local ID is APPLY_TO_NONE, just change the default value
767 // If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs
768 // If the localID is a specific object, apply the parameter change to only that object
769 private void UpdateParameterSet(List<uint> lIDs, ref float defaultLoc, string parm, uint localID, float val)
770 {
771 switch (localID)
772 {
773 case PhysParameterEntry.APPLY_TO_NONE:
774 defaultLoc = val; // setting only the default value
775 break;
776 case PhysParameterEntry.APPLY_TO_ALL:
777 defaultLoc = val; // setting ALL also sets the default value
778 List<uint> objectIDs = lIDs;
779 string xparm = parm.ToLower();
780 float xval = val;
781 TaintedObject(delegate() {
782 foreach (uint lID in objectIDs)
783 {
784 BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval);
785 }
786 });
787 break;
788 default:
789 // setting only one localID
790 TaintedUpdateParameter(parm, localID, val);
791 break;
792 }
793 }
794
795 // schedule the actual updating of the paramter to when the phys engine is not busy
796 private void TaintedUpdateParameter(string parm, uint localID, float val)
797 {
798 uint xlocalID = localID;
799 string xparm = parm.ToLower();
800 float xval = val;
801 TaintedObject(delegate() {
802 BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval);
803 });
804 }
805
806 // Get parameter.
807 // Return 'false' if not able to get the parameter.
808 public bool GetPhysicsParameter(string parm, out float value)
809 {
810 float val = 0f;
811 bool ret = true;
812 switch (parm.ToLower())
813 {
814 case "meshlod": val = (float)m_meshLOD; break;
815 case "maxsubstep": val = (float)m_maxSubSteps; break;
816 case "fixedtimestep": val = m_fixedTimeStep; break;
817 case "maxobjectmass": val = m_maximumObjectMass; break;
818
819 case "defaultfriction": val = m_params[0].defaultFriction; break;
820 case "defaultdensity": val = m_params[0].defaultDensity; break;
821 case "defaultrestitution": val = m_params[0].defaultRestitution; break;
822 case "collisionmargin": val = m_params[0].collisionMargin; break;
823 case "gravity": val = m_params[0].gravity; break;
824
825 case "lineardamping": val = m_params[0].linearDamping; break;
826 case "angulardamping": val = m_params[0].angularDamping; break;
827 case "deactivationtime": val = m_params[0].deactivationTime; break;
828 case "linearsleepingthreshold": val = m_params[0].linearSleepingThreshold; break;
829 case "angularsleepingthreshold": val = m_params[0].angularDamping; break;
830 case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break;
831 case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break;
832
833 case "terrainfriction": val = m_params[0].terrainFriction; break;
834 case "terrainhitfraction": val = m_params[0].terrainHitFraction; break;
835 case "terrainrestitution": val = m_params[0].terrainRestitution; break;
836
837 case "avatarfriction": val = m_params[0].avatarFriction; break;
838 case "avatardensity": val = m_params[0].avatarDensity; break;
839 case "avatarrestitution": val = m_params[0].avatarRestitution; break;
840 case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break;
841 case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break;
842 default: ret = false; break;
843
844 }
845 value = val;
846 return ret;
847 }
848
849 #endregion IPhysicsParameters
850
851 #endregion Runtime settable parameters
852
654} 853}
655} 854}