diff options
author | Robert Adams | 2013-02-10 09:51:34 -0800 |
---|---|---|
committer | Robert Adams | 2013-02-12 15:52:08 -0800 |
commit | fb903ff49089d5fd7a56aa2401528c3e7cf1800c (patch) | |
tree | 2e6e28f88e6b7711165a8a315e3796241c4a11d2 /OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |
parent | Extend TestJsonCreateStore() with a one key input and an input with raw numbe... (diff) | |
download | opensim-SC_OLD-fb903ff49089d5fd7a56aa2401528c3e7cf1800c.zip opensim-SC_OLD-fb903ff49089d5fd7a56aa2401528c3e7cf1800c.tar.gz opensim-SC_OLD-fb903ff49089d5fd7a56aa2401528c3e7cf1800c.tar.bz2 opensim-SC_OLD-fb903ff49089d5fd7a56aa2401528c3e7cf1800c.tar.xz |
BulletSim: More work on center-of-mass. Remove linksetinfo and rely on simulator to update info.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 150 |
1 files changed, 69 insertions, 81 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 36bae9b..1f66b56 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -93,7 +93,8 @@ public sealed class BSLinksetCompound : BSLinkset | |||
93 | { | 93 | { |
94 | private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; | 94 | private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; |
95 | 95 | ||
96 | public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) : base(scene, parent) | 96 | public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) |
97 | : base(scene, parent) | ||
97 | { | 98 | { |
98 | } | 99 | } |
99 | 100 | ||
@@ -217,59 +218,45 @@ public sealed class BSLinksetCompound : BSLinkset | |||
217 | // and that is caused by us updating the object. | 218 | // and that is caused by us updating the object. |
218 | if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) | 219 | if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) |
219 | { | 220 | { |
220 | // Gather the child info. It might not be there if the linkset is in transition. | ||
221 | BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo; | ||
222 | if (lsi != null) | ||
223 | { | ||
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, OMV.Vector3.Zero); | ||
226 | updated.LinksetInfo = newLsi; | ||
227 | |||
228 | // Find the physical instance of the child | 221 | // Find the physical instance of the child |
229 | if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) | 222 | if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) |
223 | { | ||
224 | // It is possible that the linkset is still under construction and the child is not yet | ||
225 | // inserted into the compound shape. A rebuild of the linkset in a pre-step action will | ||
226 | // build the whole thing with the new position or rotation. | ||
227 | // The index must be checked because Bullet references the child array but does no validity | ||
228 | // checking of the child index passed. | ||
229 | int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape); | ||
230 | if (updated.LinksetChildIndex < numLinksetChildren) | ||
230 | { | 231 | { |
231 | // It is possible that the linkset is still under construction and the child is not yet | 232 | BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, updated.LinksetChildIndex); |
232 | // inserted into the compound shape. A rebuild of the linkset in a pre-step action will | 233 | if (linksetChildShape.HasPhysicalShape) |
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) | ||
238 | { | 234 | { |
239 | BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); | 235 | // Found the child shape within the compound shape |
240 | if (linksetChildShape.HasPhysicalShape) | 236 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, updated.LinksetChildIndex, |
241 | { | 237 | updated.RawPosition - LinksetRoot.RawPosition, |
242 | // Found the child shape within the compound shape | 238 | updated.RawOrientation * OMV.Quaternion.Inverse(LinksetRoot.RawOrientation), |
243 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, | 239 | true /* shouldRecalculateLocalAabb */); |
244 | newLsi.OffsetFromCenterOfMass, | 240 | updatedChild = true; |
245 | newLsi.OffsetRot, | 241 | DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},pos={2},rot={3}", |
246 | true /* shouldRecalculateLocalAabb */); | 242 | updated.LocalID, whichUpdated, updated.RawPosition, updated.RawOrientation); |
247 | 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 | ||
256 | } | 243 | } |
257 | else // DEBUG DEBUG | 244 | else // DEBUG DEBUG |
258 | { // DEBUG DEBUG | 245 | { // DEBUG DEBUG |
259 | // the child is not yet in the compound shape. This is non-fatal. | 246 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}", |
260 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}", | 247 | updated.LocalID, linksetChildShape); |
261 | updated.LocalID, numLinksetChildren, lsi.Index); | ||
262 | } // DEBUG DEBUG | 248 | } // DEBUG DEBUG |
263 | } | 249 | } |
264 | else // DEBUG DEBUG | 250 | else // DEBUG DEBUG |
265 | { // DEBUG DEBUG | 251 | { // DEBUG DEBUG |
266 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID); | 252 | // the child is not yet in the compound shape. This is non-fatal. |
253 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}", | ||
254 | updated.LocalID, numLinksetChildren, updated.LinksetChildIndex); | ||
267 | } // DEBUG DEBUG | 255 | } // DEBUG DEBUG |
268 | } | 256 | } |
269 | else // DEBUG DEBUG | 257 | else // DEBUG DEBUG |
270 | { // DEBUG DEBUG | 258 | { // DEBUG DEBUG |
271 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noLinkSetInfo,rootPhysShape={1}", | 259 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID); |
272 | updated.LocalID, LinksetRoot.PhysShape); | ||
273 | } // DEBUG DEBUG | 260 | } // DEBUG DEBUG |
274 | 261 | ||
275 | if (!updatedChild) | 262 | if (!updatedChild) |
@@ -379,6 +366,8 @@ public sealed class BSLinksetCompound : BSLinkset | |||
379 | // Safe to call even if the child is not really in the linkset. | 366 | // Safe to call even if the child is not really in the linkset. |
380 | protected override void RemoveChildFromLinkset(BSPrimLinkable child) | 367 | protected override void RemoveChildFromLinkset(BSPrimLinkable child) |
381 | { | 368 | { |
369 | child.ClearDisplacement(); | ||
370 | |||
382 | if (m_children.Remove(child)) | 371 | if (m_children.Remove(child)) |
383 | { | 372 | { |
384 | DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", | 373 | DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", |
@@ -410,7 +399,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
410 | // Constraint linksets are rebuilt every time. | 399 | // Constraint linksets are rebuilt every time. |
411 | // Note that this works for rebuilding just the root after a linkset is taken apart. | 400 | // Note that this works for rebuilding just the root after a linkset is taken apart. |
412 | // Called at taint time!! | 401 | // Called at taint time!! |
413 | private bool disableCOM = true; // DEBUG DEBUG: disable until we get this debugged | 402 | private bool disableCOM = false; // DEBUG DEBUG: disable until we get this debugged |
414 | private void RecomputeLinksetCompound() | 403 | private void RecomputeLinksetCompound() |
415 | { | 404 | { |
416 | try | 405 | try |
@@ -424,30 +413,31 @@ public sealed class BSLinksetCompound : BSLinkset | |||
424 | // The center of mass for the linkset is the geometric center of the group. | 413 | // The center of mass for the linkset is the geometric center of the group. |
425 | // Compute a displacement for each component so it is relative to the center-of-mass. | 414 | // Compute a displacement for each component so it is relative to the center-of-mass. |
426 | // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass | 415 | // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass |
427 | OMV.Vector3 centerOfMass; | 416 | OMV.Vector3 centerOfMassW = LinksetRoot.RawPosition; |
428 | OMV.Vector3 centerDisplacement = OMV.Vector3.Zero; | 417 | if (!disableCOM) // DEBUG DEBUG |
429 | if (disableCOM) // DEBUG DEBUG | ||
430 | { // DEBUG DEBUG | ||
431 | centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG | ||
432 | // LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; | ||
433 | } // DEBUG DEBUG | ||
434 | else | ||
435 | { | 418 | { |
436 | centerOfMass = ComputeLinksetCenterOfMass(); | 419 | // Compute a center-of-mass in world coordinates. |
437 | // 'centerDisplacement' is the value to *add* to all the shape offsets | 420 | centerOfMassW = ComputeLinksetCenterOfMass(); |
438 | centerDisplacement = LinksetRoot.RawPosition - centerOfMass; | ||
439 | |||
440 | // Since we're displacing the center of the shape, we need to move the body in the world | ||
441 | // LinksetRoot.PositionDisplacement = centerDisplacement; | ||
442 | |||
443 | // This causes the root prim position to be set properly based on the new PositionDisplacement | ||
444 | LinksetRoot.ForcePosition = LinksetRoot.RawPosition; | ||
445 | // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM | ||
446 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); | ||
447 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", | ||
448 | LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); | ||
449 | } | 421 | } |
450 | 422 | ||
423 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); | ||
424 | |||
425 | // 'centerDisplacement' is the value to subtract from children to give physical offset position | ||
426 | OMV.Vector3 centerDisplacement = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation; | ||
427 | LinksetRoot.SetEffectiveCenterOfMassW(centerDisplacement); | ||
428 | |||
429 | // This causes the physical position of the root prim to be offset to accomodate for the displacements | ||
430 | LinksetRoot.ForcePosition = LinksetRoot.RawPosition; | ||
431 | |||
432 | // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM | ||
433 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, | ||
434 | -centerDisplacement, | ||
435 | LinksetRoot.RawOrientation, | ||
436 | false /* shouldRecalculateLocalAabb */); | ||
437 | |||
438 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", | ||
439 | LinksetRoot.LocalID, centerOfMassW, LinksetRoot.RawPosition, centerDisplacement); | ||
440 | |||
451 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", | 441 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", |
452 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); | 442 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); |
453 | 443 | ||
@@ -455,29 +445,20 @@ public sealed class BSLinksetCompound : BSLinkset | |||
455 | int memberIndex = 1; | 445 | int memberIndex = 1; |
456 | ForEachMember(delegate(BSPrimLinkable cPrim) | 446 | ForEachMember(delegate(BSPrimLinkable cPrim) |
457 | { | 447 | { |
458 | if (!IsRoot(cPrim)) | 448 | if (IsRoot(cPrim)) |
459 | { | 449 | { |
460 | // Compute the displacement of the child from the root of the linkset. | 450 | cPrim.LinksetChildIndex = 0; |
461 | // This info is saved in the child prim so the relationship does not | 451 | } |
462 | // change over time and the new child position can be computed | 452 | else |
463 | // when the linkset is being disassembled (the linkset may have moved). | 453 | { |
464 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; | 454 | cPrim.LinksetChildIndex = memberIndex; |
465 | if (lci == null) | ||
466 | { | ||
467 | lci = new BSLinksetCompoundInfo(memberIndex, LinksetRoot, cPrim, centerDisplacement); | ||
468 | cPrim.LinksetInfo = lci; | ||
469 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); | ||
470 | } | ||
471 | |||
472 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}", | ||
473 | LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci); | ||
474 | 455 | ||
475 | if (cPrim.PhysShape.isNativeShape) | 456 | if (cPrim.PhysShape.isNativeShape) |
476 | { | 457 | { |
477 | // A native shape is turned into a hull collision shape because native | 458 | // A native shape is turned into a hull collision shape because native |
478 | // shapes are not shared so we have to hullify it so it will be tracked | 459 | // shapes are not shared so we have to hullify it so it will be tracked |
479 | // and freed at the correct time. This also solves the scaling problem | 460 | // and freed at the correct time. This also solves the scaling problem |
480 | // (native shapes scaled but hull/meshes are assumed to not be). | 461 | // (native shapes scale but hull/meshes are assumed to not be). |
481 | // TODO: decide of the native shape can just be used in the compound shape. | 462 | // TODO: decide of the native shape can just be used in the compound shape. |
482 | // Use call to CreateGeomNonSpecial(). | 463 | // Use call to CreateGeomNonSpecial(). |
483 | BulletShape saveShape = cPrim.PhysShape; | 464 | BulletShape saveShape = cPrim.PhysShape; |
@@ -486,7 +467,10 @@ public sealed class BSLinksetCompound : BSLinkset | |||
486 | PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); | 467 | PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); |
487 | BulletShape newShape = cPrim.PhysShape; | 468 | BulletShape newShape = cPrim.PhysShape; |
488 | cPrim.PhysShape = saveShape; | 469 | cPrim.PhysShape = saveShape; |
489 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); | 470 | |
471 | OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; | ||
472 | OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; | ||
473 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, offsetPos, offsetRot); | ||
490 | } | 474 | } |
491 | else | 475 | else |
492 | { | 476 | { |
@@ -498,9 +482,10 @@ public sealed class BSLinksetCompound : BSLinkset | |||
498 | PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", | 482 | PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", |
499 | LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); | 483 | LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); |
500 | } | 484 | } |
501 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot); | 485 | OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement; |
486 | OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation; | ||
487 | PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot); | ||
502 | } | 488 | } |
503 | lci.Index = memberIndex; | ||
504 | memberIndex++; | 489 | memberIndex++; |
505 | } | 490 | } |
506 | return false; // 'false' says to move onto the next child in the list | 491 | return false; // 'false' says to move onto the next child in the list |
@@ -509,6 +494,9 @@ public sealed class BSLinksetCompound : BSLinkset | |||
509 | // With all of the linkset packed into the root prim, it has the mass of everyone. | 494 | // With all of the linkset packed into the root prim, it has the mass of everyone. |
510 | LinksetMass = ComputeLinksetMass(); | 495 | LinksetMass = ComputeLinksetMass(); |
511 | LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true); | 496 | LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true); |
497 | |||
498 | // Enable the physical position updator to return the position and rotation of the root shape | ||
499 | PhysicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE); | ||
512 | } | 500 | } |
513 | finally | 501 | finally |
514 | { | 502 | { |