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.cs79
1 files changed, 62 insertions, 17 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index bd03d31..2dc89b5 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,8 +194,12 @@ public sealed class BSLinksetCompound : BSLinkset
182 && !physicalUpdate 194 && !physicalUpdate
183 && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) 195 && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
184 { 196 {
185 updated.LinksetInfo = null; 197 // TODO: replace this with are calculation of the child prim's orientation and pos.
186 ScheduleRebuild(updated); 198 // TODO: for the moment, don't rebuild the compound shape.
199 // This is often just the car turning its wheels. When we can just reorient the one
200 // member shape of the compound shape, the overhead of rebuilding won't be a problem.
201 // updated.LinksetInfo = null;
202 // ScheduleRebuild(updated);
187 } 203 }
188 } 204 }
189 205
@@ -230,7 +246,7 @@ public sealed class BSLinksetCompound : BSLinkset
230 if (inTaintTime) 246 if (inTaintTime)
231 { 247 {
232 OMV.Vector3 oldPos = child.RawPosition; 248 OMV.Vector3 oldPos = child.RawPosition;
233 child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetPos; 249 child.ForcePosition = LinksetRoot.RawPosition + lci.OffsetFromRoot;
234 child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot; 250 child.ForceOrientation = LinksetRoot.RawOrientation * lci.OffsetRot;
235 DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}", 251 DetailLog("{0},BSLinksetCompound.RecomputeChildWorldPosition,oldPos={1},lci={2},newPos={3}",
236 child.LocalID, oldPos, lci, child.RawPosition); 252 child.LocalID, oldPos, lci, child.RawPosition);
@@ -238,7 +254,7 @@ public sealed class BSLinksetCompound : BSLinkset
238 else 254 else
239 { 255 {
240 // TaintedObject is not used here so the raw position is set now and not at taint-time. 256 // TaintedObject is not used here so the raw position is set now and not at taint-time.
241 child.Position = LinksetRoot.RawPosition + lci.OffsetPos; 257 child.Position = LinksetRoot.RawPosition + lci.OffsetFromRoot;
242 child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot; 258 child.Orientation = LinksetRoot.RawOrientation * lci.OffsetRot;
243 } 259 }
244 } 260 }
@@ -306,6 +322,7 @@ public sealed class BSLinksetCompound : BSLinkset
306 // Constraint linksets are rebuilt every time. 322 // Constraint linksets are rebuilt every time.
307 // Note that this works for rebuilding just the root after a linkset is taken apart. 323 // Note that this works for rebuilding just the root after a linkset is taken apart.
308 // Called at taint time!! 324 // Called at taint time!!
325 private bool disableCOM = true; // disable until we get this debugged
309 private void RecomputeLinksetCompound() 326 private void RecomputeLinksetCompound()
310 { 327 {
311 try 328 try
@@ -316,10 +333,34 @@ public sealed class BSLinksetCompound : BSLinkset
316 // Cause the root shape to be rebuilt as a compound object with just the root in it 333 // Cause the root shape to be rebuilt as a compound object with just the root in it
317 LinksetRoot.ForceBodyShapeRebuild(true); 334 LinksetRoot.ForceBodyShapeRebuild(true);
318 335
336 // The center of mass for the linkset is the geometric center of the group.
337 // Compute a displacement for each component so it is relative to the center-of-mass.
338 // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
339 OMV.Vector3 centerOfMass;
340 OMV.Vector3 centerDisplacement = OMV.Vector3.Zero;
341 if (disableCOM) // DEBUG DEBUG
342 { // DEBUG DEBUG
343 centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
344 LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
345 } // DEBUG DEBUG
346 else
347 {
348 centerOfMass = ComputeLinksetGeometricCenter();
349 centerDisplacement = centerOfMass - LinksetRoot.RawPosition;
350
351 // Since we're displacing the center of the shape, we need to move the body in the world
352 LinksetRoot.PositionDisplacement = centerDisplacement;
353
354 PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false);
355 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
356 LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement);
357 }
358
319 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", 359 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
320 LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); 360 LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
321 361
322 // Add a shape for each of the other children in the linkset 362 // Add a shape for each of the other children in the linkset
363 int memberIndex = 1;
323 ForEachMember(delegate(BSPhysObject cPrim) 364 ForEachMember(delegate(BSPhysObject cPrim)
324 { 365 {
325 if (!IsRoot(cPrim)) 366 if (!IsRoot(cPrim))
@@ -331,19 +372,21 @@ public sealed class BSLinksetCompound : BSLinkset
331 BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; 372 BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
332 if (lci == null) 373 if (lci == null)
333 { 374 {
334 // Each child position and rotation is given relative to the root. 375 // Each child position and rotation is given relative to the center-of-mass.
335 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); 376 OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
336 OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; 377 OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
378 OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
337 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; 379 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
338 380
339 // Save relative position for recomputing child's world position after moving linkset. 381 // Save relative position for recomputing child's world position after moving linkset.
340 lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); 382 lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot);
383 lci.OffsetFromRoot = displacementFromRoot;
341 cPrim.LinksetInfo = lci; 384 cPrim.LinksetInfo = lci;
342 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); 385 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
343 } 386 }
344 387
345 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", 388 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}",
346 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); 389 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci);
347 390
348 if (cPrim.PhysShape.isNativeShape) 391 if (cPrim.PhysShape.isNativeShape)
349 { 392 {
@@ -359,7 +402,7 @@ public sealed class BSLinksetCompound : BSLinkset
359 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); 402 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
360 BulletShape newShape = cPrim.PhysShape; 403 BulletShape newShape = cPrim.PhysShape;
361 cPrim.PhysShape = saveShape; 404 cPrim.PhysShape = saveShape;
362 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot); 405 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
363 } 406 }
364 else 407 else
365 { 408 {
@@ -371,8 +414,10 @@ public sealed class BSLinksetCompound : BSLinkset
371 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", 414 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
372 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); 415 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
373 } 416 }
374 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); 417 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
375 } 418 }
419 lci.Index = memberIndex;
420 memberIndex++;
376 } 421 }
377 return false; // 'false' says to move onto the next child in the list 422 return false; // 'false' says to move onto the next child in the list
378 }); 423 });