aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
diff options
context:
space:
mode:
authorRobert Adams2013-01-21 15:58:22 -0800
committerRobert Adams2013-01-21 15:58:22 -0800
commit471c4778639aec60078e6cee7c964682c959f033 (patch)
tree2e43aab8780c4b2556fd730529d5bd897fec151b /OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
parentHave SOP and LSL_Api call the proper GetCenterOfMass and GetGeometricCenter (diff)
downloadopensim-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-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs94
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 }