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.cs272
1 files changed, 177 insertions, 95 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 9c20004..6d0af63 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -37,13 +37,11 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet;
37namespace OpenSim.Region.Physics.BulletSPlugin 37namespace OpenSim.Region.Physics.BulletSPlugin
38{ 38{
39 [Serializable] 39 [Serializable]
40public sealed class BSPrim : PhysicsActor 40public sealed class BSPrim : BSPhysObject
41{ 41{
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 private static readonly string LogHeader = "[BULLETS PRIM]"; 43 private static readonly string LogHeader = "[BULLETS PRIM]";
44 44
45 private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); }
46
47 private IMesh _mesh; 45 private IMesh _mesh;
48 private PrimitiveBaseShape _pbs; 46 private PrimitiveBaseShape _pbs;
49 private ShapeData.PhysicsShapeType _shapeType; 47 private ShapeData.PhysicsShapeType _shapeType;
@@ -90,23 +88,16 @@ public sealed class BSPrim : PhysicsActor
90 private float _buoyancy; 88 private float _buoyancy;
91 89
92 // Membership in a linkset is controlled by this class. 90 // Membership in a linkset is controlled by this class.
93 private BSLinkset _linkset; 91 public override BSLinkset Linkset { get; set; }
94 public BSLinkset Linkset
95 {
96 get { return _linkset; }
97 set { _linkset = value; }
98 }
99 92
100 private int _subscribedEventsMs = 0; 93 private int _subscribedEventsMs = 0;
101 private int _nextCollisionOkTime = 0; 94 private int _nextCollisionOkTime = 0;
102 long _collidingStep; 95 long _collidingStep;
103 long _collidingGroundStep; 96 long _collidingGroundStep;
97 CollisionFlags m_currentCollisionFlags = 0;
104 98
105 private BulletBody m_body; 99 public override BulletBody BSBody { get; set; }
106 public BulletBody Body { 100 public override BulletShape BSShape { get; set; }
107 get { return m_body; }
108 set { m_body = value; }
109 }
110 101
111 private BSDynamics _vehicle; 102 private BSDynamics _vehicle;
112 103
@@ -124,6 +115,7 @@ public sealed class BSPrim : PhysicsActor
124 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); 115 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
125 _localID = localID; 116 _localID = localID;
126 _avName = primName; 117 _avName = primName;
118 _physicsActorType = (int)ActorTypes.Prim;
127 _scene = parent_scene; 119 _scene = parent_scene;
128 _position = pos; 120 _position = pos;
129 _size = size; 121 _size = size;
@@ -141,8 +133,8 @@ public sealed class BSPrim : PhysicsActor
141 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material 133 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
142 _density = _scene.Params.defaultDensity; // TODO: compute based on object material 134 _density = _scene.Params.defaultDensity; // TODO: compute based on object material
143 _restitution = _scene.Params.defaultRestitution; 135 _restitution = _scene.Params.defaultRestitution;
144 _linkset = new BSLinkset(_scene, this); // a linkset of one 136 Linkset = new BSLinkset(Scene, this); // a linkset of one
145 _vehicle = new BSDynamics(this); // add vehicleness 137 _vehicle = new BSDynamics(Scene, this); // add vehicleness
146 _mass = CalculateMass(); 138 _mass = CalculateMass();
147 // do the actual object creation at taint time 139 // do the actual object creation at taint time
148 DetailLog("{0},BSPrim.constructor,call", LocalID); 140 DetailLog("{0},BSPrim.constructor,call", LocalID);
@@ -153,23 +145,25 @@ public sealed class BSPrim : PhysicsActor
153 // Get the pointer to the physical body for this object. 145 // Get the pointer to the physical body for this object.
154 // 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
155 // of the object. Someday we'll move that into the C# code. 147 // of the object. Someday we'll move that into the C# code.
156 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 148 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
149 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
150 m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
157 }); 151 });
158 } 152 }
159 153
160 // called when this prim is being destroyed and we should free all the resources 154 // called when this prim is being destroyed and we should free all the resources
161 public void Destroy() 155 public override void Destroy()
162 { 156 {
163 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); 157 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
164 158
165 // Undo any links between me and any other object 159 // Undo any links between me and any other object
166 BSPrim parentBefore = _linkset.LinksetRoot; 160 BSPhysObject parentBefore = Linkset.LinksetRoot;
167 int childrenBefore = _linkset.NumberOfChildren; 161 int childrenBefore = Linkset.NumberOfChildren;
168 162
169 _linkset = _linkset.RemoveMeFromLinkset(this); 163 Linkset = Linkset.RemoveMeFromLinkset(this);
170 164
171 DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", 165 DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
172 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 166 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
173 167
174 // Undo any vehicle properties 168 // Undo any vehicle properties
175 this.VehicleType = (int)Vehicle.TYPE_NONE; 169 this.VehicleType = (int)Vehicle.TYPE_NONE;
@@ -193,7 +187,7 @@ public sealed class BSPrim : PhysicsActor
193 { 187 {
194 _mass = CalculateMass(); // changing size changes the mass 188 _mass = CalculateMass(); // changing size changes the mass
195 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); 189 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
196 // DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); 190 DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
197 RecreateGeomAndObject(); 191 RecreateGeomAndObject();
198 }); 192 });
199 } 193 }
@@ -232,14 +226,13 @@ public sealed class BSPrim : PhysicsActor
232 BSPrim parent = obj as BSPrim; 226 BSPrim parent = obj as BSPrim;
233 if (parent != null) 227 if (parent != null)
234 { 228 {
235 DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); 229 BSPhysObject parentBefore = Linkset.LinksetRoot;
236 BSPrim parentBefore = _linkset.LinksetRoot; 230 int childrenBefore = Linkset.NumberOfChildren;
237 int childrenBefore = _linkset.NumberOfChildren;
238 231
239 _linkset = parent.Linkset.AddMeToLinkset(this); 232 Linkset = parent.Linkset.AddMeToLinkset(this);
240 233
241 DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", 234 DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
242 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 235 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
243 } 236 }
244 return; 237 return;
245 } 238 }
@@ -248,16 +241,14 @@ public sealed class BSPrim : PhysicsActor
248 public override void delink() { 241 public override void delink() {
249 // TODO: decide if this parent checking needs to happen at taint time 242 // TODO: decide if this parent checking needs to happen at taint time
250 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen 243 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
251 DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
252 _linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.LocalID.ToString());
253 244
254 BSPrim parentBefore = _linkset.LinksetRoot; 245 BSPhysObject parentBefore = Linkset.LinksetRoot;
255 int childrenBefore = _linkset.NumberOfChildren; 246 int childrenBefore = Linkset.NumberOfChildren;
256 247
257 _linkset = _linkset.RemoveMeFromLinkset(this); 248 Linkset = Linkset.RemoveMeFromLinkset(this);
258 249
259 DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", 250 DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
260 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 251 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
261 return; 252 return;
262 } 253 }
263 254
@@ -265,28 +256,28 @@ public sealed class BSPrim : PhysicsActor
265 // Do it to the properties so the values get set in the physics engine. 256 // Do it to the properties so the values get set in the physics engine.
266 // Push the setting of the values to the viewer. 257 // Push the setting of the values to the viewer.
267 // Called at taint time! 258 // Called at taint time!
268 public void ZeroMotion() 259 public override void ZeroMotion()
269 { 260 {
270 _velocity = OMV.Vector3.Zero; 261 _velocity = OMV.Vector3.Zero;
271 _acceleration = OMV.Vector3.Zero; 262 _acceleration = OMV.Vector3.Zero;
272 _rotationalVelocity = OMV.Vector3.Zero; 263 _rotationalVelocity = OMV.Vector3.Zero;
273 264
274 // Zero some other properties directly into the physics engine 265 // Zero some other properties directly into the physics engine
275 BulletSimAPI.SetVelocity2(Body.Ptr, OMV.Vector3.Zero); 266 BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
276 BulletSimAPI.SetAngularVelocity2(Body.Ptr, OMV.Vector3.Zero); 267 BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
277 BulletSimAPI.SetInterpolation2(Body.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); 268 BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
278 BulletSimAPI.ClearForces2(Body.Ptr); 269 BulletSimAPI.ClearForces2(BSBody.Ptr);
279 } 270 }
280 271
281 public override void LockAngularMotion(OMV.Vector3 axis) 272 public override void LockAngularMotion(OMV.Vector3 axis)
282 { 273 {
283 // DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 274 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
284 return; 275 return;
285 } 276 }
286 277
287 public override OMV.Vector3 Position { 278 public override OMV.Vector3 Position {
288 get { 279 get {
289 if (!_linkset.IsRoot(this)) 280 if (!Linkset.IsRoot(this))
290 // child prims move around based on their parent. Need to get the latest location 281 // child prims move around based on their parent. Need to get the latest location
291 _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 282 _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
292 283
@@ -299,7 +290,7 @@ public sealed class BSPrim : PhysicsActor
299 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? 290 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
300 _scene.TaintedObject("BSPrim.setPosition", delegate() 291 _scene.TaintedObject("BSPrim.setPosition", delegate()
301 { 292 {
302 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 293 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
303 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 294 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
304 }); 295 });
305 } 296 }
@@ -311,23 +302,23 @@ public sealed class BSPrim : PhysicsActor
311 { 302 {
312 get 303 get
313 { 304 {
314 return _linkset.LinksetMass; 305 return Linkset.LinksetMass;
315 } 306 }
316 } 307 }
317 308
318 // used when we only want this prim's mass and not the linkset thing 309 // used when we only want this prim's mass and not the linkset thing
319 public float MassRaw { get { return _mass; } } 310 public override float MassRaw { get { return _mass; } }
320 311
321 // Is this used? 312 // Is this used?
322 public override OMV.Vector3 CenterOfMass 313 public override OMV.Vector3 CenterOfMass
323 { 314 {
324 get { return _linkset.CenterOfMass; } 315 get { return Linkset.CenterOfMass; }
325 } 316 }
326 317
327 // Is this used? 318 // Is this used?
328 public override OMV.Vector3 GeometricCenter 319 public override OMV.Vector3 GeometricCenter
329 { 320 {
330 get { return _linkset.GeometricCenter; } 321 get { return Linkset.GeometricCenter; }
331 } 322 }
332 323
333 public override OMV.Vector3 Force { 324 public override OMV.Vector3 Force {
@@ -336,9 +327,9 @@ public sealed class BSPrim : PhysicsActor
336 _force = value; 327 _force = value;
337 _scene.TaintedObject("BSPrim.setForce", delegate() 328 _scene.TaintedObject("BSPrim.setForce", delegate()
338 { 329 {
339 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); 330 DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
340 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); 331 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
341 BulletSimAPI.SetObjectForce2(Body.Ptr, _force); 332 BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
342 }); 333 });
343 } 334 }
344 } 335 }
@@ -354,7 +345,7 @@ public sealed class BSPrim : PhysicsActor
354 { 345 {
355 // Done at taint time so we're sure the physics engine is not using the variables 346 // Done at taint time so we're sure the physics engine is not using the variables
356 // Vehicle code changes the parameters for this vehicle type. 347 // Vehicle code changes the parameters for this vehicle type.
357 _vehicle.ProcessTypeChange(type); 348 _vehicle.ProcessTypeChange(type, Scene.LastSimulatedTimestep);
358 // Tell the scene about the vehicle so it will get processing each frame. 349 // Tell the scene about the vehicle so it will get processing each frame.
359 _scene.VehicleInSceneTypeChanged(this, type); 350 _scene.VehicleInSceneTypeChanged(this, type);
360 }); 351 });
@@ -391,7 +382,7 @@ public sealed class BSPrim : PhysicsActor
391 382
392 // Called each simulation step to advance vehicle characteristics. 383 // Called each simulation step to advance vehicle characteristics.
393 // Called from Scene when doing simulation step so we're in taint processing time. 384 // Called from Scene when doing simulation step so we're in taint processing time.
394 public void StepVehicle(float timeStep) 385 public override void StepVehicle(float timeStep)
395 { 386 {
396 if (IsPhysical) 387 if (IsPhysical)
397 _vehicle.Step(timeStep); 388 _vehicle.Step(timeStep);
@@ -414,7 +405,7 @@ public sealed class BSPrim : PhysicsActor
414 _velocity = value; 405 _velocity = value;
415 _scene.TaintedObject("BSPrim.setVelocity", delegate() 406 _scene.TaintedObject("BSPrim.setVelocity", delegate()
416 { 407 {
417 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 408 DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
418 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); 409 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
419 }); 410 });
420 } 411 }
@@ -422,7 +413,7 @@ public sealed class BSPrim : PhysicsActor
422 public override OMV.Vector3 Torque { 413 public override OMV.Vector3 Torque {
423 get { return _torque; } 414 get { return _torque; }
424 set { _torque = value; 415 set { _torque = value;
425 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); 416 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
426 } 417 }
427 } 418 }
428 public override float CollisionScore { 419 public override float CollisionScore {
@@ -436,7 +427,7 @@ public sealed class BSPrim : PhysicsActor
436 } 427 }
437 public override OMV.Quaternion Orientation { 428 public override OMV.Quaternion Orientation {
438 get { 429 get {
439 if (!_linkset.IsRoot(this)) 430 if (!Linkset.IsRoot(this))
440 { 431 {
441 // Children move around because tied to parent. Get a fresh value. 432 // Children move around because tied to parent. Get a fresh value.
442 _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); 433 _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
@@ -449,15 +440,14 @@ public sealed class BSPrim : PhysicsActor
449 _scene.TaintedObject("BSPrim.setOrientation", delegate() 440 _scene.TaintedObject("BSPrim.setOrientation", delegate()
450 { 441 {
451 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 442 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
452 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); 443 DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
453 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 444 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
454 }); 445 });
455 } 446 }
456 } 447 }
457 public override int PhysicsActorType { 448 public override int PhysicsActorType {
458 get { return _physicsActorType; } 449 get { return _physicsActorType; }
459 set { _physicsActorType = value; 450 set { _physicsActorType = value; }
460 }
461 } 451 }
462 public override bool IsPhysical { 452 public override bool IsPhysical {
463 get { return _isPhysical; } 453 get { return _isPhysical; }
@@ -484,30 +474,88 @@ public sealed class BSPrim : PhysicsActor
484 474
485 // Make gravity work if the object is physical and not selected 475 // Make gravity work if the object is physical and not selected
486 // No locking here because only called when it is safe 476 // No locking here because only called when it is safe
477 // There are four flags we're interested in:
478 // IsStatic: Object does not move, otherwise the object has mass and moves
479 // isSolid: other objects bounce off of this object
480 // isVolumeDetect: other objects pass through but can generate collisions
481 // collisionEvents: whether this object returns collision events
487 private void SetObjectDynamic() 482 private void SetObjectDynamic()
488 { 483 {
489 // RA: remove this for the moment. 484 // If it's becoming dynamic, it will need hullness
490 // The problem is that dynamic objects are hulls so if we are becoming physical 485 VerifyCorrectPhysicalShape();
491 // the shape has to be checked and possibly built.
492 // Maybe a VerifyCorrectPhysicalShape() routine?
493 // RecreateGeomAndObject();
494 486
495 // Bullet wants static objects to have a mass of zero 487 // Bullet wants static objects to have a mass of zero
496 float mass = IsStatic ? 0f : _mass; 488 float mass = IsStatic ? 0f : _mass;
497 489
498 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); 490 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
491 /*
492 BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr);
499 493
500 // recompute any linkset parameters 494 // Set up the object physicalness (static or dynamic)
501 _linkset.Refresh(this); 495 MakeDynamic();
502 496
503 CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); 497 // Make solid or not and arrange for collisions, etc
504 // DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); 498 MakeSolid();
499
500 m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
501
502 BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr);
503 */
504
505 // Recompute any linkset parameters.
506 // 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.
508 Linkset.Refresh(this);
509
510 DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, m_currentCollisionFlags);
511 }
512
513 // "Making dynamic" means changing to and from static.
514 // When static, gravity does not effect the object and it is fixed in space.
515 // When dynamic, the object can fall and be pushed by others.
516 // This is independent of its 'solidness' which controls what passes through
517 // this object and what interacts with it.
518 private void MakeDynamic()
519 {
520 if (IsStatic)
521 {
522 // Become a Bullet 'static' object type
523 BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
524 // Stop all movement
525 BulletSimAPI.ClearAllForces2(BSBody.Ptr);
526 // Mass is zero which disables a bunch of physics stuff in Bullet
527 BulletSimAPI.SetMassProps2(BSBody.Ptr, 0f, OMV.Vector3.Zero);
528 // There is no inertia in a static object
529 BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
530 // The activation state is 'sleeping' so Bullet will not try to act on it
531 BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING);
532 }
533 else
534 {
535 // Not a Bullet static object
536 BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
537 // 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);
541 BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass, OMV.Vector3.Zero);
542 // Inertia is based on our new mass
543 BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
544 // Force activation of the object so Bullet will act on it.
545 BulletSimAPI.Activate2(BSBody.Ptr, true);
546 }
547 }
548
549 private void MakeSolid()
550 {
505 } 551 }
506 552
507 // prims don't fly 553 // prims don't fly
508 public override bool Flying { 554 public override bool Flying {
509 get { return _flying; } 555 get { return _flying; }
510 set { _flying = value; } 556 set {
557 _flying = value;
558 }
511 } 559 }
512 public override bool SetAlwaysRun { 560 public override bool SetAlwaysRun {
513 get { return _setAlwaysRun; } 561 get { return _setAlwaysRun; }
@@ -558,7 +606,7 @@ public sealed class BSPrim : PhysicsActor
558 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 606 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
559 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 607 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
560 { 608 {
561 // DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 609 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
562 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); 610 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
563 }); 611 });
564 } 612 }
@@ -575,7 +623,7 @@ public sealed class BSPrim : PhysicsActor
575 _buoyancy = value; 623 _buoyancy = value;
576 _scene.TaintedObject("BSPrim.setBuoyancy", delegate() 624 _scene.TaintedObject("BSPrim.setBuoyancy", delegate()
577 { 625 {
578 // DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 626 DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
579 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); 627 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
580 }); 628 });
581 } 629 }
@@ -624,7 +672,7 @@ public sealed class BSPrim : PhysicsActor
624 } 672 }
625 else 673 else
626 { 674 {
627 m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); 675 m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
628 return; 676 return;
629 } 677 }
630 _scene.TaintedObject("BSPrim.AddForce", delegate() 678 _scene.TaintedObject("BSPrim.AddForce", delegate()
@@ -638,17 +686,18 @@ public sealed class BSPrim : PhysicsActor
638 } 686 }
639 m_accumulatedForces.Clear(); 687 m_accumulatedForces.Clear();
640 } 688 }
641 // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); 689 DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
642 BulletSimAPI.AddObjectForce2(Body.Ptr, fSum); 690 // For unknown reason, "ApplyCentralForce" is really additive.
691 BulletSimAPI.ApplyCentralForce2(BSBody.Ptr, fSum);
643 }); 692 });
644 } 693 }
645 694
646 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 695 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
647 // DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); 696 DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
648 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); 697 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
649 } 698 }
650 public override void SetMomentum(OMV.Vector3 momentum) { 699 public override void SetMomentum(OMV.Vector3 momentum) {
651 // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); 700 DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
652 } 701 }
653 public override void SubscribeEvents(int ms) { 702 public override void SubscribeEvents(int ms) {
654 _subscribedEventsMs = ms; 703 _subscribedEventsMs = ms;
@@ -659,7 +708,7 @@ public sealed class BSPrim : PhysicsActor
659 708
660 Scene.TaintedObject("BSPrim.SubscribeEvents", delegate() 709 Scene.TaintedObject("BSPrim.SubscribeEvents", delegate()
661 { 710 {
662 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 711 m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
663 }); 712 });
664 } 713 }
665 } 714 }
@@ -667,7 +716,7 @@ public sealed class BSPrim : PhysicsActor
667 _subscribedEventsMs = 0; 716 _subscribedEventsMs = 0;
668 Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate() 717 Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate()
669 { 718 {
670 BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 719 m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
671 }); 720 });
672 } 721 }
673 public override bool SubscribedEvents() { 722 public override bool SubscribedEvents() {
@@ -992,7 +1041,7 @@ public sealed class BSPrim : PhysicsActor
992 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); 1041 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
993 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) 1042 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
994 { 1043 {
995 // DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); 1044 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
996 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; 1045 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
997 // Bullet native objects are scaled by the Bullet engine so pass the size in 1046 // Bullet native objects are scaled by the Bullet engine so pass the size in
998 _scale = _size; 1047 _scale = _size;
@@ -1006,7 +1055,7 @@ public sealed class BSPrim : PhysicsActor
1006 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); 1055 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
1007 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) 1056 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
1008 { 1057 {
1009 // DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); 1058 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
1010 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; 1059 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
1011 _scale = _size; 1060 _scale = _size;
1012 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? 1061 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
@@ -1042,19 +1091,26 @@ public sealed class BSPrim : PhysicsActor
1042 // No locking here because this is done when we know physics is not simulating 1091 // No locking here because this is done when we know physics is not simulating
1043 private void CreateGeomMesh() 1092 private void CreateGeomMesh()
1044 { 1093 {
1045 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; 1094 // level of detail based on size and type of the object
1095 float lod = _scene.MeshLOD;
1096 if (_pbs.SculptEntry)
1097 lod = _scene.SculptLOD;
1098 float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
1099 if (maxAxis > _scene.MeshMegaPrimThreshold)
1100 lod = _scene.MeshMegaPrimLOD;
1101
1046 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); 1102 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
1047 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); 1103 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
1048 1104
1049 // if this new shape is the same as last time, don't recreate the mesh 1105 // if this new shape is the same as last time, don't recreate the mesh
1050 if (_meshKey == newMeshKey) return; 1106 if (_meshKey == newMeshKey) return;
1051 1107
1052 // DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); 1108 DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
1053 // Since we're recreating new, get rid of any previously generated shape 1109 // Since we're recreating new, get rid of any previously generated shape
1054 if (_meshKey != 0) 1110 if (_meshKey != 0)
1055 { 1111 {
1056 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); 1112 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
1057 // DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); 1113 DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
1058 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); 1114 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
1059 _mesh = null; 1115 _mesh = null;
1060 _meshKey = 0; 1116 _meshKey = 0;
@@ -1084,7 +1140,7 @@ public sealed class BSPrim : PhysicsActor
1084 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; 1140 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
1085 // meshes are already scaled by the meshmerizer 1141 // meshes are already scaled by the meshmerizer
1086 _scale = new OMV.Vector3(1f, 1f, 1f); 1142 _scale = new OMV.Vector3(1f, 1f, 1f);
1087 // DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); 1143 DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
1088 return; 1144 return;
1089 } 1145 }
1090 1146
@@ -1098,13 +1154,13 @@ public sealed class BSPrim : PhysicsActor
1098 // if the hull hasn't changed, don't rebuild it 1154 // if the hull hasn't changed, don't rebuild it
1099 if (newHullKey == _hullKey) return; 1155 if (newHullKey == _hullKey) return;
1100 1156
1101 // DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); 1157 DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
1102 1158
1103 // Since we're recreating new, get rid of any previously generated shape 1159 // Since we're recreating new, get rid of any previously generated shape
1104 if (_hullKey != 0) 1160 if (_hullKey != 0)
1105 { 1161 {
1106 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); 1162 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
1107 // DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey); 1163 DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
1108 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); 1164 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
1109 _hullKey = 0; 1165 _hullKey = 0;
1110 } 1166 }
@@ -1198,7 +1254,7 @@ public sealed class BSPrim : PhysicsActor
1198 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; 1254 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1199 // meshes are already scaled by the meshmerizer 1255 // meshes are already scaled by the meshmerizer
1200 _scale = new OMV.Vector3(1f, 1f, 1f); 1256 _scale = new OMV.Vector3(1f, 1f, 1f);
1201 // DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); 1257 DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
1202 return; 1258 return;
1203 } 1259 }
1204 1260
@@ -1210,6 +1266,27 @@ public sealed class BSPrim : PhysicsActor
1210 return; 1266 return;
1211 } 1267 }
1212 1268
1269 private void VerifyCorrectPhysicalShape()
1270 {
1271 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 {
1281 // if not static, it will need a hull to efficiently collide with things
1282 if (_hullKey == 0)
1283 {
1284 RecreateGeomAndObject();
1285 }
1286
1287 }
1288 }
1289
1213 // Create an object in Bullet if it has not already been created 1290 // Create an object in Bullet if it has not already been created
1214 // No locking here because this is done when the physics engine is not simulating 1291 // No locking here because this is done when the physics engine is not simulating
1215 // Returns 'true' if an object was actually created. 1292 // Returns 'true' if an object was actually created.
@@ -1224,7 +1301,7 @@ public sealed class BSPrim : PhysicsActor
1224 bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape); 1301 bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
1225 1302
1226 // the CreateObject() may have recreated the rigid body. Make sure we have the latest. 1303 // the CreateObject() may have recreated the rigid body. Make sure we have the latest.
1227 Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 1304 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
1228 1305
1229 return ret; 1306 return ret;
1230 } 1307 }
@@ -1277,7 +1354,7 @@ public sealed class BSPrim : PhysicsActor
1277 const float ACCELERATION_TOLERANCE = 0.01f; 1354 const float ACCELERATION_TOLERANCE = 0.01f;
1278 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; 1355 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
1279 1356
1280 public void UpdateProperties(EntityProperties entprop) 1357 public override void UpdateProperties(EntityProperties entprop)
1281 { 1358 {
1282 /* 1359 /*
1283 UpdatedProperties changed = 0; 1360 UpdatedProperties changed = 0;
@@ -1325,7 +1402,7 @@ public sealed class BSPrim : PhysicsActor
1325 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. 1402 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1326 1403
1327 // Updates only for individual prims and for the root object of a linkset. 1404 // Updates only for individual prims and for the root object of a linkset.
1328 if (_linkset.IsRoot(this)) 1405 if (Linkset.IsRoot(this))
1329 { 1406 {
1330 // Assign to the local variables so the normal set action does not happen 1407 // Assign to the local variables so the normal set action does not happen
1331 _position = entprop.Position; 1408 _position = entprop.Position;
@@ -1334,10 +1411,8 @@ public sealed class BSPrim : PhysicsActor
1334 _acceleration = entprop.Acceleration; 1411 _acceleration = entprop.Acceleration;
1335 _rotationalVelocity = entprop.RotationalVelocity; 1412 _rotationalVelocity = entprop.RotationalVelocity;
1336 1413
1337 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", 1414 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1338 // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); 1415 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1339 // DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1340 // LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1341 1416
1342 base.RequestPhysicsterseUpdate(); 1417 base.RequestPhysicsterseUpdate();
1343 } 1418 }
@@ -1353,8 +1428,9 @@ public sealed class BSPrim : PhysicsActor
1353 } 1428 }
1354 1429
1355 // I've collided with something 1430 // I've collided with something
1431 // Called at taint time from within the Step() function
1356 CollisionEventUpdate collisionCollection; 1432 CollisionEventUpdate collisionCollection;
1357 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 1433 public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1358 { 1434 {
1359 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 1435 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
1360 1436
@@ -1367,8 +1443,14 @@ public sealed class BSPrim : PhysicsActor
1367 1443
1368 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); 1444 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
1369 1445
1370 // if someone is subscribed to collision events.... 1446 // prims in the same linkset cannot collide with each other
1371 if (_subscribedEventsMs != 0) { 1447 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
1448 {
1449 return;
1450 }
1451
1452 // if someone has subscribed for collision events....
1453 if (SubscribedEvents()) {
1372 // throttle the collisions to the number of milliseconds specified in the subscription 1454 // throttle the collisions to the number of milliseconds specified in the subscription
1373 int nowTime = _scene.SimulationNowTime; 1455 int nowTime = _scene.SimulationNowTime;
1374 if (nowTime >= _nextCollisionOkTime) { 1456 if (nowTime >= _nextCollisionOkTime) {
@@ -1382,7 +1464,7 @@ public sealed class BSPrim : PhysicsActor
1382 } 1464 }
1383 1465
1384 // The scene is telling us it's time to pass our collected collisions into the simulator 1466 // The scene is telling us it's time to pass our collected collisions into the simulator
1385 public void SendCollisions() 1467 public override void SendCollisions()
1386 { 1468 {
1387 if (collisionCollection != null && collisionCollection.Count > 0) 1469 if (collisionCollection != null && collisionCollection.Count > 0)
1388 { 1470 {