diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin')
6 files changed, 280 insertions, 86 deletions
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() |