aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
diff options
context:
space:
mode:
authorRobert Adams2012-09-13 08:11:54 -0700
committerRobert Adams2012-09-15 15:31:29 -0700
commit2c5ff9399063080276a23bcd06fb696d653bef2e (patch)
tree3428eaff2697b562880c75f5f83eafcbb855c93e /OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
parentAdd basic asset connector tests to check behaviour for normal, local and temp... (diff)
downloadopensim-SC_OLD-2c5ff9399063080276a23bcd06fb696d653bef2e.zip
opensim-SC_OLD-2c5ff9399063080276a23bcd06fb696d653bef2e.tar.gz
opensim-SC_OLD-2c5ff9399063080276a23bcd06fb696d653bef2e.tar.bz2
opensim-SC_OLD-2c5ff9399063080276a23bcd06fb696d653bef2e.tar.xz
BulletSim: Way too many changes in one commit.
Many changes to BSDynamic for readability and commentary. Linkset hacking for vehicles: don't over mass the root prim. Add parameter for link constraint solver iterations. Correct uses of timestep in timescale calculations for vehicles. Reorganize code/logic for making objects static and dynamic for readability and use of API2. Changed most calls in BSPrim to use API2 calls (the new way). Avatars do not generate default Bullet collision events but do call up to the simulator for every avatar. Reduces overhead. Objects added to collision list only if they are processing collisions. Reduces overhead especially for large numbers of avatars. Generalize call for water height to GetWaterHeightAtXYZ(). Catch and correct exception getting terrain height when out of bounds. Correct race condition in Terrain Manager where creation wasn't at taint-time. Add API calls for constructing compound shapes. Move NeedsMeshing() logic into object class. Reorganize logic for object meshing to reduce rebuilding of meshs/hulls.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs196
1 files changed, 118 insertions, 78 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 6d0af63..481a8db 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -136,11 +136,11 @@ public sealed class BSPrim : BSPhysObject
136 Linkset = new BSLinkset(Scene, this); // a linkset of one 136 Linkset = new BSLinkset(Scene, this); // a linkset of one
137 _vehicle = new BSDynamics(Scene, this); // add vehicleness 137 _vehicle = new BSDynamics(Scene, this); // add vehicleness
138 _mass = CalculateMass(); 138 _mass = CalculateMass();
139 // do the actual object creation at taint time
140 DetailLog("{0},BSPrim.constructor,call", LocalID); 139 DetailLog("{0},BSPrim.constructor,call", LocalID);
140 // do the actual object creation at taint time
141 _scene.TaintedObject("BSPrim.create", delegate() 141 _scene.TaintedObject("BSPrim.create", delegate()
142 { 142 {
143 RecreateGeomAndObject(); 143 CreateGeomAndObject(true);
144 144
145 // Get the pointer to the physical body for this object. 145 // Get the pointer to the physical body for this object.
146 // At the moment, we're still letting BulletSim manage the creation and destruction 146 // At the moment, we're still letting BulletSim manage the creation and destruction
@@ -186,9 +186,10 @@ public sealed class BSPrim : BSPhysObject
186 _scene.TaintedObject("BSPrim.setSize", delegate() 186 _scene.TaintedObject("BSPrim.setSize", delegate()
187 { 187 {
188 _mass = CalculateMass(); // changing size changes the mass 188 _mass = CalculateMass(); // changing size changes the mass
189 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); 189 // Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct
190 DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); 190 // scale and margins are set.
191 RecreateGeomAndObject(); 191 CreateGeomAndObject(true);
192 DetailLog("{0}: BSPrim.setSize: size={1}, scale={2}, mass={3}, physical={4}", LocalID, _size, _scale, _mass, IsPhysical);
192 }); 193 });
193 } 194 }
194 } 195 }
@@ -198,7 +199,7 @@ public sealed class BSPrim : BSPhysObject
198 _scene.TaintedObject("BSPrim.setShape", delegate() 199 _scene.TaintedObject("BSPrim.setShape", delegate()
199 { 200 {
200 _mass = CalculateMass(); // changing the shape changes the mass 201 _mass = CalculateMass(); // changing the shape changes the mass
201 RecreateGeomAndObject(); 202 CreateGeomAndObject(false);
202 }); 203 });
203 } 204 }
204 } 205 }
@@ -279,7 +280,7 @@ public sealed class BSPrim : BSPhysObject
279 get { 280 get {
280 if (!Linkset.IsRoot(this)) 281 if (!Linkset.IsRoot(this))
281 // child prims move around based on their parent. Need to get the latest location 282 // child prims move around based on their parent. Need to get the latest location
282 _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 283 _position = BulletSimAPI.GetPosition2(BSBody.Ptr);
283 284
284 // don't do the GetObjectPosition for root elements because this function is called a zillion times 285 // don't do the GetObjectPosition for root elements because this function is called a zillion times
285 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 286 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
@@ -291,7 +292,7 @@ public sealed class BSPrim : BSPhysObject
291 _scene.TaintedObject("BSPrim.setPosition", delegate() 292 _scene.TaintedObject("BSPrim.setPosition", delegate()
292 { 293 {
293 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 294 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
294 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 295 BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
295 }); 296 });
296 } 297 }
297 } 298 }
@@ -302,7 +303,8 @@ public sealed class BSPrim : BSPhysObject
302 { 303 {
303 get 304 get
304 { 305 {
305 return Linkset.LinksetMass; 306 // return Linkset.LinksetMass;
307 return _mass;
306 } 308 }
307 } 309 }
308 310
@@ -328,7 +330,6 @@ public sealed class BSPrim : BSPhysObject
328 _scene.TaintedObject("BSPrim.setForce", delegate() 330 _scene.TaintedObject("BSPrim.setForce", delegate()
329 { 331 {
330 DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); 332 DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
331 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
332 BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force); 333 BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
333 }); 334 });
334 } 335 }
@@ -406,7 +407,7 @@ public sealed class BSPrim : BSPhysObject
406 _scene.TaintedObject("BSPrim.setVelocity", delegate() 407 _scene.TaintedObject("BSPrim.setVelocity", delegate()
407 { 408 {
408 DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 409 DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
409 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); 410 BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity);
410 }); 411 });
411 } 412 }
412 } 413 }
@@ -430,7 +431,7 @@ public sealed class BSPrim : BSPhysObject
430 if (!Linkset.IsRoot(this)) 431 if (!Linkset.IsRoot(this))
431 { 432 {
432 // Children move around because tied to parent. Get a fresh value. 433 // Children move around because tied to parent. Get a fresh value.
433 _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); 434 _orientation = BulletSimAPI.GetOrientation2(BSBody.Ptr);
434 } 435 }
435 return _orientation; 436 return _orientation;
436 } 437 }
@@ -441,7 +442,7 @@ public sealed class BSPrim : BSPhysObject
441 { 442 {
442 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 443 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
443 DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); 444 DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
444 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 445 BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
445 }); 446 });
446 } 447 }
447 } 448 }
@@ -483,31 +484,37 @@ public sealed class BSPrim : BSPhysObject
483 { 484 {
484 // If it's becoming dynamic, it will need hullness 485 // If it's becoming dynamic, it will need hullness
485 VerifyCorrectPhysicalShape(); 486 VerifyCorrectPhysicalShape();
487 UpdatePhysicalParameters();
488 }
486 489
490 private void UpdatePhysicalParameters()
491 {
492 /*
487 // Bullet wants static objects to have a mass of zero 493 // Bullet wants static objects to have a mass of zero
488 float mass = IsStatic ? 0f : _mass; 494 float mass = IsStatic ? 0f : _mass;
489 495
490 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); 496 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
491 /* 497 */
492 BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr); 498 BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr);
493 499
494 // Set up the object physicalness (static or dynamic) 500 // Set up the object physicalness (does gravity and collisions move this object)
495 MakeDynamic(); 501 MakeDynamic(IsStatic);
496 502
497 // Make solid or not and arrange for collisions, etc 503 // Make solid or not (do things bounce off or pass through this object)
498 MakeSolid(); 504 MakeSolid(IsSolid);
499 505
500 m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr); 506 // Arrange for collisions events if the simulator wants them
507 EnableCollisions(SubscribedEvents());
501 508
502 BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr); 509 BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr);
503 */
504 510
505 // Recompute any linkset parameters. 511 // Recompute any linkset parameters.
506 // When going from non-physical to physical, this re-enables the constraints that 512 // When going from non-physical to physical, this re-enables the constraints that
507 // had been automatically disabled when the mass was set to zero. 513 // had been automatically disabled when the mass was set to zero.
508 Linkset.Refresh(this); 514 Linkset.Refresh(this);
509 515
510 DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, m_currentCollisionFlags); 516 DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3}, cf={4}",
517 LocalID, IsStatic, IsSolid, _mass, m_currentCollisionFlags);
511 } 518 }
512 519
513 // "Making dynamic" means changing to and from static. 520 // "Making dynamic" means changing to and from static.
@@ -515,12 +522,12 @@ public sealed class BSPrim : BSPhysObject
515 // When dynamic, the object can fall and be pushed by others. 522 // When dynamic, the object can fall and be pushed by others.
516 // This is independent of its 'solidness' which controls what passes through 523 // This is independent of its 'solidness' which controls what passes through
517 // this object and what interacts with it. 524 // this object and what interacts with it.
518 private void MakeDynamic() 525 private void MakeDynamic(bool makeStatic)
519 { 526 {
520 if (IsStatic) 527 if (makeStatic)
521 { 528 {
522 // Become a Bullet 'static' object type 529 // Become a Bullet 'static' object type
523 BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); 530 m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
524 // Stop all movement 531 // Stop all movement
525 BulletSimAPI.ClearAllForces2(BSBody.Ptr); 532 BulletSimAPI.ClearAllForces2(BSBody.Ptr);
526 // Mass is zero which disables a bunch of physics stuff in Bullet 533 // Mass is zero which disables a bunch of physics stuff in Bullet
@@ -533,12 +540,11 @@ public sealed class BSPrim : BSPhysObject
533 else 540 else
534 { 541 {
535 // Not a Bullet static object 542 // Not a Bullet static object
536 BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); 543 m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
537 // A dynamic object has mass 544 // A dynamic object has mass
538 BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, OMV.Vector3.Zero);
539 // The shape is interesting and has mass and a center of gravity
540 IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr); 545 IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr);
541 BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass, OMV.Vector3.Zero); 546 OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass);
547 BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, inertia);
542 // Inertia is based on our new mass 548 // Inertia is based on our new mass
543 BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr); 549 BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
544 // Force activation of the object so Bullet will act on it. 550 // Force activation of the object so Bullet will act on it.
@@ -546,8 +552,31 @@ public sealed class BSPrim : BSPhysObject
546 } 552 }
547 } 553 }
548 554
549 private void MakeSolid() 555 // "Making solid" means that other object will not pass through this object.
556 private void MakeSolid(bool makeSolid)
550 { 557 {
558 if (makeSolid)
559 {
560 // Easy in Bullet -- just remove the object flag that controls collision response
561 m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
562 }
563 else
564 {
565 m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
566 }
567 }
568
569 // Turn on or off the flag controlling whether collision events are returned to the simulator.
570 private void EnableCollisions(bool wantsCollisionEvents)
571 {
572 if (wantsCollisionEvents)
573 {
574 m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
575 }
576 else
577 {
578 m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
579 }
551 } 580 }
552 581
553 // prims don't fly 582 // prims don't fly
@@ -607,7 +636,7 @@ public sealed class BSPrim : BSPhysObject
607 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 636 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
608 { 637 {
609 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 638 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
610 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); 639 BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity);
611 }); 640 });
612 } 641 }
613 } 642 }
@@ -624,7 +653,10 @@ public sealed class BSPrim : BSPhysObject
624 _scene.TaintedObject("BSPrim.setBuoyancy", delegate() 653 _scene.TaintedObject("BSPrim.setBuoyancy", delegate()
625 { 654 {
626 DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 655 DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
627 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); 656 // Buoyancy is faked by changing the gravity applied to the object
657 float grav = Scene.Params.gravity * (1f - _buoyancy);
658 BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav));
659 // BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
628 }); 660 });
629 } 661 }
630 } 662 }
@@ -686,8 +718,8 @@ public sealed class BSPrim : BSPhysObject
686 } 718 }
687 m_accumulatedForces.Clear(); 719 m_accumulatedForces.Clear();
688 } 720 }
689 DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); 721 DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum);
690 // For unknown reason, "ApplyCentralForce" is really additive. 722 // For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object.
691 BulletSimAPI.ApplyCentralForce2(BSBody.Ptr, fSum); 723 BulletSimAPI.ApplyCentralForce2(BSBody.Ptr, fSum);
692 }); 724 });
693 } 725 }
@@ -1030,29 +1062,36 @@ public sealed class BSPrim : BSPhysObject
1030 // Returns 'true' if the geometry was rebuilt 1062 // Returns 'true' if the geometry was rebuilt
1031 private bool CreateGeom(bool forceRebuild) 1063 private bool CreateGeom(bool forceRebuild)
1032 { 1064 {
1033 // the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
1034 bool ret = false; 1065 bool ret = false;
1035 if (!_scene.NeedsMeshing(_pbs)) 1066 bool haveShape = false;
1067
1068 // If the prim attributes are simple, this could be a simple Bullet native shape
1069 if ((_pbs.SculptEntry && !Scene.ShouldMeshSculptedPrim)
1070 || (_pbs.ProfileBegin == 0 && _pbs.ProfileEnd == 0
1071 && _pbs.ProfileHollow == 0
1072 && _pbs.PathTwist == 0 && _pbs.PathTwistBegin == 0
1073 && _pbs.PathBegin == 0 && _pbs.PathEnd == 0
1074 && _pbs.PathTaperX == 0 && _pbs.PathTaperY == 0
1075 && _pbs.PathScaleX == 100 && _pbs.PathScaleY == 100
1076 && _pbs.PathShearX == 0 && _pbs.PathShearY == 0) )
1036 { 1077 {
1037 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) 1078 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
1038 { 1079 {
1039 // if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) 1080 haveShape = true;
1040 // { 1081 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
1041 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); 1082 {
1042 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) 1083 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
1043 { 1084 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
1044 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); 1085 // Bullet native objects are scaled by the Bullet engine so pass the size in
1045 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; 1086 _scale = _size;
1046 // Bullet native objects are scaled by the Bullet engine so pass the size in 1087 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
1047 _scale = _size; 1088 ret = true;
1048 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? 1089 }
1049 ret = true;
1050 }
1051 // }
1052 } 1090 }
1053 else 1091 else
1054 { 1092 {
1055 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); 1093 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
1094 haveShape = true;
1056 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) 1095 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
1057 { 1096 {
1058 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); 1097 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
@@ -1063,16 +1102,16 @@ public sealed class BSPrim : BSPhysObject
1063 } 1102 }
1064 } 1103 }
1065 } 1104 }
1066 else 1105 // If a simple shape isn't happening, create a mesh and possibly a hull
1106 if (!haveShape)
1067 { 1107 {
1068 if (IsPhysical) 1108 if (IsPhysical)
1069 { 1109 {
1070 if (forceRebuild || _hullKey == 0) 1110 if (forceRebuild || _hullKey == 0)
1071 { 1111 {
1072 // physical objects require a hull for interaction. 1112 // physical objects require a hull for interaction.
1073 // This will create the mesh if it doesn't already exist 1113 // This also creates the mesh if it doesn't already exist
1074 CreateGeomHull(); 1114 ret = CreateGeomHull();
1075 ret = true;
1076 } 1115 }
1077 } 1116 }
1078 else 1117 else
@@ -1080,8 +1119,7 @@ public sealed class BSPrim : BSPhysObject
1080 if (forceRebuild || _meshKey == 0) 1119 if (forceRebuild || _meshKey == 0)
1081 { 1120 {
1082 // Static (non-physical) objects only need a mesh for bumping into 1121 // Static (non-physical) objects only need a mesh for bumping into
1083 CreateGeomMesh(); 1122 ret = CreateGeomMesh();
1084 ret = true;
1085 } 1123 }
1086 } 1124 }
1087 } 1125 }
@@ -1089,7 +1127,8 @@ public sealed class BSPrim : BSPhysObject
1089 } 1127 }
1090 1128
1091 // No locking here because this is done when we know physics is not simulating 1129 // No locking here because this is done when we know physics is not simulating
1092 private void CreateGeomMesh() 1130 // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
1131 private bool CreateGeomMesh()
1093 { 1132 {
1094 // level of detail based on size and type of the object 1133 // level of detail based on size and type of the object
1095 float lod = _scene.MeshLOD; 1134 float lod = _scene.MeshLOD;
@@ -1103,7 +1142,7 @@ public sealed class BSPrim : BSPhysObject
1103 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); 1142 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
1104 1143
1105 // if this new shape is the same as last time, don't recreate the mesh 1144 // if this new shape is the same as last time, don't recreate the mesh
1106 if (_meshKey == newMeshKey) return; 1145 if (_meshKey == newMeshKey) return false;
1107 1146
1108 DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); 1147 DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
1109 // Since we're recreating new, get rid of any previously generated shape 1148 // Since we're recreating new, get rid of any previously generated shape
@@ -1140,19 +1179,19 @@ public sealed class BSPrim : BSPhysObject
1140 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; 1179 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
1141 // meshes are already scaled by the meshmerizer 1180 // meshes are already scaled by the meshmerizer
1142 _scale = new OMV.Vector3(1f, 1f, 1f); 1181 _scale = new OMV.Vector3(1f, 1f, 1f);
1143 DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); 1182 return true;
1144 return;
1145 } 1183 }
1146 1184
1147 // No locking here because this is done when we know physics is not simulating 1185 // No locking here because this is done when we know physics is not simulating
1148 private void CreateGeomHull() 1186 // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
1187 private bool CreateGeomHull()
1149 { 1188 {
1150 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; 1189 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
1151 ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod); 1190 ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod);
1152 // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey); 1191 // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey);
1153 1192
1154 // if the hull hasn't changed, don't rebuild it 1193 // if the hull hasn't changed, don't rebuild it
1155 if (newHullKey == _hullKey) return; 1194 if (newHullKey == _hullKey) return false;
1156 1195
1157 DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); 1196 DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
1158 1197
@@ -1255,7 +1294,7 @@ public sealed class BSPrim : BSPhysObject
1255 // meshes are already scaled by the meshmerizer 1294 // meshes are already scaled by the meshmerizer
1256 _scale = new OMV.Vector3(1f, 1f, 1f); 1295 _scale = new OMV.Vector3(1f, 1f, 1f);
1257 DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); 1296 DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
1258 return; 1297 return true;
1259 } 1298 }
1260 1299
1261 // Callback from convex hull creater with a newly created hull. 1300 // Callback from convex hull creater with a newly created hull.
@@ -1268,20 +1307,12 @@ public sealed class BSPrim : BSPhysObject
1268 1307
1269 private void VerifyCorrectPhysicalShape() 1308 private void VerifyCorrectPhysicalShape()
1270 { 1309 {
1271 if (IsStatic) 1310 if (!IsStatic)
1272 {
1273 // if static, we don't need a hull so, if there is one, rebuild without it
1274 if (_hullKey != 0)
1275 {
1276 RecreateGeomAndObject();
1277 }
1278 }
1279 else
1280 { 1311 {
1281 // if not static, it will need a hull to efficiently collide with things 1312 // if not static, it will need a hull to efficiently collide with things
1282 if (_hullKey == 0) 1313 if (_hullKey == 0)
1283 { 1314 {
1284 RecreateGeomAndObject(); 1315 CreateGeomAndObject(false);
1285 } 1316 }
1286 1317
1287 } 1318 }
@@ -1300,8 +1331,9 @@ public sealed class BSPrim : BSPhysObject
1300 // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); 1331 // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
1301 bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape); 1332 bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
1302 1333
1303 // the CreateObject() may have recreated the rigid body. Make sure we have the latest. 1334 // the CreateObject() may have recreated the rigid body. Make sure we have the latest address.
1304 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 1335 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
1336 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
1305 1337
1306 return ret; 1338 return ret;
1307 } 1339 }
@@ -1325,15 +1357,20 @@ public sealed class BSPrim : BSPhysObject
1325 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; 1357 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
1326 } 1358 }
1327 1359
1328
1329 // Rebuild the geometry and object. 1360 // Rebuild the geometry and object.
1330 // This is called when the shape changes so we need to recreate the mesh/hull. 1361 // This is called when the shape changes so we need to recreate the mesh/hull.
1331 // No locking here because this is done when the physics engine is not simulating 1362 // No locking here because this is done when the physics engine is not simulating
1332 private void RecreateGeomAndObject() 1363 private void CreateGeomAndObject(bool forceRebuild)
1333 { 1364 {
1334 // m_log.DebugFormat("{0}: RecreateGeomAndObject. lID={1}", LogHeader, _localID); 1365 // m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, _localID, forceRebuild);
1335 if (CreateGeom(true)) 1366 // Create the geometry that will make up the object
1367 if (CreateGeom(forceRebuild))
1368 {
1369 // Create the object and place it into the world
1336 CreateObject(); 1370 CreateObject();
1371 // Make sure the properties are set on the new object
1372 UpdatePhysicalParameters();
1373 }
1337 return; 1374 return;
1338 } 1375 }
1339 1376
@@ -1430,9 +1467,10 @@ public sealed class BSPrim : BSPhysObject
1430 // I've collided with something 1467 // I've collided with something
1431 // Called at taint time from within the Step() function 1468 // Called at taint time from within the Step() function
1432 CollisionEventUpdate collisionCollection; 1469 CollisionEventUpdate collisionCollection;
1433 public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 1470 public override bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1434 { 1471 {
1435 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 1472 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
1473 bool ret = false;
1436 1474
1437 // The following lines make IsColliding() and IsCollidingGround() work 1475 // The following lines make IsColliding() and IsCollidingGround() work
1438 _collidingStep = _scene.SimulationStep; 1476 _collidingStep = _scene.SimulationStep;
@@ -1446,7 +1484,7 @@ public sealed class BSPrim : BSPhysObject
1446 // prims in the same linkset cannot collide with each other 1484 // prims in the same linkset cannot collide with each other
1447 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) 1485 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
1448 { 1486 {
1449 return; 1487 return ret;
1450 } 1488 }
1451 1489
1452 // if someone has subscribed for collision events.... 1490 // if someone has subscribed for collision events....
@@ -1459,8 +1497,10 @@ public sealed class BSPrim : BSPhysObject
1459 if (collisionCollection == null) 1497 if (collisionCollection == null)
1460 collisionCollection = new CollisionEventUpdate(); 1498 collisionCollection = new CollisionEventUpdate();
1461 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 1499 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
1500 ret = true;
1462 } 1501 }
1463 } 1502 }
1503 return ret;
1464 } 1504 }
1465 1505
1466 // The scene is telling us it's time to pass our collected collisions into the simulator 1506 // The scene is telling us it's time to pass our collected collisions into the simulator