28 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Runtime.InteropServices;
33 using System.Threading;
34 using OpenSim.Framework;
35 using OpenSim.Framework.Monitoring;
36 using OpenSim.Region.Framework.Scenes;
37 using OpenSim.Region.Framework.Interfaces;
38 using OpenSim.Region.PhysicsModules.SharedBase;
44 namespace OpenSim.
Region.PhysicsModule.BulletS
46 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"BulletSPhysicsScene")]
49 internal static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
50 internal static readonly
string LogHeader =
"[BULLETS SCENE]";
52 private bool m_Enabled =
false;
53 private IConfigSource m_Config;
56 public string RegionName {
get;
private set; }
58 public string BulletSimVersion =
"?";
61 public string BulletEngineName {
get;
private set; }
71 public HashSet<BSPhysObject> ObjectsWithCollisions =
new HashSet<BSPhysObject>();
72 public HashSet<BSPhysObject> ObjectsWithNoMoreCollisions =
new HashSet<BSPhysObject>();
79 public HashSet<BSPhysObject> ObjectsWithUpdates =
new HashSet<BSPhysObject>();
83 private HashSet<BSPhysObject> AvatarsInScene =
new HashSet<BSPhysObject>();
87 public ILog Logger {
get {
return m_log; } }
90 public uint WorldID {
get;
private set; }
99 internal int m_maxSubSteps;
100 internal float m_fixedTimeStep;
102 internal float m_simulatedTime;
104 internal long m_simulationStep = 0;
105 public long SimulationStep {
get {
return m_simulationStep; } }
108 public static long NotASimulationStep = -1234;
110 internal float LastTimeStep {
get;
private set; }
112 internal float NominalFrameRate {
get; set; }
115 public delegate
void PreStepAction(
float timeStep);
116 public delegate
void PostStepAction(
float timeStep);
122 public int SimulationNowTime {
get;
private set; }
125 private bool m_initialized =
false;
129 public bool InTaintTime {
get;
private set; }
132 internal int m_maxCollisionsPerFrame;
135 internal int m_maxUpdatesPerFrame;
141 private ManualResetEvent m_updateWaitEvent;
143 public const uint TERRAIN_ID = 0;
144 public const uint GROUNDPLANE_ID = 1;
145 public const uint CHILDTERRAIN_ID = 2;
147 public float SimpleWaterLevel {
get; set; }
152 get {
return UnmanagedParams[0]; }
154 public Vector3 DefaultGravity
156 get {
return new Vector3(0f, 0f, Params.gravity); }
159 public float DefaultGravityZ
161 get {
return Params.gravity; }
168 public delegate
void TaintCallback();
169 private struct TaintCallbackEntry
173 public TaintCallback callback;
174 public TaintCallbackEntry(
string pIdent, TaintCallback pCallBack)
176 originator = BSScene.DetailLogZero;
178 callback = pCallBack;
180 public TaintCallbackEntry(
string pOrigin,
string pIdent, TaintCallback pCallBack)
182 originator = pOrigin;
184 callback = pCallBack;
188 private List<TaintCallbackEntry> _taintOperations;
189 private Dictionary<string, TaintCallbackEntry> _postTaintOperations;
190 private List<TaintCallbackEntry> _postStepOperations;
194 internal ConfigurationParameters[] UnmanagedParams;
198 private bool m_physicsLoggingEnabled;
199 private string m_physicsLoggingDir;
200 private string m_physicsLoggingPrefix;
201 private int m_physicsLoggingFileMinutes;
202 private bool m_physicsLoggingDoFlush;
203 private bool m_physicsPhysicalDumpEnabled;
204 public int PhysicsMetricDumpFrames {
get; set; }
206 public bool VehicleLoggingEnabled {
get;
private set; }
207 public bool VehiclePhysicalLoggingEnabled {
get;
private set; }
209 #region INonSharedRegionModule
212 get {
return "BulletSim"; }
215 public Type ReplaceableInterface
223 IConfig config = source.Configs[
"Startup"];
226 string physics = config.GetString(
"physics", string.Empty);
246 RegionName = scene.RegionInfo.RegionName;
247 PhysicsSceneName = EngineType +
"/" + RegionName;
251 Initialise(m_Config, extent);
253 base.Initialise(scene.PhysicsRequestAsset,
270 mesher = scene.RequestModuleInterface<
IMesher>();
272 m_log.WarnFormat(
"{0} No mesher. Things will not work well.", LogHeader);
274 scene.PhysicsEnabled =
true;
278 #region Initialization
280 private void Initialise(IConfigSource config, Vector3 regionExtent)
282 _taintOperations =
new List<TaintCallbackEntry>();
283 _postTaintOperations =
new Dictionary<string, TaintCallbackEntry>();
284 _postStepOperations =
new List<TaintCallbackEntry>();
285 PhysObjects =
new Dictionary<uint, BSPhysObject>();
288 m_simulatedTime = 0f;
295 GetInitialParameterValues(config);
301 m_log.WarnFormat(
"{0} Forcing terrain implementation to heightmap for large region", LogHeader);
306 PE = SelectUnderlyingBulletEngine(BulletEngineName);
311 if (m_physicsLoggingEnabled)
313 PhysicsLogging =
new LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes, m_physicsLoggingDoFlush);
314 PhysicsLogging.ErrorLogger = m_log;
322 m_collisionArray =
new CollisionDesc[m_maxCollisionsPerFrame];
323 m_updateArray =
new EntityProperties[m_maxUpdatesPerFrame];
329 Vector3 worldExtent = regionExtent;
331 World = PE.Initialize(worldExtent, Params, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame, ref m_updateArray);
333 Constraints =
new BSConstraintCollection(World);
335 TerrainManager =
new BSTerrainManager(
this, worldExtent);
336 TerrainManager.CreateInitialGroundPlaneAndTerrain();
339 m_log.InfoFormat(
"{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation);
342 m_initialized =
true;
345 if (BSParam.UseSeparatePhysicsThread)
349 = WorkManager.StartThread(
350 BulletSPluginPhysicsThread,
351 string.Format(
"{0} ({1})", BulletEngineName, RegionName),
352 ThreadPriority.Normal,
360 private void GetInitialParameterValues(IConfigSource config)
362 ConfigurationParameters parms =
new ConfigurationParameters();
363 UnmanagedParams[0] = parms;
365 BSParam.SetParameterDefaultValues(
this);
370 IConfig pConfig = config.Configs[
"BulletSim"];
373 BSParam.SetParameterConfigurationValues(
this, pConfig);
376 BulletEngineName = pConfig.GetString(
"BulletEngine",
"BulletUnmanaged");
380 m_physicsLoggingEnabled = pConfig.GetBoolean(
"PhysicsLoggingEnabled",
false);
381 m_physicsLoggingDir = pConfig.GetString(
"PhysicsLoggingDir",
".");
382 m_physicsLoggingPrefix = pConfig.GetString(
"PhysicsLoggingPrefix",
"physics-%REGIONNAME%-");
383 m_physicsLoggingFileMinutes = pConfig.GetInt(
"PhysicsLoggingFileMinutes", 5);
384 m_physicsLoggingDoFlush = pConfig.GetBoolean(
"PhysicsLoggingDoFlush",
false);
385 m_physicsPhysicalDumpEnabled = pConfig.GetBoolean(
"PhysicsPhysicalDumpEnabled",
false);
387 VehicleLoggingEnabled = pConfig.GetBoolean(
"VehicleLoggingEnabled",
false);
388 VehiclePhysicalLoggingEnabled = pConfig.GetBoolean(
"VehiclePhysicalLoggingEnabled",
false);
391 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace(
"%REGIONNAME%", RegionName);
396 BulletEngineName =
"BulletUnmanaged";
397 m_physicsLoggingEnabled =
false;
398 VehicleLoggingEnabled =
false;
402 BSMaterials.InitializeFromDefaults(Params);
406 BSMaterials.InitializefromParameters(pConfig);
412 float ParamBoolean(IConfig config,
string parmName,
float deflt)
415 if (config.Contains(parmName))
417 ret = ConfigurationParameters.numericFalse;
418 if (config.GetBoolean(parmName,
false))
420 ret = ConfigurationParameters.numericTrue;
430 private BSAPITemplate SelectUnderlyingBulletEngine(
string engineName)
434 BSAPITemplate ret = null;
436 string selectionName = engineName.ToLower();
437 int hyphenIndex = engineName.IndexOf(
"-");
439 selectionName = engineName.ToLower().Substring(0, hyphenIndex - 1);
441 switch (selectionName)
444 case "bulletunmanaged":
445 ret =
new BSAPIUnman(engineName,
this);
448 ret =
new BSAPIXNA(engineName,
this);
450 m_log.InfoFormat(
"{0} Disabling some physics features not implemented by BulletXNA", LogHeader);
451 m_log.InfoFormat(
"{0} Disabling ShouldUseBulletHACD", LogHeader);
452 BSParam.ShouldUseBulletHACD =
false;
453 m_log.InfoFormat(
"{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader);
454 BSParam.ShouldUseSingleConvexHullForPrims =
false;
455 m_log.InfoFormat(
"{0} Disabling ShouldUseGImpactShapeForPrims", LogHeader);
456 BSParam.ShouldUseGImpactShapeForPrims =
false;
457 m_log.InfoFormat(
"{0} Setting terrain implimentation to Heightmap", LogHeader);
458 BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap;
464 m_log.ErrorFormat(
"{0} COULD NOT SELECT BULLET ENGINE: '[BulletSim]PhysicsEngine' must be either 'BulletUnmanaged-*' or 'BulletXNA-*'", LogHeader);
468 m_log.InfoFormat(
"{0} Selected bullet engine {1} -> {2}/{3}", LogHeader, engineName, ret.BulletEngineName, ret.BulletEngineVersion);
479 m_initialized =
false;
483 foreach (KeyValuePair<uint, BSPhysObject> kvp
in PhysObjects)
491 if (Constraints != null)
493 Constraints.Dispose();
503 if (TerrainManager != null)
505 TerrainManager.ReleaseGroundPlaneAndTerrain();
506 TerrainManager.Dispose();
507 TerrainManager = null;
514 PhysicsLogging.Close();
516 #endregion // Construction and Initialization
518 #region Prim and Avatar addition and removal
520 public override PhysicsActor AddAvatar(
string avName, Vector3 position, Vector3 velocity, Vector3 size,
bool isFlying)
522 m_log.ErrorFormat(
"{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
526 public override PhysicsActor AddAvatar(uint localID,
string avName, Vector3 position, Vector3 size,
float footOffset,
bool isFlying)
530 if (!m_initialized)
return null;
532 BSCharacter actor =
new BSCharacter(localID, avName,
this, position, Vector3.Zero, size, footOffset, isFlying);
534 PhysObjects.Add(localID, actor);
539 lock (AvatarsInSceneLock)
540 AvatarsInScene.Add(actor);
549 if (!m_initialized)
return;
557 PhysObjects.Remove(bsactor.LocalID);
559 lock (AvatarsInSceneLock)
560 AvatarsInScene.Remove(bsactor);
564 m_log.WarnFormat(
"{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e);
571 m_log.ErrorFormat(
"{0}: Requested to remove avatar that is not a BSCharacter. ID={1}, type={2}",
572 LogHeader, actor.LocalID, actor.GetType().Name);
578 if (!m_initialized)
return;
583 DetailLog(
"{0},RemovePrim,call", bsprim.
LocalID);
587 lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID);
591 m_log.ErrorFormat(
"{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e);
598 m_log.ErrorFormat(
"{0}: Attempt to remove prim that is not a BSPrim type.", LogHeader);
603 Vector3 size, Quaternion
rotation,
bool isPhysical, uint localID)
607 if (!m_initialized)
return null;
612 lock (PhysObjects) PhysObjects.Add(localID, prim);
621 #endregion // Prim and Avatar addition and removal
633 if (!BSParam.UseSeparatePhysicsThread)
635 DoPhysicsStep(timeStep);
637 return SendUpdatesToSimulator(timeStep);
642 private void DoPhysicsStep(
float timeStep)
645 if (!m_initialized)
return;
647 LastTimeStep = timeStep;
649 int updatedEntityCount = 0;
650 int collidersCount = 0;
652 int beforeTime = Util.EnvironmentTickCount();
655 int numTaints = _taintOperations.Count;
663 TriggerPreStepEvent(timeStep);
666 numTaints += _taintOperations.Count;
673 if (m_physicsPhysicalDumpEnabled)
674 PE.DumpAllInfo(
World);
681 numSubSteps = PE.PhysicsStep(
World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
685 m_log.WarnFormat(
"{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
686 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
687 DetailLog(
"{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
688 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
689 updatedEntityCount = 0;
694 if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0))
695 PE.DumpPhysicsStatistics(
World);
698 SimulationNowTime = Util.EnvironmentTickCount();
705 if (collidersCount > 0)
709 for (
int ii = 0; ii < collidersCount; ii++)
711 uint cA = m_collisionArray[ii].aID;
712 uint cB = m_collisionArray[ii].bID;
713 Vector3 point = m_collisionArray[ii].point;
714 Vector3 normal = m_collisionArray[ii].normal;
715 float penetration = m_collisionArray[ii].penetration;
716 SendCollision(cA, cB, point, normal, penetration);
717 SendCollision(cB, cA, point, -normal, penetration);
727 if (updatedEntityCount > 0)
731 for (
int ii = 0; ii < updatedEntityCount; ii++)
733 EntityProperties entprop = m_updateArray[ii];
735 if (PhysObjects.TryGetValue(entprop.ID, out pobj))
737 if (pobj.IsInitialized)
738 pobj.UpdateProperties(entprop);
746 TriggerPostStepEvent(timeStep);
748 simTime = Util.EnvironmentTickCountSubtract(beforeTime);
749 if (PhysicsLogging.Enabled)
751 DetailLog(
"{0},DoPhysicsStep,complete,frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}",
752 DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps,
753 updatedEntityCount, collidersCount, ObjectsWithCollisions.Count);
758 if (m_physicsPhysicalDumpEnabled)
759 PE.DumpAllInfo(
World);
765 m_simulatedTime += (float)numSubSteps * m_fixedTimeStep;
776 ObjectsWithUpdates.Add(updatee);
782 private float SendUpdatesToSimulator(
float timeStep)
784 if (!m_initialized)
return 5.0f;
786 DetailLog(
"{0},SendUpdatesToSimulator,collisions={1},updates={2},simedTime={3}",
791 if (ObjectsWithCollisions.Count > 0)
797 ObjectsWithNoMoreCollisions.Add(bsp);
806 HashSet<BSPhysObject> tempAvatarsInScene;
807 lock (AvatarsInSceneLock)
809 tempAvatarsInScene =
new HashSet<BSPhysObject>(AvatarsInScene);
811 foreach (BSPhysObject actor
in tempAvatarsInScene)
813 if (!ObjectsWithCollisions.Contains(actor))
814 actor.SendCollisions();
816 tempAvatarsInScene = null;
823 if (ObjectsWithNoMoreCollisions.Count > 0)
825 foreach (BSPhysObject po
in ObjectsWithNoMoreCollisions)
826 ObjectsWithCollisions.Remove(po);
827 ObjectsWithNoMoreCollisions.Clear();
832 HashSet<BSPhysObject> updatedObjects = null;
835 if (ObjectsWithUpdates.Count > 0)
837 updatedObjects = ObjectsWithUpdates;
838 ObjectsWithUpdates =
new HashSet<BSPhysObject>();
841 if (updatedObjects != null)
843 foreach (BSPhysObject obj
in updatedObjects)
845 obj.RequestPhysicsterseUpdate();
847 updatedObjects.Clear();
852 float simTime = m_simulatedTime / timeStep;
853 m_simulatedTime = 0f;
858 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal,
float penetration)
860 if (localID <= TerrainManager.HighestTerrainID)
865 BSPhysObject collider;
867 if (!PhysObjects.TryGetValue(localID, out collider))
870 DetailLog(
"{0},BSScene.SendCollision,colliderNotInObjectList,id={1},with={2}", DetailLogZero, localID, collidingWith);
875 BSPhysObject collidee = null;
876 PhysObjects.TryGetValue(collidingWith, out collidee);
880 if (collider.IsInitialized)
882 if (collider.Collide(collidee, collidePoint, collideNormal, penetration))
887 ObjectsWithCollisions.Add(collider);
897 Thread.CurrentThread.Priority = ThreadPriority.Highest;
898 m_updateWaitEvent =
new ManualResetEvent(
false);
900 while (m_initialized)
902 int beginSimulationRealtimeMS = Util.EnvironmentTickCount();
905 DoPhysicsStep(BSParam.PhysicsTimeStep);
907 int simulationRealtimeMS = Util.EnvironmentTickCountSubtract(beginSimulationRealtimeMS);
908 int simulationTimeVsRealtimeDifferenceMS = ((int)(BSParam.PhysicsTimeStep*1000f)) - simulationRealtimeMS;
910 if (simulationTimeVsRealtimeDifferenceMS > 0)
914 m_updateWaitEvent.WaitOne(simulationTimeVsRealtimeDifferenceMS);
922 DetailLog(
"{0},BulletSPluginPhysicsThread,longerThanRealtime={1}",
BSScene.
DetailLogZero, simulationTimeVsRealtimeDifferenceMS);
925 Watchdog.UpdateThread();
928 Watchdog.RemoveThread();
931 #endregion // Simulation
938 TerrainManager.SetTerrain(heightMap);
943 SimpleWaterLevel = baseheight;
954 return TerrainManager.SupportsCombining();
961 TerrainManager.Combine(pScene, offset, extents);
967 TerrainManager.UnCombine(pScene);
970 #endregion // Terrain
974 Dictionary<uint, float> topColliders;
978 foreach (KeyValuePair<uint, BSPhysObject> kvp
in PhysObjects)
980 kvp.Value.ComputeCollisionScore();
983 List<BSPhysObject> orderedPrims =
new List<BSPhysObject>(PhysObjects.Values);
984 orderedPrims.OrderByDescending(p => p.CollisionScore);
985 topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
991 public override bool IsThreaded {
get {
return false; } }
994 public override object Extension(
string pFunct, params
object[] pParams)
996 DetailLog(
"{0} BSScene.Extension,op={1}", DetailLogZero, pFunct);
997 return base.Extension(pFunct, pParams);
999 #endregion // Extensions
1003 float pathShearX = pbs.PathShearX < 128 ? (float)pbs.
PathShearX * 0.01f : (
float)(pbs.PathShearX - 256) * 0.01f;
1004 float pathShearY = pbs.PathShearY < 128 ? (float)pbs.
PathShearY * 0.01f : (
float)(pbs.PathShearY - 256) * 0.01f;
1005 float pathBegin = (float)pbs.
PathBegin * 2.0e-5f;
1006 float pathEnd = 1.0f - (
float)pbs.PathEnd * 2.0e-5f;
1007 float pathScaleX = (float)(200 - pbs.
PathScaleX) * 0.01f;
1008 float pathScaleY = (float)(200 - pbs.
PathScaleY) * 0.01f;
1009 float pathTaperX = pbs.PathTaperX * 0.01f;
1010 float pathTaperY = pbs.PathTaperY * 0.01f;
1012 float profileBegin = (float)pbs.
ProfileBegin * 2.0e-5f;
1013 float profileEnd = 1.0f - (
float)pbs.ProfileEnd * 2.0e-5f;
1015 if (profileHollow > 0.95f)
1016 profileHollow = 0.95f;
1018 StringBuilder buff =
new StringBuilder();
1019 buff.Append(
"shape=");
1022 buff.Append(
"hollow=");
1025 buff.Append(
"pathCurve=");
1028 buff.Append(
"profCurve=");
1031 buff.Append(
"profHollow=");
1032 buff.Append(profileHollow.ToString());
1034 buff.Append(
"pathBegEnd=");
1035 buff.Append(pathBegin.ToString());
1037 buff.Append(pathEnd.ToString());
1039 buff.Append(
"profileBegEnd=");
1040 buff.Append(profileBegin.ToString());
1042 buff.Append(profileEnd.ToString());
1044 buff.Append(
"scaleXY=");
1045 buff.Append(pathScaleX.ToString());
1047 buff.Append(pathScaleY.ToString());
1049 buff.Append(
"shearXY=");
1050 buff.Append(pathShearX.ToString());
1052 buff.Append(pathShearY.ToString());
1054 buff.Append(
"taperXY=");
1055 buff.Append(pbs.PathTaperX.ToString());
1057 buff.Append(pbs.PathTaperY.ToString());
1059 buff.Append(
"skew=");
1060 buff.Append(pbs.PathSkew.ToString());
1062 buff.Append(
"twist/Beg=");
1063 buff.Append(pbs.PathTwist.ToString());
1065 buff.Append(pbs.PathTwistBegin.ToString());
1067 return buff.ToString();
1084 public void TaintedObject(
string pOriginator,
string pIdent, TaintCallback pCallback)
1086 TaintedObject(
false , pOriginator, pIdent, pCallback);
1088 public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback)
1090 TaintedObject(
false , m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1092 public void TaintedObject(
bool inTaintTime, String pIdent, TaintCallback pCallback)
1096 public void TaintedObject(
bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
1098 TaintedObject(inTaintTime, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1102 public void TaintedObject(
bool inTaintTime,
string pOriginator,
string pIdent, TaintCallback pCallback)
1104 if (!m_initialized)
return;
1112 _taintOperations.Add(
new TaintCallbackEntry(pOriginator, pIdent, pCallback));
1117 private void TriggerPreStepEvent(
float timeStep)
1119 PreStepAction actions = BeforeStep;
1120 if (actions != null)
1125 private void TriggerPostStepEvent(
float timeStep)
1127 PostStepAction actions = AfterStep;
1128 if (actions != null)
1138 ProcessRegularTaints();
1139 ProcessPostTaintTaints();
1142 private void ProcessRegularTaints()
1144 if (m_initialized && _taintOperations.Count > 0)
1147 List<TaintCallbackEntry> oldList;
1150 oldList = _taintOperations;
1151 _taintOperations =
new List<TaintCallbackEntry>();
1154 foreach (TaintCallbackEntry tcbe
in oldList)
1158 DetailLog(
"{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident);
1163 m_log.ErrorFormat(
"{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e);
1175 string IDAsString = ID.ToString();
1176 string uniqueIdent = ident +
"-" + IDAsString;
1179 _postTaintOperations[uniqueIdent] =
new TaintCallbackEntry(IDAsString, uniqueIdent, callback);
1186 private void ProcessPostTaintTaints()
1188 if (m_initialized && _postTaintOperations.Count > 0)
1190 Dictionary<string, TaintCallbackEntry> oldList;
1193 oldList = _postTaintOperations;
1194 _postTaintOperations =
new Dictionary<string, TaintCallbackEntry>();
1197 foreach (KeyValuePair<string,TaintCallbackEntry> kvp
in oldList)
1201 DetailLog(
"{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key);
1202 kvp.Value.callback();
1206 m_log.ErrorFormat(
"{0}: ProcessPostTaintTaints: {1}: Exception: {2}", LogHeader, kvp.Key, e);
1218 DetailLog(
"{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
1219 m_log.ErrorFormat(
"{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
1225 #endregion // Taints
1227 #region IPhysicsParameters
1231 BSParam.BuildParameterTable();
1232 return BSParam.SettableParameters;
1246 if (BSParam.TryGetParameter(parm, out theParam))
1249 theParam.SetValue(
this, val);
1252 if (theParam.HasSetOnObject)
1258 List<uint> objectIDs =
new List<uint>();
1261 case PhysParameterEntry.APPLY_TO_NONE:
1263 objectIDs.Add(TERRAIN_ID);
1264 TaintedUpdateParameter(parm, objectIDs, val);
1266 case PhysParameterEntry.APPLY_TO_ALL:
1267 lock (PhysObjects) objectIDs =
new List<uint>(PhysObjects.Keys);
1268 TaintedUpdateParameter(parm, objectIDs, val);
1272 objectIDs.Add(localID);
1273 TaintedUpdateParameter(parm, objectIDs, val);
1284 private void TaintedUpdateParameter(
string parm, List<uint> lIDs,
string val)
1287 List<uint> xlIDs = lIDs;
1288 string xparm = parm;
1289 TaintedObject(DetailLogZero,
"BSScene.UpdateParameterSet", delegate() {
1291 if (BSParam.TryGetParameter(xparm, out thisParam))
1293 if (thisParam.HasSetOnObject)
1295 foreach (uint lID
in xlIDs)
1298 if (PhysObjects.TryGetValue(lID, out theObject))
1299 thisParam.SetOnObject(
this, theObject);
1310 string val = String.Empty;
1313 if (BSParam.TryGetParameter(parm, out theParam))
1315 val = theParam.GetValue(
this);
1322 #endregion IPhysicsParameters
1327 PhysicsLogging.Write(msg, args);
1330 public const string DetailLogZero =
"0000000000";
override void GetResults()
bool GetPhysicsParameter(string parm, out string value)
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
Class for writing a high performance, high volume log file. Sometimes, to debug, one has a high volum...
override void RemovePrim(PhysicsActor prim)
Remove a prim.
void PostUpdate(BSPhysObject updatee)
uint RegionSizeX
X dimension of the region.
void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback)
static string PrimitiveBaseShapeToString(PrimitiveBaseShape pbs)
uint RegionSizeY
X dimension of the region.
void PostTaintObject(String ident, uint ID, TaintCallback callback)
override Dictionary< uint, float > GetTopColliders()
RegionSettings RegionSettings
void DetailLog(string msg, params Object[] args)
PhysParameterEntry[] GetParameterList()
Dictionary< uint, BSPhysObject > PhysObjects
bool AssertInTaintTime(string whereFrom)
override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback)
override void SetWaterLevel(float baseheight)
override bool SupportsCombining()
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
override object Extension(string pFunct, params object[] pParams)
override void UnCombine(PhysicsScene pScene)
override void DeleteTerrain()
ProfileShape ProfileShape
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
void BulletSPluginPhysicsThread()
override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
Add an avatar
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
override float Simulate(float timeStep)
Perform a simulation of the current physics scene over the given timestep.
void TaintedObject(bool inTaintTime, string pOriginator, string pIdent, TaintCallback pCallback)
override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float footOffset, bool isFlying)
override void AddPhysicsActorTaint(PhysicsActor prim)
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
override void RemoveAvatar(PhysicsActor actor)
Remove an avatar.
virtual bool SendCollisions()
const string DetailLogZero
void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
uint RegionSizeZ
Z dimension of the region.
virtual RegionInfo RegionInfo
void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical, uint localID)
bool SetPhysicsParameter(string parm, string val, uint localID)
override void SetTerrain(float[] heightMap)