diff options
author | Robert Adams | 2013-01-21 15:58:22 -0800 |
---|---|---|
committer | Robert Adams | 2013-01-21 15:58:22 -0800 |
commit | 471c4778639aec60078e6cee7c964682c959f033 (patch) | |
tree | 2e43aab8780c4b2556fd730529d5bd897fec151b /OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |
parent | Have SOP and LSL_Api call the proper GetCenterOfMass and GetGeometricCenter (diff) | |
download | opensim-SC-471c4778639aec60078e6cee7c964682c959f033.zip opensim-SC-471c4778639aec60078e6cee7c964682c959f033.tar.gz opensim-SC-471c4778639aec60078e6cee7c964682c959f033.tar.bz2 opensim-SC-471c4778639aec60078e6cee7c964682c959f033.tar.xz |
BulletSim: allow changing position and rotation of a child of a linkset
without rebuilding the whole compound shape. Should make vehicles move
smoother.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 94 |
1 files changed, 74 insertions, 20 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 8c9a774..27d8ad0 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 | ||
@@ -372,15 +434,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
372 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; | 434 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; |
373 | if (lci == null) | 435 | if (lci == null) |
374 | { | 436 | { |
375 | // Each child position and rotation is given relative to the center-of-mass. | 437 | 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; | 438 | cPrim.LinksetInfo = lci; |
385 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); | 439 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); |
386 | } | 440 | } |