BulletSim: add implementation of 'physSetLinksetType' and 'physGetLinksetType'

and processing routines in BulletSim.
Add linkset rebuild/conversion routine in BSLinkset.
TeleportWork
Robert Adams 2013-08-01 17:43:06 -07:00
parent 5bcccfc305
commit 24df15dab7
9 changed files with 159 additions and 7 deletions

View File

@ -49,10 +49,20 @@ public class ExtendedPhysics : INonSharedRegionModule
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static string LogHeader = "[EXTENDED PHYSICS]"; private static string LogHeader = "[EXTENDED PHYSICS]";
// =============================================================
// Since BulletSim is a plugin, this these values aren't defined easily in one place. // Since BulletSim is a plugin, this these values aren't defined easily in one place.
// This table must coorespond to an identical table in BSScene. // This table must correspond to an identical table in BSScene.
// Per scene functions. See BSScene.
// Per avatar functions. See BSCharacter.
// Per prim functions. See BSPrim.
public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType"; public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
// =============================================================
private IConfig Configuration { get; set; } private IConfig Configuration { get; set; }
private bool Enabled { get; set; } private bool Enabled { get; set; }
private Scene BaseScene { get; set; } private Scene BaseScene { get; set; }
@ -123,6 +133,7 @@ public class ExtendedPhysics : INonSharedRegionModule
// Register as LSL functions all the [ScriptInvocation] marked methods. // Register as LSL functions all the [ScriptInvocation] marked methods.
Comms.RegisterScriptInvocations(this); Comms.RegisterScriptInvocations(this);
Comms.RegisterConstants(this);
// When an object is modified, we might need to update its extended physics parameters // When an object is modified, we might need to update its extended physics parameters
BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
@ -136,7 +147,6 @@ public class ExtendedPhysics : INonSharedRegionModule
private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
{ {
throw new NotImplementedException();
} }
// Event generated when some property of a prim changes. // Event generated when some property of a prim changes.
@ -168,9 +178,11 @@ public class ExtendedPhysics : INonSharedRegionModule
public static int PHYS_LINKSET_TYPE_MANUAL = 2; public static int PHYS_LINKSET_TYPE_MANUAL = 2;
[ScriptInvocation] [ScriptInvocation]
public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
{ {
if (!Enabled) return; int ret = -1;
if (!Enabled) return ret;
// The part that is requesting the change. // The part that is requesting the change.
SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
@ -186,7 +198,7 @@ public class ExtendedPhysics : INonSharedRegionModule
Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
if (rootPhysActor != null) if (rootPhysActor != null)
{ {
rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType);
} }
else else
{ {
@ -204,6 +216,49 @@ public class ExtendedPhysics : INonSharedRegionModule
{ {
m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
} }
return ret;
}
[ScriptInvocation]
public int physGetLinksetType(UUID hostID, UUID scriptID)
{
int ret = -1;
if (!Enabled) return ret;
// The part that is requesting the change.
SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
if (requestingPart != null)
{
// The type is is always on the root of a linkset.
SceneObjectGroup containingGroup = requestingPart.ParentGroup;
SceneObjectPart rootPart = containingGroup.RootPart;
if (rootPart != null)
{
Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
if (rootPhysActor != null)
{
ret = (int)rootPhysActor.Extension(PhysFunctGetLinksetType);
}
else
{
m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
LogHeader, rootPart.Name, hostID);
}
}
else
{
m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
LogHeader, requestingPart.Name, hostID);
}
}
else
{
m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
}
return ret;
} }
} }
} }

View File

@ -79,6 +79,8 @@ public abstract class BSLinkset
} }
} }
public LinksetImplementation LinksetImpl { get; protected set; }
public BSPrimLinkable LinksetRoot { get; protected set; } public BSPrimLinkable LinksetRoot { get; protected set; }
protected BSScene m_physicsScene { get; private set; } protected BSScene m_physicsScene { get; private set; }

View File

@ -42,6 +42,7 @@ public sealed class BSLinksetCompound : BSLinkset
public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) public BSLinksetCompound(BSScene scene, BSPrimLinkable parent)
: base(scene, parent) : base(scene, parent)
{ {
LinksetImpl = LinksetImplementation.Compound;
} }
// ================================================================ // ================================================================

View File

@ -107,6 +107,7 @@ public sealed class BSLinksetConstraints : BSLinkset
public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
{ {
LinksetImpl = LinksetImplementation.Constraint;
} }
// When physical properties are changed the linkset needs to recalculate // When physical properties are changed the linkset needs to recalculate

View File

@ -1541,6 +1541,50 @@ public class BSPrim : BSPhysObject
PhysicalActors.RemoveDependencies(); PhysicalActors.RemoveDependencies();
} }
#region Extension
public override object Extension(string pFunct, params object[] pParams)
{
object ret = null;
switch (pFunct)
{
case BSScene.PhysFunctGetLinksetType:
{
BSPrimLinkable myHandle = this as BSPrimLinkable;
if (myHandle != null)
{
ret = (object)myHandle.LinksetType;
}
m_log.DebugFormat("{0} Extension.physGetLinksetType, type={1}", LogHeader, ret);
break;
}
case BSScene.PhysFunctSetLinksetType:
{
if (pParams.Length > 0)
{
BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[0];
BSPrimLinkable myHandle = this as BSPrimLinkable;
if (myHandle != null && myHandle.Linkset.IsRoot(myHandle))
{
PhysScene.TaintedObject("BSPrim.PhysFunctSetLinksetType", delegate()
{
// Cause the linkset type to change
m_log.DebugFormat("{0} Extension.physSetLinksetType, oldType={1}, newType={2}",
LogHeader, myHandle.Linkset.LinksetImpl, linksetType);
myHandle.ConvertLinkset(linksetType);
});
}
ret = (object)(int)linksetType;
}
break;
}
default:
ret = base.Extension(pFunct, pParams);
break;
}
return ret;
}
#endregion // Extension
// The physics engine says that properties have updated. Update same and inform // The physics engine says that properties have updated. Update same and inform
// the world that things have changed. // the world that things have changed.
// NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims. // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims.

View File

@ -233,5 +233,35 @@ public class BSPrimLinkable : BSPrimDisplaced
base.HasSomeCollision = value; base.HasSomeCollision = value;
} }
} }
// Convert the existing linkset of this prim into a new type.
public bool ConvertLinkset(BSLinkset.LinksetImplementation newType)
{
bool ret = false;
if (LinksetType != newType)
{
BSLinkset oldLinkset = Linkset;
BSLinkset newLinkset = BSLinkset.Factory(PhysScene, this);
// Pick up any physical dependencies this linkset might have in the physics engine.
oldLinkset.RemoveDependencies(this);
// Copy the linkset children from the old linkset to the new (will be a new instance from the factory)
oldLinkset.ForEachLinkInfo((li) =>
{
oldLinkset.RemoveMeFromLinkset(li.member);
newLinkset.AddMeToLinkset(li.member);
li.member.Linkset = newLinkset;
return false;
});
this.Linkset = newLinkset;
// Force the shape and linkset to get reconstructed
newLinkset.Refresh(this);
this.ForceBodyShapeRebuild(true);
}
return ret;
}
} }
} }

View File

@ -862,6 +862,23 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
public override bool IsThreaded { get { return false; } } public override bool IsThreaded { get { return false; } }
#region Extensions
// =============================================================
// Per scene functions. See below.
// Per avatar functions. See BSCharacter.
// Per prim functions. See BSPrim.
public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
// =============================================================
public override object Extension(string pFunct, params object[] pParams)
{
return base.Extension(pFunct, pParams);
}
#endregion // Extensions
#region Taints #region Taints
// The simulation execution order is: // The simulation execution order is:
// Simulate() // Simulate()

View File

@ -317,7 +317,8 @@ namespace OpenSim.Region.Physics.Manager
// Extendable interface for new, physics engine specific operations // Extendable interface for new, physics engine specific operations
public virtual object Extension(string pFunct, params object[] pParams) public virtual object Extension(string pFunct, params object[] pParams)
{ {
throw new NotImplementedException(); // A NOP of the physics engine does not implement this feature
return null;
} }
} }

View File

@ -338,7 +338,8 @@ namespace OpenSim.Region.Physics.Manager
// Extendable interface for new, physics engine specific operations // Extendable interface for new, physics engine specific operations
public virtual object Extension(string pFunct, params object[] pParams) public virtual object Extension(string pFunct, params object[] pParams)
{ {
throw new NotImplementedException(); // A NOP if the extension thing is not implemented by the physics engine
return null;
} }
} }
} }