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 | |
parent | Extend TestJsonCreateStore() with a one key input and an input with raw numbe... (diff) | |
download | opensim-SC-fb903ff49089d5fd7a56aa2401528c3e7cf1800c.zip opensim-SC-fb903ff49089d5fd7a56aa2401528c3e7cf1800c.tar.gz opensim-SC-fb903ff49089d5fd7a56aa2401528c3e7cf1800c.tar.bz2 opensim-SC-fb903ff49089d5fd7a56aa2401528c3e7cf1800c.tar.xz |
BulletSim: More work on center-of-mass. Remove linksetinfo and rely on simulator to update info.
Diffstat (limited to '')
8 files changed, 162 insertions, 124 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 7ab86d2..3f83ef0 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | |||
@@ -225,9 +225,10 @@ public enum CollisionFlags : uint | |||
225 | CF_DISABLE_VISUALIZE_OBJECT = 1 << 5, | 225 | CF_DISABLE_VISUALIZE_OBJECT = 1 << 5, |
226 | CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, | 226 | CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, |
227 | // Following used by BulletSim to control collisions and updates | 227 | // Following used by BulletSim to control collisions and updates |
228 | BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, | 228 | BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, // return collision events from unmanaged to managed |
229 | BS_FLOATS_ON_WATER = 1 << 11, | 229 | BS_FLOATS_ON_WATER = 1 << 11, // the object should float at water level |
230 | BS_VEHICLE_COLLISIONS = 1 << 12, | 230 | BS_VEHICLE_COLLISIONS = 1 << 12, // return collisions for vehicle ground checking |
231 | BS_RETURN_ROOT_COMPOUND_SHAPE = 1 << 13, // return the pos/rot of the root shape in a compound shape | ||
231 | BS_NONE = 0, | 232 | BS_NONE = 0, |
232 | BS_ALL = 0xFFFFFFFF | 233 | BS_ALL = 0xFFFFFFFF |
233 | }; | 234 | }; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index f781aea..04fb05b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -274,7 +274,7 @@ public sealed class BSCharacter : BSPhysObject | |||
274 | // This test is done if moving forward, not flying and is colliding with something. | 274 | // This test is done if moving forward, not flying and is colliding with something. |
275 | // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}", | 275 | // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}", |
276 | // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count); | 276 | // LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count); |
277 | if (IsColliding && !Flying && TargetSpeed > 0.1f /* && ForwardSpeed < 0.1f */) | 277 | if (IsColliding && !Flying && TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */) |
278 | { | 278 | { |
279 | // The range near the character's feet where we will consider stairs | 279 | // The range near the character's feet where we will consider stairs |
280 | float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f; | 280 | float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index e35311f..4ece1eb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -127,6 +127,8 @@ public abstract class BSLinkset | |||
127 | m_children = new HashSet<BSPrimLinkable>(); | 127 | m_children = new HashSet<BSPrimLinkable>(); |
128 | LinksetMass = parent.RawMass; | 128 | LinksetMass = parent.RawMass; |
129 | Rebuilding = false; | 129 | Rebuilding = false; |
130 | |||
131 | parent.ClearDisplacement(); | ||
130 | } | 132 | } |
131 | 133 | ||
132 | // Link to a linkset where the child knows the parent. | 134 | // Link to a linkset where the child knows the parent. |
@@ -280,6 +282,7 @@ public abstract class BSLinkset | |||
280 | return mass; | 282 | return mass; |
281 | } | 283 | } |
282 | 284 | ||
285 | // Computes linkset's center of mass in world coordinates. | ||
283 | protected virtual OMV.Vector3 ComputeLinksetCenterOfMass() | 286 | protected virtual OMV.Vector3 ComputeLinksetCenterOfMass() |
284 | { | 287 | { |
285 | OMV.Vector3 com; | 288 | OMV.Vector3 com; |
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 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index de69fa0..8ebb532 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -136,6 +136,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
136 | 136 | ||
137 | // The objects base shape information. Null if not a prim type shape. | 137 | // The objects base shape information. Null if not a prim type shape. |
138 | public PrimitiveBaseShape BaseShape { get; protected set; } | 138 | public PrimitiveBaseShape BaseShape { get; protected set; } |
139 | |||
139 | // Some types of objects have preferred physical representations. | 140 | // Some types of objects have preferred physical representations. |
140 | // Returns SHAPE_UNKNOWN if there is no preference. | 141 | // Returns SHAPE_UNKNOWN if there is no preference. |
141 | public virtual BSPhysicsShapeType PreferredPhysicalShape | 142 | public virtual BSPhysicsShapeType PreferredPhysicalShape |
@@ -150,15 +151,17 @@ public abstract class BSPhysObject : PhysicsActor | |||
150 | public EntityProperties LastEntityProperties { get; set; } | 151 | public EntityProperties LastEntityProperties { get; set; } |
151 | 152 | ||
152 | public virtual OMV.Vector3 Scale { get; set; } | 153 | public virtual OMV.Vector3 Scale { get; set; } |
153 | public abstract bool IsSolid { get; } | ||
154 | public abstract bool IsStatic { get; } | ||
155 | public abstract bool IsSelected { get; } | ||
156 | 154 | ||
157 | // It can be confusing for an actor to know if it should move or update an object | 155 | // It can be confusing for an actor to know if it should move or update an object |
158 | // depeneding on the setting of 'selected', 'physical, ... | 156 | // depeneding on the setting of 'selected', 'physical, ... |
159 | // This flag is the true test -- if true, the object is being acted on in the physical world | 157 | // This flag is the true test -- if true, the object is being acted on in the physical world |
160 | public abstract bool IsPhysicallyActive { get; } | 158 | public abstract bool IsPhysicallyActive { get; } |
161 | 159 | ||
160 | // Detailed state of the object. | ||
161 | public abstract bool IsSolid { get; } | ||
162 | public abstract bool IsStatic { get; } | ||
163 | public abstract bool IsSelected { get; } | ||
164 | |||
162 | // Materialness | 165 | // Materialness |
163 | public MaterialAttributes.Material Material { get; private set; } | 166 | public MaterialAttributes.Material Material { get; private set; } |
164 | public override void SetMaterial(int material) | 167 | public override void SetMaterial(int material) |
@@ -185,14 +188,6 @@ public abstract class BSPhysObject : PhysicsActor | |||
185 | public abstract OMV.Quaternion RawOrientation { get; set; } | 188 | public abstract OMV.Quaternion RawOrientation { get; set; } |
186 | public abstract OMV.Quaternion ForceOrientation { get; set; } | 189 | public abstract OMV.Quaternion ForceOrientation { get; set; } |
187 | 190 | ||
188 | public virtual float TargetSpeed | ||
189 | { | ||
190 | get | ||
191 | { | ||
192 | OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); | ||
193 | return characterOrientedVelocity.X; | ||
194 | } | ||
195 | } | ||
196 | public abstract OMV.Vector3 RawVelocity { get; set; } | 191 | public abstract OMV.Vector3 RawVelocity { get; set; } |
197 | public abstract OMV.Vector3 ForceVelocity { get; set; } | 192 | public abstract OMV.Vector3 ForceVelocity { get; set; } |
198 | 193 | ||
@@ -202,6 +197,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
202 | 197 | ||
203 | public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } | 198 | public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } |
204 | 199 | ||
200 | // The current velocity forward | ||
205 | public virtual float ForwardSpeed | 201 | public virtual float ForwardSpeed |
206 | { | 202 | { |
207 | get | 203 | get |
@@ -210,6 +206,19 @@ public abstract class BSPhysObject : PhysicsActor | |||
210 | return characterOrientedVelocity.X; | 206 | return characterOrientedVelocity.X; |
211 | } | 207 | } |
212 | } | 208 | } |
209 | // The forward speed we are trying to achieve (TargetVelocity) | ||
210 | public virtual float TargetVelocitySpeed | ||
211 | { | ||
212 | get | ||
213 | { | ||
214 | OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation)); | ||
215 | return characterOrientedVelocity.X; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | // The user can optionally set the center of mass. The user's setting will override any | ||
220 | // computed center-of-mass (like in linksets). | ||
221 | public OMV.Vector3? UserSetCenterOfMass { get; set; } | ||
213 | 222 | ||
214 | #region Collisions | 223 | #region Collisions |
215 | 224 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index cf7aa0f..a76f8b9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -442,7 +442,7 @@ public class BSPrim : BSPhysObject | |||
442 | RegisterPreStepAction("BSPrim.setForce", LocalID, | 442 | RegisterPreStepAction("BSPrim.setForce", LocalID, |
443 | delegate(float timeStep) | 443 | delegate(float timeStep) |
444 | { | 444 | { |
445 | if (!IsPhysicallyActive) | 445 | if (!IsPhysicallyActive || _force == OMV.Vector3.Zero) |
446 | { | 446 | { |
447 | UnRegisterPreStepAction("BSPrim.setForce", LocalID); | 447 | UnRegisterPreStepAction("BSPrim.setForce", LocalID); |
448 | return; | 448 | return; |
@@ -647,7 +647,7 @@ public class BSPrim : BSPhysObject | |||
647 | RegisterPreStepAction("BSPrim.setTorque", LocalID, | 647 | RegisterPreStepAction("BSPrim.setTorque", LocalID, |
648 | delegate(float timeStep) | 648 | delegate(float timeStep) |
649 | { | 649 | { |
650 | if (!IsPhysicallyActive) | 650 | if (!IsPhysicallyActive || _torque == OMV.Vector3.Zero) |
651 | { | 651 | { |
652 | UnRegisterPreStepAction("BSPrim.setTorque", LocalID); | 652 | UnRegisterPreStepAction("BSPrim.setTorque", LocalID); |
653 | return; | 653 | return; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs index 6401308..b9f2cca 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs | |||
@@ -44,72 +44,107 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
44 | { | 44 | { |
45 | public class BSPrimDisplaced : BSPrim | 45 | public class BSPrimDisplaced : BSPrim |
46 | { | 46 | { |
47 | // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is. | 47 | // The purpose of this module is to do any mapping between what the simulator thinks |
48 | // Because Bullet needs the zero coordinate to be the center of mass of the linkset, | 48 | // the prim position and orientation is and what the physical position/orientation. |
49 | // sometimes it is necessary to displace the position the physics engine thinks | 49 | // This difference happens because Bullet assumes the center-of-mass is the <0,0,0> |
50 | // the position is. PositionDisplacement must be added and removed from the | 50 | // of the prim/linkset. The simulator tracks the location of the prim/linkset by |
51 | // position as the simulator position is stored and fetched from the physics | 51 | // the location of the root prim. So, if center-of-mass is anywhere but the origin |
52 | // engine. Similar to OrientationDisplacement. | 52 | // of the root prim, the physical origin is displaced from the simulator origin. |
53 | // | ||
54 | // This routine works by capturing the Force* setting of position/orientation/... and | ||
55 | // adjusting the simulator values (being set) into the physical values. | ||
56 | // The conversion is also done in the opposite direction (physical origin -> simulator origin). | ||
57 | // | ||
58 | // The updateParameter call is also captured and the values from the physics engine | ||
59 | // are converted into simulator origin values before being passed to the base | ||
60 | // class. | ||
61 | |||
53 | public virtual OMV.Vector3 PositionDisplacement { get; set; } | 62 | public virtual OMV.Vector3 PositionDisplacement { get; set; } |
54 | public virtual OMV.Quaternion OrientationDisplacement { get; set; } | 63 | public virtual OMV.Quaternion OrientationDisplacement { get; set; } |
55 | public virtual OMV.Vector3 CenterOfMassLocation { get; set; } | ||
56 | public virtual OMV.Vector3 GeometricCenterLocation { get; set; } | ||
57 | 64 | ||
58 | public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, | 65 | public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, |
59 | OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) | 66 | OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) |
60 | : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) | 67 | : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) |
61 | { | 68 | { |
62 | CenterOfMassLocation = RawPosition; | 69 | ClearDisplacement(); |
63 | GeometricCenterLocation = RawPosition; | ||
64 | } | 70 | } |
65 | 71 | ||
66 | public override Vector3 ForcePosition | 72 | public void ClearDisplacement() |
73 | { | ||
74 | PositionDisplacement = OMV.Vector3.Zero; | ||
75 | OrientationDisplacement = OMV.Quaternion.Identity; | ||
76 | } | ||
77 | |||
78 | // Set this sets and computes the displacement from the passed prim to the center-of-mass. | ||
79 | // A user set value for center-of-mass overrides whatever might be passed in here. | ||
80 | // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates). | ||
81 | public virtual void SetEffectiveCenterOfMassW(Vector3 centerOfMassDisplacement) | ||
67 | { | 82 | { |
68 | get | 83 | Vector3 comDisp; |
84 | if (UserSetCenterOfMass.HasValue) | ||
85 | comDisp = (OMV.Vector3)UserSetCenterOfMass; | ||
86 | else | ||
87 | comDisp = centerOfMassDisplacement; | ||
88 | |||
89 | if (comDisp == Vector3.Zero) | ||
69 | { | 90 | { |
70 | return base.ForcePosition; | 91 | // If there is no diplacement. Things get reset. |
92 | PositionDisplacement = OMV.Vector3.Zero; | ||
93 | OrientationDisplacement = OMV.Quaternion.Identity; | ||
71 | } | 94 | } |
72 | set | 95 | else |
73 | { | 96 | { |
74 | base.ForcePosition = value; | 97 | // Remember the displacement from root as well as the origional rotation of the |
75 | CenterOfMassLocation = RawPosition; | 98 | // new center-of-mass. |
76 | GeometricCenterLocation = RawPosition; | 99 | PositionDisplacement = comDisp; |
100 | OrientationDisplacement = OMV.Quaternion.Identity; | ||
77 | } | 101 | } |
78 | } | 102 | } |
79 | 103 | ||
80 | public override Quaternion ForceOrientation | 104 | public override Vector3 ForcePosition |
81 | { | 105 | { |
82 | get | 106 | get { return base.ForcePosition; } |
107 | set | ||
83 | { | 108 | { |
84 | return base.ForceOrientation; | 109 | if (PositionDisplacement != OMV.Vector3.Zero) |
110 | base.ForcePosition = value - (PositionDisplacement * RawOrientation); | ||
111 | else | ||
112 | base.ForcePosition = value; | ||
85 | } | 113 | } |
114 | } | ||
115 | |||
116 | public override Quaternion ForceOrientation | ||
117 | { | ||
118 | get { return base.ForceOrientation; } | ||
86 | set | 119 | set |
87 | { | 120 | { |
88 | base.ForceOrientation = value; | 121 | base.ForceOrientation = value; |
89 | } | 122 | } |
90 | } | 123 | } |
91 | 124 | ||
125 | // TODO: decide if this is the right place for these variables. | ||
126 | // Somehow incorporate the optional settability by the user. | ||
92 | // Is this used? | 127 | // Is this used? |
93 | public override OMV.Vector3 CenterOfMass | 128 | public override OMV.Vector3 CenterOfMass |
94 | { | 129 | { |
95 | get { return CenterOfMassLocation; } | 130 | get { return RawPosition; } |
96 | } | 131 | } |
97 | 132 | ||
98 | // Is this used? | 133 | // Is this used? |
99 | public override OMV.Vector3 GeometricCenter | 134 | public override OMV.Vector3 GeometricCenter |
100 | { | 135 | { |
101 | get { return GeometricCenterLocation; } | 136 | get { return RawPosition; } |
102 | } | 137 | } |
103 | 138 | ||
104 | |||
105 | public override void UpdateProperties(EntityProperties entprop) | 139 | public override void UpdateProperties(EntityProperties entprop) |
106 | { | 140 | { |
107 | // Undo any center-of-mass displacement that might have been done. | 141 | // Undo any center-of-mass displacement that might have been done. |
108 | if (PositionDisplacement != OMV.Vector3.Zero) | 142 | if (PositionDisplacement != OMV.Vector3.Zero || OrientationDisplacement != OMV.Quaternion.Identity) |
109 | { | 143 | { |
110 | // Correct for any rotation around the center-of-mass | 144 | // Correct for any rotation around the center-of-mass |
111 | // TODO!!! | 145 | // TODO!!! |
112 | entprop.Position -= PositionDisplacement; | 146 | entprop.Position = entprop.Position + (PositionDisplacement * entprop.Rotation); |
147 | entprop.Rotation = something; | ||
113 | } | 148 | } |
114 | 149 | ||
115 | base.UpdateProperties(entprop); | 150 | base.UpdateProperties(entprop); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 9898562..96f9762 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs | |||
@@ -38,6 +38,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
38 | public class BSPrimLinkable : BSPrimDisplaced | 38 | public class BSPrimLinkable : BSPrimDisplaced |
39 | { | 39 | { |
40 | public BSLinkset Linkset { get; set; } | 40 | public BSLinkset Linkset { get; set; } |
41 | // The index of this child prim. | ||
42 | public int LinksetChildIndex { get; set; } | ||
43 | |||
41 | public BSLinksetInfo LinksetInfo { get; set; } | 44 | public BSLinksetInfo LinksetInfo { get; set; } |
42 | 45 | ||
43 | public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, | 46 | public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, |
@@ -90,7 +93,6 @@ public class BSPrimLinkable : BSPrimDisplaced | |||
90 | DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", | 93 | DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", |
91 | LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); | 94 | LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); |
92 | return; | 95 | return; |
93 | base.delink(); | ||
94 | } | 96 | } |
95 | 97 | ||
96 | // When simulator changes position, this might be moving a child of the linkset. | 98 | // When simulator changes position, this might be moving a child of the linkset. |