diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 113 |
1 files changed, 82 insertions, 31 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 8c9a774..2c8dd23 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -51,6 +51,21 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo | |||
51 | OffsetFromCenterOfMass = p; | 51 | OffsetFromCenterOfMass = p; |
52 | OffsetRot = r; | 52 | OffsetRot = r; |
53 | } | 53 | } |
54 | // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape) | ||
55 | public BSLinksetCompoundInfo(int indx, BSPhysObject root, BSPhysObject child, OMV.Vector3 centerDisplacement) | ||
56 | { | ||
57 | // Each child position and rotation is given relative to the center-of-mass. | ||
58 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation); | ||
59 | OMV.Vector3 displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation; | ||
60 | OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; | ||
61 | OMV.Quaternion displacementRot = child.RawOrientation * invRootOrientation; | ||
62 | |||
63 | // Save relative position for recomputing child's world position after moving linkset. | ||
64 | Index = indx; | ||
65 | OffsetFromRoot = displacementFromRoot; | ||
66 | OffsetFromCenterOfMass = displacementFromCOM; | ||
67 | OffsetRot = displacementRot; | ||
68 | } | ||
54 | public override void Clear() | 69 | public override void Clear() |
55 | { | 70 | { |
56 | Index = 0; | 71 | Index = 0; |
@@ -182,24 +197,71 @@ public sealed class BSLinksetCompound : BSLinkset | |||
182 | 197 | ||
183 | // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then. | 198 | // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then. |
184 | // Called at taint-time. | 199 | // Called at taint-time. |
185 | public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate) | 200 | public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject updated) |
186 | { | 201 | { |
187 | // The user moving a child around requires the rebuilding of the linkset compound shape | 202 | // The user moving a child around requires the rebuilding of the linkset compound shape |
188 | // One problem is this happens when a border is crossed -- the simulator implementation | 203 | // One problem is this happens when a border is crossed -- the simulator implementation |
189 | // is to store the position into the group which causes the move of the object | 204 | // stores the position into the group which causes the move of the object |
190 | // but it also means all the child positions get updated. | 205 | // but it also means all the child positions get updated. |
191 | // What would cause an unnecessary rebuild so we make sure the linkset is in a | 206 | // What would cause an unnecessary rebuild so we make sure the linkset is in a |
192 | // region before bothering to do a rebuild. | 207 | // region before bothering to do a rebuild. |
193 | if (!IsRoot(updated) | 208 | if (!IsRoot(updated) && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) |
194 | && !physicalUpdate | ||
195 | && PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition)) | ||
196 | { | 209 | { |
197 | // TODO: replace this with are calculation of the child prim's orientation and pos. | 210 | // If a child of the linkset is updating only the position or rotation, that can be done |
198 | // TODO: for the moment, don't rebuild the compound shape. | 211 | // without rebuilding the linkset. |
199 | // This is often just the car turning its wheels. When we can just reorient the one | 212 | // If a handle for the child can be fetch, we update the child here. If a rebuild was |
200 | // member shape of the compound shape, the overhead of rebuilding won't be a problem. | 213 | // scheduled by someone else, the rebuild will just replace this setting. |
201 | // updated.LinksetInfo = null; | 214 | |
202 | // ScheduleRebuild(updated); | 215 | bool updatedChild = false; |
216 | // Anything other than updating position or orientation usually means a physical update | ||
217 | // and that is caused by us updating the object. | ||
218 | if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0) | ||
219 | { | ||
220 | // Gather the child info. It might not be there if the linkset is in transition. | ||
221 | BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo; | ||
222 | if (LinksetRoot.PhysShape.HasPhysicalShape && lsi != null) | ||
223 | { | ||
224 | if (PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape)) | ||
225 | { | ||
226 | BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index); | ||
227 | if (linksetChildShape.HasPhysicalShape) | ||
228 | { | ||
229 | // Compute the offset from the center-of-gravity | ||
230 | BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); | ||
231 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index, | ||
232 | newLsi.OffsetFromCenterOfMass, | ||
233 | newLsi.OffsetRot, | ||
234 | true /* shouldRecalculateLocalAabb */); | ||
235 | DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1}newLsi={2}", | ||
236 | updated.LocalID, whichUpdated, newLsi); | ||
237 | updated.LinksetInfo = newLsi; | ||
238 | updatedChild = true; | ||
239 | } | ||
240 | else // DEBUG DEBUG | ||
241 | { // DEBUG DEBUG | ||
242 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noChildShape,shape={1}", | ||
243 | updated.LocalID, linksetChildShape); | ||
244 | } // DEBUG DEBUG | ||
245 | } | ||
246 | else // DEBUG DEBUG | ||
247 | { // DEBUG DEBUG | ||
248 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,notCompound", updated.LocalID); | ||
249 | } // DEBUG DEBUG | ||
250 | } | ||
251 | else // DEBUG DEBUG | ||
252 | { // DEBUG DEBUG | ||
253 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,rootPhysShape={1},lsi={2}", | ||
254 | updated.LocalID, LinksetRoot.PhysShape, lsi == null ? "NULL" : lsi.ToString()); | ||
255 | } // DEBUG DEBUG | ||
256 | if (!updatedChild) | ||
257 | { | ||
258 | // If couldn't do the individual child, the linkset needs a rebuild to incorporate the new child info. | ||
259 | DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}", | ||
260 | updated.LocalID, whichUpdated); | ||
261 | updated.LinksetInfo = null; // setting to 'null' causes relative position to be recomputed. | ||
262 | ScheduleRebuild(updated); | ||
263 | } | ||
264 | } | ||
203 | } | 265 | } |
204 | } | 266 | } |
205 | 267 | ||
@@ -228,13 +290,6 @@ public sealed class BSLinksetCompound : BSLinkset | |||
228 | return ret; | 290 | return ret; |
229 | } | 291 | } |
230 | 292 | ||
231 | // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', | ||
232 | // this routine will restore the removed constraints. | ||
233 | // Called at taint-time!! | ||
234 | public override void RestoreBodyDependencies(BSPrim child) | ||
235 | { | ||
236 | } | ||
237 | |||
238 | // When the linkset is built, the child shape is added to the compound shape relative to the | 293 | // When the linkset is built, the child shape is added to the compound shape relative to the |
239 | // root shape. The linkset then moves around but this does not move the actual child | 294 | // root shape. The linkset then moves around but this does not move the actual child |
240 | // prim. The child prim's location must be recomputed based on the location of the root shape. | 295 | // prim. The child prim's location must be recomputed based on the location of the root shape. |
@@ -322,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
322 | // Constraint linksets are rebuilt every time. | 377 | // Constraint linksets are rebuilt every time. |
323 | // Note that this works for rebuilding just the root after a linkset is taken apart. | 378 | // Note that this works for rebuilding just the root after a linkset is taken apart. |
324 | // Called at taint time!! | 379 | // Called at taint time!! |
325 | private bool disableCOM = true; // disable until we get this debugged | 380 | private bool disableCOM = false; // disable until we get this debugged |
326 | private void RecomputeLinksetCompound() | 381 | private void RecomputeLinksetCompound() |
327 | { | 382 | { |
328 | try | 383 | try |
@@ -345,12 +400,16 @@ public sealed class BSLinksetCompound : BSLinkset | |||
345 | } // DEBUG DEBUG | 400 | } // DEBUG DEBUG |
346 | else | 401 | else |
347 | { | 402 | { |
348 | centerOfMass = ComputeLinksetGeometricCenter(); | 403 | centerOfMass = ComputeLinksetCenterOfMass(); |
349 | centerDisplacement = centerOfMass - LinksetRoot.RawPosition; | 404 | // 'centerDisplacement' is the value to *add* to all the shape offsets |
405 | centerDisplacement = LinksetRoot.RawPosition - centerOfMass; | ||
350 | 406 | ||
351 | // Since we're displacing the center of the shape, we need to move the body in the world | 407 | // Since we're displacing the center of the shape, we need to move the body in the world |
352 | LinksetRoot.PositionDisplacement = centerDisplacement; | 408 | LinksetRoot.PositionDisplacement = centerDisplacement; |
353 | 409 | ||
410 | // This causes the root prim position to be set properly based on the new PositionDisplacement | ||
411 | LinksetRoot.ForcePosition = LinksetRoot.RawPosition; | ||
412 | // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM | ||
354 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); | 413 | PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); |
355 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", | 414 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", |
356 | LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); | 415 | LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); |
@@ -372,15 +431,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
372 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; | 431 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; |
373 | if (lci == null) | 432 | if (lci == null) |
374 | { | 433 | { |
375 | // Each child position and rotation is given relative to the center-of-mass. | 434 | lci = new BSLinksetCompoundInfo(memberIndex, LinksetRoot, cPrim, centerDisplacement); |
376 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); | ||
377 | OMV.Vector3 displacementFromRoot = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; | ||
378 | OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; | ||
379 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; | ||
380 | |||
381 | // Save relative position for recomputing child's world position after moving linkset. | ||
382 | lci = new BSLinksetCompoundInfo(memberIndex, displacementFromCOM, displacementRot); | ||
383 | lci.OffsetFromRoot = displacementFromRoot; | ||
384 | cPrim.LinksetInfo = lci; | 435 | cPrim.LinksetInfo = lci; |
385 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); | 436 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); |
386 | } | 437 | } |
@@ -390,7 +441,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
390 | 441 | ||
391 | if (cPrim.PhysShape.isNativeShape) | 442 | if (cPrim.PhysShape.isNativeShape) |
392 | { | 443 | { |
393 | // A native shape is turning into a hull collision shape because native | 444 | // A native shape is turned into a hull collision shape because native |
394 | // shapes are not shared so we have to hullify it so it will be tracked | 445 | // shapes are not shared so we have to hullify it so it will be tracked |
395 | // and freed at the correct time. This also solves the scaling problem | 446 | // and freed at the correct time. This also solves the scaling problem |
396 | // (native shapes scaled but hull/meshes are assumed to not be). | 447 | // (native shapes scaled but hull/meshes are assumed to not be). |