diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 55 |
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. |
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 | } |
@@ -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 | }); |