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.cs55
1 files changed, 42 insertions, 13 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index bd03d31..ad8024c 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 }
@@ -316,10 +329,23 @@ public sealed class BSLinksetCompound : BSLinkset
316 // Cause the root shape to be rebuilt as a compound object with just the root in it 329 // Cause the root shape to be rebuilt as a compound object with just the root in it
317 LinksetRoot.ForceBodyShapeRebuild(true); 330 LinksetRoot.ForceBodyShapeRebuild(true);
318 331
332 // The center of mass for the linkset is the geometric center of the group.
333 // Compute a displacement for each component so it is relative to the center-of-mass.
334 OMV.Vector3 centerOfMass = ComputeLinksetGeometricCenter();
335 OMV.Vector3 centerDisplacement = centerOfMass - LinksetRoot.RawPosition;
336
337 // Since we're displacing the center of the shape, we need to move the body in the world
338 LinksetRoot.PositionDisplacement = centerDisplacement * LinksetRoot.RawOrientation;
339
340 PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false);
341 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
342 LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement);
343
319 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", 344 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
320 LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); 345 LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
321 346
322 // Add a shape for each of the other children in the linkset 347 // Add a shape for each of the other children in the linkset
348 int memberIndex = 1;
323 ForEachMember(delegate(BSPhysObject cPrim) 349 ForEachMember(delegate(BSPhysObject cPrim)
324 { 350 {
325 if (!IsRoot(cPrim)) 351 if (!IsRoot(cPrim))
@@ -337,13 +363,14 @@ public sealed class BSLinksetCompound : BSLinkset
337 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; 363 OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
338 364
339 // Save relative position for recomputing child's world position after moving linkset. 365 // Save relative position for recomputing child's world position after moving linkset.
340 lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); 366 lci = new BSLinksetCompoundInfo(memberIndex, displacementPos, displacementRot);
367 lci.OffsetFromCenterOfMass = displacementPos - centerDisplacement;
341 cPrim.LinksetInfo = lci; 368 cPrim.LinksetInfo = lci;
342 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); 369 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
343 } 370 }
344 371
345 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", 372 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}",
346 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); 373 LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci);
347 374
348 if (cPrim.PhysShape.isNativeShape) 375 if (cPrim.PhysShape.isNativeShape)
349 { 376 {
@@ -359,7 +386,7 @@ public sealed class BSLinksetCompound : BSLinkset
359 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); 386 PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
360 BulletShape newShape = cPrim.PhysShape; 387 BulletShape newShape = cPrim.PhysShape;
361 cPrim.PhysShape = saveShape; 388 cPrim.PhysShape = saveShape;
362 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot); 389 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
363 } 390 }
364 else 391 else
365 { 392 {
@@ -371,8 +398,10 @@ public sealed class BSLinksetCompound : BSLinkset
371 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", 398 PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
372 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); 399 LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
373 } 400 }
374 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); 401 PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
375 } 402 }
403 lci.Index = memberIndex;
404 memberIndex++;
376 } 405 }
377 return false; // 'false' says to move onto the next child in the list 406 return false; // 'false' says to move onto the next child in the list
378 }); 407 });