aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRobert Adams2012-10-29 14:33:31 -0700
committerRobert Adams2012-11-03 21:14:41 -0700
commit93fe384cce42e91337f446fd658ef29ca3d9f733 (patch)
tree8ed885f7b33d929a73a8742063b5a7f9e32a98bb
parentBulletSim: Add gravity force to vehicle. Some debugging additions. (diff)
downloadopensim-SC-93fe384cce42e91337f446fd658ef29ca3d9f733.zip
opensim-SC-93fe384cce42e91337f446fd658ef29ca3d9f733.tar.gz
opensim-SC-93fe384cce42e91337f446fd658ef29ca3d9f733.tar.bz2
opensim-SC-93fe384cce42e91337f446fd658ef29ca3d9f733.tar.xz
BulletSim: Use the PostTaints operation to build the linkset once before the next simulation step. This eliminates the management of children vs taintChildren and simplifies the constratin creation code.
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs52
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs140
2 files changed, 68 insertions, 124 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 569d2e7..187951e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -61,16 +61,7 @@ public abstract class BSLinkset
61 public int LinksetID { get; private set; } 61 public int LinksetID { get; private set; }
62 62
63 // The children under the root in this linkset. 63 // The children under the root in this linkset.
64 // There are two lists of children: the current children at runtime
65 // and the children at taint-time. For instance, if you delink a
66 // child from the linkset, the child is removed from m_children
67 // but the constraint won't be removed until taint time.
68 // Two lists lets this track the 'current' children and
69 // the physical 'taint' children separately.
70 // After taint processing and before the simulation step, these
71 // two lists must be the same.
72 protected HashSet<BSPhysObject> m_children; 64 protected HashSet<BSPhysObject> m_children;
73 protected HashSet<BSPhysObject> m_taintChildren;
74 65
75 // We lock the diddling of linkset classes to prevent any badness. 66 // We lock the diddling of linkset classes to prevent any badness.
76 // This locks the modification of the instances of this class. Changes 67 // This locks the modification of the instances of this class. Changes
@@ -110,7 +101,6 @@ public abstract class BSLinkset
110 PhysicsScene = scene; 101 PhysicsScene = scene;
111 LinksetRoot = parent; 102 LinksetRoot = parent;
112 m_children = new HashSet<BSPhysObject>(); 103 m_children = new HashSet<BSPhysObject>();
113 m_taintChildren = new HashSet<BSPhysObject>();
114 m_mass = parent.MassRaw; 104 m_mass = parent.MassRaw;
115 } 105 }
116 106
@@ -192,7 +182,7 @@ public abstract class BSLinkset
192 lock (m_linksetActivityLock) 182 lock (m_linksetActivityLock)
193 { 183 {
194 action(LinksetRoot); 184 action(LinksetRoot);
195 foreach (BSPhysObject po in m_taintChildren) 185 foreach (BSPhysObject po in m_children)
196 { 186 {
197 if (action(po)) 187 if (action(po))
198 break; 188 break;
@@ -201,9 +191,24 @@ public abstract class BSLinkset
201 return ret; 191 return ret;
202 } 192 }
203 193
194 // I am the root of a linkset and a new child is being added
195 // Called while LinkActivity is locked.
196 protected abstract void AddChildToLinkset(BSPhysObject child);
197
198 // Forcefully removing a child from a linkset.
199 // This is not being called by the child so we have to make sure the child doesn't think
200 // it's still connected to the linkset.
201 // Normal OpenSimulator operation will never do this because other SceneObjectPart information
202 // also has to be updated (like pointer to prim's parent).
203 protected abstract void RemoveChildFromOtherLinkset(BSPhysObject pchild);
204
205 // I am the root of a linkset and one of my children is being removed.
206 // Safe to call even if the child is not really in my linkset.
207 protected abstract void RemoveChildFromLinkset(BSPhysObject child);
208
204 // When physical properties are changed the linkset needs to recalculate 209 // When physical properties are changed the linkset needs to recalculate
205 // its internal properties. 210 // its internal properties.
206 // May be called at runtime or taint-time (just pass the appropriate flag). 211 // May be called at runtime or taint-time.
207 public abstract void Refresh(BSPhysObject requestor); 212 public abstract void Refresh(BSPhysObject requestor);
208 213
209 // The object is going dynamic (physical). Do any setup necessary 214 // The object is going dynamic (physical). Do any setup necessary
@@ -238,8 +243,6 @@ public abstract class BSLinkset
238 public abstract void RestoreBodyDependencies(BSPrim child); 243 public abstract void RestoreBodyDependencies(BSPrim child);
239 244
240 // ================================================================ 245 // ================================================================
241 // Below this point is internal magic
242
243 protected virtual float ComputeLinksetMass() 246 protected virtual float ComputeLinksetMass()
244 { 247 {
245 float mass = LinksetRoot.MassRaw; 248 float mass = LinksetRoot.MassRaw;
@@ -264,7 +267,7 @@ public abstract class BSLinkset
264 com = LinksetRoot.Position * LinksetRoot.MassRaw; 267 com = LinksetRoot.Position * LinksetRoot.MassRaw;
265 float totalMass = LinksetRoot.MassRaw; 268 float totalMass = LinksetRoot.MassRaw;
266 269
267 foreach (BSPhysObject bp in m_taintChildren) 270 foreach (BSPhysObject bp in m_children)
268 { 271 {
269 com += bp.Position * bp.MassRaw; 272 com += bp.Position * bp.MassRaw;
270 totalMass += bp.MassRaw; 273 totalMass += bp.MassRaw;
@@ -283,31 +286,16 @@ public abstract class BSLinkset
283 { 286 {
284 com = LinksetRoot.Position; 287 com = LinksetRoot.Position;
285 288
286 foreach (BSPhysObject bp in m_taintChildren) 289 foreach (BSPhysObject bp in m_children)
287 { 290 {
288 com += bp.Position * bp.MassRaw; 291 com += bp.Position * bp.MassRaw;
289 } 292 }
290 com /= (m_taintChildren.Count + 1); 293 com /= (m_children.Count + 1);
291 } 294 }
292 295
293 return com; 296 return com;
294 } 297 }
295 298
296 // I am the root of a linkset and a new child is being added
297 // Called while LinkActivity is locked.
298 protected abstract void AddChildToLinkset(BSPhysObject child);
299
300 // Forcefully removing a child from a linkset.
301 // This is not being called by the child so we have to make sure the child doesn't think
302 // it's still connected to the linkset.
303 // Normal OpenSimulator operation will never do this because other SceneObjectPart information
304 // also has to be updated (like pointer to prim's parent).
305 protected abstract void RemoveChildFromOtherLinkset(BSPhysObject pchild);
306
307 // I am the root of a linkset and one of my children is being removed.
308 // Safe to call even if the child is not really in my linkset.
309 protected abstract void RemoveChildFromLinkset(BSPhysObject child);
310
311 // Invoke the detailed logger and output something if it's enabled. 299 // Invoke the detailed logger and output something if it's enabled.
312 protected void DetailLog(string msg, params Object[] args) 300 protected void DetailLog(string msg, params Object[] args)
313 { 301 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index 086aa12..6c1fa2a 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -54,7 +54,7 @@ public sealed class BSLinksetConstraints : BSLinkset
54 // Queue to happen after all the other taint processing 54 // Queue to happen after all the other taint processing
55 PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() 55 PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
56 { 56 {
57 RecomputeLinksetConstraintVariables(); 57 RecomputeLinksetConstraints();
58 }); 58 });
59 59
60 } 60 }
@@ -98,24 +98,13 @@ public sealed class BSLinksetConstraints : BSLinkset
98 98
99 lock (m_linksetActivityLock) 99 lock (m_linksetActivityLock)
100 { 100 {
101 if (IsRoot(child)) 101 // Just undo all the constraints for this linkset. Rebuild at the end of the step.
102 { 102 DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
103 // If the one with the dependency is root, must undo all children 103 child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"));
104 DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
105 child.LocalID, LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"));
106 104
107 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); 105 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
108 } 106 // Cause the constraints, et al to be rebuilt before the next simulation step.
109 else 107 Refresh(LinksetRoot);
110 {
111 DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
112 child.LocalID,
113 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
114 child.LocalID, child.BSBody.ptr.ToString("X"));
115 // ret = PhysicallyUnlinkAChildFromRoot(LinksetRoot, child);
116 // Despite the function name, this removes any link to the specified object.
117 ret = PhysicallyUnlinkAllChildrenFromRoot(child);
118 }
119 } 108 }
120 return ret; 109 return ret;
121 } 110 }
@@ -125,26 +114,7 @@ public sealed class BSLinksetConstraints : BSLinkset
125 // Called at taint-time!! 114 // Called at taint-time!!
126 public override void RestoreBodyDependencies(BSPrim child) 115 public override void RestoreBodyDependencies(BSPrim child)
127 { 116 {
128 lock (m_linksetActivityLock) 117 // The Refresh operation will build any missing constraints.
129 {
130 if (IsRoot(child))
131 {
132 DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreChildrenForRoot,rID={1},numChild={2}",
133 child.LocalID, LinksetRoot.LocalID, m_taintChildren.Count);
134 foreach (BSPhysObject bpo in m_taintChildren)
135 {
136 PhysicallyLinkAChildToRoot(LinksetRoot, bpo);
137 }
138 }
139 else
140 {
141 DetailLog("{0},BSLinksetConstraint.RestoreBodyDependencies,restoreSingleChild,rID={1},rBody={2},cID={3},cBody={4}",
142 LinksetRoot.LocalID,
143 LinksetRoot.LocalID, LinksetRoot.BSBody.ptr.ToString("X"),
144 child.LocalID, child.BSBody.ptr.ToString("X"));
145 PhysicallyLinkAChildToRoot(LinksetRoot, child);
146 }
147 }
148 } 118 }
149 119
150 // ================================================================ 120 // ================================================================
@@ -163,18 +133,7 @@ public sealed class BSLinksetConstraints : BSLinkset
163 133
164 DetailLog("{0},AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 134 DetailLog("{0},AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
165 135
166 PhysicsScene.TaintedObject("AddChildToLinkset", delegate() 136 // Cause constraints and assorted properties to be recomputed before the next simulation step.
167 {
168 DetailLog("{0},AddChildToLinkset,taint,rID={1},rBody={2},cID={3},cBody={4}",
169 rootx.LocalID,
170 rootx.LocalID, rootx.BSBody.ptr.ToString("X"),
171 childx.LocalID, childx.BSBody.ptr.ToString("X"));
172 // Since this is taint-time, the body and shape could have changed for the child
173 rootx.ForcePosition = rootx.Position; // DEBUG
174 childx.ForcePosition = childx.Position; // DEBUG
175 PhysicallyLinkAChildToRoot(rootx, childx);
176 m_taintChildren.Add(child);
177 });
178 Refresh(LinksetRoot); 137 Refresh(LinksetRoot);
179 } 138 }
180 return; 139 return;
@@ -207,7 +166,6 @@ public sealed class BSLinksetConstraints : BSLinkset
207 166
208 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 167 PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
209 { 168 {
210 m_taintChildren.Remove(child);
211 PhysicallyUnlinkAChildFromRoot(rootx, childx); 169 PhysicallyUnlinkAChildFromRoot(rootx, childx);
212 }); 170 });
213 // See that the linkset parameters are recomputed at the end of the taint time. 171 // See that the linkset parameters are recomputed at the end of the taint time.
@@ -225,6 +183,12 @@ public sealed class BSLinksetConstraints : BSLinkset
225 // Called at taint time! 183 // Called at taint time!
226 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) 184 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
227 { 185 {
186 // Don't build the constraint when asked. Put it off until just before the simulation step.
187 Refresh(rootPrim);
188 }
189
190 private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim)
191 {
228 // Zero motion for children so they don't interpolate 192 // Zero motion for children so they don't interpolate
229 childPrim.ZeroMotion(); 193 childPrim.ZeroMotion();
230 194
@@ -235,7 +199,7 @@ public sealed class BSLinksetConstraints : BSLinkset
235 // real world coordinate of midpoint between the two objects 199 // real world coordinate of midpoint between the two objects
236 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); 200 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
237 201
238 DetailLog("{0},BSLinksetConstraint.PhysicallyLinkAChildToRoot,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", 202 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
239 rootPrim.LocalID, 203 rootPrim.LocalID,
240 rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"), 204 rootPrim.LocalID, rootPrim.BSBody.ptr.ToString("X"),
241 childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"), 205 childPrim.LocalID, childPrim.BSBody.ptr.ToString("X"),
@@ -297,6 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset
297 { 261 {
298 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations); 262 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations);
299 } 263 }
264 return constrain;
300 } 265 }
301 266
302 // Remove linkage between myself and a particular child 267 // Remove linkage between myself and a particular child
@@ -337,56 +302,47 @@ public sealed class BSLinksetConstraints : BSLinkset
337 } 302 }
338 303
339 // Call each of the constraints that make up this linkset and recompute the 304 // Call each of the constraints that make up this linkset and recompute the
340 // various transforms and variables. Used when objects are added or removed 305 // various transforms and variables. Create constraints of not created yet.
341 // from a linkset to make sure the constraints know about the new mass and 306 // Called before the simulation step to make sure the constraint based linkset
342 // geometry. 307 // is all initialized.
343 // Must only be called at taint time!! 308 // Must only be called at taint time!!
344 private void RecomputeLinksetConstraintVariables() 309 private void RecomputeLinksetConstraints()
345 { 310 {
346 float linksetMass = LinksetMass; 311 float linksetMass = LinksetMass;
347 foreach (BSPhysObject child in m_taintChildren) 312 LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
313
314 // For a multiple object linkset, set everybody's center of mass to the set's center of mass
315 OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
316 BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity);
317
318 // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
319 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
320 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,setCenterOfMass,COM={1},rBody={2},linksetMass={3}",
321 LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass);
322
323 foreach (BSPhysObject child in m_children)
348 { 324 {
325 // A child in the linkset physically shows the mass of the whole linkset.
326 // This allows Bullet to apply enough force on the child to move the whole linkset.
327 // (Also do the mass stuff before recomputing the constraint so mass is not zero.)
328 BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity);
329 child.UpdatePhysicalMassProperties(linksetMass);
330
349 BSConstraint constrain; 331 BSConstraint constrain;
350 if (PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain)) 332 if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain))
351 {
352 // DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",
353 // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID);
354 constrain.RecomputeConstraintVariables(linksetMass);
355 }
356 else
357 { 333 {
358 // Non-fatal error that happens when children are being added to the linkset but 334 // If constraint doesn't exist yet, create it.
359 // their constraints have not been created yet. 335 constrain = BuildConstraint(LinksetRoot, child);
360 break;
361 } 336 }
362 } 337 constrain.RecomputeConstraintVariables(linksetMass);
363 338
364 // If the whole linkset is not here, doesn't make sense to recompute linkset wide values 339 // DEBUG: see of inter-linkset collisions are causing problems
365 if (m_children.Count == m_taintChildren.Count) 340 // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr,
366 { 341 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
367 // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass
368 OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
369 BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity);
370 // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
371 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
372 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraintVariables,setCenterOfMass,COM={1},rBody={2},linksetMass={3}",
373 LinksetRoot.LocalID, centerOfMass, LinksetRoot.BSBody.ptr.ToString("X"), linksetMass);
374 foreach (BSPhysObject child in m_taintChildren)
375 {
376 BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity);
377 // A child in the linkset physically shows the mass of the whole linkset.
378 // This allows Bullet to apply enough force on the child to move the whole linkset.
379 child.UpdatePhysicalMassProperties(linksetMass);
380 // DEBUG: see of inter-linkset collisions are causing problems
381 // BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr,
382 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
383 }
384 // Also update the root's physical mass to the whole linkset
385 LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
386 342
387 // BulletSimAPI.DumpAllInfo2(PhysicsScene.World.ptr); // DEBUG DEBUG DEBUG 343 // BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG
388 } 344 }
389 return; 345
390 } 346 }
391} 347}
392} 348}