From 87ee0c395ed82f27c2a52b5023d8036eb7e355c9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 2 Aug 2013 09:44:01 -0700 Subject: [PATCH 1/5] Fix problem with modInvoke defined integer constants being build into scripts as boxed integers rather than proper reference to a new LSLInteger. This fixes an exception when using a registered integer constant in a script. --- .../Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs | 4 ++-- .../Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 21bae27282..92dd8137d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -319,7 +319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api object[] convertedParms = new object[parms.Length]; for (int i = 0; i < parms.Length; i++) - convertedParms[i] = ConvertFromLSL(parms[i],signature[i], fname); + convertedParms[i] = ConvertFromLSL(parms[i], signature[i], fname); // now call the function, the contract with the function is that it will always return // non-null but don't trust it completely @@ -444,7 +444,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - MODError(String.Format("{1}: parameter type mismatch; expecting {0}",type.Name, fname)); + MODError(String.Format("{0}: parameter type mismatch; expecting {1}, type(parm)={2}", fname, type.Name, lslparm.GetType())); return null; } diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 9e32f4031a..6aa717db03 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -937,7 +937,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { string retval = null; if (value is int) - retval = ((int)value).ToString(); + retval = String.Format("new LSL_Types.LSLInteger({0})",((int)value).ToString()); else if (value is float) retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString()); else if (value is string) From 5bcccfc305ae4f5a74b9b816781a2a643daa23b3 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 1 Aug 2013 12:35:22 -0700 Subject: [PATCH 2/5] BulletSim: add BSLinkInfo structure to remember link specific information for each link in a linkset. Extend BSLinksetConstraint to create and use BSLinkInfo with the default static constraint. --- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 51 +++-- .../BulletSPlugin/BSLinksetCompound.cs | 4 +- .../BulletSPlugin/BSLinksetConstraints.cs | 191 ++++++++++++------ 3 files changed, 167 insertions(+), 79 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 7f946662ad..9613fe05e9 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -70,6 +70,15 @@ public abstract class BSLinkset return ret; } + public class BSLinkInfo + { + public BSPrimLinkable member; + public BSLinkInfo(BSPrimLinkable pMember) + { + member = pMember; + } + } + public BSPrimLinkable LinksetRoot { get; protected set; } protected BSScene m_physicsScene { get; private set; } @@ -78,7 +87,8 @@ public abstract class BSLinkset public int LinksetID { get; private set; } // The children under the root in this linkset. - protected HashSet m_children; + // protected HashSet m_children; + protected Dictionary m_children; // We lock the diddling of linkset classes to prevent any badness. // This locks the modification of the instances of this class. Changes @@ -109,7 +119,7 @@ public abstract class BSLinkset m_nextLinksetID = 1; m_physicsScene = scene; LinksetRoot = parent; - m_children = new HashSet(); + m_children = new Dictionary(); LinksetMass = parent.RawMass; Rebuilding = false; @@ -170,17 +180,7 @@ public abstract class BSLinkset bool ret = false; lock (m_linksetActivityLock) { - ret = m_children.Contains(child); - /* Safer version but the above should work - foreach (BSPrimLinkable bp in m_children) - { - if (child.LocalID == bp.LocalID) - { - ret = true; - break; - } - } - */ + ret = m_children.ContainsKey(child); } return ret; } @@ -194,7 +194,24 @@ public abstract class BSLinkset lock (m_linksetActivityLock) { action(LinksetRoot); - foreach (BSPrimLinkable po in m_children) + foreach (BSPrimLinkable po in m_children.Keys) + { + if (action(po)) + break; + } + } + return ret; + } + + // Perform an action on each member of the linkset including root prim. + // Depends on the action on whether this should be done at taint time. + public delegate bool ForEachLinkInfoAction(BSLinkInfo obj); + public virtual bool ForEachLinkInfo(ForEachLinkInfoAction action) + { + bool ret = false; + lock (m_linksetActivityLock) + { + foreach (BSLinkInfo po in m_children.Values) { if (action(po)) break; @@ -364,7 +381,7 @@ public abstract class BSLinkset { lock (m_linksetActivityLock) { - foreach (BSPrimLinkable bp in m_children) + foreach (BSPrimLinkable bp in m_children.Keys) { mass += bp.RawMass; } @@ -382,7 +399,7 @@ public abstract class BSLinkset com = LinksetRoot.Position * LinksetRoot.RawMass; float totalMass = LinksetRoot.RawMass; - foreach (BSPrimLinkable bp in m_children) + foreach (BSPrimLinkable bp in m_children.Keys) { com += bp.Position * bp.RawMass; totalMass += bp.RawMass; @@ -401,7 +418,7 @@ public abstract class BSLinkset { com = LinksetRoot.Position; - foreach (BSPrimLinkable bp in m_children) + foreach (BSPrimLinkable bp in m_children.Keys) { com += bp.Position; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 6359046ca8..53c35846b7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -257,7 +257,7 @@ public sealed class BSLinksetCompound : BSLinkset { if (!HasChild(child)) { - m_children.Add(child); + m_children.Add(child, new BSLinkInfo(child)); DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); @@ -353,7 +353,7 @@ public sealed class BSLinksetCompound : BSLinkset // Add the shapes of all the components of the linkset int memberIndex = 1; - ForEachMember(delegate(BSPrimLinkable cPrim) + ForEachMember((cPrim) => { if (IsRoot(cPrim)) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index f17d698462..d98bf77342 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -36,6 +36,75 @@ public sealed class BSLinksetConstraints : BSLinkset { // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; + public class BSLinkInfoConstraint : BSLinkInfo + { + public ConstraintType constraintType; + public BSConstraint constraint; + public OMV.Vector3 linearLimitLow; + public OMV.Vector3 linearLimitHigh; + public OMV.Vector3 angularLimitLow; + public OMV.Vector3 angularLimitHigh; + public bool useFrameOffset; + public bool enableTransMotor; + public float transMotorMaxVel; + public float transMotorMaxForce; + public float cfm; + public float erp; + public float solverIterations; + + public BSLinkInfoConstraint(BSPrimLinkable pMember) + : base(pMember) + { + constraint = null; + ResetToFixedConstraint(); + } + + // Set all the parameters for this constraint to a fixed, non-movable constraint. + public void ResetToFixedConstraint() + { + constraintType = ConstraintType.D6_CONSTRAINT_TYPE; + linearLimitLow = OMV.Vector3.Zero; + linearLimitHigh = OMV.Vector3.Zero; + angularLimitLow = OMV.Vector3.Zero; + angularLimitHigh = OMV.Vector3.Zero; + useFrameOffset = BSParam.LinkConstraintUseFrameOffset; + enableTransMotor = BSParam.LinkConstraintEnableTransMotor; + transMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel; + transMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce; + cfm = BSParam.LinkConstraintCFM; + erp = BSParam.LinkConstraintERP; + solverIterations = BSParam.LinkConstraintSolverIterations; + } + + // Given a constraint, apply the current constraint parameters to same. + public void SetConstraintParameters(BSConstraint constrain) + { + switch (constraintType) + { + case ConstraintType.D6_CONSTRAINT_TYPE: + BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; + if (constrain6dof != null) + { + // zero linear and angular limits makes the objects unable to move in relation to each other + constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh); + constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh); + + // tweek the constraint to increase stability + constrain6dof.UseFrameOffset(useFrameOffset); + constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce); + constrain6dof.SetCFMAndERP(cfm, erp); + if (solverIterations != 0f) + { + constrain6dof.SetSolverIterations(solverIterations); + } + } + break; + default: + break; + } + } + } + public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) { } @@ -142,7 +211,7 @@ public sealed class BSLinksetConstraints : BSLinkset { if (!HasChild(child)) { - m_children.Add(child); + m_children.Add(child, new BSLinkInfoConstraint(child)); DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); @@ -190,73 +259,74 @@ public sealed class BSLinksetConstraints : BSLinkset } // Create a static constraint between the two passed objects - private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) + private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li) { + BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint; + if (liConstraint == null) + return null; + // Zero motion for children so they don't interpolate - childPrim.ZeroMotion(true); + li.member.ZeroMotion(true); - // Relative position normalized to the root prim - // Essentually a vector pointing from center of rootPrim to center of childPrim - OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position; + BSConstraint constrain = null; - // real world coordinate of midpoint between the two objects - OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); + switch (liConstraint.constraintType) + { + case ConstraintType.D6_CONSTRAINT_TYPE: + // Relative position normalized to the root prim + // Essentually a vector pointing from center of rootPrim to center of li.member + OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position; - DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", - rootPrim.LocalID, - rootPrim.LocalID, rootPrim.PhysBody.AddrString, - childPrim.LocalID, childPrim.PhysBody.AddrString, - rootPrim.Position, childPrim.Position, midPoint); + // real world coordinate of midpoint between the two objects + OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); - // create a constraint that allows no freedom of movement between the two objects - // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 + DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", + rootPrim.LocalID, + rootPrim.LocalID, rootPrim.PhysBody.AddrString, + liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString, + rootPrim.Position, liConstraint.member.Position, midPoint); - BSConstraint6Dof constrain = new BSConstraint6Dof( - m_physicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true ); - // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true ); + // create a constraint that allows no freedom of movement between the two objects + // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 - /* NOTE: below is an attempt to build constraint with full frame computation, etc. - * Using the midpoint is easier since it lets the Bullet code manipulate the transforms - * of the objects. - * Code left for future programmers. - // ================================================================================== - // relative position normalized to the root prim - OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); - OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation; + constrain = new BSConstraint6Dof( + m_physicsScene.World, rootPrim.PhysBody, liConstraint.member.PhysBody, midPoint, true, true ); - // relative rotation of the child to the parent - OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; - OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); + /* NOTE: below is an attempt to build constraint with full frame computation, etc. + * Using the midpoint is easier since it lets the Bullet code manipulate the transforms + * of the objects. + * Code left for future programmers. + // ================================================================================== + // relative position normalized to the root prim + OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); + OMV.Vector3 childRelativePosition = (liConstraint.member.Position - rootPrim.Position) * invThisOrientation; - DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); - BS6DofConstraint constrain = new BS6DofConstraint( - PhysicsScene.World, rootPrim.Body, childPrim.Body, - OMV.Vector3.Zero, - OMV.Quaternion.Inverse(rootPrim.Orientation), - OMV.Vector3.Zero, - OMV.Quaternion.Inverse(childPrim.Orientation), - true, - true - ); - // ================================================================================== - */ + // relative rotation of the child to the parent + OMV.Quaternion childRelativeRotation = invThisOrientation * liConstraint.member.Orientation; + OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation); + + DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, liConstraint.member.LocalID); + constrain = new BS6DofConstraint( + PhysicsScene.World, rootPrim.Body, liConstraint.member.Body, + OMV.Vector3.Zero, + OMV.Quaternion.Inverse(rootPrim.Orientation), + OMV.Vector3.Zero, + OMV.Quaternion.Inverse(liConstraint.member.Orientation), + true, + true + ); + // ================================================================================== + */ + + break; + default: + break; + } + + liConstraint.SetConstraintParameters(constrain); m_physicsScene.Constraints.AddConstraint(constrain); - // zero linear and angular limits makes the objects unable to move in relation to each other - constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); - constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); - - // tweek the constraint to increase stability - constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset); - constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor, - BSParam.LinkConstraintTransMotorMaxVel, - BSParam.LinkConstraintTransMotorMaxForce); - constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP); - if (BSParam.LinkConstraintSolverIterations != 0f) - { - constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); - } return constrain; } @@ -317,23 +387,24 @@ public sealed class BSLinksetConstraints : BSLinkset return; // Note the 'finally' clause at the botton which will get executed. } - foreach (BSPrimLinkable child in m_children) + ForEachLinkInfo((li) => { // A child in the linkset physically shows the mass of the whole linkset. // This allows Bullet to apply enough force on the child to move the whole linkset. // (Also do the mass stuff before recomputing the constraint so mass is not zero.) - child.UpdatePhysicalMassProperties(linksetMass, true); + li.member.UpdatePhysicalMassProperties(linksetMass, true); BSConstraint constrain; - if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) + if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, li.member.PhysBody, out constrain)) { // If constraint doesn't exist yet, create it. - constrain = BuildConstraint(LinksetRoot, child); + constrain = BuildConstraint(LinksetRoot, li); } constrain.RecomputeConstraintVariables(linksetMass); // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG - } + return false; // 'false' says to keep processing other members + }); } finally { From 24df15dab7befd50f7a45eb54f001e6e481f0ec4 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 1 Aug 2013 17:43:06 -0700 Subject: [PATCH 3/5] BulletSim: add implementation of 'physSetLinksetType' and 'physGetLinksetType' and processing routines in BulletSim. Add linkset rebuild/conversion routine in BSLinkset. --- .../ExtendedPhysics/ExtendedPhysics.cs | 65 +++++++++++++++++-- .../Region/Physics/BulletSPlugin/BSLinkset.cs | 2 + .../BulletSPlugin/BSLinksetCompound.cs | 1 + .../BulletSPlugin/BSLinksetConstraints.cs | 1 + .../Region/Physics/BulletSPlugin/BSPrim.cs | 44 +++++++++++++ .../Physics/BulletSPlugin/BSPrimLinkable.cs | 30 +++++++++ .../Region/Physics/BulletSPlugin/BSScene.cs | 17 +++++ .../Region/Physics/Manager/PhysicsActor.cs | 3 +- .../Region/Physics/Manager/PhysicsScene.cs | 3 +- 9 files changed, 159 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs index 0cbc5f9e76..d1d318c562 100755 --- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs @@ -49,10 +49,20 @@ public class ExtendedPhysics : INonSharedRegionModule private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static string LogHeader = "[EXTENDED PHYSICS]"; + // ============================================================= // 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"; + // ============================================================= + private IConfig Configuration { get; set; } private bool Enabled { get; set; } private Scene BaseScene { get; set; } @@ -123,6 +133,7 @@ public class ExtendedPhysics : INonSharedRegionModule // Register as LSL functions all the [ScriptInvocation] marked methods. Comms.RegisterScriptInvocations(this); + Comms.RegisterConstants(this); // When an object is modified, we might need to update its extended physics parameters BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; @@ -136,7 +147,6 @@ public class ExtendedPhysics : INonSharedRegionModule private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) { - throw new NotImplementedException(); } // 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; [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. SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); @@ -186,7 +198,7 @@ public class ExtendedPhysics : INonSharedRegionModule Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; if (rootPhysActor != null) { - rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); + ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); } else { @@ -204,6 +216,49 @@ public class ExtendedPhysics : INonSharedRegionModule { 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; } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 9613fe05e9..3afd52e142 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -79,6 +79,8 @@ public abstract class BSLinkset } } + public LinksetImplementation LinksetImpl { get; protected set; } + public BSPrimLinkable LinksetRoot { get; protected set; } protected BSScene m_physicsScene { get; private set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 53c35846b7..085d195d83 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -42,6 +42,7 @@ public sealed class BSLinksetCompound : BSLinkset public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) : base(scene, parent) { + LinksetImpl = LinksetImplementation.Compound; } // ================================================================ diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index d98bf77342..4bac222ab2 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -107,6 +107,7 @@ public sealed class BSLinksetConstraints : BSLinkset public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) { + LinksetImpl = LinksetImplementation.Constraint; } // When physical properties are changed the linkset needs to recalculate diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index e92a1d2bc5..a0b6abc01f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1541,6 +1541,50 @@ public class BSPrim : BSPhysObject 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 world that things have changed. // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 2f392da971..c565998086 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -233,5 +233,35 @@ public class BSPrimLinkable : BSPrimDisplaced 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; + } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 41aca3b2a7..79ac5a5ba0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -862,6 +862,23 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters 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 // The simulation execution order is: // Simulate() diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 2500f27ede..1750853aeb 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -317,7 +317,8 @@ namespace OpenSim.Region.Physics.Manager // Extendable interface for new, physics engine specific operations 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; } } diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 07a1d36f6f..c93206d09d 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -338,7 +338,8 @@ namespace OpenSim.Region.Physics.Manager // Extendable interface for new, physics engine specific operations 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; } } } From 5bdfd55ace4b673d8aaa3f25fd4bb675b1b28263 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 2 Aug 2013 10:32:43 -0700 Subject: [PATCH 4/5] BulletSim: When converting linkset types, don't try to change the list of linkset children while iterating through the list. --- .../Physics/BulletSPlugin/BSPrimLinkable.cs | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index c565998086..7179a6d571 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -240,26 +240,37 @@ public class BSPrimLinkable : BSPrimDisplaced bool ret = false; if (LinksetType != newType) { - BSLinkset oldLinkset = Linkset; + // Set the implementation type first so the call to BSLinkset.Factory gets the new type. + this.LinksetType = newType; + + BSLinkset oldLinkset = this.Linkset; BSLinkset newLinkset = BSLinkset.Factory(PhysScene, this); + this.Linkset = newLinkset; + // 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) => + // Create a list of the children (mainly because can't interate through a list that's changing) + List children = new List(); + oldLinkset.ForEachMember((child) => { - oldLinkset.RemoveMeFromLinkset(li.member); - newLinkset.AddMeToLinkset(li.member); - li.member.Linkset = newLinkset; - return false; + if (!oldLinkset.IsRoot(child)) + children.Add(child); + return false; // 'false' says to continue to next member }); - this.Linkset = newLinkset; + // Remove the children from the old linkset and add to the new (will be a new instance from the factory) + foreach (BSPrimLinkable child in children) + { + oldLinkset.RemoveMeFromLinkset(child); + newLinkset.AddMeToLinkset(child); + child.Linkset = newLinkset; + } // Force the shape and linkset to get reconstructed newLinkset.Refresh(this); - this.ForceBodyShapeRebuild(true); + this.ForceBodyShapeRebuild(true /* inTaintTime */); } return ret; } From 54b1071556edf264835f990bb3595064d2b2e2f0 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 2 Aug 2013 23:12:54 +0100 Subject: [PATCH 5/5] Allow older teleport ConnectorProtocolVersion of "SIMULATION/0.1" to be manually forced in a new [SimulationService] config setting. This is for testing and debugging purposes to help determine whether a particular issue may be teleport related or not "SIMULATION/0.2" (the newer teleport protocol) remains the default. If the source simulator only implements "SIMULATION/0.1" this will correctly allow fallback to the older protocol. Specifying "SIMULATION/0.1" will force the older, less efficient protocol to always be used. --- .../Simulation/LocalSimulationConnector.cs | 33 +++++++++++-------- .../Simulation/RemoteSimulationConnector.cs | 21 +++++------- bin/config-include/Grid.ini | 11 +++++++ bin/config-include/Standalone.ini | 11 +++++++ 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 697ce682c5..7aadb87b87 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -63,35 +63,40 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation /// private bool m_ModuleEnabled = false; - public LocalSimulationConnectorModule() - { - ServiceVersion = "SIMULATION/0.2"; - } - #region Region Module interface - public void Initialise(IConfigSource config) + public void Initialise(IConfigSource configSource) { - IConfig moduleConfig = config.Configs["Modules"]; + IConfig moduleConfig = configSource.Configs["Modules"]; if (moduleConfig != null) { string name = moduleConfig.GetString("SimulationServices", ""); if (name == Name) { - //IConfig userConfig = config.Configs["SimulationService"]; - //if (userConfig == null) - //{ - // m_log.Error("[AVATAR CONNECTOR]: SimulationService missing from OpenSim.ini"); - // return; - //} + InitialiseService(configSource); m_ModuleEnabled = true; - m_log.Info("[SIMULATION CONNECTOR]: Local simulation enabled"); + m_log.Info("[LOCAL SIMULATION CONNECTOR]: Local simulation enabled."); } } } + public void InitialiseService(IConfigSource configSource) + { + IConfig config = configSource.Configs["SimulationService"]; + if (config != null) + { + ServiceVersion = config.GetString("ConnectorProtocolVersion", "SIMULATION/0.2"); + + if (ServiceVersion != "SIMULATION/0.1" && ServiceVersion != "SIMULATION/0.2") + throw new Exception(string.Format("Invalid ConnectorProtocolVersion {0}", ServiceVersion)); + + m_log.InfoFormat( + "[LOCAL SIMULATION CONNECTOR]: Initialzied with connector protocol version {0}", ServiceVersion); + } + } + public void PostInitialise() { } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 8722b80ced..f45f560a96 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -50,9 +50,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteSimulationConnectorModule")] public class RemoteSimulationConnectorModule : ISharedRegionModule, ISimulationService { - private bool initialized = false; private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private bool initialized = false; protected bool m_enabled = false; protected Scene m_aScene; // RemoteSimulationConnector does not care about local regions; it delegates that to the Local module @@ -64,27 +64,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation #region Region Module interface - public virtual void Initialise(IConfigSource config) + public virtual void Initialise(IConfigSource configSource) { - - IConfig moduleConfig = config.Configs["Modules"]; + IConfig moduleConfig = configSource.Configs["Modules"]; if (moduleConfig != null) { string name = moduleConfig.GetString("SimulationServices", ""); if (name == Name) { - //IConfig userConfig = config.Configs["SimulationService"]; - //if (userConfig == null) - //{ - // m_log.Error("[AVATAR CONNECTOR]: SimulationService missing from OpenSim.ini"); - // return; - //} + m_localBackend = new LocalSimulationConnectorModule(); + + m_localBackend.InitialiseService(configSource); m_remoteConnector = new SimulationServiceConnector(); m_enabled = true; - m_log.Info("[SIMULATION CONNECTOR]: Remote simulation enabled"); + m_log.Info("[REMOTE SIMULATION CONNECTOR]: Remote simulation enabled."); } } } @@ -142,8 +138,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation } protected virtual void InitOnce(Scene scene) - { - m_localBackend = new LocalSimulationConnectorModule(); + { m_aScene = scene; //m_regionClient = new RegionToRegionClient(m_aScene, m_hyperlinkService); m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName); diff --git a/bin/config-include/Grid.ini b/bin/config-include/Grid.ini index 15ba55a27f..1837bdd752 100644 --- a/bin/config-include/Grid.ini +++ b/bin/config-include/Grid.ini @@ -30,6 +30,17 @@ SimulationServiceInConnector = true LibraryModule = true +[SimulationService] + ; This is the protocol version which the simulator advertises to the source destination when acting as a target destination for a teleport + ; It is used to control the teleport handoff process. + ; Valid values are + ; "SIMULATION/0.2" + ; - this is the default. A source simulator which only implements "SIMULATION/0.1" can still teleport with that protocol + ; - this protocol is more efficient than "SIMULATION/0.1" + ; "SIMULATION/0.1" + ; - this is an older teleport protocol used in OpenSimulator 0.7.5 and before. + ConnectorProtocolVersion = "SIMULATION/0.2" + [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService" diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index d3b9cb4c85..7b7beb2cf0 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -26,6 +26,17 @@ GridInfoServiceInConnector = true MapImageServiceInConnector = true +[SimulationService] + ; This is the protocol version which the simulator advertises to the source destination when acting as a target destination for a teleport + ; It is used to control the teleport handoff process. + ; Valid values are + ; "SIMULATION/0.2" + ; - this is the default. A source simulator which only implements "SIMULATION/0.1" can still teleport with that protocol + ; - this protocol is more efficient than "SIMULATION/0.1" + ; "SIMULATION/0.1" + ; - this is an older teleport protocol used in OpenSimulator 0.7.5 and before. + ConnectorProtocolVersion = "SIMULATION/0.2" + [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService"