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.cs285
1 files changed, 146 insertions, 139 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 2b3fa25..68a0db6 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -45,7 +45,6 @@ public sealed class BSPrim : BSPhysObject
45 private static readonly string LogHeader = "[BULLETS PRIM]"; 45 private static readonly string LogHeader = "[BULLETS PRIM]";
46 46
47 // _size is what the user passed. Scale is what we pass to the physics engine with the mesh. 47 // _size is what the user passed. Scale is what we pass to the physics engine with the mesh.
48 // Often Scale is unity because the meshmerizer will apply _size when creating the mesh.
49 private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user 48 private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user
50 49
51 private bool _grabbed; 50 private bool _grabbed;
@@ -93,7 +92,7 @@ public sealed class BSPrim : BSPhysObject
93 _physicsActorType = (int)ActorTypes.Prim; 92 _physicsActorType = (int)ActorTypes.Prim;
94 _position = pos; 93 _position = pos;
95 _size = size; 94 _size = size;
96 Scale = size; // the scale will be set by CreateGeom depending on object type 95 Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
97 _orientation = rotation; 96 _orientation = rotation;
98 _buoyancy = 1f; 97 _buoyancy = 1f;
99 _velocity = OMV.Vector3.Zero; 98 _velocity = OMV.Vector3.Zero;
@@ -101,15 +100,20 @@ public sealed class BSPrim : BSPhysObject
101 BaseShape = pbs; 100 BaseShape = pbs;
102 _isPhysical = pisPhysical; 101 _isPhysical = pisPhysical;
103 _isVolumeDetect = false; 102 _isVolumeDetect = false;
104 _friction = PhysicsScene.Params.defaultFriction; // TODO: compute based on object material 103
105 _density = PhysicsScene.Params.defaultDensity; // TODO: compute based on object material 104 // Someday set default attributes based on the material but, for now, we don't know the prim material yet.
105 // MaterialAttributes primMat = BSMaterials.GetAttributes(Material, pisPhysical);
106 _density = PhysicsScene.Params.defaultDensity;
107 _friction = PhysicsScene.Params.defaultFriction;
106 _restitution = PhysicsScene.Params.defaultRestitution; 108 _restitution = PhysicsScene.Params.defaultRestitution;
109
107 _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness 110 _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness
111
108 _mass = CalculateMass(); 112 _mass = CalculateMass();
109 113
110 // No body or shape yet 114 // No body or shape yet
111 PhysBody = new BulletBody(LocalID, IntPtr.Zero); 115 PhysBody = new BulletBody(LocalID);
112 PhysShape = new BulletShape(IntPtr.Zero); 116 PhysShape = new BulletShape();
113 117
114 DetailLog("{0},BSPrim.constructor,call", LocalID); 118 DetailLog("{0},BSPrim.constructor,call", LocalID);
115 // do the actual object creation at taint time 119 // do the actual object creation at taint time
@@ -143,7 +147,9 @@ public sealed class BSPrim : BSPhysObject
143 DetailLog("{0},BSPrim.Destroy,taint,", LocalID); 147 DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
144 // If there are physical body and shape, release my use of same. 148 // If there are physical body and shape, release my use of same.
145 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); 149 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null);
150 PhysBody.Clear();
146 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); 151 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null);
152 PhysShape.Clear();
147 }); 153 });
148 } 154 }
149 155
@@ -157,12 +163,10 @@ public sealed class BSPrim : BSPhysObject
157 // We presume the scale and size are the same. If scale must be changed for 163 // We presume the scale and size are the same. If scale must be changed for
158 // the physical shape, that is done when the geometry is built. 164 // the physical shape, that is done when the geometry is built.
159 _size = value; 165 _size = value;
166 Scale = _size;
160 ForceBodyShapeRebuild(false); 167 ForceBodyShapeRebuild(false);
161 } 168 }
162 } 169 }
163 // Scale is what we set in the physics engine. It is different than 'size' in that
164 // 'size' can be encorporated into the mesh. In that case, the scale is <1,1,1>.
165 public override OMV.Vector3 Scale { get; set; }
166 170
167 public override PrimitiveBaseShape Shape { 171 public override PrimitiveBaseShape Shape {
168 set { 172 set {
@@ -189,13 +193,17 @@ public sealed class BSPrim : BSPhysObject
189 } 193 }
190 } 194 }
191 public override bool Selected { 195 public override bool Selected {
192 set { 196 set
193 _isSelected = value; 197 {
194 PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() 198 if (value != _isSelected)
195 { 199 {
196 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); 200 _isSelected = value;
197 SetObjectDynamic(false); 201 PhysicsScene.TaintedObject("BSPrim.setSelected", delegate()
198 }); 202 {
203 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
204 SetObjectDynamic(false);
205 });
206 }
199 } 207 }
200 } 208 }
201 public override void CrossingFailure() { return; } 209 public override void CrossingFailure() { return; }
@@ -244,7 +252,8 @@ public sealed class BSPrim : BSPhysObject
244 // Zero some other properties in the physics engine 252 // Zero some other properties in the physics engine
245 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 253 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
246 { 254 {
247 BulletSimAPI.ClearAllForces2(PhysBody.ptr); 255 if (PhysBody.HasPhysicalBody)
256 BulletSimAPI.ClearAllForces2(PhysBody.ptr);
248 }); 257 });
249 } 258 }
250 public override void ZeroAngularMotion(bool inTaintTime) 259 public override void ZeroAngularMotion(bool inTaintTime)
@@ -253,8 +262,12 @@ public sealed class BSPrim : BSPhysObject
253 // Zero some other properties in the physics engine 262 // Zero some other properties in the physics engine
254 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 263 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
255 { 264 {
256 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); 265 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
257 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); 266 if (PhysBody.HasPhysicalBody)
267 {
268 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
269 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
270 }
258 }); 271 });
259 } 272 }
260 273
@@ -271,9 +284,12 @@ public sealed class BSPrim : BSPhysObject
271 } 284 }
272 public override OMV.Vector3 Position { 285 public override OMV.Vector3 Position {
273 get { 286 get {
287 /* NOTE: this refetch is not necessary. The simulator knows about linkset children
288 * and does not fetch this position info for children. Thus this is commented out.
274 // child prims move around based on their parent. Need to get the latest location 289 // child prims move around based on their parent. Need to get the latest location
275 if (!Linkset.IsRoot(this)) 290 if (!Linkset.IsRoot(this))
276 _position = Linkset.Position(this); 291 _position = Linkset.PositionGet(this);
292 */
277 293
278 // don't do the GetObjectPosition for root elements because this function is called a zillion times. 294 // don't do the GetObjectPosition for root elements because this function is called a zillion times.
279 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); 295 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
@@ -281,18 +297,22 @@ public sealed class BSPrim : BSPhysObject
281 } 297 }
282 set { 298 set {
283 // If the position must be forced into the physics engine, use ForcePosition. 299 // If the position must be forced into the physics engine, use ForcePosition.
300 // All positions are given in world positions.
284 if (_position == value) 301 if (_position == value)
285 { 302 {
303 DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation);
286 return; 304 return;
287 } 305 }
288 _position = value; 306 _position = value;
289 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
290 PositionSanityCheck(false); 307 PositionSanityCheck(false);
308
309 // A linkset might need to know if a component information changed.
310 Linkset.UpdateProperties(this, false);
311
291 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() 312 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
292 { 313 {
293 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 314 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
294 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 315 ForcePosition = _position;
295 ActivateIfPhysical(false);
296 }); 316 });
297 } 317 }
298 } 318 }
@@ -303,9 +323,11 @@ public sealed class BSPrim : BSPhysObject
303 } 323 }
304 set { 324 set {
305 _position = value; 325 _position = value;
306 // PositionSanityCheck(); // Don't do this! Causes a loop and caller should know better. 326 if (PhysBody.HasPhysicalBody)
307 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 327 {
308 ActivateIfPhysical(false); 328 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
329 ActivateIfPhysical(false);
330 }
309 } 331 }
310 } 332 }
311 333
@@ -316,39 +338,46 @@ public sealed class BSPrim : BSPhysObject
316 { 338 {
317 bool ret = false; 339 bool ret = false;
318 340
341 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position))
342 {
343 // The physical object is out of the known/simulated area.
344 // Upper levels of code will handle the transition to other areas so, for
345 // the time, we just ignore the position.
346 return ret;
347 }
348
319 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); 349 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
320 OMV.Vector3 upForce = OMV.Vector3.Zero; 350 OMV.Vector3 upForce = OMV.Vector3.Zero;
321 if (Position.Z < terrainHeight) 351 if (RawPosition.Z < terrainHeight)
322 { 352 {
323 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 353 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
324 float targetHeight = terrainHeight + (Size.Z / 2f); 354 float targetHeight = terrainHeight + (Size.Z / 2f);
325 // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. 355 // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec.
326 upForce.Z = (terrainHeight - Position.Z) * 1f; 356 upForce.Z = (terrainHeight - RawPosition.Z) * 1f;
327 ret = true; 357 ret = true;
328 } 358 }
329 359
330 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) 360 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
331 { 361 {
332 float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); 362 float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position);
333 // TODO: a floating motor so object will bob in the water 363 // TODO: a floating motor so object will bob in the water
334 if (Math.Abs(Position.Z - waterHeight) > 0.1f) 364 if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f)
335 { 365 {
336 // Upforce proportional to the distance away from the water. Correct the error in 1 sec. 366 // Upforce proportional to the distance away from the water. Correct the error in 1 sec.
337 upForce.Z = (waterHeight - Position.Z) * 1f; 367 upForce.Z = (waterHeight - RawPosition.Z) * 1f;
338 ret = true; 368 ret = true;
339 } 369 }
340 } 370 }
341 371
342 // TODO: check for out of bounds
343
344 // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. 372 // The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
373 // TODO: This should be intergrated with a geneal physics action mechanism.
374 // TODO: This should be moderated with PID'ness.
345 if (ret) 375 if (ret)
346 { 376 {
347 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck:belowTerrain", delegate() 377 // Apply upforce and overcome gravity.
348 { 378 OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
349 // Apply upforce and overcome gravity. 379 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
350 ForceVelocity = ForceVelocity + upForce - PhysicsScene.DefaultGravity; 380 AddForce(correctionForce, false, inTaintTime);
351 });
352 } 381 }
353 return ret; 382 return ret;
354 } 383 }
@@ -408,7 +437,8 @@ public sealed class BSPrim : BSPhysObject
408 PhysicsScene.TaintedObject("BSPrim.setForce", delegate() 437 PhysicsScene.TaintedObject("BSPrim.setForce", delegate()
409 { 438 {
410 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); 439 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
411 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); 440 if (PhysBody.HasPhysicalBody)
441 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force);
412 }); 442 });
413 } 443 }
414 } 444 }
@@ -502,15 +532,18 @@ public sealed class BSPrim : BSPhysObject
502 PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() 532 PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate()
503 { 533 {
504 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 534 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
505 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); 535 ForceVelocity = _velocity;
506 }); 536 });
507 } 537 }
508 } 538 }
509 public override OMV.Vector3 ForceVelocity { 539 public override OMV.Vector3 ForceVelocity {
510 get { return _velocity; } 540 get { return _velocity; }
511 set { 541 set {
542 PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity");
543
512 _velocity = value; 544 _velocity = value;
513 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); 545 if (PhysBody.HasPhysicalBody)
546 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
514 } 547 }
515 } 548 }
516 public override OMV.Vector3 Torque { 549 public override OMV.Vector3 Torque {
@@ -537,23 +570,32 @@ public sealed class BSPrim : BSPhysObject
537 } 570 }
538 public override OMV.Quaternion Orientation { 571 public override OMV.Quaternion Orientation {
539 get { 572 get {
573 /* NOTE: this refetch is not necessary. The simulator knows about linkset children
574 * and does not fetch this position info for children. Thus this is commented out.
540 // Children move around because tied to parent. Get a fresh value. 575 // Children move around because tied to parent. Get a fresh value.
541 if (!Linkset.IsRoot(this)) 576 if (!Linkset.IsRoot(this))
542 { 577 {
543 _orientation = Linkset.Orientation(this); 578 _orientation = Linkset.OrientationGet(this);
544 } 579 }
580 */
545 return _orientation; 581 return _orientation;
546 } 582 }
547 set { 583 set {
548 if (_orientation == value) 584 if (_orientation == value)
549 return; 585 return;
550 _orientation = value; 586 _orientation = value;
551 // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? 587
588 // A linkset might need to know if a component information changed.
589 Linkset.UpdateProperties(this, false);
590
552 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() 591 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
553 { 592 {
554 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); 593 if (PhysBody.HasPhysicalBody)
555 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); 594 {
556 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 595 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
596 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
597 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
598 }
557 }); 599 });
558 } 600 }
559 } 601 }
@@ -644,10 +686,7 @@ public sealed class BSPrim : BSPhysObject
644 BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); 686 BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
645 687
646 // Collision filter can be set only when the object is in the world 688 // Collision filter can be set only when the object is in the world
647 if (PhysBody.collisionFilter != 0 || PhysBody.collisionMask != 0) 689 PhysBody.ApplyCollisionMask();
648 {
649 BulletSimAPI.SetCollisionFilterMask2(PhysBody.ptr, (uint)PhysBody.collisionFilter, (uint)PhysBody.collisionMask);
650 }
651 690
652 // Recompute any linkset parameters. 691 // Recompute any linkset parameters.
653 // When going from non-physical to physical, this re-enables the constraints that 692 // When going from non-physical to physical, this re-enables the constraints that
@@ -672,8 +711,12 @@ public sealed class BSPrim : BSPhysObject
672 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 711 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
673 // Stop all movement 712 // Stop all movement
674 ZeroMotion(true); 713 ZeroMotion(true);
675 // Center of mass is at the center of the object 714
676 // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); 715 // Set various physical properties so other object interact properly
716 MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
717 BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
718 BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
719
677 // Mass is zero which disables a bunch of physics stuff in Bullet 720 // Mass is zero which disables a bunch of physics stuff in Bullet
678 UpdatePhysicalMassProperties(0f); 721 UpdatePhysicalMassProperties(0f);
679 // Set collision detection parameters 722 // Set collision detection parameters
@@ -682,24 +725,27 @@ public sealed class BSPrim : BSPhysObject
682 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); 725 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold);
683 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); 726 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius);
684 } 727 }
685 // There can be special things needed for implementing linksets 728
686 Linkset.MakeStatic(this);
687 // The activation state is 'disabled' so Bullet will not try to act on it. 729 // The activation state is 'disabled' so Bullet will not try to act on it.
688 BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); 730 // BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
689 // Start it out sleeping and physical actions could wake it up. 731 // Start it out sleeping and physical actions could wake it up.
690 // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); 732 BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING);
733
734 // This collides like a static object
735 PhysBody.collisionType = CollisionType.Static;
691 736
692 PhysBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; 737 // There can be special things needed for implementing linksets
693 PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; 738 Linkset.MakeStatic(this);
694 } 739 }
695 else 740 else
696 { 741 {
697 // Not a Bullet static object 742 // Not a Bullet static object
698 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 743 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
699 744
700 // Set various physical properties so internal dynamic properties will get computed correctly as they are set 745 // Set various physical properties so other object interact properly
701 BulletSimAPI.SetFriction2(PhysBody.ptr, PhysicsScene.Params.defaultFriction); 746 MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true);
702 BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.defaultRestitution); 747 BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
748 BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
703 749
704 // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 750 // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
705 // Since this can be called multiple times, only zero forces when becoming physical 751 // Since this can be called multiple times, only zero forces when becoming physical
@@ -727,16 +773,15 @@ public sealed class BSPrim : BSPhysObject
727 BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); 773 BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold);
728 BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); 774 BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold);
729 775
730 // There might be special things needed for implementing linksets. 776 // This collides like an object.
731 Linkset.MakeDynamic(this); 777 PhysBody.collisionType = CollisionType.Dynamic;
732 778
733 // Force activation of the object so Bullet will act on it. 779 // Force activation of the object so Bullet will act on it.
734 // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. 780 // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
735 BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); 781 BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG);
736 // BulletSimAPI.Activate2(BSBody.ptr, true);
737 782
738 PhysBody.collisionFilter = CollisionFilterGroups.ObjectFilter; 783 // There might be special things needed for implementing linksets.
739 PhysBody.collisionMask = CollisionFilterGroups.ObjectMask; 784 Linkset.MakeDynamic(this);
740 } 785 }
741 } 786 }
742 787
@@ -763,8 +808,9 @@ public sealed class BSPrim : BSPhysObject
763 m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); 808 m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType);
764 } 809 }
765 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); 810 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
766 PhysBody.collisionFilter = CollisionFilterGroups.VolumeDetectFilter; 811
767 PhysBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; 812 // Change collision info from a static object to a ghosty collision object
813 PhysBody.collisionType = CollisionType.VolumeDetect;
768 } 814 }
769 } 815 }
770 816
@@ -839,15 +885,6 @@ public sealed class BSPrim : BSPhysObject
839 } 885 }
840 public override OMV.Vector3 RotationalVelocity { 886 public override OMV.Vector3 RotationalVelocity {
841 get { 887 get {
842 /*
843 OMV.Vector3 pv = OMV.Vector3.Zero;
844 // if close to zero, report zero
845 // This is copied from ODE but I'm not sure why it returns zero but doesn't
846 // zero the property in the physics engine.
847 if (_rotationalVelocity.ApproxEquals(pv, 0.2f))
848 return pv;
849 */
850
851 return _rotationalVelocity; 888 return _rotationalVelocity;
852 } 889 }
853 set { 890 set {
@@ -856,7 +893,8 @@ public sealed class BSPrim : BSPhysObject
856 PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 893 PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
857 { 894 {
858 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 895 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
859 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); 896 if (PhysBody.HasPhysicalBody)
897 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
860 }); 898 });
861 } 899 }
862 } 900 }
@@ -891,8 +929,11 @@ public sealed class BSPrim : BSPhysObject
891 _buoyancy = value; 929 _buoyancy = value;
892 // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 930 // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
893 // Buoyancy is faked by changing the gravity applied to the object 931 // Buoyancy is faked by changing the gravity applied to the object
894 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); 932 if (PhysBody.HasPhysicalBody)
895 BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); 933 {
934 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
935 BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
936 }
896 } 937 }
897 } 938 }
898 939
@@ -960,7 +1001,8 @@ public sealed class BSPrim : BSPhysObject
960 } 1001 }
961 DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum); 1002 DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum);
962 if (fSum != OMV.Vector3.Zero) 1003 if (fSum != OMV.Vector3.Zero)
963 BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); 1004 if (PhysBody.HasPhysicalBody)
1005 BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum);
964 }); 1006 });
965 } 1007 }
966 1008
@@ -971,7 +1013,8 @@ public sealed class BSPrim : BSPhysObject
971 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyForceImpulse", delegate() 1013 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyForceImpulse", delegate()
972 { 1014 {
973 DetailLog("{0},BSPrim.ApplyForceImpulse,taint,tImpulse={1}", LocalID, applyImpulse); 1015 DetailLog("{0},BSPrim.ApplyForceImpulse,taint,tImpulse={1}", LocalID, applyImpulse);
974 BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse); 1016 if (PhysBody.HasPhysicalBody)
1017 BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse);
975 }); 1018 });
976 } 1019 }
977 1020
@@ -1007,18 +1050,23 @@ public sealed class BSPrim : BSPhysObject
1007 DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum); 1050 DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum);
1008 if (fSum != OMV.Vector3.Zero) 1051 if (fSum != OMV.Vector3.Zero)
1009 { 1052 {
1010 BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum); 1053 if (PhysBody.HasPhysicalBody)
1054 BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum);
1011 _torque = fSum; 1055 _torque = fSum;
1012 } 1056 }
1013 }); 1057 });
1014 } 1058 }
1015 // A torque impulse. 1059 // A torque impulse.
1060 // ApplyTorqueImpulse adds torque directly to the angularVelocity.
1061 // AddAngularForce accumulates the force and applied it to the angular velocity all at once.
1062 // Computed as: angularVelocity += impulse * inertia;
1016 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) 1063 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
1017 { 1064 {
1018 OMV.Vector3 applyImpulse = impulse; 1065 OMV.Vector3 applyImpulse = impulse;
1019 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() 1066 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate()
1020 { 1067 {
1021 BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); 1068 if (PhysBody.HasPhysicalBody)
1069 BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse);
1022 }); 1070 });
1023 } 1071 }
1024 1072
@@ -1326,7 +1374,7 @@ public sealed class BSPrim : BSPhysObject
1326 // Rebuild the geometry and object. 1374 // Rebuild the geometry and object.
1327 // This is called when the shape changes so we need to recreate the mesh/hull. 1375 // This is called when the shape changes so we need to recreate the mesh/hull.
1328 // Called at taint-time!!! 1376 // Called at taint-time!!!
1329 private void CreateGeomAndObject(bool forceRebuild) 1377 public void CreateGeomAndObject(bool forceRebuild)
1330 { 1378 {
1331 // If this prim is part of a linkset, we must remove and restore the physical 1379 // If this prim is part of a linkset, we must remove and restore the physical
1332 // links if the body is rebuilt. 1380 // links if the body is rebuilt.
@@ -1336,12 +1384,11 @@ public sealed class BSPrim : BSPhysObject
1336 // Create the correct physical representation for this type of object. 1384 // Create the correct physical representation for this type of object.
1337 // Updates PhysBody and PhysShape with the new information. 1385 // Updates PhysBody and PhysShape with the new information.
1338 // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. 1386 // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary.
1339 // Returns 'true' if either the body or the shape was changed.
1340 PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody) 1387 PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody)
1341 { 1388 {
1342 // Called if the current prim body is about to be destroyed. 1389 // Called if the current prim body is about to be destroyed.
1343 // Remove all the physical dependencies on the old body. 1390 // Remove all the physical dependencies on the old body.
1344 // (Maybe someday make the changing of BSShape an event handled by BSLinkset.) 1391 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
1345 needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); 1392 needToRestoreLinkset = Linkset.RemoveBodyDependencies(this);
1346 needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this); 1393 needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this);
1347 }); 1394 });
@@ -1381,54 +1428,16 @@ public sealed class BSPrim : BSPhysObject
1381 1428
1382 public override void UpdateProperties(EntityProperties entprop) 1429 public override void UpdateProperties(EntityProperties entprop)
1383 { 1430 {
1384 /* 1431 // Updates only for individual prims and for the root object of a linkset.
1385 UpdatedProperties changed = 0; 1432 if (Linkset.IsRoot(this))
1386 // assign to the local variables so the normal set action does not happen
1387 // if (_position != entprop.Position)
1388 if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE))
1389 {
1390 _position = entprop.Position;
1391 changed |= UpdatedProperties.Position;
1392 }
1393 // if (_orientation != entprop.Rotation)
1394 if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE))
1395 {
1396 _orientation = entprop.Rotation;
1397 changed |= UpdatedProperties.Rotation;
1398 }
1399 // if (_velocity != entprop.Velocity)
1400 if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE))
1401 {
1402 _velocity = entprop.Velocity;
1403 changed |= UpdatedProperties.Velocity;
1404 }
1405 // if (_acceleration != entprop.Acceleration)
1406 if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE))
1407 {
1408 _acceleration = entprop.Acceleration;
1409 changed |= UpdatedProperties.Acceleration;
1410 }
1411 // if (_rotationalVelocity != entprop.RotationalVelocity)
1412 if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE))
1413 {
1414 _rotationalVelocity = entprop.RotationalVelocity;
1415 changed |= UpdatedProperties.RotationalVel;
1416 }
1417 if (changed != 0)
1418 { 1433 {
1419 // Only update the position of single objects and linkset roots 1434 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
1420 if (Linkset.IsRoot(this)) 1435 // TODO: handle physics introduced by Bullet with computed vehicle physics.
1436 if (_vehicle.IsActive)
1421 { 1437 {
1422 base.RequestPhysicsterseUpdate(); 1438 entprop.RotationalVelocity = OMV.Vector3.Zero;
1423 } 1439 }
1424 }
1425 */
1426 1440
1427 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1428
1429 // Updates only for individual prims and for the root object of a linkset.
1430 if (Linkset.IsRoot(this))
1431 {
1432 // Assign directly to the local variables so the normal set action does not happen 1441 // Assign directly to the local variables so the normal set action does not happen
1433 _position = entprop.Position; 1442 _position = entprop.Position;
1434 _orientation = entprop.Rotation; 1443 _orientation = entprop.Rotation;
@@ -1437,21 +1446,19 @@ public sealed class BSPrim : BSPhysObject
1437 _rotationalVelocity = entprop.RotationalVelocity; 1446 _rotationalVelocity = entprop.RotationalVelocity;
1438 1447
1439 // The sanity check can change the velocity and/or position. 1448 // The sanity check can change the velocity and/or position.
1440 if (PositionSanityCheck(true)) 1449 if (IsPhysical && PositionSanityCheck(true))
1441 { 1450 {
1442 entprop.Position = _position; 1451 entprop.Position = _position;
1443 entprop.Velocity = _velocity; 1452 entprop.Velocity = _velocity;
1444 } 1453 }
1445 1454
1446 // remember the current and last set values 1455 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG
1447 LastEntityProperties = CurrentEntityProperties;
1448 CurrentEntityProperties = entprop;
1449
1450 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation;
1451 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", 1456 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}",
1452 LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); 1457 LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);
1453 1458
1454 // BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, BSBody.ptr); // DEBUG DEBUG DEBUG 1459 // remember the current and last set values
1460 LastEntityProperties = CurrentEntityProperties;
1461 CurrentEntityProperties = entprop;
1455 1462
1456 base.RequestPhysicsterseUpdate(); 1463 base.RequestPhysicsterseUpdate();
1457 } 1464 }
@@ -1466,7 +1473,7 @@ public sealed class BSPrim : BSPhysObject
1466 */ 1473 */
1467 1474
1468 // The linkset implimentation might want to know about this. 1475 // The linkset implimentation might want to know about this.
1469 Linkset.UpdateProperties(this); 1476 Linkset.UpdateProperties(this, true);
1470 } 1477 }
1471} 1478}
1472} 1479}