aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-08-02 23:16:41 +0100
committerJustin Clark-Casey (justincc)2013-08-02 23:17:20 +0100
commit4ff3757f86dc8727a861d43b639d9b2341be9108 (patch)
tree00730c20dd9f5f2dc7bf12379425701bc3dcdfd1
parentAllow older teleport ConnectorProtocolVersion of "SIMULATION/0.1" to be manua... (diff)
parentBulletSim: When converting linkset types, don't try to change the list (diff)
downloadopensim-SC_OLD-4ff3757f86dc8727a861d43b639d9b2341be9108.zip
opensim-SC_OLD-4ff3757f86dc8727a861d43b639d9b2341be9108.tar.gz
opensim-SC_OLD-4ff3757f86dc8727a861d43b639d9b2341be9108.tar.bz2
opensim-SC_OLD-4ff3757f86dc8727a861d43b639d9b2341be9108.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs6
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs65
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs53
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs5
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs206
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs44
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs41
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs17
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs3
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs2
12 files changed, 353 insertions, 96 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 17da0d9..456c8cc 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1568,8 +1568,14 @@ namespace OpenSim.Region.Framework.Scenes
1568 // Here's where you get them. 1568 // Here's where you get them.
1569 m_AgentControlFlags = flags; 1569 m_AgentControlFlags = flags;
1570 m_headrotation = agentData.HeadRotation; 1570 m_headrotation = agentData.HeadRotation;
1571 byte oldState = State;
1571 State = agentData.State; 1572 State = agentData.State;
1572 1573
1574 // We need to send this back to the client in order to stop the edit beams
1575 if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
1576 ControllingClient.SendAgentTerseUpdate(this);
1577
1578
1573 PhysicsActor actor = PhysicsActor; 1579 PhysicsActor actor = PhysicsActor;
1574 if (actor == null) 1580 if (actor == null)
1575 { 1581 {
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
index 0cbc5f9..d1d318c 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
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 private static string LogHeader = "[EXTENDED PHYSICS]"; 50 private static string LogHeader = "[EXTENDED PHYSICS]";
51 51
52 // =============================================================
52 // Since BulletSim is a plugin, this these values aren't defined easily in one place. 53 // Since BulletSim is a plugin, this these values aren't defined easily in one place.
53 // This table must coorespond to an identical table in BSScene. 54 // This table must correspond to an identical table in BSScene.
55
56 // Per scene functions. See BSScene.
57
58 // Per avatar functions. See BSCharacter.
59
60 // Per prim functions. See BSPrim.
61 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
54 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType"; 62 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
55 63
64 // =============================================================
65
56 private IConfig Configuration { get; set; } 66 private IConfig Configuration { get; set; }
57 private bool Enabled { get; set; } 67 private bool Enabled { get; set; }
58 private Scene BaseScene { get; set; } 68 private Scene BaseScene { get; set; }
@@ -123,6 +133,7 @@ public class ExtendedPhysics : INonSharedRegionModule
123 133
124 // Register as LSL functions all the [ScriptInvocation] marked methods. 134 // Register as LSL functions all the [ScriptInvocation] marked methods.
125 Comms.RegisterScriptInvocations(this); 135 Comms.RegisterScriptInvocations(this);
136 Comms.RegisterConstants(this);
126 137
127 // When an object is modified, we might need to update its extended physics parameters 138 // When an object is modified, we might need to update its extended physics parameters
128 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; 139 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
@@ -136,7 +147,6 @@ public class ExtendedPhysics : INonSharedRegionModule
136 147
137 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) 148 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
138 { 149 {
139 throw new NotImplementedException();
140 } 150 }
141 151
142 // Event generated when some property of a prim changes. 152 // Event generated when some property of a prim changes.
@@ -168,9 +178,11 @@ public class ExtendedPhysics : INonSharedRegionModule
168 public static int PHYS_LINKSET_TYPE_MANUAL = 2; 178 public static int PHYS_LINKSET_TYPE_MANUAL = 2;
169 179
170 [ScriptInvocation] 180 [ScriptInvocation]
171 public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) 181 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
172 { 182 {
173 if (!Enabled) return; 183 int ret = -1;
184
185 if (!Enabled) return ret;
174 186
175 // The part that is requesting the change. 187 // The part that is requesting the change.
176 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); 188 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
@@ -186,7 +198,7 @@ public class ExtendedPhysics : INonSharedRegionModule
186 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor; 198 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
187 if (rootPhysActor != null) 199 if (rootPhysActor != null)
188 { 200 {
189 rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType); 201 ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType);
190 } 202 }
191 else 203 else
192 { 204 {
@@ -204,6 +216,49 @@ public class ExtendedPhysics : INonSharedRegionModule
204 { 216 {
205 m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); 217 m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
206 } 218 }
219 return ret;
220 }
221
222 [ScriptInvocation]
223 public int physGetLinksetType(UUID hostID, UUID scriptID)
224 {
225 int ret = -1;
226
227 if (!Enabled) return ret;
228
229 // The part that is requesting the change.
230 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
231
232 if (requestingPart != null)
233 {
234 // The type is is always on the root of a linkset.
235 SceneObjectGroup containingGroup = requestingPart.ParentGroup;
236 SceneObjectPart rootPart = containingGroup.RootPart;
237
238 if (rootPart != null)
239 {
240 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
241 if (rootPhysActor != null)
242 {
243 ret = (int)rootPhysActor.Extension(PhysFunctGetLinksetType);
244 }
245 else
246 {
247 m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
248 LogHeader, rootPart.Name, hostID);
249 }
250 }
251 else
252 {
253 m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
254 LogHeader, requestingPart.Name, hostID);
255 }
256 }
257 else
258 {
259 m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
260 }
261 return ret;
207 } 262 }
208} 263}
209} 264}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 7f94666..3afd52e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -70,6 +70,17 @@ public abstract class BSLinkset
70 return ret; 70 return ret;
71 } 71 }
72 72
73 public class BSLinkInfo
74 {
75 public BSPrimLinkable member;
76 public BSLinkInfo(BSPrimLinkable pMember)
77 {
78 member = pMember;
79 }
80 }
81
82 public LinksetImplementation LinksetImpl { get; protected set; }
83
73 public BSPrimLinkable LinksetRoot { get; protected set; } 84 public BSPrimLinkable LinksetRoot { get; protected set; }
74 85
75 protected BSScene m_physicsScene { get; private set; } 86 protected BSScene m_physicsScene { get; private set; }
@@ -78,7 +89,8 @@ public abstract class BSLinkset
78 public int LinksetID { get; private set; } 89 public int LinksetID { get; private set; }
79 90
80 // The children under the root in this linkset. 91 // The children under the root in this linkset.
81 protected HashSet<BSPrimLinkable> m_children; 92 // protected HashSet<BSPrimLinkable> m_children;
93 protected Dictionary<BSPrimLinkable, BSLinkInfo> m_children;
82 94
83 // We lock the diddling of linkset classes to prevent any badness. 95 // We lock the diddling of linkset classes to prevent any badness.
84 // This locks the modification of the instances of this class. Changes 96 // This locks the modification of the instances of this class. Changes
@@ -109,7 +121,7 @@ public abstract class BSLinkset
109 m_nextLinksetID = 1; 121 m_nextLinksetID = 1;
110 m_physicsScene = scene; 122 m_physicsScene = scene;
111 LinksetRoot = parent; 123 LinksetRoot = parent;
112 m_children = new HashSet<BSPrimLinkable>(); 124 m_children = new Dictionary<BSPrimLinkable, BSLinkInfo>();
113 LinksetMass = parent.RawMass; 125 LinksetMass = parent.RawMass;
114 Rebuilding = false; 126 Rebuilding = false;
115 127
@@ -170,17 +182,7 @@ public abstract class BSLinkset
170 bool ret = false; 182 bool ret = false;
171 lock (m_linksetActivityLock) 183 lock (m_linksetActivityLock)
172 { 184 {
173 ret = m_children.Contains(child); 185 ret = m_children.ContainsKey(child);
174 /* Safer version but the above should work
175 foreach (BSPrimLinkable bp in m_children)
176 {
177 if (child.LocalID == bp.LocalID)
178 {
179 ret = true;
180 break;
181 }
182 }
183 */
184 } 186 }
185 return ret; 187 return ret;
186 } 188 }
@@ -194,7 +196,24 @@ public abstract class BSLinkset
194 lock (m_linksetActivityLock) 196 lock (m_linksetActivityLock)
195 { 197 {
196 action(LinksetRoot); 198 action(LinksetRoot);
197 foreach (BSPrimLinkable po in m_children) 199 foreach (BSPrimLinkable po in m_children.Keys)
200 {
201 if (action(po))
202 break;
203 }
204 }
205 return ret;
206 }
207
208 // Perform an action on each member of the linkset including root prim.
209 // Depends on the action on whether this should be done at taint time.
210 public delegate bool ForEachLinkInfoAction(BSLinkInfo obj);
211 public virtual bool ForEachLinkInfo(ForEachLinkInfoAction action)
212 {
213 bool ret = false;
214 lock (m_linksetActivityLock)
215 {
216 foreach (BSLinkInfo po in m_children.Values)
198 { 217 {
199 if (action(po)) 218 if (action(po))
200 break; 219 break;
@@ -364,7 +383,7 @@ public abstract class BSLinkset
364 { 383 {
365 lock (m_linksetActivityLock) 384 lock (m_linksetActivityLock)
366 { 385 {
367 foreach (BSPrimLinkable bp in m_children) 386 foreach (BSPrimLinkable bp in m_children.Keys)
368 { 387 {
369 mass += bp.RawMass; 388 mass += bp.RawMass;
370 } 389 }
@@ -382,7 +401,7 @@ public abstract class BSLinkset
382 com = LinksetRoot.Position * LinksetRoot.RawMass; 401 com = LinksetRoot.Position * LinksetRoot.RawMass;
383 float totalMass = LinksetRoot.RawMass; 402 float totalMass = LinksetRoot.RawMass;
384 403
385 foreach (BSPrimLinkable bp in m_children) 404 foreach (BSPrimLinkable bp in m_children.Keys)
386 { 405 {
387 com += bp.Position * bp.RawMass; 406 com += bp.Position * bp.RawMass;
388 totalMass += bp.RawMass; 407 totalMass += bp.RawMass;
@@ -401,7 +420,7 @@ public abstract class BSLinkset
401 { 420 {
402 com = LinksetRoot.Position; 421 com = LinksetRoot.Position;
403 422
404 foreach (BSPrimLinkable bp in m_children) 423 foreach (BSPrimLinkable bp in m_children.Keys)
405 { 424 {
406 com += bp.Position; 425 com += bp.Position;
407 } 426 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 6359046..085d195 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -42,6 +42,7 @@ public sealed class BSLinksetCompound : BSLinkset
42 public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) 42 public BSLinksetCompound(BSScene scene, BSPrimLinkable parent)
43 : base(scene, parent) 43 : base(scene, parent)
44 { 44 {
45 LinksetImpl = LinksetImplementation.Compound;
45 } 46 }
46 47
47 // ================================================================ 48 // ================================================================
@@ -257,7 +258,7 @@ public sealed class BSLinksetCompound : BSLinkset
257 { 258 {
258 if (!HasChild(child)) 259 if (!HasChild(child))
259 { 260 {
260 m_children.Add(child); 261 m_children.Add(child, new BSLinkInfo(child));
261 262
262 DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 263 DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
263 264
@@ -353,7 +354,7 @@ public sealed class BSLinksetCompound : BSLinkset
353 354
354 // Add the shapes of all the components of the linkset 355 // Add the shapes of all the components of the linkset
355 int memberIndex = 1; 356 int memberIndex = 1;
356 ForEachMember(delegate(BSPrimLinkable cPrim) 357 ForEachMember((cPrim) =>
357 { 358 {
358 if (IsRoot(cPrim)) 359 if (IsRoot(cPrim))
359 { 360 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index f17d698..4bac222 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -36,8 +36,78 @@ public sealed class BSLinksetConstraints : BSLinkset
36{ 36{
37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; 37 // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
38 38
39 public class BSLinkInfoConstraint : BSLinkInfo
40 {
41 public ConstraintType constraintType;
42 public BSConstraint constraint;
43 public OMV.Vector3 linearLimitLow;
44 public OMV.Vector3 linearLimitHigh;
45 public OMV.Vector3 angularLimitLow;
46 public OMV.Vector3 angularLimitHigh;
47 public bool useFrameOffset;
48 public bool enableTransMotor;
49 public float transMotorMaxVel;
50 public float transMotorMaxForce;
51 public float cfm;
52 public float erp;
53 public float solverIterations;
54
55 public BSLinkInfoConstraint(BSPrimLinkable pMember)
56 : base(pMember)
57 {
58 constraint = null;
59 ResetToFixedConstraint();
60 }
61
62 // Set all the parameters for this constraint to a fixed, non-movable constraint.
63 public void ResetToFixedConstraint()
64 {
65 constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
66 linearLimitLow = OMV.Vector3.Zero;
67 linearLimitHigh = OMV.Vector3.Zero;
68 angularLimitLow = OMV.Vector3.Zero;
69 angularLimitHigh = OMV.Vector3.Zero;
70 useFrameOffset = BSParam.LinkConstraintUseFrameOffset;
71 enableTransMotor = BSParam.LinkConstraintEnableTransMotor;
72 transMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel;
73 transMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce;
74 cfm = BSParam.LinkConstraintCFM;
75 erp = BSParam.LinkConstraintERP;
76 solverIterations = BSParam.LinkConstraintSolverIterations;
77 }
78
79 // Given a constraint, apply the current constraint parameters to same.
80 public void SetConstraintParameters(BSConstraint constrain)
81 {
82 switch (constraintType)
83 {
84 case ConstraintType.D6_CONSTRAINT_TYPE:
85 BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof;
86 if (constrain6dof != null)
87 {
88 // zero linear and angular limits makes the objects unable to move in relation to each other
89 constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh);
90 constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh);
91
92 // tweek the constraint to increase stability
93 constrain6dof.UseFrameOffset(useFrameOffset);
94 constrain6dof.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce);
95 constrain6dof.SetCFMAndERP(cfm, erp);
96 if (solverIterations != 0f)
97 {
98 constrain6dof.SetSolverIterations(solverIterations);
99 }
100 }
101 break;
102 default:
103 break;
104 }
105 }
106 }
107
39 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) 108 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
40 { 109 {
110 LinksetImpl = LinksetImplementation.Constraint;
41 } 111 }
42 112
43 // When physical properties are changed the linkset needs to recalculate 113 // When physical properties are changed the linkset needs to recalculate
@@ -142,7 +212,7 @@ public sealed class BSLinksetConstraints : BSLinkset
142 { 212 {
143 if (!HasChild(child)) 213 if (!HasChild(child))
144 { 214 {
145 m_children.Add(child); 215 m_children.Add(child, new BSLinkInfoConstraint(child));
146 216
147 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 217 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
148 218
@@ -190,73 +260,74 @@ public sealed class BSLinksetConstraints : BSLinkset
190 } 260 }
191 261
192 // Create a static constraint between the two passed objects 262 // Create a static constraint between the two passed objects
193 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim) 263 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li)
194 { 264 {
265 BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint;
266 if (liConstraint == null)
267 return null;
268
195 // Zero motion for children so they don't interpolate 269 // Zero motion for children so they don't interpolate
196 childPrim.ZeroMotion(true); 270 li.member.ZeroMotion(true);
197
198 // Relative position normalized to the root prim
199 // Essentually a vector pointing from center of rootPrim to center of childPrim
200 OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position;
201
202 // real world coordinate of midpoint between the two objects
203 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
204
205 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
206 rootPrim.LocalID,
207 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
208 childPrim.LocalID, childPrim.PhysBody.AddrString,
209 rootPrim.Position, childPrim.Position, midPoint);
210
211 // create a constraint that allows no freedom of movement between the two objects
212 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
213
214 BSConstraint6Dof constrain = new BSConstraint6Dof(
215 m_physicsScene.World, rootPrim.PhysBody, childPrim.PhysBody, midPoint, true, true );
216 // PhysicsScene.World, childPrim.BSBody, rootPrim.BSBody, midPoint, true, true );
217
218 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
219 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
220 * of the objects.
221 * Code left for future programmers.
222 // ==================================================================================
223 // relative position normalized to the root prim
224 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
225 OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation;
226
227 // relative rotation of the child to the parent
228 OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
229 OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation);
230
231 DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
232 BS6DofConstraint constrain = new BS6DofConstraint(
233 PhysicsScene.World, rootPrim.Body, childPrim.Body,
234 OMV.Vector3.Zero,
235 OMV.Quaternion.Inverse(rootPrim.Orientation),
236 OMV.Vector3.Zero,
237 OMV.Quaternion.Inverse(childPrim.Orientation),
238 true,
239 true
240 );
241 // ==================================================================================
242 */
243 271
244 m_physicsScene.Constraints.AddConstraint(constrain); 272 BSConstraint constrain = null;
245 273
246 // zero linear and angular limits makes the objects unable to move in relation to each other 274 switch (liConstraint.constraintType)
247 constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
248 constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
249
250 // tweek the constraint to increase stability
251 constrain.UseFrameOffset(BSParam.LinkConstraintUseFrameOffset);
252 constrain.TranslationalLimitMotor(BSParam.LinkConstraintEnableTransMotor,
253 BSParam.LinkConstraintTransMotorMaxVel,
254 BSParam.LinkConstraintTransMotorMaxForce);
255 constrain.SetCFMAndERP(BSParam.LinkConstraintCFM, BSParam.LinkConstraintERP);
256 if (BSParam.LinkConstraintSolverIterations != 0f)
257 { 275 {
258 constrain.SetSolverIterations(BSParam.LinkConstraintSolverIterations); 276 case ConstraintType.D6_CONSTRAINT_TYPE:
277 // Relative position normalized to the root prim
278 // Essentually a vector pointing from center of rootPrim to center of li.member
279 OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position;
280
281 // real world coordinate of midpoint between the two objects
282 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
283
284 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
285 rootPrim.LocalID,
286 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
287 liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString,
288 rootPrim.Position, liConstraint.member.Position, midPoint);
289
290 // create a constraint that allows no freedom of movement between the two objects
291 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
292
293 constrain = new BSConstraint6Dof(
294 m_physicsScene.World, rootPrim.PhysBody, liConstraint.member.PhysBody, midPoint, true, true );
295
296 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
297 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
298 * of the objects.
299 * Code left for future programmers.
300 // ==================================================================================
301 // relative position normalized to the root prim
302 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
303 OMV.Vector3 childRelativePosition = (liConstraint.member.Position - rootPrim.Position) * invThisOrientation;
304
305 // relative rotation of the child to the parent
306 OMV.Quaternion childRelativeRotation = invThisOrientation * liConstraint.member.Orientation;
307 OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation);
308
309 DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, liConstraint.member.LocalID);
310 constrain = new BS6DofConstraint(
311 PhysicsScene.World, rootPrim.Body, liConstraint.member.Body,
312 OMV.Vector3.Zero,
313 OMV.Quaternion.Inverse(rootPrim.Orientation),
314 OMV.Vector3.Zero,
315 OMV.Quaternion.Inverse(liConstraint.member.Orientation),
316 true,
317 true
318 );
319 // ==================================================================================
320 */
321
322 break;
323 default:
324 break;
259 } 325 }
326
327 liConstraint.SetConstraintParameters(constrain);
328
329 m_physicsScene.Constraints.AddConstraint(constrain);
330
260 return constrain; 331 return constrain;
261 } 332 }
262 333
@@ -317,23 +388,24 @@ public sealed class BSLinksetConstraints : BSLinkset
317 return; // Note the 'finally' clause at the botton which will get executed. 388 return; // Note the 'finally' clause at the botton which will get executed.
318 } 389 }
319 390
320 foreach (BSPrimLinkable child in m_children) 391 ForEachLinkInfo((li) =>
321 { 392 {
322 // A child in the linkset physically shows the mass of the whole linkset. 393 // A child in the linkset physically shows the mass of the whole linkset.
323 // This allows Bullet to apply enough force on the child to move the whole linkset. 394 // This allows Bullet to apply enough force on the child to move the whole linkset.
324 // (Also do the mass stuff before recomputing the constraint so mass is not zero.) 395 // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
325 child.UpdatePhysicalMassProperties(linksetMass, true); 396 li.member.UpdatePhysicalMassProperties(linksetMass, true);
326 397
327 BSConstraint constrain; 398 BSConstraint constrain;
328 if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) 399 if (!m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, li.member.PhysBody, out constrain))
329 { 400 {
330 // If constraint doesn't exist yet, create it. 401 // If constraint doesn't exist yet, create it.
331 constrain = BuildConstraint(LinksetRoot, child); 402 constrain = BuildConstraint(LinksetRoot, li);
332 } 403 }
333 constrain.RecomputeConstraintVariables(linksetMass); 404 constrain.RecomputeConstraintVariables(linksetMass);
334 405
335 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG 406 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
336 } 407 return false; // 'false' says to keep processing other members
408 });
337 } 409 }
338 finally 410 finally
339 { 411 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index e92a1d2..a0b6abc 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -1541,6 +1541,50 @@ public class BSPrim : BSPhysObject
1541 PhysicalActors.RemoveDependencies(); 1541 PhysicalActors.RemoveDependencies();
1542 } 1542 }
1543 1543
1544 #region Extension
1545 public override object Extension(string pFunct, params object[] pParams)
1546 {
1547 object ret = null;
1548 switch (pFunct)
1549 {
1550 case BSScene.PhysFunctGetLinksetType:
1551 {
1552 BSPrimLinkable myHandle = this as BSPrimLinkable;
1553 if (myHandle != null)
1554 {
1555 ret = (object)myHandle.LinksetType;
1556 }
1557 m_log.DebugFormat("{0} Extension.physGetLinksetType, type={1}", LogHeader, ret);
1558 break;
1559 }
1560 case BSScene.PhysFunctSetLinksetType:
1561 {
1562 if (pParams.Length > 0)
1563 {
1564 BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[0];
1565 BSPrimLinkable myHandle = this as BSPrimLinkable;
1566 if (myHandle != null && myHandle.Linkset.IsRoot(myHandle))
1567 {
1568 PhysScene.TaintedObject("BSPrim.PhysFunctSetLinksetType", delegate()
1569 {
1570 // Cause the linkset type to change
1571 m_log.DebugFormat("{0} Extension.physSetLinksetType, oldType={1}, newType={2}",
1572 LogHeader, myHandle.Linkset.LinksetImpl, linksetType);
1573 myHandle.ConvertLinkset(linksetType);
1574 });
1575 }
1576 ret = (object)(int)linksetType;
1577 }
1578 break;
1579 }
1580 default:
1581 ret = base.Extension(pFunct, pParams);
1582 break;
1583 }
1584 return ret;
1585 }
1586 #endregion // Extension
1587
1544 // The physics engine says that properties have updated. Update same and inform 1588 // The physics engine says that properties have updated. Update same and inform
1545 // the world that things have changed. 1589 // the world that things have changed.
1546 // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims. 1590 // 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 2f392da..7179a6d 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
@@ -233,5 +233,46 @@ public class BSPrimLinkable : BSPrimDisplaced
233 base.HasSomeCollision = value; 233 base.HasSomeCollision = value;
234 } 234 }
235 } 235 }
236
237 // Convert the existing linkset of this prim into a new type.
238 public bool ConvertLinkset(BSLinkset.LinksetImplementation newType)
239 {
240 bool ret = false;
241 if (LinksetType != newType)
242 {
243 // Set the implementation type first so the call to BSLinkset.Factory gets the new type.
244 this.LinksetType = newType;
245
246 BSLinkset oldLinkset = this.Linkset;
247 BSLinkset newLinkset = BSLinkset.Factory(PhysScene, this);
248
249 this.Linkset = newLinkset;
250
251 // Pick up any physical dependencies this linkset might have in the physics engine.
252 oldLinkset.RemoveDependencies(this);
253
254 // Create a list of the children (mainly because can't interate through a list that's changing)
255 List<BSPrimLinkable> children = new List<BSPrimLinkable>();
256 oldLinkset.ForEachMember((child) =>
257 {
258 if (!oldLinkset.IsRoot(child))
259 children.Add(child);
260 return false; // 'false' says to continue to next member
261 });
262
263 // Remove the children from the old linkset and add to the new (will be a new instance from the factory)
264 foreach (BSPrimLinkable child in children)
265 {
266 oldLinkset.RemoveMeFromLinkset(child);
267 newLinkset.AddMeToLinkset(child);
268 child.Linkset = newLinkset;
269 }
270
271 // Force the shape and linkset to get reconstructed
272 newLinkset.Refresh(this);
273 this.ForceBodyShapeRebuild(true /* inTaintTime */);
274 }
275 return ret;
276 }
236} 277}
237} 278}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 41aca3b..79ac5a5 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
862 862
863 public override bool IsThreaded { get { return false; } } 863 public override bool IsThreaded { get { return false; } }
864 864
865 #region Extensions
866 // =============================================================
867 // Per scene functions. See below.
868
869 // Per avatar functions. See BSCharacter.
870
871 // Per prim functions. See BSPrim.
872 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
873 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
874 // =============================================================
875
876 public override object Extension(string pFunct, params object[] pParams)
877 {
878 return base.Extension(pFunct, pParams);
879 }
880 #endregion // Extensions
881
865 #region Taints 882 #region Taints
866 // The simulation execution order is: 883 // The simulation execution order is:
867 // Simulate() 884 // Simulate()
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 2500f27..1750853 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -317,7 +317,8 @@ namespace OpenSim.Region.Physics.Manager
317 // Extendable interface for new, physics engine specific operations 317 // Extendable interface for new, physics engine specific operations
318 public virtual object Extension(string pFunct, params object[] pParams) 318 public virtual object Extension(string pFunct, params object[] pParams)
319 { 319 {
320 throw new NotImplementedException(); 320 // A NOP of the physics engine does not implement this feature
321 return null;
321 } 322 }
322 } 323 }
323 324
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 07a1d36..c93206d 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -338,7 +338,8 @@ namespace OpenSim.Region.Physics.Manager
338 // Extendable interface for new, physics engine specific operations 338 // Extendable interface for new, physics engine specific operations
339 public virtual object Extension(string pFunct, params object[] pParams) 339 public virtual object Extension(string pFunct, params object[] pParams)
340 { 340 {
341 throw new NotImplementedException(); 341 // A NOP if the extension thing is not implemented by the physics engine
342 return null;
342 } 343 }
343 } 344 }
344} 345}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 21bae27..92dd813 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
319 319
320 object[] convertedParms = new object[parms.Length]; 320 object[] convertedParms = new object[parms.Length];
321 for (int i = 0; i < parms.Length; i++) 321 for (int i = 0; i < parms.Length; i++)
322 convertedParms[i] = ConvertFromLSL(parms[i],signature[i], fname); 322 convertedParms[i] = ConvertFromLSL(parms[i], signature[i], fname);
323 323
324 // now call the function, the contract with the function is that it will always return 324 // now call the function, the contract with the function is that it will always return
325 // non-null but don't trust it completely 325 // non-null but don't trust it completely
@@ -444,7 +444,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
444 } 444 }
445 } 445 }
446 446
447 MODError(String.Format("{1}: parameter type mismatch; expecting {0}",type.Name, fname)); 447 MODError(String.Format("{0}: parameter type mismatch; expecting {1}, type(parm)={2}", fname, type.Name, lslparm.GetType()));
448 return null; 448 return null;
449 } 449 }
450 450
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 9e32f40..6aa717d 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
937 { 937 {
938 string retval = null; 938 string retval = null;
939 if (value is int) 939 if (value is int)
940 retval = ((int)value).ToString(); 940 retval = String.Format("new LSL_Types.LSLInteger({0})",((int)value).ToString());
941 else if (value is float) 941 else if (value is float)
942 retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString()); 942 retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString());
943 else if (value is string) 943 else if (value is string)