aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs272
1 files changed, 136 insertions, 136 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 2b3fa25..758d92b 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;
@@ -108,8 +107,8 @@ public sealed class BSPrim : BSPhysObject
108 _mass = CalculateMass(); 107 _mass = CalculateMass();
109 108
110 // No body or shape yet 109 // No body or shape yet
111 PhysBody = new BulletBody(LocalID, IntPtr.Zero); 110 PhysBody = new BulletBody(LocalID);
112 PhysShape = new BulletShape(IntPtr.Zero); 111 PhysShape = new BulletShape();
113 112
114 DetailLog("{0},BSPrim.constructor,call", LocalID); 113 DetailLog("{0},BSPrim.constructor,call", LocalID);
115 // do the actual object creation at taint time 114 // do the actual object creation at taint time
@@ -143,7 +142,9 @@ public sealed class BSPrim : BSPhysObject
143 DetailLog("{0},BSPrim.Destroy,taint,", LocalID); 142 DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
144 // If there are physical body and shape, release my use of same. 143 // If there are physical body and shape, release my use of same.
145 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); 144 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null);
145 PhysBody.Clear();
146 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); 146 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null);
147 PhysShape.Clear();
147 }); 148 });
148 } 149 }
149 150
@@ -157,12 +158,10 @@ public sealed class BSPrim : BSPhysObject
157 // We presume the scale and size are the same. If scale must be changed for 158 // 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. 159 // the physical shape, that is done when the geometry is built.
159 _size = value; 160 _size = value;
161 Scale = _size;
160 ForceBodyShapeRebuild(false); 162 ForceBodyShapeRebuild(false);
161 } 163 }
162 } 164 }
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 165
167 public override PrimitiveBaseShape Shape { 166 public override PrimitiveBaseShape Shape {
168 set { 167 set {
@@ -189,13 +188,17 @@ public sealed class BSPrim : BSPhysObject
189 } 188 }
190 } 189 }
191 public override bool Selected { 190 public override bool Selected {
192 set { 191 set
193 _isSelected = value; 192 {
194 PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() 193 if (value != _isSelected)
195 { 194 {
196 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); 195 _isSelected = value;
197 SetObjectDynamic(false); 196 PhysicsScene.TaintedObject("BSPrim.setSelected", delegate()
198 }); 197 {
198 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
199 SetObjectDynamic(false);
200 });
201 }
199 } 202 }
200 } 203 }
201 public override void CrossingFailure() { return; } 204 public override void CrossingFailure() { return; }
@@ -244,7 +247,8 @@ public sealed class BSPrim : BSPhysObject
244 // Zero some other properties in the physics engine 247 // Zero some other properties in the physics engine
245 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 248 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
246 { 249 {
247 BulletSimAPI.ClearAllForces2(PhysBody.ptr); 250 if (PhysBody.HasPhysicalBody)
251 BulletSimAPI.ClearAllForces2(PhysBody.ptr);
248 }); 252 });
249 } 253 }
250 public override void ZeroAngularMotion(bool inTaintTime) 254 public override void ZeroAngularMotion(bool inTaintTime)
@@ -253,8 +257,12 @@ public sealed class BSPrim : BSPhysObject
253 // Zero some other properties in the physics engine 257 // Zero some other properties in the physics engine
254 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 258 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
255 { 259 {
256 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); 260 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
257 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); 261 if (PhysBody.HasPhysicalBody)
262 {
263 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
264 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
265 }
258 }); 266 });
259 } 267 }
260 268
@@ -271,9 +279,12 @@ public sealed class BSPrim : BSPhysObject
271 } 279 }
272 public override OMV.Vector3 Position { 280 public override OMV.Vector3 Position {
273 get { 281 get {
282 /* NOTE: this refetch is not necessary. The simulator knows about linkset children
283 * 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 284 // child prims move around based on their parent. Need to get the latest location
275 if (!Linkset.IsRoot(this)) 285 if (!Linkset.IsRoot(this))
276 _position = Linkset.Position(this); 286 _position = Linkset.PositionGet(this);
287 */
277 288
278 // don't do the GetObjectPosition for root elements because this function is called a zillion times. 289 // 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); 290 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
@@ -281,18 +292,22 @@ public sealed class BSPrim : BSPhysObject
281 } 292 }
282 set { 293 set {
283 // If the position must be forced into the physics engine, use ForcePosition. 294 // If the position must be forced into the physics engine, use ForcePosition.
295 // All positions are given in world positions.
284 if (_position == value) 296 if (_position == value)
285 { 297 {
298 DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation);
286 return; 299 return;
287 } 300 }
288 _position = value; 301 _position = value;
289 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
290 PositionSanityCheck(false); 302 PositionSanityCheck(false);
303
304 // A linkset might need to know if a component information changed.
305 Linkset.UpdateProperties(this, false);
306
291 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() 307 PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
292 { 308 {
293 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 309 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
294 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 310 ForcePosition = _position;
295 ActivateIfPhysical(false);
296 }); 311 });
297 } 312 }
298 } 313 }
@@ -303,9 +318,11 @@ public sealed class BSPrim : BSPhysObject
303 } 318 }
304 set { 319 set {
305 _position = value; 320 _position = value;
306 // PositionSanityCheck(); // Don't do this! Causes a loop and caller should know better. 321 if (PhysBody.HasPhysicalBody)
307 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 322 {
308 ActivateIfPhysical(false); 323 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
324 ActivateIfPhysical(false);
325 }
309 } 326 }
310 } 327 }
311 328
@@ -316,39 +333,46 @@ public sealed class BSPrim : BSPhysObject
316 { 333 {
317 bool ret = false; 334 bool ret = false;
318 335
336 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position))
337 {
338 // The physical object is out of the known/simulated area.
339 // Upper levels of code will handle the transition to other areas so, for
340 // the time, we just ignore the position.
341 return ret;
342 }
343
319 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); 344 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
320 OMV.Vector3 upForce = OMV.Vector3.Zero; 345 OMV.Vector3 upForce = OMV.Vector3.Zero;
321 if (Position.Z < terrainHeight) 346 if (RawPosition.Z < terrainHeight)
322 { 347 {
323 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 348 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
324 float targetHeight = terrainHeight + (Size.Z / 2f); 349 float targetHeight = terrainHeight + (Size.Z / 2f);
325 // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec. 350 // Upforce proportional to the distance away from the terrain. Correct the error in 1 sec.
326 upForce.Z = (terrainHeight - Position.Z) * 1f; 351 upForce.Z = (terrainHeight - RawPosition.Z) * 1f;
327 ret = true; 352 ret = true;
328 } 353 }
329 354
330 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) 355 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
331 { 356 {
332 float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position); 357 float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position);
333 // TODO: a floating motor so object will bob in the water 358 // TODO: a floating motor so object will bob in the water
334 if (Math.Abs(Position.Z - waterHeight) > 0.1f) 359 if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f)
335 { 360 {
336 // Upforce proportional to the distance away from the water. Correct the error in 1 sec. 361 // Upforce proportional to the distance away from the water. Correct the error in 1 sec.
337 upForce.Z = (waterHeight - Position.Z) * 1f; 362 upForce.Z = (waterHeight - RawPosition.Z) * 1f;
338 ret = true; 363 ret = true;
339 } 364 }
340 } 365 }
341 366
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. 367 // The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
368 // TODO: This should be intergrated with a geneal physics action mechanism.
369 // TODO: This should be moderated with PID'ness.
345 if (ret) 370 if (ret)
346 { 371 {
347 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck:belowTerrain", delegate() 372 // Apply upforce and overcome gravity.
348 { 373 OMV.Vector3 correctionForce = upForce - PhysicsScene.DefaultGravity;
349 // Apply upforce and overcome gravity. 374 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce);
350 ForceVelocity = ForceVelocity + upForce - PhysicsScene.DefaultGravity; 375 AddForce(correctionForce, false, inTaintTime);
351 });
352 } 376 }
353 return ret; 377 return ret;
354 } 378 }
@@ -408,7 +432,8 @@ public sealed class BSPrim : BSPhysObject
408 PhysicsScene.TaintedObject("BSPrim.setForce", delegate() 432 PhysicsScene.TaintedObject("BSPrim.setForce", delegate()
409 { 433 {
410 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); 434 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
411 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force); 435 if (PhysBody.HasPhysicalBody)
436 BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force);
412 }); 437 });
413 } 438 }
414 } 439 }
@@ -502,7 +527,8 @@ public sealed class BSPrim : BSPhysObject
502 PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() 527 PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate()
503 { 528 {
504 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 529 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
505 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); 530 if (PhysBody.HasPhysicalBody)
531 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
506 }); 532 });
507 } 533 }
508 } 534 }
@@ -537,23 +563,32 @@ public sealed class BSPrim : BSPhysObject
537 } 563 }
538 public override OMV.Quaternion Orientation { 564 public override OMV.Quaternion Orientation {
539 get { 565 get {
566 /* NOTE: this refetch is not necessary. The simulator knows about linkset children
567 * 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. 568 // Children move around because tied to parent. Get a fresh value.
541 if (!Linkset.IsRoot(this)) 569 if (!Linkset.IsRoot(this))
542 { 570 {
543 _orientation = Linkset.Orientation(this); 571 _orientation = Linkset.OrientationGet(this);
544 } 572 }
573 */
545 return _orientation; 574 return _orientation;
546 } 575 }
547 set { 576 set {
548 if (_orientation == value) 577 if (_orientation == value)
549 return; 578 return;
550 _orientation = value; 579 _orientation = value;
551 // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? 580
581 // A linkset might need to know if a component information changed.
582 Linkset.UpdateProperties(this, false);
583
552 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() 584 PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
553 { 585 {
554 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr); 586 if (PhysBody.HasPhysicalBody)
555 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); 587 {
556 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 588 // _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
589 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
590 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
591 }
557 }); 592 });
558 } 593 }
559 } 594 }
@@ -644,10 +679,7 @@ public sealed class BSPrim : BSPhysObject
644 BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); 679 BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
645 680
646 // Collision filter can be set only when the object is in the world 681 // Collision filter can be set only when the object is in the world
647 if (PhysBody.collisionFilter != 0 || PhysBody.collisionMask != 0) 682 PhysBody.ApplyCollisionMask();
648 {
649 BulletSimAPI.SetCollisionFilterMask2(PhysBody.ptr, (uint)PhysBody.collisionFilter, (uint)PhysBody.collisionMask);
650 }
651 683
652 // Recompute any linkset parameters. 684 // Recompute any linkset parameters.
653 // When going from non-physical to physical, this re-enables the constraints that 685 // When going from non-physical to physical, this re-enables the constraints that
@@ -672,8 +704,12 @@ public sealed class BSPrim : BSPhysObject
672 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 704 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
673 // Stop all movement 705 // Stop all movement
674 ZeroMotion(true); 706 ZeroMotion(true);
675 // Center of mass is at the center of the object 707
676 // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); 708 // Set various physical properties so other object interact properly
709 MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
710 BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
711 BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
712
677 // Mass is zero which disables a bunch of physics stuff in Bullet 713 // Mass is zero which disables a bunch of physics stuff in Bullet
678 UpdatePhysicalMassProperties(0f); 714 UpdatePhysicalMassProperties(0f);
679 // Set collision detection parameters 715 // Set collision detection parameters
@@ -682,24 +718,27 @@ public sealed class BSPrim : BSPhysObject
682 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold); 718 BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, PhysicsScene.Params.ccdMotionThreshold);
683 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); 719 BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius);
684 } 720 }
685 // There can be special things needed for implementing linksets 721
686 Linkset.MakeStatic(this);
687 // The activation state is 'disabled' so Bullet will not try to act on it. 722 // The activation state is 'disabled' so Bullet will not try to act on it.
688 BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION); 723 // BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
689 // Start it out sleeping and physical actions could wake it up. 724 // Start it out sleeping and physical actions could wake it up.
690 // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); 725 BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING);
726
727 // This collides like a static object
728 PhysBody.collisionType = CollisionType.Static;
691 729
692 PhysBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; 730 // There can be special things needed for implementing linksets
693 PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; 731 Linkset.MakeStatic(this);
694 } 732 }
695 else 733 else
696 { 734 {
697 // Not a Bullet static object 735 // Not a Bullet static object
698 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 736 CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
699 737
700 // Set various physical properties so internal dynamic properties will get computed correctly as they are set 738 // Set various physical properties so other object interact properly
701 BulletSimAPI.SetFriction2(PhysBody.ptr, PhysicsScene.Params.defaultFriction); 739 MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true);
702 BulletSimAPI.SetRestitution2(PhysBody.ptr, PhysicsScene.Params.defaultRestitution); 740 BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
741 BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
703 742
704 // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 743 // 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 744 // Since this can be called multiple times, only zero forces when becoming physical
@@ -727,16 +766,15 @@ public sealed class BSPrim : BSPhysObject
727 BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); 766 BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold);
728 BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); 767 BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold);
729 768
730 // There might be special things needed for implementing linksets. 769 // This collides like an object.
731 Linkset.MakeDynamic(this); 770 PhysBody.collisionType = CollisionType.Dynamic;
732 771
733 // Force activation of the object so Bullet will act on it. 772 // Force activation of the object so Bullet will act on it.
734 // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. 773 // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
735 BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); 774 BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG);
736 // BulletSimAPI.Activate2(BSBody.ptr, true);
737 775
738 PhysBody.collisionFilter = CollisionFilterGroups.ObjectFilter; 776 // There might be special things needed for implementing linksets.
739 PhysBody.collisionMask = CollisionFilterGroups.ObjectMask; 777 Linkset.MakeDynamic(this);
740 } 778 }
741 } 779 }
742 780
@@ -763,8 +801,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); 801 m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType);
764 } 802 }
765 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); 803 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
766 PhysBody.collisionFilter = CollisionFilterGroups.VolumeDetectFilter; 804
767 PhysBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; 805 // Change collision info from a static object to a ghosty collision object
806 PhysBody.collisionType = CollisionType.VolumeDetect;
768 } 807 }
769 } 808 }
770 809
@@ -839,15 +878,6 @@ public sealed class BSPrim : BSPhysObject
839 } 878 }
840 public override OMV.Vector3 RotationalVelocity { 879 public override OMV.Vector3 RotationalVelocity {
841 get { 880 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; 881 return _rotationalVelocity;
852 } 882 }
853 set { 883 set {
@@ -856,7 +886,8 @@ public sealed class BSPrim : BSPhysObject
856 PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 886 PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
857 { 887 {
858 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 888 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
859 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity); 889 if (PhysBody.HasPhysicalBody)
890 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
860 }); 891 });
861 } 892 }
862 } 893 }
@@ -891,8 +922,11 @@ public sealed class BSPrim : BSPhysObject
891 _buoyancy = value; 922 _buoyancy = value;
892 // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 923 // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
893 // Buoyancy is faked by changing the gravity applied to the object 924 // Buoyancy is faked by changing the gravity applied to the object
894 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); 925 if (PhysBody.HasPhysicalBody)
895 BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); 926 {
927 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
928 BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
929 }
896 } 930 }
897 } 931 }
898 932
@@ -960,7 +994,8 @@ public sealed class BSPrim : BSPhysObject
960 } 994 }
961 DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum); 995 DetailLog("{0},BSPrim.AddForce,taint,force={1}", LocalID, fSum);
962 if (fSum != OMV.Vector3.Zero) 996 if (fSum != OMV.Vector3.Zero)
963 BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum); 997 if (PhysBody.HasPhysicalBody)
998 BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, fSum);
964 }); 999 });
965 } 1000 }
966 1001
@@ -971,7 +1006,8 @@ public sealed class BSPrim : BSPhysObject
971 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyForceImpulse", delegate() 1006 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyForceImpulse", delegate()
972 { 1007 {
973 DetailLog("{0},BSPrim.ApplyForceImpulse,taint,tImpulse={1}", LocalID, applyImpulse); 1008 DetailLog("{0},BSPrim.ApplyForceImpulse,taint,tImpulse={1}", LocalID, applyImpulse);
974 BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse); 1009 if (PhysBody.HasPhysicalBody)
1010 BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse);
975 }); 1011 });
976 } 1012 }
977 1013
@@ -1007,18 +1043,23 @@ public sealed class BSPrim : BSPhysObject
1007 DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum); 1043 DetailLog("{0},BSPrim.AddAngularForce,taint,aForce={1}", LocalID, fSum);
1008 if (fSum != OMV.Vector3.Zero) 1044 if (fSum != OMV.Vector3.Zero)
1009 { 1045 {
1010 BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum); 1046 if (PhysBody.HasPhysicalBody)
1047 BulletSimAPI.ApplyTorque2(PhysBody.ptr, fSum);
1011 _torque = fSum; 1048 _torque = fSum;
1012 } 1049 }
1013 }); 1050 });
1014 } 1051 }
1015 // A torque impulse. 1052 // A torque impulse.
1053 // ApplyTorqueImpulse adds torque directly to the angularVelocity.
1054 // AddAngularForce accumulates the force and applied it to the angular velocity all at once.
1055 // Computed as: angularVelocity += impulse * inertia;
1016 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) 1056 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
1017 { 1057 {
1018 OMV.Vector3 applyImpulse = impulse; 1058 OMV.Vector3 applyImpulse = impulse;
1019 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() 1059 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate()
1020 { 1060 {
1021 BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); 1061 if (PhysBody.HasPhysicalBody)
1062 BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse);
1022 }); 1063 });
1023 } 1064 }
1024 1065
@@ -1326,7 +1367,7 @@ public sealed class BSPrim : BSPhysObject
1326 // Rebuild the geometry and object. 1367 // Rebuild the geometry and object.
1327 // This is called when the shape changes so we need to recreate the mesh/hull. 1368 // This is called when the shape changes so we need to recreate the mesh/hull.
1328 // Called at taint-time!!! 1369 // Called at taint-time!!!
1329 private void CreateGeomAndObject(bool forceRebuild) 1370 public void CreateGeomAndObject(bool forceRebuild)
1330 { 1371 {
1331 // If this prim is part of a linkset, we must remove and restore the physical 1372 // If this prim is part of a linkset, we must remove and restore the physical
1332 // links if the body is rebuilt. 1373 // links if the body is rebuilt.
@@ -1336,12 +1377,11 @@ public sealed class BSPrim : BSPhysObject
1336 // Create the correct physical representation for this type of object. 1377 // Create the correct physical representation for this type of object.
1337 // Updates PhysBody and PhysShape with the new information. 1378 // Updates PhysBody and PhysShape with the new information.
1338 // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. 1379 // 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) 1380 PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody)
1341 { 1381 {
1342 // Called if the current prim body is about to be destroyed. 1382 // Called if the current prim body is about to be destroyed.
1343 // Remove all the physical dependencies on the old body. 1383 // Remove all the physical dependencies on the old body.
1344 // (Maybe someday make the changing of BSShape an event handled by BSLinkset.) 1384 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
1345 needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); 1385 needToRestoreLinkset = Linkset.RemoveBodyDependencies(this);
1346 needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this); 1386 needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this);
1347 }); 1387 });
@@ -1381,54 +1421,16 @@ public sealed class BSPrim : BSPhysObject
1381 1421
1382 public override void UpdateProperties(EntityProperties entprop) 1422 public override void UpdateProperties(EntityProperties entprop)
1383 { 1423 {
1384 /* 1424 // Updates only for individual prims and for the root object of a linkset.
1385 UpdatedProperties changed = 0; 1425 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 { 1426 {
1419 // Only update the position of single objects and linkset roots 1427 // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
1420 if (Linkset.IsRoot(this)) 1428 // TODO: handle physics introduced by Bullet with computed vehicle physics.
1429 if (_vehicle.IsActive)
1421 { 1430 {
1422 base.RequestPhysicsterseUpdate(); 1431 entprop.RotationalVelocity = OMV.Vector3.Zero;
1423 } 1432 }
1424 }
1425 */
1426
1427 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1428 1433
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 1434 // Assign directly to the local variables so the normal set action does not happen
1433 _position = entprop.Position; 1435 _position = entprop.Position;
1434 _orientation = entprop.Rotation; 1436 _orientation = entprop.Rotation;
@@ -1437,21 +1439,19 @@ public sealed class BSPrim : BSPhysObject
1437 _rotationalVelocity = entprop.RotationalVelocity; 1439 _rotationalVelocity = entprop.RotationalVelocity;
1438 1440
1439 // The sanity check can change the velocity and/or position. 1441 // The sanity check can change the velocity and/or position.
1440 if (PositionSanityCheck(true)) 1442 if (IsPhysical && PositionSanityCheck(true))
1441 { 1443 {
1442 entprop.Position = _position; 1444 entprop.Position = _position;
1443 entprop.Velocity = _velocity; 1445 entprop.Velocity = _velocity;
1444 } 1446 }
1445 1447
1446 // remember the current and last set values 1448 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}", 1449 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}",
1452 LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); 1450 LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);
1453 1451
1454 // BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, BSBody.ptr); // DEBUG DEBUG DEBUG 1452 // remember the current and last set values
1453 LastEntityProperties = CurrentEntityProperties;
1454 CurrentEntityProperties = entprop;
1455 1455
1456 base.RequestPhysicsterseUpdate(); 1456 base.RequestPhysicsterseUpdate();
1457 } 1457 }
@@ -1466,7 +1466,7 @@ public sealed class BSPrim : BSPhysObject
1466 */ 1466 */
1467 1467
1468 // The linkset implimentation might want to know about this. 1468 // The linkset implimentation might want to know about this.
1469 Linkset.UpdateProperties(this); 1469 Linkset.UpdateProperties(this, true);
1470 } 1470 }
1471} 1471}
1472} 1472}