aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
diff options
context:
space:
mode:
authorRobert Adams2013-02-10 09:51:34 -0800
committerRobert Adams2013-02-12 15:52:08 -0800
commitfb903ff49089d5fd7a56aa2401528c3e7cf1800c (patch)
tree2e6e28f88e6b7711165a8a315e3796241c4a11d2 /OpenSim/Region/Physics/BulletSPlugin
parentExtend TestJsonCreateStore() with a one key input and an input with raw numbe... (diff)
downloadopensim-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 '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs7
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs3
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs150
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs31
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs85
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs4
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{
45public class BSPrimDisplaced : BSPrim 45public 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
38public class BSPrimLinkable : BSPrimDisplaced 38public 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.