aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
diff options
context:
space:
mode:
authorRobert Adams2012-09-20 10:12:51 -0700
committerRobert Adams2012-09-27 22:01:26 -0700
commit22290ef35aa13edb1501c69b3cce63a885302563 (patch)
tree2c4762479fb5336c3338acdd2d761fc8c15a04e9 /OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
parentBulletSim: add class and infrastructure for shape and object (diff)
downloadopensim-SC-22290ef35aa13edb1501c69b3cce63a885302563.zip
opensim-SC-22290ef35aa13edb1501c69b3cce63a885302563.tar.gz
opensim-SC-22290ef35aa13edb1501c69b3cce63a885302563.tar.bz2
opensim-SC-22290ef35aa13edb1501c69b3cce63a885302563.tar.xz
BulletSim: complete code for managed code shape and body tracking. Not debugged.
Eliminate some null exceptions created adding the above code. Add and remove some detailed logging statements.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs121
1 files changed, 78 insertions, 43 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 4d17e6c..4d2c70c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -96,7 +96,7 @@ public sealed class BSPrim : BSPhysObject
96 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) 96 OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
97 { 97 {
98 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); 98 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
99 base.BaseInitialize(parent_scene, localID, primName); 99 base.BaseInitialize(parent_scene, localID, primName, "BSPrim");
100 _physicsActorType = (int)ActorTypes.Prim; 100 _physicsActorType = (int)ActorTypes.Prim;
101 _position = pos; 101 _position = pos;
102 _size = size; 102 _size = size;
@@ -115,17 +115,17 @@ public sealed class BSPrim : BSPhysObject
115 _restitution = PhysicsScene.Params.defaultRestitution; 115 _restitution = PhysicsScene.Params.defaultRestitution;
116 _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness 116 _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness
117 _mass = CalculateMass(); 117 _mass = CalculateMass();
118
119 // No body or shape yet
120 BSBody = new BulletBody(LocalID, IntPtr.Zero);
121 BSShape = new BulletShape(IntPtr.Zero);
122
118 DetailLog("{0},BSPrim.constructor,call", LocalID); 123 DetailLog("{0},BSPrim.constructor,call", LocalID);
119 // do the actual object creation at taint time 124 // do the actual object creation at taint time
120 PhysicsScene.TaintedObject("BSPrim.create", delegate() 125 PhysicsScene.TaintedObject("BSPrim.create", delegate()
121 { 126 {
122 CreateGeomAndObject(true); 127 CreateGeomAndObject(true);
123 128
124 // Get the pointer to the physical body for this object.
125 // At the moment, we're still letting BulletSim manage the creation and destruction
126 // of the object. Someday we'll move that into the C# code.
127 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID));
128 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
129 CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr); 129 CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
130 }); 130 });
131 } 131 }
@@ -168,17 +168,24 @@ public sealed class BSPrim : BSPhysObject
168 // Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct 168 // Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct
169 // scale and margins are set. 169 // scale and margins are set.
170 CreateGeomAndObject(true); 170 CreateGeomAndObject(true);
171 DetailLog("{0}: BSPrim.setSize: size={1}, scale={2}, mass={3}, physical={4}", LocalID, _size, _scale, _mass, IsPhysical); 171 DetailLog("{0},BSPrim.setSize,size={1},scale={2},mass={3},physical={4}", LocalID, _size, _scale, _mass, IsPhysical);
172 }); 172 });
173 } 173 }
174 } 174 }
175 // Scale is what we set in the physics engine. It is different than 'size' in that
176 // 'size' can be encorporated into the mesh. In that case, the scale is <1,1,1>.
177 public OMV.Vector3 Scale
178 {
179 get { return _scale; }
180 set { _scale = value; }
181 }
175 public override PrimitiveBaseShape Shape { 182 public override PrimitiveBaseShape Shape {
176 set { 183 set {
177 _pbs = value; 184 _pbs = value;
178 PhysicsScene.TaintedObject("BSPrim.setShape", delegate() 185 PhysicsScene.TaintedObject("BSPrim.setShape", delegate()
179 { 186 {
180 _mass = CalculateMass(); // changing the shape changes the mass 187 _mass = CalculateMass(); // changing the shape changes the mass
181 CreateGeomAndObject(false); 188 CreateGeomAndObject(true);
182 }); 189 });
183 } 190 }
184 } 191 }
@@ -191,7 +198,7 @@ public sealed class BSPrim : BSPhysObject
191 _isSelected = value; 198 _isSelected = value;
192 PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() 199 PhysicsScene.TaintedObject("BSPrim.setSelected", delegate()
193 { 200 {
194 SetObjectDynamic(); 201 SetObjectDynamic(false);
195 }); 202 });
196 } 203 }
197 } 204 }
@@ -371,7 +378,7 @@ public sealed class BSPrim : BSPhysObject
371 PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() 378 PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
372 { 379 {
373 DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); 380 DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect);
374 SetObjectDynamic(); 381 SetObjectDynamic(true);
375 }); 382 });
376 return; 383 return;
377 } 384 }
@@ -433,7 +440,7 @@ public sealed class BSPrim : BSPhysObject
433 PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() 440 PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate()
434 { 441 {
435 DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); 442 DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
436 SetObjectDynamic(); 443 SetObjectDynamic(true);
437 }); 444 });
438 } 445 }
439 } 446 }
@@ -445,7 +452,7 @@ public sealed class BSPrim : BSPhysObject
445 } 452 }
446 453
447 // An object is solid if it's not phantom and if it's not doing VolumeDetect 454 // An object is solid if it's not phantom and if it's not doing VolumeDetect
448 private bool IsSolid 455 public bool IsSolid
449 { 456 {
450 get { return !IsPhantom && !_isVolumeDetect; } 457 get { return !IsPhantom && !_isVolumeDetect; }
451 } 458 }
@@ -457,21 +464,23 @@ public sealed class BSPrim : BSPhysObject
457 // isSolid: other objects bounce off of this object 464 // isSolid: other objects bounce off of this object
458 // isVolumeDetect: other objects pass through but can generate collisions 465 // isVolumeDetect: other objects pass through but can generate collisions
459 // collisionEvents: whether this object returns collision events 466 // collisionEvents: whether this object returns collision events
460 private void SetObjectDynamic() 467 private void SetObjectDynamic(bool forceRebuild)
461 { 468 {
469#if CSHARP_BODY_MANAGEMENT
470 // Recreate the physical object if necessary
471 CreateGeomAndObject(forceRebuild);
472#else
462 // If it's becoming dynamic, it will need hullness 473 // If it's becoming dynamic, it will need hullness
463 VerifyCorrectPhysicalShape(); 474 VerifyCorrectPhysicalShape();
464 UpdatePhysicalParameters(); 475 UpdatePhysicalParameters();
476#endif // CSHARP_BODY_MANAGEMENT
465 } 477 }
466 478
467 private void UpdatePhysicalParameters() 479 private void UpdatePhysicalParameters()
468 { 480 {
469 /* 481 DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape);
470 // Bullet wants static objects to have a mass of zero
471 float mass = IsStatic ? 0f : _mass;
472 482
473 BulletSimAPI.SetObjectProperties(Scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); 483 // Mangling all the physical properties requires the object to be out of the physical world
474 */
475 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr); 484 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr);
476 485
477 // Make solid or not (do things bounce off or pass through this object) 486 // Make solid or not (do things bounce off or pass through this object)
@@ -517,8 +526,8 @@ public sealed class BSPrim : BSPhysObject
517 // There can be special things needed for implementing linksets 526 // There can be special things needed for implementing linksets
518 Linkset.MakeStatic(this); 527 Linkset.MakeStatic(this);
519 // The activation state is 'sleeping' so Bullet will not try to act on it 528 // The activation state is 'sleeping' so Bullet will not try to act on it
520 // BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING); 529 BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING);
521 BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.DISABLE_SIMULATION); 530 // BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.DISABLE_SIMULATION);
522 } 531 }
523 else 532 else
524 { 533 {
@@ -560,8 +569,8 @@ public sealed class BSPrim : BSPhysObject
560 // the functions after this one set up the state of a possibly newly created collision body. 569 // the functions after this one set up the state of a possibly newly created collision body.
561 private void MakeSolid(bool makeSolid) 570 private void MakeSolid(bool makeSolid)
562 { 571 {
572#if !CSHARP_BODY_MANAGEMENT
563 CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.Ptr); 573 CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.Ptr);
564 /*
565 if (makeSolid) 574 if (makeSolid)
566 { 575 {
567 if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0) 576 if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0)
@@ -569,11 +578,16 @@ public sealed class BSPrim : BSPhysObject
569 // Solid things are made out of rigid bodies. Remove this old body from the world 578 // Solid things are made out of rigid bodies. Remove this old body from the world
570 // and use this shape in a new rigid body. 579 // and use this shape in a new rigid body.
571 BulletBody oldBody = BSBody; 580 BulletBody oldBody = BSBody;
572 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr); 581 // Zero out the pointer to the shape in the old body so the shape will not get freed
573 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr)); 582 BSShape.Ptr = BulletSimAPI.GetCollisionShape2(oldBody.Ptr);
583 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.Ptr, oldBody.Ptr, IntPtr.Zero);
584 // Get rid of the old body and remove it from BulletSim's object list
585 BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID);
586
587 // Create the new body with the shape
574 BSBody = new BulletBody(LocalID, BulletSimAPI.CreateBodyFromShape2(PhysicsScene.World.Ptr, BSShape.Ptr, _position, _orientation)); 588 BSBody = new BulletBody(LocalID, BulletSimAPI.CreateBodyFromShape2(PhysicsScene.World.Ptr, BSShape.Ptr, _position, _orientation));
575 BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, oldBody.Ptr); 589 BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
576 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, BSBody.Ptr); 590 DetailLog("{0},BSPrim.MakeSolid:rigidBody,body={1},shape={2}", LocalID, BSBody, BSShape);
577 } 591 }
578 } 592 }
579 else 593 else
@@ -583,23 +597,20 @@ public sealed class BSPrim : BSPhysObject
583 // Non-solid things are made out of ghost objects. Remove this old body from the world 597 // Non-solid things are made out of ghost objects. Remove this old body from the world
584 // and use this shape in a new rigid body. 598 // and use this shape in a new rigid body.
585 BulletBody oldBody = BSBody; 599 BulletBody oldBody = BSBody;
586 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr); 600
587 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr)); 601 // Zero out the pointer to the shape in the old body so the shape will not get freed
602 BSShape.Ptr = BulletSimAPI.GetCollisionShape2(oldBody.Ptr);
603 BulletSimAPI.SetCollisionShape2(PhysicsScene.World.Ptr, oldBody.Ptr, IntPtr.Zero);
604 // Get rid of the old body and remove it from BulletSim's object list
605 BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID);
606
588 BSBody = new BulletBody(LocalID, 607 BSBody = new BulletBody(LocalID,
589 BulletSimAPI.CreateGhostFromShape2(PhysicsScene.World.Ptr, BSShape.Ptr, _position, _orientation)); 608 BulletSimAPI.CreateGhostFromShape2(PhysicsScene.World.Ptr, BSShape.Ptr, _position, _orientation));
590 if (BSBody.Ptr == IntPtr.Zero) 609 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
591 { 610 DetailLog("{0},BSPrim.MakeGhostBody,body={1},shape={2}", LocalID, BSBody, BSShape);
592 m_log.ErrorFormat("{0} BSPrim.MakeSolid: failed creation of ghost object. LocalID=[1}", LogHeader, LocalID);
593 BSBody = oldBody;
594 }
595 else
596 {
597 BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, oldBody.Ptr);
598 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, BSBody.Ptr);
599 }
600 } 611 }
601 } 612 }
602 */ 613#endif
603 } 614 }
604 615
605 // Turn on or off the flag controlling whether collision events are returned to the simulator. 616 // Turn on or off the flag controlling whether collision events are returned to the simulator.
@@ -1067,6 +1078,7 @@ public sealed class BSPrim : BSPhysObject
1067 }// end CalculateMass 1078 }// end CalculateMass
1068 #endregion Mass Calculation 1079 #endregion Mass Calculation
1069 1080
1081#if !CSHARP_BODY_MANAGEMENT
1070 // Create the geometry information in Bullet for later use. 1082 // Create the geometry information in Bullet for later use.
1071 // The objects needs a hull if it's physical otherwise a mesh is enough. 1083 // The objects needs a hull if it's physical otherwise a mesh is enough.
1072 // No locking here because this is done when we know physics is not simulating. 1084 // No locking here because this is done when we know physics is not simulating.
@@ -1095,6 +1107,7 @@ public sealed class BSPrim : BSPhysObject
1095 { 1107 {
1096 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); 1108 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
1097 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; 1109 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
1110 _meshKey = (ulong)ShapeData.FixedShapeKey.KEY_SPHERE;
1098 // Bullet native objects are scaled by the Bullet engine so pass the size in 1111 // Bullet native objects are scaled by the Bullet engine so pass the size in
1099 _scale = _size; 1112 _scale = _size;
1100 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? 1113 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
@@ -1109,6 +1122,7 @@ public sealed class BSPrim : BSPhysObject
1109 { 1122 {
1110 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); 1123 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
1111 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; 1124 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
1125 _meshKey = (ulong)ShapeData.FixedShapeKey.KEY_BOX;
1112 _scale = _size; 1126 _scale = _size;
1113 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? 1127 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
1114 ret = true; 1128 ret = true;
@@ -1136,6 +1150,7 @@ public sealed class BSPrim : BSPhysObject
1136 } 1150 }
1137 } 1151 }
1138 } 1152 }
1153
1139 return ret; 1154 return ret;
1140 } 1155 }
1141 1156
@@ -1345,12 +1360,9 @@ public sealed class BSPrim : BSPhysObject
1345 // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, LocalID, shape.Type); 1360 // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, LocalID, shape.Type);
1346 bool ret = BulletSimAPI.CreateObject(PhysicsScene.WorldID, shape); 1361 bool ret = BulletSimAPI.CreateObject(PhysicsScene.WorldID, shape);
1347 1362
1348 // the CreateObject() may have recreated the rigid body. Make sure we have the latest address.
1349 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID));
1350 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
1351
1352 return ret; 1363 return ret;
1353 } 1364 }
1365#endif // !CSHARP_BODY_MANAGEMENT
1354 1366
1355 // Copy prim's info into the BulletSim shape description structure 1367 // Copy prim's info into the BulletSim shape description structure
1356 public void FillShapeInfo(out ShapeData shape) 1368 public void FillShapeInfo(out ShapeData shape)
@@ -1369,22 +1381,45 @@ public sealed class BSPrim : BSPhysObject
1369 shape.Restitution = _restitution; 1381 shape.Restitution = _restitution;
1370 shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; 1382 shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse;
1371 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; 1383 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
1384 shape.Solid = IsSolid ? ShapeData.numericFalse : ShapeData.numericTrue;
1385 shape.Size = _size;
1372 } 1386 }
1373
1374 // Rebuild the geometry and object. 1387 // Rebuild the geometry and object.
1375 // This is called when the shape changes so we need to recreate the mesh/hull. 1388 // This is called when the shape changes so we need to recreate the mesh/hull.
1376 // No locking here because this is done when the physics engine is not simulating 1389 // No locking here because this is done when the physics engine is not simulating
1377 private void CreateGeomAndObject(bool forceRebuild) 1390 private void CreateGeomAndObject(bool forceRebuild)
1378 { 1391 {
1392#if CSHARP_BODY_MANAGEMENT
1393 ShapeData shapeData;
1394 FillShapeInfo(out shapeData);
1395
1396 // Create the correct physical representation for this type of object.
1397 // Updates BSBody and BSShape with the new information.
1398 if (PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs))
1399 {
1400 // Make sure the properties are set on the new object
1401 UpdatePhysicalParameters();
1402 }
1403#else
1379 // m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, LocalID, forceRebuild); 1404 // m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, LocalID, forceRebuild);
1380 // Create the geometry that will make up the object 1405 // Create the geometry that will make up the object
1381 if (CreateGeom(forceRebuild)) 1406 if (CreateGeom(forceRebuild))
1382 { 1407 {
1383 // Create the object and place it into the world 1408 // Create the object and place it into the world
1384 CreateObject(); 1409 CreateObject();
1410
1411 // the CreateObject() may have recreated the rigid body. Make sure we have the latest address.
1412 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID));
1413 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr), _shapeType);
1414 BSShape.shapeKey = _meshKey;
1415 DetailLog("{0},BSPrim.CreateGeomAndObject,body={1},shape={2}", LocalID, BSBody, BSShape);
1416
1385 // Make sure the properties are set on the new object 1417 // Make sure the properties are set on the new object
1386 UpdatePhysicalParameters(); 1418 UpdatePhysicalParameters();
1387 } 1419 }
1420
1421
1422#endif // CSHARP_BODY_MANAGEMENT
1388 return; 1423 return;
1389 } 1424 }
1390 1425