aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs208
1 files changed, 116 insertions, 92 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 71a4303..a19d6d7 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -133,10 +133,7 @@ public sealed class BSPrim : PhysicsActor
133 _parentPrim = null; // not a child or a parent 133 _parentPrim = null; // not a child or a parent
134 _vehicle = new BSDynamics(this); // add vehicleness 134 _vehicle = new BSDynamics(this); // add vehicleness
135 _childrenPrims = new List<BSPrim>(); 135 _childrenPrims = new List<BSPrim>();
136 if (_isPhysical) 136 _mass = CalculateMass();
137 _mass = CalculateMass();
138 else
139 _mass = 0f;
140 // do the actual object creation at taint time 137 // do the actual object creation at taint time
141 _scene.TaintedObject(delegate() 138 _scene.TaintedObject(delegate()
142 { 139 {
@@ -149,22 +146,26 @@ public sealed class BSPrim : PhysicsActor
149 { 146 {
150 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); 147 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
151 // DetailLog("{0},Destroy", LocalID); 148 // DetailLog("{0},Destroy", LocalID);
149
152 // Undo any vehicle properties 150 // Undo any vehicle properties
153 _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); 151 _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
154 _scene.RemoveVehiclePrim(this); // just to make sure 152 _scene.RemoveVehiclePrim(this); // just to make sure
155 153
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() 154 _scene.TaintedObject(delegate()
165 { 155 {
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 // make sure there are no possible children depending on me
165 UnlinkAllChildren();
166
166 // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. 167 // everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
167 BulletSimAPI.DestroyObject(_scene.WorldID, _localID); 168 BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
168 }); 169 });
169 } 170 }
170 171
@@ -177,8 +178,8 @@ public sealed class BSPrim : PhysicsActor
177 _size = value; 178 _size = value;
178 _scene.TaintedObject(delegate() 179 _scene.TaintedObject(delegate()
179 { 180 {
180 if (_isPhysical) _mass = CalculateMass(); // changing size changes the mass 181 _mass = CalculateMass(); // changing size changes the mass
181 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, _mass, _isPhysical); 182 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, Mass, IsPhysical);
182 RecreateGeomAndObject(); 183 RecreateGeomAndObject();
183 }); 184 });
184 } 185 }
@@ -188,7 +189,7 @@ public sealed class BSPrim : PhysicsActor
188 _pbs = value; 189 _pbs = value;
189 _scene.TaintedObject(delegate() 190 _scene.TaintedObject(delegate()
190 { 191 {
191 if (_isPhysical) _mass = CalculateMass(); // changing the shape changes the mass 192 _mass = CalculateMass(); // changing the shape changes the mass
192 RecreateGeomAndObject(); 193 RecreateGeomAndObject();
193 }); 194 });
194 } 195 }
@@ -272,7 +273,10 @@ public sealed class BSPrim : PhysicsActor
272 DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID); 273 DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID);
273 _childrenPrims.Add(child); 274 _childrenPrims.Add(child);
274 child._parentPrim = this; // the child has gained a parent 275 child._parentPrim = this; // the child has gained a parent
275 RecreateGeomAndObject(); // rebuild my shape with the new child added 276 // RecreateGeomAndObject(); // rebuild my shape with the new child added
277 LinkAChildToMe(pchild); // build the physical binding between me and the child
278
279 _mass = CalculateMass();
276 } 280 }
277 }); 281 });
278 return; 282 return;
@@ -288,14 +292,21 @@ public sealed class BSPrim : PhysicsActor
288 if (_childrenPrims.Contains(child)) 292 if (_childrenPrims.Contains(child))
289 { 293 {
290 DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); 294 DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
291 DetailLog("{0},RemoveChildToLinkset,child={1}", LocalID, pchild.LocalID); 295 DetailLog("{0},RemoveChildFromLinkset,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); 296 _childrenPrims.Remove(child);
297 child._parentPrim = null; // the child has lost its parent 297 child._parentPrim = null; // the child has lost its parent
298 RecreateGeomAndObject(); // rebuild my shape with the child removed 298 if (_childrenPrims.Count == 0)
299 {
300 // if the linkset is empty, make sure all linkages have been removed
301 UnlinkAllChildren();
302 }
303 else
304 {
305 // RecreateGeomAndObject(); // rebuild my shape with the child removed
306 UnlinkAChildFromMe(pchild);
307 }
308
309 _mass = CalculateMass();
299 } 310 }
300 else 311 else
301 { 312 {
@@ -314,12 +325,19 @@ public sealed class BSPrim : PhysicsActor
314 // Set motion values to zero. 325 // Set motion values to zero.
315 // Do it to the properties so the values get set in the physics engine. 326 // Do it to the properties so the values get set in the physics engine.
316 // Push the setting of the values to the viewer. 327 // Push the setting of the values to the viewer.
328 // Called at taint time!
317 private void ZeroMotion() 329 private void ZeroMotion()
318 { 330 {
319 Velocity = OMV.Vector3.Zero; 331 _velocity = OMV.Vector3.Zero;
320 _acceleration = OMV.Vector3.Zero; 332 _acceleration = OMV.Vector3.Zero;
321 RotationalVelocity = OMV.Vector3.Zero; 333 _rotationalVelocity = OMV.Vector3.Zero;
322 base.RequestPhysicsterseUpdate(); 334
335 // Zero some other properties directly into the physics engine
336 IntPtr obj = BulletSimAPI.GetBodyHandleWorldID2(_scene.WorldID, LocalID);
337 BulletSimAPI.SetVelocity2(obj, OMV.Vector3.Zero);
338 BulletSimAPI.SetAngularVelocity2(obj, OMV.Vector3.Zero);
339 BulletSimAPI.SetInterpolation2(obj, OMV.Vector3.Zero, OMV.Vector3.Zero);
340 BulletSimAPI.ClearForces2(obj);
323 } 341 }
324 342
325 public override void LockAngularMotion(OMV.Vector3 axis) 343 public override void LockAngularMotion(OMV.Vector3 axis)
@@ -347,9 +365,17 @@ public sealed class BSPrim : PhysicsActor
347 }); 365 });
348 } 366 }
349 } 367 }
368
369 // Return the effective mass of the object. Non-physical objects do not have mass.
350 public override float Mass { 370 public override float Mass {
351 get { return _mass; } 371 get {
372 if (IsPhysical)
373 return _mass;
374 else
375 return 0f;
376 }
352 } 377 }
378
353 public override OMV.Vector3 Force { 379 public override OMV.Vector3 Force {
354 get { return _force; } 380 get { return _force; }
355 set { 381 set {
@@ -429,7 +455,8 @@ public sealed class BSPrim : PhysicsActor
429 // Called from Scene when doing simulation step so we're in taint processing time. 455 // Called from Scene when doing simulation step so we're in taint processing time.
430 public void StepVehicle(float timeStep) 456 public void StepVehicle(float timeStep)
431 { 457 {
432 _vehicle.Step(timeStep); 458 if (IsPhysical)
459 _vehicle.Step(timeStep);
433 } 460 }
434 461
435 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more 462 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
@@ -526,20 +553,13 @@ public sealed class BSPrim : PhysicsActor
526 { 553 {
527 // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); 554 // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid);
528 // non-physical things work best with a mass of zero 555 // non-physical things work best with a mass of zero
529 if (IsStatic) 556 if (!IsStatic)
530 {
531 _mass = 0f;
532 }
533 else
534 { 557 {
535 _mass = CalculateMass(); 558 _mass = CalculateMass();
536 // If it's dynamic, make sure the hull has been created for it
537 // This shouldn't do much work if the object had previously been built
538 RecreateGeomAndObject(); 559 RecreateGeomAndObject();
539
540 } 560 }
541 DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, _mass); 561 DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, Mass);
542 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass); 562 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), Mass);
543 } 563 }
544 564
545 // prims don't fly 565 // prims don't fly
@@ -1234,7 +1254,7 @@ public sealed class BSPrim : PhysicsActor
1234 if (IsRootOfLinkset) 1254 if (IsRootOfLinkset)
1235 { 1255 {
1236 // Create a linkset around this object 1256 // Create a linkset around this object
1237 CreateLinksetWithConstraints(); 1257 CreateLinkset();
1238 } 1258 }
1239 else 1259 else
1240 { 1260 {
@@ -1247,30 +1267,6 @@ public sealed class BSPrim : PhysicsActor
1247 } 1267 }
1248 } 1268 }
1249 1269
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 1270 // Copy prim's info into the BulletSim shape description structure
1275 public void FillShapeInfo(out ShapeData shape) 1271 public void FillShapeInfo(out ShapeData shape)
1276 { 1272 {
@@ -1280,7 +1276,7 @@ public sealed class BSPrim : PhysicsActor
1280 shape.Rotation = _orientation; 1276 shape.Rotation = _orientation;
1281 shape.Velocity = _velocity; 1277 shape.Velocity = _velocity;
1282 shape.Scale = _scale; 1278 shape.Scale = _scale;
1283 shape.Mass = _isPhysical ? _mass : 0f; 1279 shape.Mass = Mass;
1284 shape.Buoyancy = _buoyancy; 1280 shape.Buoyancy = _buoyancy;
1285 shape.HullKey = _hullKey; 1281 shape.HullKey = _hullKey;
1286 shape.MeshKey = _meshKey; 1282 shape.MeshKey = _meshKey;
@@ -1290,45 +1286,73 @@ public sealed class BSPrim : PhysicsActor
1290 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; 1286 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
1291 } 1287 }
1292 1288
1289 #region Linkset creation and destruction
1290
1293 // Create the linkset by putting constraints between the objects of the set so they cannot move 1291 // Create the linkset by putting constraints between the objects of the set so they cannot move
1294 // relative to each other. 1292 // relative to each other.
1295 // TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added 1293 void CreateLinkset()
1296 void CreateLinksetWithConstraints()
1297 { 1294 {
1298 DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); 1295 DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
1299 1296
1300 // remove any constraints that might be in place 1297 // remove any constraints that might be in place
1301 foreach (BSPrim prim in _childrenPrims) 1298 DebugLog("{0}: CreateLinkset: RemoveConstraints between me and any children", LogHeader, LocalID);
1302 { 1299 BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
1303 DebugLog("{0}: CreateLinkset: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID); 1300
1304 BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID);
1305 }
1306 // create constraints between the root prim and each of the children 1301 // create constraints between the root prim and each of the children
1307 foreach (BSPrim prim in _childrenPrims) 1302 foreach (BSPrim prim in _childrenPrims)
1308 { 1303 {
1309 // Zero motion for children so they don't interpolate 1304 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 } 1305 }
1330 } 1306 }
1331 1307
1308 // Create a constraint between me (root of linkset) and the passed prim (the child).
1309 // Called at taint time!
1310 private void LinkAChildToMe(BSPrim childPrim)
1311 {
1312 // Zero motion for children so they don't interpolate
1313 childPrim.ZeroMotion();
1314
1315 // relative position normalized to the root prim
1316 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
1317 OMV.Vector3 childRelativePosition = (childPrim._position - this._position) * invThisOrientation;
1318
1319 // relative rotation of the child to the parent
1320 OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim._orientation;
1321
1322 // create a constraint that allows no freedom of movement between the two objects
1323 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
1324 DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
1325 DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
1326 BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, childPrim.LocalID,
1327 childRelativePosition,
1328 childRelativeRotation,
1329 OMV.Vector3.Zero,
1330 OMV.Quaternion.Identity,
1331 OMV.Vector3.Zero, OMV.Vector3.Zero,
1332 OMV.Vector3.Zero, OMV.Vector3.Zero);
1333 }
1334
1335 // Remove linkage between myself and a particular child
1336 // Called at taint time!
1337 private void UnlinkAChildFromMe(BSPrim childPrim)
1338 {
1339 DebugLog("{0}: UnlinkAChildFromMe: RemoveConstraint between root prim {1} and child prim {2}",
1340 LogHeader, LocalID, childPrim.LocalID);
1341 DetailLog("{0},UnlinkAChildFromMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
1342 BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
1343 }
1344
1345 // Remove linkage between myself and any possible children I might have
1346 // Called at taint time!
1347 private void UnlinkAllChildren()
1348 {
1349 DebugLog("{0}: UnlinkAllChildren:", LogHeader);
1350 DetailLog("{0},UnlinkAllChildren,taint", LocalID);
1351 BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
1352 }
1353
1354 #endregion // Linkset creation and destruction
1355
1332 // Rebuild the geometry and object. 1356 // Rebuild the geometry and object.
1333 // This is called when the shape changes so we need to recreate the mesh/hull. 1357 // 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 1358 // No locking here because this is done when the physics engine is not simulating
@@ -1405,7 +1429,7 @@ public sealed class BSPrim : PhysicsActor
1405 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. 1429 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1406 1430
1407 // Updates only for individual prims and for the root object of a linkset. 1431 // Updates only for individual prims and for the root object of a linkset.
1408 if (this._parentPrim == null) 1432 if (_parentPrim == null)
1409 { 1433 {
1410 // Assign to the local variables so the normal set action does not happen 1434 // Assign to the local variables so the normal set action does not happen
1411 _position = entprop.Position; 1435 _position = entprop.Position;