diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 72 |
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. |
41 | sealed class BSLinksetCompoundInfo : BSLinksetInfo | 41 | sealed 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 | }); |