diff options
author | Robert Adams | 2012-07-23 09:30:28 -0700 |
---|---|---|
committer | Robert Adams | 2012-07-23 16:32:24 -0700 |
commit | 73f9e14b4326042dd218abd11f72eb46339c3a29 (patch) | |
tree | 511ba016b27758f4925c6bffefcaefd6614e809d | |
parent | Change attachment handling to remove object from the scene first as per (diff) | |
download | opensim-SC_OLD-73f9e14b4326042dd218abd11f72eb46339c3a29.zip opensim-SC_OLD-73f9e14b4326042dd218abd11f72eb46339c3a29.tar.gz opensim-SC_OLD-73f9e14b4326042dd218abd11f72eb46339c3a29.tar.bz2 opensim-SC_OLD-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\!).
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 136 |
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 |