28 using System.Collections.Generic;
30 using System.Reflection;
32 using System.Threading;
34 using OpenSim.Framework;
35 using OpenSim.Region.Framework;
36 using OpenSim.Region.Framework.Interfaces;
37 using OpenSim.Region.Framework.Scenes;
38 using OpenSim.Region.PhysicsModules.SharedBase;
45 namespace OpenSim.
Region.PhysicsModule.BulletS
47 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule")]
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private static string LogHeader =
"[EXTENDED PHYSICS]";
62 public const string PhysFunctGetLinksetType =
"BulletSim.GetLinksetType";
63 public const string PhysFunctSetLinksetType =
"BulletSim.SetLinksetType";
64 public const string PhysFunctChangeLinkFixed =
"BulletSim.ChangeLinkFixed";
65 public const string PhysFunctChangeLinkType =
"BulletSim.ChangeLinkType";
66 public const string PhysFunctGetLinkType =
"BulletSim.GetLinkType";
67 public const string PhysFunctChangeLinkParams =
"BulletSim.ChangeLinkParams";
68 public const string PhysFunctAxisLockLimits =
"BulletSim.AxisLockLimits";
72 private IConfig Configuration {
get; set; }
73 private bool Enabled {
get; set; }
74 private Scene BaseScene {
get; set; }
77 #region INonSharedRegionModule
79 public string Name {
get {
return this.GetType().Name; } }
90 if ((Configuration = config.Configs[
"ExtendedPhysics"]) != null)
92 Enabled = Configuration.GetBoolean(
"Enabled", Enabled);
97 m_log.ErrorFormat(
"{0} Initialization error: {0}", LogHeader, e);
100 m_log.InfoFormat(
"{0} module {1} enabled", LogHeader, (Enabled ?
"is" :
"is not"));
105 if (BaseScene != null)
107 BaseScene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene;
108 BaseScene.EventManager.OnSceneObjectPartUpdated -= EventManager_OnSceneObjectPartUpdated;
119 if (BaseScene != null && BaseScene == scene)
127 if (!Enabled)
return;
134 m_log.WarnFormat(
"{0} ScriptModuleComms interface not defined", LogHeader);
141 Comms.RegisterScriptInvocations(
this);
142 Comms.RegisterConstants(
this);
145 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
146 BaseScene.EventManager.OnSceneObjectPartUpdated += EventManager_OnSceneObjectPartUpdated;
150 public Type ReplaceableInterface {
get {
return null; } }
152 #endregion // INonSharedRegionModule
159 private void EventManager_OnSceneObjectPartUpdated(
SceneObjectPart sop,
bool isFullUpdate)
164 public const int PHYS_CENTER_OF_MASS = 1 << 0;
169 string ret = string.Empty;
171 if (BaseScene.PhysicsScene != null)
173 ret = BaseScene.PhysicsScene.EngineType;
182 public const int PHYS_AXIS_LOCK_LINEAR = 14700;
184 public const int PHYS_AXIS_LOCK_LINEAR_X = 14701;
186 public const int PHYS_AXIS_LIMIT_LINEAR_X = 14702;
188 public const int PHYS_AXIS_LOCK_LINEAR_Y = 14703;
190 public const int PHYS_AXIS_LIMIT_LINEAR_Y = 14704;
192 public const int PHYS_AXIS_LOCK_LINEAR_Z = 14705;
194 public const int PHYS_AXIS_LIMIT_LINEAR_Z = 14706;
196 public const int PHYS_AXIS_LOCK_ANGULAR = 14707;
198 public const int PHYS_AXIS_LOCK_ANGULAR_X = 14708;
200 public const int PHYS_AXIS_LIMIT_ANGULAR_X = 14709;
202 public const int PHYS_AXIS_LOCK_ANGULAR_Y = 14710;
204 public const int PHYS_AXIS_LIMIT_ANGULAR_Y = 14711;
206 public const int PHYS_AXIS_LOCK_ANGULAR_Z = 14712;
208 public const int PHYS_AXIS_LIMIT_ANGULAR_Z = 14713;
210 public const int PHYS_AXIS_UNLOCK_LINEAR = 14714;
212 public const int PHYS_AXIS_UNLOCK_LINEAR_X = 14715;
214 public const int PHYS_AXIS_UNLOCK_LINEAR_Y = 14716;
216 public const int PHYS_AXIS_UNLOCK_LINEAR_Z = 14717;
218 public const int PHYS_AXIS_UNLOCK_ANGULAR = 14718;
220 public const int PHYS_AXIS_UNLOCK_ANGULAR_X = 14719;
222 public const int PHYS_AXIS_UNLOCK_ANGULAR_Y = 14720;
224 public const int PHYS_AXIS_UNLOCK_ANGULAR_Z = 14721;
226 public const int PHYS_AXIS_UNLOCK = 14722;
232 if (!Enabled)
return ret;
235 if (GetRootPhysActor(hostID, out rootPhysActor))
237 object[] parms2 = AddToBeginningOfArray(rootPhysActor, null, parms);
238 ret = MakeIntError(rootPhysActor.Extension(PhysFunctAxisLockLimits, parms2));
245 public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0;
247 public const int PHYS_LINKSET_TYPE_COMPOUND = 1;
249 public const int PHYS_LINKSET_TYPE_MANUAL = 2;
255 if (!Enabled)
return ret;
260 if (requestingPart != null)
266 if (rootPart != null)
269 if (rootPhysActor != null)
276 containingGroup.ScriptSetPhysicsStatus(
false);
284 containingGroup.UpdateGroupPosition(containingGroup.AbsolutePosition);
285 containingGroup.UpdateGroupRotationR(containingGroup.GroupRotation);
287 object[] parms2 = { rootPhysActor, null, linksetType };
288 ret = MakeIntError(rootPhysActor.
Extension(PhysFunctSetLinksetType, parms2));
291 containingGroup.ScriptSetPhysicsStatus(
true);
297 object[] parms2 = { rootPhysActor, null, linksetType };
298 ret = MakeIntError(rootPhysActor.
Extension(PhysFunctSetLinksetType, parms2));
303 m_log.WarnFormat(
"{0} physSetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
304 LogHeader, rootPart.Name, hostID);
309 m_log.WarnFormat(
"{0} physSetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
310 LogHeader, requestingPart.Name, hostID);
315 m_log.WarnFormat(
"{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
324 if (!Enabled)
return ret;
327 if (GetRootPhysActor(hostID, out rootPhysActor))
329 object[] parms2 = { rootPhysActor, null };
330 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2));
334 m_log.WarnFormat(
"{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
340 public const int PHYS_LINK_TYPE_FIXED = 1234;
342 public const int PHYS_LINK_TYPE_HINGE = 4;
344 public const int PHYS_LINK_TYPE_SPRING = 9;
346 public const int PHYS_LINK_TYPE_6DOF = 6;
348 public const int PHYS_LINK_TYPE_SLIDER = 7;
355 if (!Enabled)
return ret;
360 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
362 object[] parms2 = { rootPhysActor, childPhysActor, typeCode };
363 ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkType, parms2));
374 if (!Enabled)
return ret;
379 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
381 object[] parms2 = { rootPhysActor, childPhysActor };
382 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinkType, parms2));
394 if (!Enabled)
return ret;
399 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
401 object[] parms2 = { rootPhysActor, childPhysActor , PHYS_LINK_TYPE_FIXED };
402 ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkType, parms2));
410 public const int PHYS_PARAM_MIN = 14401;
413 public const int PHYS_PARAM_FRAMEINA_LOC = 14401;
415 public const int PHYS_PARAM_FRAMEINA_ROT = 14402;
417 public const int PHYS_PARAM_FRAMEINB_LOC = 14403;
419 public const int PHYS_PARAM_FRAMEINB_ROT = 14404;
421 public const int PHYS_PARAM_LINEAR_LIMIT_LOW = 14405;
423 public const int PHYS_PARAM_LINEAR_LIMIT_HIGH = 14406;
425 public const int PHYS_PARAM_ANGULAR_LIMIT_LOW = 14407;
427 public const int PHYS_PARAM_ANGULAR_LIMIT_HIGH = 14408;
429 public const int PHYS_PARAM_USE_FRAME_OFFSET = 14409;
431 public const int PHYS_PARAM_ENABLE_TRANSMOTOR = 14410;
433 public const int PHYS_PARAM_TRANSMOTOR_MAXVEL = 14411;
435 public const int PHYS_PARAM_TRANSMOTOR_MAXFORCE = 14412;
437 public const int PHYS_PARAM_CFM = 14413;
439 public const int PHYS_PARAM_ERP = 14414;
441 public const int PHYS_PARAM_SOLVER_ITERATIONS = 14415;
443 public const int PHYS_PARAM_SPRING_AXIS_ENABLE = 14416;
445 public const int PHYS_PARAM_SPRING_DAMPING = 14417;
447 public const int PHYS_PARAM_SPRING_STIFFNESS = 14418;
449 public const int PHYS_PARAM_LINK_TYPE = 14419;
451 public const int PHYS_PARAM_USE_LINEAR_FRAMEA = 14420;
453 public const int PHYS_PARAM_SPRING_EQUILIBRIUM_POINT = 14421;
455 public const int PHYS_PARAM_MAX = 14421;
459 public const int PHYS_AXIS_ALL = -1;
461 public const int PHYS_AXIS_LINEAR_ALL = -2;
463 public const int PHYS_AXIS_ANGULAR_ALL = -3;
465 public const int PHYS_AXIS_LINEAR_X = 0;
467 public const int PHYS_AXIS_LINEAR_Y = 1;
469 public const int PHYS_AXIS_LINEAR_Z = 2;
471 public const int PHYS_AXIS_ANGULAR_X = 3;
473 public const int PHYS_AXIS_ANGULAR_Y = 4;
475 public const int PHYS_AXIS_ANGULAR_Z = 5;
482 if (!Enabled)
return ret;
487 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
489 object[] parms2 = AddToBeginningOfArray(rootPhysActor, childPhysActor, parms);
490 ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkParams, parms2));
496 private bool GetRootPhysActor(UUID hostID, out
PhysicsActor rootPhysActor)
500 return GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor);
506 rootPhysActor = null;
507 containingGroup = null;
512 requestingPart = BaseScene.GetSceneObjectPart(hostID);
513 if (requestingPart != null)
516 containingGroup = requestingPart.ParentGroup;
517 if (containingGroup != null && !containingGroup.IsDeleted)
519 rootPart = containingGroup.RootPart;
520 if (rootPart != null)
522 rootPhysActor = rootPart.PhysActor;
523 if (rootPhysActor != null)
529 m_log.WarnFormat(
"{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}",
530 LogHeader, rootPart.Name, hostID);
535 m_log.WarnFormat(
"{0} GetRootAndChildPhysActors: Root part does not exist. RequestingPartName={1}, hostID={2}",
536 LogHeader, requestingPart.Name, hostID);
541 m_log.WarnFormat(
"{0} GetRootAndChildPhysActors: Containing group missing or deleted. hostID={1}", LogHeader, hostID);
546 m_log.WarnFormat(
"{0} GetRootAndChildPhysActors: cannot find script object in scene. hostID={1}", LogHeader, hostID);
554 private bool GetRootAndChildPhysActors(UUID hostID,
int linkNum, out
PhysicsActor rootPhysActor, out
PhysicsActor childPhysActor)
557 rootPhysActor = null;
558 childPhysActor = null;
563 if (GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor))
566 if (linkPart != null)
568 childPhysActor = linkPart.PhysActor;
569 if (childPhysActor != null)
575 m_log.WarnFormat(
"{0} GetRootAndChildPhysActors: Link part has no physical actor. rootName={1}, hostID={2}, linknum={3}",
576 LogHeader, rootPart.Name, hostID, linkNum);
581 m_log.WarnFormat(
"{0} GetRootAndChildPhysActors: Could not find linknum part. rootName={1}, hostID={2}, linknum={3}",
582 LogHeader, rootPart.Name, hostID, linkNum);
587 m_log.WarnFormat(
"{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}",
588 LogHeader, rootPart.Name, hostID);
595 private object[] AddToBeginningOfArray(
object firstOne,
object secondOne,
object[] prevArray)
597 object[] newArray =
new object[2 + prevArray.Length];
598 newArray[0] = firstOne;
599 newArray[1] = secondOne;
600 prevArray.CopyTo(newArray, 2);
605 private int MakeIntError(
object extensionRet)
608 if (extensionRet != null)
612 ret = (int)extensionRet;
virtual object Extension(string pFunct, params object[] pParams)
int physChangeLinkParams(UUID hostID, UUID scriptID, int linkNum, object[] parms)
int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
int physGetLinkType(UUID hostID, UUID scriptID, int linkNum)
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 RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
int physAxisLock(UUID hostID, UUID scriptID, object[] parms)
int physGetLinksetType(UUID hostID, UUID scriptID)
Interface for communication between OpenSim modules and in-world scripts
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void Initialise(IConfigSource config)
This is called to initialize the region module. For shared modules, this is called exactly once...
int physChangeLinkType(UUID hostID, UUID scriptID, int linkNum, int typeCode)
int physChangeLinkFixed(UUID hostID, UUID scriptID, int linkNum)
string physGetEngineType(UUID hostID, UUID scriptID)
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...