diff options
author | Robert Adams | 2011-08-18 14:32:09 -0700 |
---|---|---|
committer | Mic Bowman | 2011-08-18 14:32:09 -0700 |
commit | fef73a1a1011126d4df2da2279caae9cef7984d1 (patch) | |
tree | af54473f37f419648b98c4b8ddc815ff7aea98a3 /OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |
parent | BulletSim: fix problem with not convex hulling large objects by creating unit... (diff) | |
download | opensim-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.cs | 223 |
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 | // |
59 | namespace OpenSim.Region.Physics.BulletSPlugin | 59 | namespace OpenSim.Region.Physics.BulletSPlugin |
60 | { | 60 | { |
61 | public class BSScene : PhysicsScene | 61 | public 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 | } |