aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
diff options
context:
space:
mode:
authorRobert Adams2012-07-23 09:30:28 -0700
committerRobert Adams2012-07-23 16:32:24 -0700
commit73f9e14b4326042dd218abd11f72eb46339c3a29 (patch)
tree511ba016b27758f4925c6bffefcaefd6614e809d /OpenSim/Region/Physics/BulletSPlugin
parentChange attachment handling to remove object from the scene first as per (diff)
downloadopensim-SC-73f9e14b4326042dd218abd11f72eb46339c3a29.zip
opensim-SC-73f9e14b4326042dd218abd11f72eb46339c3a29.tar.gz
opensim-SC-73f9e14b4326042dd218abd11f72eb46339c3a29.tar.bz2
opensim-SC-73f9e14b4326042dd218abd11f72eb46339c3a29.tar.xz
BulletSim: improve linking to add each link individually rather than rebuilding the object each time. Makes it an O(n) operation rather than O(n\!).
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs136
1 files changed, 76 insertions, 60 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 71a4303..a749a97 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -149,22 +149,26 @@ public sealed class BSPrim : PhysicsActor
149 { 149 {
150 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); 150 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
151 // DetailLog("{0},Destroy", LocalID); 151 // DetailLog("{0},Destroy", LocalID);
152
152 // Undo any vehicle properties 153 // Undo any vehicle properties
153 _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); 154 _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
154 _scene.RemoveVehiclePrim(this); // just to make sure 155 _scene.RemoveVehiclePrim(this); // just to make sure
155 156
156 // undo any dependance with/on other objects
157 if (_parentPrim != null)
158 {
159 // If I'm someone's child, tell them to forget about me.
160 _parentPrim.RemoveChildFromLinkset(this);
161 _parentPrim = null;
162 }
163
164 _scene.TaintedObject(delegate() 157 _scene.TaintedObject(delegate()
165 { 158 {
159 // undo any dependance with/on other objects
160 if (_parentPrim != null)
161 {
162 // If I'm someone's child, tell them to forget about me.
163 _parentPrim.RemoveChildFromLinkset(this);
164 _parentPrim = null;
165 }
166
167 // make sure there are no possible children depending on me
168 UnlinkAllChildren();
169
166 // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. 170 // everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
167 BulletSimAPI.DestroyObject(_scene.WorldID, _localID); 171 BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
168 }); 172 });
169 } 173 }
170 174
@@ -272,7 +276,8 @@ public sealed class BSPrim : PhysicsActor
272 DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID); 276 DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID);
273 _childrenPrims.Add(child); 277 _childrenPrims.Add(child);
274 child._parentPrim = this; // the child has gained a parent 278 child._parentPrim = this; // the child has gained a parent
275 RecreateGeomAndObject(); // rebuild my shape with the new child added 279 // RecreateGeomAndObject(); // rebuild my shape with the new child added
280 LinkAChildToMe(pchild); // build the physical binding between me and the child
276 } 281 }
277 }); 282 });
278 return; 283 return;
@@ -289,13 +294,18 @@ public sealed class BSPrim : PhysicsActor
289 { 294 {
290 DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); 295 DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
291 DetailLog("{0},RemoveChildToLinkset,child={1}", LocalID, pchild.LocalID); 296 DetailLog("{0},RemoveChildToLinkset,child={1}", LocalID, pchild.LocalID);
292 if (!BulletSimAPI.RemoveConstraintByID(_scene.WorldID, child.LocalID))
293 {
294 m_log.ErrorFormat("{0}: RemoveChildFromLinkset: Failed remove constraint for {1}", LogHeader, child.LocalID);
295 }
296 _childrenPrims.Remove(child); 297 _childrenPrims.Remove(child);
297 child._parentPrim = null; // the child has lost its parent 298 child._parentPrim = null; // the child has lost its parent
298 RecreateGeomAndObject(); // rebuild my shape with the child removed 299 if (_childrenPrims.Count == 0)
300 {
301 // if the linkset is empty, make sure all linkages have been removed
302 UnlinkAllChildren();
303 }
304 else
305 {
306 // RecreateGeomAndObject(); // rebuild my shape with the child removed
307 UnlinkAChildFromMe(pchild);
308 }
299 } 309 }
300 else 310 else
301 { 311 {
@@ -1247,30 +1257,6 @@ public sealed class BSPrim : PhysicsActor
1247 } 1257 }
1248 } 1258 }
1249 1259
1250 // Create a linkset by creating a compound hull at the root prim that consists of all
1251 // the children.
1252 // NOTE: This does not allow proper collisions with the children prims so it is not a workable solution
1253 void CreateLinksetWithCompoundHull()
1254 {
1255 // If I am the root prim of a linkset, replace my physical shape with all the
1256 // pieces of the children.
1257 // All of the children should have called CreateGeom so they have a hull
1258 // in the physics engine already. Here we pull together all of those hulls
1259 // into one shape.
1260 int totalPrimsInLinkset = _childrenPrims.Count + 1;
1261 // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, totalPrimsInLinkset);
1262 ShapeData[] shapes = new ShapeData[totalPrimsInLinkset];
1263 FillShapeInfo(out shapes[0]);
1264 int ii = 1;
1265 foreach (BSPrim prim in _childrenPrims)
1266 {
1267 // m_log.DebugFormat("{0}: CreateLinkset: adding prim {1}", LogHeader, prim.LocalID);
1268 prim.FillShapeInfo(out shapes[ii]);
1269 ii++;
1270 }
1271 BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes);
1272 }
1273
1274 // Copy prim's info into the BulletSim shape description structure 1260 // Copy prim's info into the BulletSim shape description structure
1275 public void FillShapeInfo(out ShapeData shape) 1261 public void FillShapeInfo(out ShapeData shape)
1276 { 1262 {
@@ -1290,9 +1276,10 @@ public sealed class BSPrim : PhysicsActor
1290 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; 1276 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
1291 } 1277 }
1292 1278
1279 #region Linkset creation and destruction
1280
1293 // Create the linkset by putting constraints between the objects of the set so they cannot move 1281 // Create the linkset by putting constraints between the objects of the set so they cannot move
1294 // relative to each other. 1282 // relative to each other.
1295 // TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added
1296 void CreateLinksetWithConstraints() 1283 void CreateLinksetWithConstraints()
1297 { 1284 {
1298 DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); 1285 DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
@@ -1306,29 +1293,58 @@ public sealed class BSPrim : PhysicsActor
1306 // create constraints between the root prim and each of the children 1293 // create constraints between the root prim and each of the children
1307 foreach (BSPrim prim in _childrenPrims) 1294 foreach (BSPrim prim in _childrenPrims)
1308 { 1295 {
1309 // Zero motion for children so they don't interpolate 1296 LinkAChildToMe(prim);
1310 prim.ZeroMotion();
1311
1312 // relative position normalized to the root prim
1313 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
1314 OMV.Vector3 childRelativePosition = (prim._position - this._position) * invThisOrientation;
1315
1316 // relative rotation of the child to the parent
1317 OMV.Quaternion childRelativeRotation = invThisOrientation * prim._orientation;
1318
1319 // this is a constraint that allows no freedom of movement between the two objects
1320 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
1321 DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
1322 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID,
1323 childRelativePosition,
1324 childRelativeRotation,
1325 OMV.Vector3.Zero,
1326 OMV.Quaternion.Identity,
1327 OMV.Vector3.Zero, OMV.Vector3.Zero,
1328 OMV.Vector3.Zero, OMV.Vector3.Zero);
1329 } 1297 }
1330 } 1298 }
1331 1299
1300 // Create a constraint between me (root of linkset) and the passed prim (the child).
1301 // Called at taint time!
1302 private void LinkAChildToMe(BSPrim childPrim)
1303 {
1304 // Zero motion for children so they don't interpolate
1305 childPrim.ZeroMotion();
1306
1307 // relative position normalized to the root prim
1308 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
1309 OMV.Vector3 childRelativePosition = (childPrim._position - this._position) * invThisOrientation;
1310
1311 // relative rotation of the child to the parent
1312 OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim._orientation;
1313
1314 // create a constraint that allows no freedom of movement between the two objects
1315 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
1316 DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
1317 DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
1318 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, childPrim.LocalID,
1319 childRelativePosition,
1320 childRelativeRotation,
1321 OMV.Vector3.Zero,
1322 OMV.Quaternion.Identity,
1323 OMV.Vector3.Zero, OMV.Vector3.Zero,
1324 OMV.Vector3.Zero, OMV.Vector3.Zero);
1325 }
1326
1327 // Remove linkage between myself and a particular child
1328 // Called at taint time!
1329 private void UnlinkAChildFromMe(BSPrim childPrim)
1330 {
1331 DebugLog("{0}: UnlinkAChildFromMe: RemoveConstraint between root prim {1} and child prim {2}",
1332 LogHeader, LocalID, childPrim.LocalID);
1333 DetailLog("{0},UnlinkAChildFromMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
1334 BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
1335 }
1336
1337 // Remove linkage between myself and any possible children I might have
1338 // Called at taint time!
1339 private void UnlinkAllChildren()
1340 {
1341 DebugLog("{0}: UnlinkAllChildren:", LogHeader);
1342 DetailLog("{0},UnlinkAllChildren,taint", LocalID);
1343 BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
1344 }
1345
1346 #endregion // Linkset creation and destruction
1347
1332 // Rebuild the geometry and object. 1348 // Rebuild the geometry and object.
1333 // This is called when the shape changes so we need to recreate the mesh/hull. 1349 // This is called when the shape changes so we need to recreate the mesh/hull.
1334 // No locking here because this is done when the physics engine is not simulating 1350 // No locking here because this is done when the physics engine is not simulating