aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs72
1 files changed, 57 insertions, 15 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index bd03d31..5a1b5c7 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -40,23 +40,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin
40// removed from the linkset. 40// removed from the linkset.
41sealed class BSLinksetCompoundInfo : BSLinksetInfo 41sealed class BSLinksetCompoundInfo : BSLinksetInfo
42{ 42{
43 public OMV.Vector3 OffsetPos; 43 public int Index;
44 public OMV.Vector3 OffsetFromRoot;
45 public OMV.Vector3 OffsetFromCenterOfMass;
44 public OMV.Quaternion OffsetRot; 46 public OMV.Quaternion OffsetRot;
45 public BSLinksetCompoundInfo(OMV.Vector3 p, OMV.Quaternion r) 47 public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r)
46 { 48 {
47 OffsetPos = p; 49 Index = indx;
50 OffsetFromRoot = p;
51 OffsetFromCenterOfMass = p;
48 OffsetRot = r; 52 OffsetRot = r;
49 } 53 }
50 public override void Clear() 54 public override void Clear()
51 { 55 {
52 OffsetPos = OMV.Vector3.Zero; 56 Index = 0;
57 OffsetFromRoot = OMV.Vector3.Zero;
58 OffsetFromCenterOfMass = OMV.Vector3.Zero;
53 OffsetRot = OMV.Quaternion.Identity; 59 OffsetRot = OMV.Quaternion.Identity;
54 } 60 }
55 public override string ToString() 61 public override string ToString()
56 { 62 {
57 StringBuilder buff = new StringBuilder(); 63 StringBuilder buff = new StringBuilder();
58 buff.Append("<p="); 64 buff.Append("<i=");
59 buff.Append(OffsetPos.ToString()); 65 buff.Append(Index.ToString());
66 buff.Append(",p=");
67 buff.Append(OffsetFromRoot.ToString());
68 buff.Append(",m=");
69 buff.Append(OffsetFromCenterOfMass.ToString());
60 buff.Append(",r="); 70 buff.Append(",r=");
61 buff.Append(OffsetRot.ToString()); 71 buff.Append(OffsetRot.ToString());
62 buff.Append(">"); 72 buff.Append(">");
@@ -170,6 +180,8 @@ public sealed class BSLinksetCompound : BSLinkset
170 return ret; 180 return ret;
171 } 181 }
172 182
183 // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
184 // Called at taint-time.
173 public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) 185 public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate)
174 { 186 {
175 // The user moving a child around requires the rebuilding of the linkset compound shape 187 // The user moving a child around requires the rebuilding of the linkset compound shape
@@ -182,6 +194,7 @@ public sealed class BSLinksetCompound : BSLinkset
182 && !physicalUpdate 194 && !physicalUpdate
183 && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) 195 && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
184 { 196 {
197 // TODO: replace this with are calculation of the child prim's orientation and pos.
185 updated.LinksetInfo = null; 198 updated.LinksetInfo = null;
186 ScheduleRebuild(updated); 199 ScheduleRebuild(updated);
187 } 200 }
@@ -230,7 +243,7 @@ public sealed class BSLinksetCompound : BSLinkset
230 if (inTaintTime) 243 if (inTaintTime)
231 { 244 {
232 OMV.Vector3 oldPos = child.RawPosition; 245 OMV.Vector3 oldPos = child.RawPosition;
233 child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; 246 child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot;
234 child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; 247 child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
235 DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", 248 DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
236 child.LocalID, oldPos, lci, child.RawPosition); 249 child.LocalID, oldPos, lci, child.RawPosition);
@@ -238,7 +251,7 @@ public sealed class BSLinksetCompound : BSLinkset
238 else 251 else
239 { 252 {
240 // TaintedObject is not used here so the raw position is set now and not at taint-time. 253 // TaintedObject is not used here so the raw position is set now and not at taint-time.
241 child.Position = LinksetRoot.RawPosition + lci.OffsetPos; 254 child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot;
242 child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; 255 child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
243 } 256 }
244 } 257 }
@@ -306,6 +319,7 @@ public sealed class BSLinksetCompound : BSLinkset
306 // Constraint linksets are rebuilt every time. 319 // Constraint linksets are rebuilt every time.
307 // Note that this works for rebuilding just the root after a linkset is taken apart. 320 // Note that this works for rebuilding just the root after a linkset is taken apart.
308 // Called at taint time!! 321 // Called at taint time!!
322 private bool disableCOM = true; // disable until we get this debugged
309 private void RecomputeLinksetCompound() 323 private void RecomputeLinksetCompound()
310 { 324 {
311 try 325 try
@@ -316,10 +330,34 @@ public sealed class BSLinksetCompound : BSLinkset
316 // Cause the root shape to be rebuilt as a compound object with just the root in it 330 // Cause the root shape to be rebuilt as a compound object with just the root in it
317 LinksetRoot.ForceBodyShapeRebuild(true); 331 LinksetRoot.ForceBodyShapeRebuild(true);
318 332
333 // The center of mass for the linkset is the geometric center of the group.
334 // Compute a displacement for each component so it is relative to the center-of-mass.
335 // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
336 OMV.Vector3 centerOfMass;
337 OMV.Vector3 centerDisplacement = OMV.Vector3.Zero;
338 if (disableCOM) // DEBUG DEBUG
339 { // DEBUG DEBUG
340 centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
341 LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
342 } // DEBUG DEBUG
343 else
344 {
345 centerOfMass = ComputeLinksetGeometricCenter();
346 centerDisplacement = centerOfMass - LinksetRoot.RawPosition;
347
348 // Since we're displacing the center of the shape, we need to move the body in the world
349 LinksetRoot.PositionDisplacement = centerDisplacement;
350
351 PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false);
352 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
353 LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement);
354 }
355
319 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", 356 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
320 LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); 357 LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
321 358
322 // Add a shape for each of the other children in the linkset 359 // Add a shape for each of the other children in the linkset
360 int memberIndex = 1;
323 ForEachMember(delegate(BSPhysObject cPrim) 361 ForEachMember(delegate(BSPhysObject cPrim)
324 { 362 {
325 if (!IsRoot(cPrim)) 363 if (!IsRoot(cPrim))
@@ -331,19 +369,21 @@ public sealed class BSLinksetCompound : BSLinkset
331 BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; 369 BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
332 if (lci == null) 370 if (lci == null)
333 { 371 {
334 // Each child position and rotation is given relative to the root. 372 // Each child position and rotation is given relative to the center-of-mass.
335 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); 373 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
336 OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; 374 OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
375 OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
337 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; 376 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
338 377
339 // Save relative position for recomputing child's world position after moving linkset. 378 // Save relative position for recomputing child's world position after moving linkset.
340 lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); 379 lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot);
380 lci.OffsetFromRoot = displacementFromRoot;
341 cPrim.LinksetInfo = lci; 381 cPrim.LinksetInfo = lci;
342 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); 382 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
343 } 383 }
344 384
345 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", 385 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}",
346 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); 386 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci);
347 387
348 if (cPrim.PhysShape.isNativeShape) 388 if (cPrim.PhysShape.isNativeShape)
349 { 389 {
@@ -359,7 +399,7 @@ public sealed class BSLinksetCompound : BSLinkset
359 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); 399 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
360 BulletShape newShape = cPrim.PhysShape; 400 BulletShape newShape = cPrim.PhysShape;
361 cPrim.PhysShape = saveShape; 401 cPrim.PhysShape = saveShape;
362 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot); 402 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
363 } 403 }
364 else 404 else
365 { 405 {
@@ -371,8 +411,10 @@ public sealed class BSLinksetCompound : BSLinkset
371 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", 411 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
372 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); 412 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
373 } 413 }
374 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); 414 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
375 } 415 }
416 lci.Index = memberIndex;
417 memberIndex++;
376 } 418 }
377 return false; // 'false' says to move onto the next child in the list 419 return false; // 'false' says to move onto the next child in the list
378 }); 420 });