diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 54dc458..0c4db40 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -219,43 +219,65 @@ public sealed class BSLinksetCompound : BSLinkset | |||
219 | { | 219 | { |
220 | // Gather the child info. It might not be there if the linkset is in transition. | 220 | // Gather the child info. It might not be there if the linkset is in transition. |
221 | BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo; | 221 | BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo; |
222 | if (LinksetRoot.PhysShape.HasPhysicalShape && lsi != null) | 222 | if (lsi != null) |
223 | { | 223 | { |
224 | if (PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) | 224 | // Since the child moved or rotationed, it needs a new relative position within the linkset |
225 | BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); | ||
226 | updated.LinksetInfo = newLsi; | ||
227 | |||
228 | // Find the physical instance of the child | ||
229 | if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) | ||
225 | { | 230 | { |
226 | BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); | 231 | // It is possible that the linkset is still under construction and the child is not yet |
227 | if (linksetChildShape.HasPhysicalShape) | 232 | // inserted into the compound shape. A rebuild of the linkset in a pre-step action will |
233 | // build the whole thing with the new position or rotation. | ||
234 | // The index must be checked because Bullet references the child array but does no validity | ||
235 | // checking of the child index passed. | ||
236 | int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape); | ||
237 | if (lsi.Index < numLinksetChildren) | ||
228 | { | 238 | { |
229 | // Compute the offset from the center-of-gravity | 239 | BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); |
230 | BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); | 240 | if (linksetChildShape.HasPhysicalShape) |
231 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, | 241 | { |
232 | newLsi.OffsetFromCenterOfMass, | 242 | // Found the child shape within the compound shape |
233 | newLsi.OffsetRot, | 243 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, |
234 | true /* shouldRecalculateLocalAabb */); | 244 | newLsi.OffsetFromCenterOfMass, |
235 | DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}", | 245 | newLsi.OffsetRot, |
236 | updated.LocalID, whichUpdated, newLsi); | 246 | true /* shouldRecalculateLocalAabb */); |
237 | updated.LinksetInfo = newLsi; | 247 | updatedChild = true; |
238 | updatedChild = true; | 248 | DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}", |
249 | updated.LocalID, whichUpdated, newLsi); | ||
250 | } | ||
251 | else // DEBUG DEBUG | ||
252 | { // DEBUG DEBUG | ||
253 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}", | ||
254 | updated.LocalID, linksetChildShape); | ||
255 | } // DEBUG DEBUG | ||
239 | } | 256 | } |
240 | else // DEBUG DEBUG | 257 | else // DEBUG DEBUG |
241 | { // DEBUG DEBUG | 258 | { // DEBUG DEBUG |
242 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}", | 259 | // the child is not yet in the compound shape. This is non-fatal. |
243 | updated.LocalID, linksetChildShape); | 260 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}", |
261 | updated.LocalID, numLinksetChildren, lsi.Index); | ||
244 | } // DEBUG DEBUG | 262 | } // DEBUG DEBUG |
245 | } | 263 | } |
246 | else // DEBUG DEBUG | 264 | else // DEBUG DEBUG |
247 | { // DEBUG DEBUG | 265 | { // DEBUG DEBUG |
248 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,notCompound", updated.LocalID); | 266 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID); |
249 | } // DEBUG DEBUG | 267 | } // DEBUG DEBUG |
250 | } | 268 | } |
251 | else // DEBUG DEBUG | 269 | else // DEBUG DEBUG |
252 | { // DEBUG DEBUG | 270 | { // DEBUG DEBUG |
253 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,rootPhysShape={1},lsi={2}", | 271 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noLinkSetInfo,rootPhysShape={1}", |
254 | updated.LocalID, LinksetRoot.PhysShape, lsi == null ? "NULL" : lsi.ToString()); | 272 | updated.LocalID, LinksetRoot.PhysShape); |
255 | } // DEBUG DEBUG | 273 | } // DEBUG DEBUG |
274 | |||
256 | if (!updatedChild) | 275 | if (!updatedChild) |
257 | { | 276 | { |
258 | // If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info. | 277 | // If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info. |
278 | // Note: there are several ways through this code that will not update the child if | ||
279 | // the linkset is being rebuilt. In this case, scheduling a rebuild is a NOOP since | ||
280 | // there will already be a rebuild scheduled. | ||
259 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}", | 281 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}", |
260 | updated.LocalID, whichUpdated); | 282 | updated.LocalID, whichUpdated); |
261 | updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed. | 283 | updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed. |
@@ -274,13 +296,14 @@ public sealed class BSLinksetCompound : BSLinkset | |||
274 | bool ret = false; | 296 | bool ret = false; |
275 | 297 | ||
276 | DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", | 298 | DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", |
277 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, IsRoot(child)); | 299 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child)); |
278 | 300 | ||
279 | if (!IsRoot(child)) | 301 | if (!IsRoot(child)) |
280 | { | 302 | { |
281 | // Because it is a convenient time, recompute child world position and rotation based on | 303 | // Because it is a convenient time, recompute child world position and rotation based on |
282 | // its position in the linkset. | 304 | // its position in the linkset. |
283 | RecomputeChildWorldPosition(child, true); | 305 | RecomputeChildWorldPosition(child, true /* inTaintTime */); |
306 | child.LinksetInfo = null; | ||
284 | } | 307 | } |
285 | 308 | ||
286 | // Cannot schedule a refresh/rebuild here because this routine is called when | 309 | // Cannot schedule a refresh/rebuild here because this routine is called when |
@@ -295,6 +318,14 @@ public sealed class BSLinksetCompound : BSLinkset | |||
295 | // prim. The child prim's location must be recomputed based on the location of the root shape. | 318 | // prim. The child prim's location must be recomputed based on the location of the root shape. |
296 | private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) | 319 | private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) |
297 | { | 320 | { |
321 | // For the moment (20130201), disable this computation (converting the child physical addr back to | ||
322 | // a region address) until we have a good handle on center-of-mass offsets and what the physics | ||
323 | // engine moving a child actually means. | ||
324 | // The simulator keeps track of where children should be as the linkset moves. Setting | ||
325 | // the pos/rot here does not effect that knowledge as there is no good way for the | ||
326 | // physics engine to send the simulator an update for a child. | ||
327 | |||
328 | /* | ||
298 | BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; | 329 | BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; |
299 | if (lci != null) | 330 | if (lci != null) |
300 | { | 331 | { |
@@ -323,6 +354,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
323 | // LogHeader, child.LocalID); | 354 | // LogHeader, child.LocalID); |
324 | DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID); | 355 | DetailLog("{0},BSLinksetCompound.recomputeChildWorldPosition,noRelativePositonInfo", child.LocalID); |
325 | } | 356 | } |
357 | */ | ||
326 | } | 358 | } |
327 | 359 | ||
328 | // ================================================================ | 360 | // ================================================================ |
@@ -356,6 +388,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
356 | 388 | ||
357 | // Cause the child's body to be rebuilt and thus restored to normal operation | 389 | // Cause the child's body to be rebuilt and thus restored to normal operation |
358 | RecomputeChildWorldPosition(child, false); | 390 | RecomputeChildWorldPosition(child, false); |
391 | child.LinksetInfo = null; | ||
359 | child.ForceBodyShapeRebuild(false); | 392 | child.ForceBodyShapeRebuild(false); |
360 | 393 | ||
361 | if (!HasAnyChildren) | 394 | if (!HasAnyChildren) |
@@ -377,16 +410,16 @@ public sealed class BSLinksetCompound : BSLinkset | |||
377 | // Constraint linksets are rebuilt every time. | 410 | // Constraint linksets are rebuilt every time. |
378 | // Note that this works for rebuilding just the root after a linkset is taken apart. | 411 | // Note that this works for rebuilding just the root after a linkset is taken apart. |
379 | // Called at taint time!! | 412 | // Called at taint time!! |
380 | private bool disableCOM = true; // disable until we get this debugged | 413 | private bool disableCOM = true; // DEBUG DEBUG: disable until we get this debugged |
381 | private void RecomputeLinksetCompound() | 414 | private void RecomputeLinksetCompound() |
382 | { | 415 | { |
383 | try | 416 | try |
384 | { | 417 | { |
385 | // Suppress rebuilding while rebuilding | 418 | // Suppress rebuilding while rebuilding. (We know rebuilding is on only one thread.) |
386 | Rebuilding = true; | 419 | Rebuilding = true; |
387 | 420 | ||
388 | // Cause the root shape to be rebuilt as a compound object with just the root in it | 421 | // Cause the root shape to be rebuilt as a compound object with just the root in it |
389 | LinksetRoot.ForceBodyShapeRebuild(true); | 422 | LinksetRoot.ForceBodyShapeRebuild(true /* inTaintTime */); |
390 | 423 | ||
391 | // The center of mass for the linkset is the geometric center of the group. | 424 | // The center of mass for the linkset is the geometric center of the group. |
392 | // Compute a displacement for each component so it is relative to the center-of-mass. | 425 | // Compute a displacement for each component so it is relative to the center-of-mass. |