diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 220 |
1 files changed, 140 insertions, 80 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index f7b68ba..aeeb4dd 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -46,12 +46,10 @@ public sealed class BSPrim : BSPhysObject | |||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | private static readonly string LogHeader = "[BULLETS PRIM]"; | 47 | private static readonly string LogHeader = "[BULLETS PRIM]"; |
48 | 48 | ||
49 | private PrimitiveBaseShape _pbs; | 49 | // _size is what the user passed. Scale is what we pass to the physics engine with the mesh. |
50 | 50 | // Often Scale is unity because the meshmerizer will apply _size when creating the mesh. | |
51 | // _size is what the user passed. _scale is what we pass to the physics engine with the mesh. | ||
52 | // Often _scale is unity because the meshmerizer will apply _size when creating the mesh. | ||
53 | private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user | 51 | private OMV.Vector3 _size; // the multiplier for each mesh dimension as passed by the user |
54 | private OMV.Vector3 _scale; // the multiplier for each mesh dimension for the mesh as created by the meshmerizer | 52 | // private OMV.Vector3 _scale; // the multiplier for each mesh dimension for the mesh as created by the meshmerizer |
55 | 53 | ||
56 | private bool _grabbed; | 54 | private bool _grabbed; |
57 | private bool _isSelected; | 55 | private bool _isSelected; |
@@ -98,12 +96,12 @@ public sealed class BSPrim : BSPhysObject | |||
98 | _physicsActorType = (int)ActorTypes.Prim; | 96 | _physicsActorType = (int)ActorTypes.Prim; |
99 | _position = pos; | 97 | _position = pos; |
100 | _size = size; | 98 | _size = size; |
101 | _scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type | 99 | Scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type |
102 | _orientation = rotation; | 100 | _orientation = rotation; |
103 | _buoyancy = 1f; | 101 | _buoyancy = 1f; |
104 | _velocity = OMV.Vector3.Zero; | 102 | _velocity = OMV.Vector3.Zero; |
105 | _rotationalVelocity = OMV.Vector3.Zero; | 103 | _rotationalVelocity = OMV.Vector3.Zero; |
106 | _pbs = pbs; | 104 | BaseShape = pbs; |
107 | _isPhysical = pisPhysical; | 105 | _isPhysical = pisPhysical; |
108 | _isVolumeDetect = false; | 106 | _isVolumeDetect = false; |
109 | _friction = PhysicsScene.Params.defaultFriction; // TODO: compute based on object material | 107 | _friction = PhysicsScene.Params.defaultFriction; // TODO: compute based on object material |
@@ -160,33 +158,32 @@ public sealed class BSPrim : BSPhysObject | |||
160 | get { return _size; } | 158 | get { return _size; } |
161 | set { | 159 | set { |
162 | _size = value; | 160 | _size = value; |
163 | PhysicsScene.TaintedObject("BSPrim.setSize", delegate() | 161 | ForceBodyShapeRebuild(false); |
164 | { | ||
165 | _mass = CalculateMass(); // changing size changes the mass | ||
166 | // Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct | ||
167 | // scale and margins are set. | ||
168 | CreateGeomAndObject(true); | ||
169 | // DetailLog("{0},BSPrim.setSize,size={1},scale={2},mass={3},physical={4}", LocalID, _size, _scale, _mass, IsPhysical); | ||
170 | }); | ||
171 | } | 162 | } |
172 | } | 163 | } |
173 | // Scale is what we set in the physics engine. It is different than 'size' in that | 164 | // Scale is what we set in the physics engine. It is different than 'size' in that |
174 | // 'size' can be encorporated into the mesh. In that case, the scale is <1,1,1>. | 165 | // 'size' can be encorporated into the mesh. In that case, the scale is <1,1,1>. |
175 | public OMV.Vector3 Scale | 166 | public override OMV.Vector3 Scale { get; set; } |
176 | { | 167 | |
177 | get { return _scale; } | ||
178 | set { _scale = value; } | ||
179 | } | ||
180 | public override PrimitiveBaseShape Shape { | 168 | public override PrimitiveBaseShape Shape { |
181 | set { | 169 | set { |
182 | _pbs = value; | 170 | BaseShape = value; |
183 | PhysicsScene.TaintedObject("BSPrim.setShape", delegate() | 171 | ForceBodyShapeRebuild(false); |
184 | { | ||
185 | _mass = CalculateMass(); // changing the shape changes the mass | ||
186 | CreateGeomAndObject(true); | ||
187 | }); | ||
188 | } | 172 | } |
189 | } | 173 | } |
174 | public override bool ForceBodyShapeRebuild(bool inTaintTime) | ||
175 | { | ||
176 | BSScene.TaintCallback rebuildOperation = delegate() | ||
177 | { | ||
178 | _mass = CalculateMass(); // changing the shape changes the mass | ||
179 | CreateGeomAndObject(true); | ||
180 | }; | ||
181 | if (inTaintTime) | ||
182 | rebuildOperation(); | ||
183 | else | ||
184 | PhysicsScene.TaintedObject("BSPrim.ForceBodyShapeRebuild", rebuildOperation); | ||
185 | return true; | ||
186 | } | ||
190 | public override bool Grabbed { | 187 | public override bool Grabbed { |
191 | set { _grabbed = value; | 188 | set { _grabbed = value; |
192 | } | 189 | } |
@@ -196,7 +193,7 @@ public sealed class BSPrim : BSPhysObject | |||
196 | _isSelected = value; | 193 | _isSelected = value; |
197 | PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() | 194 | PhysicsScene.TaintedObject("BSPrim.setSelected", delegate() |
198 | { | 195 | { |
199 | // DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); | 196 | DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); |
200 | SetObjectDynamic(false); | 197 | SetObjectDynamic(false); |
201 | }); | 198 | }); |
202 | } | 199 | } |
@@ -265,6 +262,11 @@ public sealed class BSPrim : BSPhysObject | |||
265 | return _position; | 262 | return _position; |
266 | } | 263 | } |
267 | set { | 264 | set { |
265 | // If you must push the position into the physics engine, use ForcePosition. | ||
266 | if (_position == value) | ||
267 | { | ||
268 | return; | ||
269 | } | ||
268 | _position = value; | 270 | _position = value; |
269 | // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? | 271 | // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? |
270 | PositionSanityCheck(); | 272 | PositionSanityCheck(); |
@@ -320,9 +322,9 @@ public sealed class BSPrim : BSPhysObject | |||
320 | } | 322 | } |
321 | 323 | ||
322 | // A version of the sanity check that also makes sure a new position value is | 324 | // A version of the sanity check that also makes sure a new position value is |
323 | // pushed back to the physics engine. This routine would be used by anyone | 325 | // pushed to the physics engine. This routine would be used by anyone |
324 | // who is not already pushing the value. | 326 | // who is not already pushing the value. |
325 | private bool PositionSanityCheck2(bool atTaintTime) | 327 | private bool PositionSanityCheck(bool inTaintTime) |
326 | { | 328 | { |
327 | bool ret = false; | 329 | bool ret = false; |
328 | if (PositionSanityCheck()) | 330 | if (PositionSanityCheck()) |
@@ -332,9 +334,9 @@ public sealed class BSPrim : BSPhysObject | |||
332 | BSScene.TaintCallback sanityOperation = delegate() | 334 | BSScene.TaintCallback sanityOperation = delegate() |
333 | { | 335 | { |
334 | DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 336 | DetailLog("{0},BSPrim.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
335 | BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); | 337 | ForcePosition = _position; |
336 | }; | 338 | }; |
337 | if (atTaintTime) | 339 | if (inTaintTime) |
338 | sanityOperation(); | 340 | sanityOperation(); |
339 | else | 341 | else |
340 | PhysicsScene.TaintedObject("BSPrim.PositionSanityCheck", sanityOperation); | 342 | PhysicsScene.TaintedObject("BSPrim.PositionSanityCheck", sanityOperation); |
@@ -453,7 +455,6 @@ public sealed class BSPrim : BSPhysObject | |||
453 | } | 455 | } |
454 | return; | 456 | return; |
455 | } | 457 | } |
456 | |||
457 | public override OMV.Vector3 Velocity { | 458 | public override OMV.Vector3 Velocity { |
458 | get { return _velocity; } | 459 | get { return _velocity; } |
459 | set { | 460 | set { |
@@ -465,6 +466,13 @@ public sealed class BSPrim : BSPhysObject | |||
465 | }); | 466 | }); |
466 | } | 467 | } |
467 | } | 468 | } |
469 | public override OMV.Vector3 ForceVelocity { | ||
470 | get { return _velocity; } | ||
471 | set { | ||
472 | _velocity = value; | ||
473 | BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity); | ||
474 | } | ||
475 | } | ||
468 | public override OMV.Vector3 Torque { | 476 | public override OMV.Vector3 Torque { |
469 | get { return _torque; } | 477 | get { return _torque; } |
470 | set { _torque = value; | 478 | set { _torque = value; |
@@ -490,6 +498,8 @@ public sealed class BSPrim : BSPhysObject | |||
490 | return _orientation; | 498 | return _orientation; |
491 | } | 499 | } |
492 | set { | 500 | set { |
501 | if (_orientation == value) | ||
502 | return; | ||
493 | _orientation = value; | 503 | _orientation = value; |
494 | // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? | 504 | // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint? |
495 | PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() | 505 | PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() |
@@ -534,13 +544,13 @@ public sealed class BSPrim : BSPhysObject | |||
534 | } | 544 | } |
535 | 545 | ||
536 | // An object is static (does not move) if selected or not physical | 546 | // An object is static (does not move) if selected or not physical |
537 | private bool IsStatic | 547 | public override bool IsStatic |
538 | { | 548 | { |
539 | get { return _isSelected || !IsPhysical; } | 549 | get { return _isSelected || !IsPhysical; } |
540 | } | 550 | } |
541 | 551 | ||
542 | // An object is solid if it's not phantom and if it's not doing VolumeDetect | 552 | // An object is solid if it's not phantom and if it's not doing VolumeDetect |
543 | public bool IsSolid | 553 | public override bool IsSolid |
544 | { | 554 | { |
545 | get { return !IsPhantom && !_isVolumeDetect; } | 555 | get { return !IsPhantom && !_isVolumeDetect; } |
546 | } | 556 | } |
@@ -570,7 +580,7 @@ public sealed class BSPrim : BSPhysObject | |||
570 | // Set up the object physicalness (does gravity and collisions move this object) | 580 | // Set up the object physicalness (does gravity and collisions move this object) |
571 | MakeDynamic(IsStatic); | 581 | MakeDynamic(IsStatic); |
572 | 582 | ||
573 | // Update vehicle specific parameters | 583 | // Update vehicle specific parameters (after MakeDynamic() so can change physical parameters) |
574 | _vehicle.Refresh(); | 584 | _vehicle.Refresh(); |
575 | 585 | ||
576 | // Arrange for collision events if the simulator wants them | 586 | // Arrange for collision events if the simulator wants them |
@@ -593,7 +603,7 @@ public sealed class BSPrim : BSPhysObject | |||
593 | // Recompute any linkset parameters. | 603 | // Recompute any linkset parameters. |
594 | // When going from non-physical to physical, this re-enables the constraints that | 604 | // When going from non-physical to physical, this re-enables the constraints that |
595 | // had been automatically disabled when the mass was set to zero. | 605 | // had been automatically disabled when the mass was set to zero. |
596 | Linkset.Refresh(this); | 606 | Linkset.Refresh(this, true); |
597 | 607 | ||
598 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", | 608 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", |
599 | LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); | 609 | LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); |
@@ -618,10 +628,18 @@ public sealed class BSPrim : BSPhysObject | |||
618 | BulletSimAPI.SetMassProps2(BSBody.ptr, 0f, OMV.Vector3.Zero); | 628 | BulletSimAPI.SetMassProps2(BSBody.ptr, 0f, OMV.Vector3.Zero); |
619 | // There is no inertia in a static object | 629 | // There is no inertia in a static object |
620 | BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); | 630 | BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); |
631 | // Set collision detection parameters | ||
632 | if (PhysicsScene.Params.ccdMotionThreshold > 0f) | ||
633 | { | ||
634 | BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); | ||
635 | BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); | ||
636 | } | ||
621 | // There can be special things needed for implementing linksets | 637 | // There can be special things needed for implementing linksets |
622 | Linkset.MakeStatic(this); | 638 | Linkset.MakeStatic(this); |
623 | // The activation state is 'disabled' so Bullet will not try to act on it | 639 | // The activation state is 'disabled' so Bullet will not try to act on it. |
624 | BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_SIMULATION); | 640 | BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.DISABLE_SIMULATION); |
641 | // Start it out sleeping and physical actions could wake it up. | ||
642 | // BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); | ||
625 | 643 | ||
626 | BSBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; | 644 | BSBody.collisionFilter = CollisionFilterGroups.StaticObjectFilter; |
627 | BSBody.collisionMask = CollisionFilterGroups.StaticObjectMask; | 645 | BSBody.collisionMask = CollisionFilterGroups.StaticObjectMask; |
@@ -638,12 +656,22 @@ public sealed class BSPrim : BSPhysObject | |||
638 | // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 | 656 | // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 |
639 | BulletSimAPI.ClearAllForces2(BSBody.ptr); | 657 | BulletSimAPI.ClearAllForces2(BSBody.ptr); |
640 | 658 | ||
659 | // For good measure, make sure the transform is set through to the motion state | ||
660 | BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); | ||
661 | |||
641 | // A dynamic object has mass | 662 | // A dynamic object has mass |
642 | IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.ptr); | 663 | IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.ptr); |
643 | OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Mass); | 664 | OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Mass); |
644 | BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia); | 665 | BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia); |
645 | BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); | 666 | BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); |
646 | 667 | ||
668 | // Set collision detection parameters | ||
669 | if (PhysicsScene.Params.ccdMotionThreshold > 0f) | ||
670 | { | ||
671 | BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); | ||
672 | BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); | ||
673 | } | ||
674 | |||
647 | // Various values for simulation limits | 675 | // Various values for simulation limits |
648 | BulletSimAPI.SetDamping2(BSBody.ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); | 676 | BulletSimAPI.SetDamping2(BSBody.ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); |
649 | BulletSimAPI.SetDeactivationTime2(BSBody.ptr, PhysicsScene.Params.deactivationTime); | 677 | BulletSimAPI.SetDeactivationTime2(BSBody.ptr, PhysicsScene.Params.deactivationTime); |
@@ -655,8 +683,8 @@ public sealed class BSPrim : BSPhysObject | |||
655 | 683 | ||
656 | // Force activation of the object so Bullet will act on it. | 684 | // Force activation of the object so Bullet will act on it. |
657 | // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. | 685 | // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. |
658 | BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); | 686 | BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG); |
659 | BulletSimAPI.Activate2(BSBody.ptr, true); | 687 | // BulletSimAPI.Activate2(BSBody.ptr, true); |
660 | 688 | ||
661 | BSBody.collisionFilter = CollisionFilterGroups.ObjectFilter; | 689 | BSBody.collisionFilter = CollisionFilterGroups.ObjectFilter; |
662 | BSBody.collisionMask = CollisionFilterGroups.ObjectMask; | 690 | BSBody.collisionMask = CollisionFilterGroups.ObjectMask; |
@@ -774,6 +802,15 @@ public sealed class BSPrim : BSPhysObject | |||
774 | }); | 802 | }); |
775 | } | 803 | } |
776 | } | 804 | } |
805 | public override OMV.Vector3 ForceRotationalVelocity { | ||
806 | get { | ||
807 | return _rotationalVelocity; | ||
808 | } | ||
809 | set { | ||
810 | _rotationalVelocity = value; | ||
811 | BulletSimAPI.SetAngularVelocity2(BSBody.ptr, _rotationalVelocity); | ||
812 | } | ||
813 | } | ||
777 | public override bool Kinematic { | 814 | public override bool Kinematic { |
778 | get { return _kinematic; } | 815 | get { return _kinematic; } |
779 | set { _kinematic = value; | 816 | set { _kinematic = value; |
@@ -786,13 +823,20 @@ public sealed class BSPrim : BSPhysObject | |||
786 | _buoyancy = value; | 823 | _buoyancy = value; |
787 | PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate() | 824 | PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate() |
788 | { | 825 | { |
789 | // DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 826 | ForceBuoyancy = _buoyancy; |
790 | // Buoyancy is faked by changing the gravity applied to the object | ||
791 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); | ||
792 | BulletSimAPI.SetGravity2(BSBody.ptr, new OMV.Vector3(0f, 0f, grav)); | ||
793 | }); | 827 | }); |
794 | } | 828 | } |
795 | } | 829 | } |
830 | public override float ForceBuoyancy { | ||
831 | get { return _buoyancy; } | ||
832 | set { | ||
833 | _buoyancy = value; | ||
834 | // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | ||
835 | // Buoyancy is faked by changing the gravity applied to the object | ||
836 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); | ||
837 | BulletSimAPI.SetGravity2(BSBody.ptr, new OMV.Vector3(0f, 0f, grav)); | ||
838 | } | ||
839 | } | ||
796 | 840 | ||
797 | // Used for MoveTo | 841 | // Used for MoveTo |
798 | public override OMV.Vector3 PIDTarget { | 842 | public override OMV.Vector3 PIDTarget { |
@@ -828,6 +872,9 @@ public sealed class BSPrim : BSPhysObject | |||
828 | 872 | ||
829 | private List<OMV.Vector3> m_accumulatedForces = new List<OMV.Vector3>(); | 873 | private List<OMV.Vector3> m_accumulatedForces = new List<OMV.Vector3>(); |
830 | public override void AddForce(OMV.Vector3 force, bool pushforce) { | 874 | public override void AddForce(OMV.Vector3 force, bool pushforce) { |
875 | AddForce(force, pushforce, false); | ||
876 | } | ||
877 | public void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { | ||
831 | // for an object, doesn't matter if force is a pushforce or not | 878 | // for an object, doesn't matter if force is a pushforce or not |
832 | if (force.IsFinite()) | 879 | if (force.IsFinite()) |
833 | { | 880 | { |
@@ -840,11 +887,12 @@ public sealed class BSPrim : BSPhysObject | |||
840 | m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); | 887 | m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID); |
841 | return; | 888 | return; |
842 | } | 889 | } |
843 | PhysicsScene.TaintedObject("BSPrim.AddForce", delegate() | 890 | BSScene.TaintCallback addForceOperation = delegate() |
844 | { | 891 | { |
845 | OMV.Vector3 fSum = OMV.Vector3.Zero; | 892 | OMV.Vector3 fSum = OMV.Vector3.Zero; |
846 | lock (m_accumulatedForces) | 893 | lock (m_accumulatedForces) |
847 | { | 894 | { |
895 | // Sum the accumulated additional forces for one big force to apply once. | ||
848 | foreach (OMV.Vector3 v in m_accumulatedForces) | 896 | foreach (OMV.Vector3 v in m_accumulatedForces) |
849 | { | 897 | { |
850 | fSum += v; | 898 | fSum += v; |
@@ -854,7 +902,11 @@ public sealed class BSPrim : BSPhysObject | |||
854 | // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum); | 902 | // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum); |
855 | // For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object. | 903 | // For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object. |
856 | BulletSimAPI.ApplyCentralForce2(BSBody.ptr, fSum); | 904 | BulletSimAPI.ApplyCentralForce2(BSBody.ptr, fSum); |
857 | }); | 905 | }; |
906 | if (inTaintTime) | ||
907 | addForceOperation(); | ||
908 | else | ||
909 | PhysicsScene.TaintedObject("BSPrim.AddForce", addForceOperation); | ||
858 | } | 910 | } |
859 | 911 | ||
860 | public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { | 912 | public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { |
@@ -872,19 +924,19 @@ public sealed class BSPrim : BSPhysObject | |||
872 | float tmp; | 924 | float tmp; |
873 | 925 | ||
874 | float returnMass = 0; | 926 | float returnMass = 0; |
875 | float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; | 927 | float hollowAmount = (float)BaseShape.ProfileHollow * 2.0e-5f; |
876 | float hollowVolume = hollowAmount * hollowAmount; | 928 | float hollowVolume = hollowAmount * hollowAmount; |
877 | 929 | ||
878 | switch (_pbs.ProfileShape) | 930 | switch (BaseShape.ProfileShape) |
879 | { | 931 | { |
880 | case ProfileShape.Square: | 932 | case ProfileShape.Square: |
881 | // default box | 933 | // default box |
882 | 934 | ||
883 | if (_pbs.PathCurve == (byte)Extrusion.Straight) | 935 | if (BaseShape.PathCurve == (byte)Extrusion.Straight) |
884 | { | 936 | { |
885 | if (hollowAmount > 0.0) | 937 | if (hollowAmount > 0.0) |
886 | { | 938 | { |
887 | switch (_pbs.HollowShape) | 939 | switch (BaseShape.HollowShape) |
888 | { | 940 | { |
889 | case HollowShape.Square: | 941 | case HollowShape.Square: |
890 | case HollowShape.Same: | 942 | case HollowShape.Same: |
@@ -908,19 +960,19 @@ public sealed class BSPrim : BSPhysObject | |||
908 | } | 960 | } |
909 | } | 961 | } |
910 | 962 | ||
911 | else if (_pbs.PathCurve == (byte)Extrusion.Curve1) | 963 | else if (BaseShape.PathCurve == (byte)Extrusion.Curve1) |
912 | { | 964 | { |
913 | //a tube | 965 | //a tube |
914 | 966 | ||
915 | volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); | 967 | volume *= 0.78539816339e-2f * (float)(200 - BaseShape.PathScaleX); |
916 | tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY); | 968 | tmp= 1.0f -2.0e-2f * (float)(200 - BaseShape.PathScaleY); |
917 | volume -= volume*tmp*tmp; | 969 | volume -= volume*tmp*tmp; |
918 | 970 | ||
919 | if (hollowAmount > 0.0) | 971 | if (hollowAmount > 0.0) |
920 | { | 972 | { |
921 | hollowVolume *= hollowAmount; | 973 | hollowVolume *= hollowAmount; |
922 | 974 | ||
923 | switch (_pbs.HollowShape) | 975 | switch (BaseShape.HollowShape) |
924 | { | 976 | { |
925 | case HollowShape.Square: | 977 | case HollowShape.Square: |
926 | case HollowShape.Same: | 978 | case HollowShape.Same: |
@@ -945,13 +997,13 @@ public sealed class BSPrim : BSPhysObject | |||
945 | 997 | ||
946 | case ProfileShape.Circle: | 998 | case ProfileShape.Circle: |
947 | 999 | ||
948 | if (_pbs.PathCurve == (byte)Extrusion.Straight) | 1000 | if (BaseShape.PathCurve == (byte)Extrusion.Straight) |
949 | { | 1001 | { |
950 | volume *= 0.78539816339f; // elipse base | 1002 | volume *= 0.78539816339f; // elipse base |
951 | 1003 | ||
952 | if (hollowAmount > 0.0) | 1004 | if (hollowAmount > 0.0) |
953 | { | 1005 | { |
954 | switch (_pbs.HollowShape) | 1006 | switch (BaseShape.HollowShape) |
955 | { | 1007 | { |
956 | case HollowShape.Same: | 1008 | case HollowShape.Same: |
957 | case HollowShape.Circle: | 1009 | case HollowShape.Circle: |
@@ -973,10 +1025,10 @@ public sealed class BSPrim : BSPhysObject | |||
973 | } | 1025 | } |
974 | } | 1026 | } |
975 | 1027 | ||
976 | else if (_pbs.PathCurve == (byte)Extrusion.Curve1) | 1028 | else if (BaseShape.PathCurve == (byte)Extrusion.Curve1) |
977 | { | 1029 | { |
978 | volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); | 1030 | volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - BaseShape.PathScaleX); |
979 | tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); | 1031 | tmp = 1.0f - .02f * (float)(200 - BaseShape.PathScaleY); |
980 | volume *= (1.0f - tmp * tmp); | 1032 | volume *= (1.0f - tmp * tmp); |
981 | 1033 | ||
982 | if (hollowAmount > 0.0) | 1034 | if (hollowAmount > 0.0) |
@@ -985,7 +1037,7 @@ public sealed class BSPrim : BSPhysObject | |||
985 | // calculate the hollow volume by it's shape compared to the prim shape | 1037 | // calculate the hollow volume by it's shape compared to the prim shape |
986 | hollowVolume *= hollowAmount; | 1038 | hollowVolume *= hollowAmount; |
987 | 1039 | ||
988 | switch (_pbs.HollowShape) | 1040 | switch (BaseShape.HollowShape) |
989 | { | 1041 | { |
990 | case HollowShape.Same: | 1042 | case HollowShape.Same: |
991 | case HollowShape.Circle: | 1043 | case HollowShape.Circle: |
@@ -1009,7 +1061,7 @@ public sealed class BSPrim : BSPhysObject | |||
1009 | break; | 1061 | break; |
1010 | 1062 | ||
1011 | case ProfileShape.HalfCircle: | 1063 | case ProfileShape.HalfCircle: |
1012 | if (_pbs.PathCurve == (byte)Extrusion.Curve1) | 1064 | if (BaseShape.PathCurve == (byte)Extrusion.Curve1) |
1013 | { | 1065 | { |
1014 | volume *= 0.52359877559829887307710723054658f; | 1066 | volume *= 0.52359877559829887307710723054658f; |
1015 | } | 1067 | } |
@@ -1017,7 +1069,7 @@ public sealed class BSPrim : BSPhysObject | |||
1017 | 1069 | ||
1018 | case ProfileShape.EquilateralTriangle: | 1070 | case ProfileShape.EquilateralTriangle: |
1019 | 1071 | ||
1020 | if (_pbs.PathCurve == (byte)Extrusion.Straight) | 1072 | if (BaseShape.PathCurve == (byte)Extrusion.Straight) |
1021 | { | 1073 | { |
1022 | volume *= 0.32475953f; | 1074 | volume *= 0.32475953f; |
1023 | 1075 | ||
@@ -1025,7 +1077,7 @@ public sealed class BSPrim : BSPhysObject | |||
1025 | { | 1077 | { |
1026 | 1078 | ||
1027 | // calculate the hollow volume by it's shape compared to the prim shape | 1079 | // calculate the hollow volume by it's shape compared to the prim shape |
1028 | switch (_pbs.HollowShape) | 1080 | switch (BaseShape.HollowShape) |
1029 | { | 1081 | { |
1030 | case HollowShape.Same: | 1082 | case HollowShape.Same: |
1031 | case HollowShape.Triangle: | 1083 | case HollowShape.Triangle: |
@@ -1050,11 +1102,11 @@ public sealed class BSPrim : BSPhysObject | |||
1050 | volume *= (1.0f - hollowVolume); | 1102 | volume *= (1.0f - hollowVolume); |
1051 | } | 1103 | } |
1052 | } | 1104 | } |
1053 | else if (_pbs.PathCurve == (byte)Extrusion.Curve1) | 1105 | else if (BaseShape.PathCurve == (byte)Extrusion.Curve1) |
1054 | { | 1106 | { |
1055 | volume *= 0.32475953f; | 1107 | volume *= 0.32475953f; |
1056 | volume *= 0.01f * (float)(200 - _pbs.PathScaleX); | 1108 | volume *= 0.01f * (float)(200 - BaseShape.PathScaleX); |
1057 | tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); | 1109 | tmp = 1.0f - .02f * (float)(200 - BaseShape.PathScaleY); |
1058 | volume *= (1.0f - tmp * tmp); | 1110 | volume *= (1.0f - tmp * tmp); |
1059 | 1111 | ||
1060 | if (hollowAmount > 0.0) | 1112 | if (hollowAmount > 0.0) |
@@ -1062,7 +1114,7 @@ public sealed class BSPrim : BSPhysObject | |||
1062 | 1114 | ||
1063 | hollowVolume *= hollowAmount; | 1115 | hollowVolume *= hollowAmount; |
1064 | 1116 | ||
1065 | switch (_pbs.HollowShape) | 1117 | switch (BaseShape.HollowShape) |
1066 | { | 1118 | { |
1067 | case HollowShape.Same: | 1119 | case HollowShape.Same: |
1068 | case HollowShape.Triangle: | 1120 | case HollowShape.Triangle: |
@@ -1102,26 +1154,26 @@ public sealed class BSPrim : BSPhysObject | |||
1102 | float profileBegin; | 1154 | float profileBegin; |
1103 | float profileEnd; | 1155 | float profileEnd; |
1104 | 1156 | ||
1105 | if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) | 1157 | if (BaseShape.PathCurve == (byte)Extrusion.Straight || BaseShape.PathCurve == (byte)Extrusion.Flexible) |
1106 | { | 1158 | { |
1107 | taperX1 = _pbs.PathScaleX * 0.01f; | 1159 | taperX1 = BaseShape.PathScaleX * 0.01f; |
1108 | if (taperX1 > 1.0f) | 1160 | if (taperX1 > 1.0f) |
1109 | taperX1 = 2.0f - taperX1; | 1161 | taperX1 = 2.0f - taperX1; |
1110 | taperX = 1.0f - taperX1; | 1162 | taperX = 1.0f - taperX1; |
1111 | 1163 | ||
1112 | taperY1 = _pbs.PathScaleY * 0.01f; | 1164 | taperY1 = BaseShape.PathScaleY * 0.01f; |
1113 | if (taperY1 > 1.0f) | 1165 | if (taperY1 > 1.0f) |
1114 | taperY1 = 2.0f - taperY1; | 1166 | taperY1 = 2.0f - taperY1; |
1115 | taperY = 1.0f - taperY1; | 1167 | taperY = 1.0f - taperY1; |
1116 | } | 1168 | } |
1117 | else | 1169 | else |
1118 | { | 1170 | { |
1119 | taperX = _pbs.PathTaperX * 0.01f; | 1171 | taperX = BaseShape.PathTaperX * 0.01f; |
1120 | if (taperX < 0.0f) | 1172 | if (taperX < 0.0f) |
1121 | taperX = -taperX; | 1173 | taperX = -taperX; |
1122 | taperX1 = 1.0f - taperX; | 1174 | taperX1 = 1.0f - taperX; |
1123 | 1175 | ||
1124 | taperY = _pbs.PathTaperY * 0.01f; | 1176 | taperY = BaseShape.PathTaperY * 0.01f; |
1125 | if (taperY < 0.0f) | 1177 | if (taperY < 0.0f) |
1126 | taperY = -taperY; | 1178 | taperY = -taperY; |
1127 | taperY1 = 1.0f - taperY; | 1179 | taperY1 = 1.0f - taperY; |
@@ -1131,13 +1183,13 @@ public sealed class BSPrim : BSPhysObject | |||
1131 | 1183 | ||
1132 | volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); | 1184 | volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); |
1133 | 1185 | ||
1134 | pathBegin = (float)_pbs.PathBegin * 2.0e-5f; | 1186 | pathBegin = (float)BaseShape.PathBegin * 2.0e-5f; |
1135 | pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f; | 1187 | pathEnd = 1.0f - (float)BaseShape.PathEnd * 2.0e-5f; |
1136 | volume *= (pathEnd - pathBegin); | 1188 | volume *= (pathEnd - pathBegin); |
1137 | 1189 | ||
1138 | // this is crude aproximation | 1190 | // this is crude aproximation |
1139 | profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f; | 1191 | profileBegin = (float)BaseShape.ProfileBegin * 2.0e-5f; |
1140 | profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f; | 1192 | profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f; |
1141 | volume *= (profileEnd - profileBegin); | 1193 | volume *= (profileEnd - profileBegin); |
1142 | 1194 | ||
1143 | returnMass = _density * volume; | 1195 | returnMass = _density * volume; |
@@ -1172,7 +1224,8 @@ public sealed class BSPrim : BSPhysObject | |||
1172 | shape.Position = _position; | 1224 | shape.Position = _position; |
1173 | shape.Rotation = _orientation; | 1225 | shape.Rotation = _orientation; |
1174 | shape.Velocity = _velocity; | 1226 | shape.Velocity = _velocity; |
1175 | shape.Scale = _scale; | 1227 | shape.Size = _size; |
1228 | shape.Scale = Scale; | ||
1176 | shape.Mass = _isPhysical ? _mass : 0f; | 1229 | shape.Mass = _isPhysical ? _mass : 0f; |
1177 | shape.Buoyancy = _buoyancy; | 1230 | shape.Buoyancy = _buoyancy; |
1178 | shape.HullKey = 0; | 1231 | shape.HullKey = 0; |
@@ -1182,7 +1235,6 @@ public sealed class BSPrim : BSPhysObject | |||
1182 | shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; | 1235 | shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; |
1183 | shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; | 1236 | shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; |
1184 | shape.Solid = IsSolid ? ShapeData.numericFalse : ShapeData.numericTrue; | 1237 | shape.Solid = IsSolid ? ShapeData.numericFalse : ShapeData.numericTrue; |
1185 | shape.Size = _size; | ||
1186 | } | 1238 | } |
1187 | // Rebuild the geometry and object. | 1239 | // Rebuild the geometry and object. |
1188 | // This is called when the shape changes so we need to recreate the mesh/hull. | 1240 | // This is called when the shape changes so we need to recreate the mesh/hull. |
@@ -1199,11 +1251,12 @@ public sealed class BSPrim : BSPhysObject | |||
1199 | // Create the correct physical representation for this type of object. | 1251 | // Create the correct physical representation for this type of object. |
1200 | // Updates BSBody and BSShape with the new information. | 1252 | // Updates BSBody and BSShape with the new information. |
1201 | // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. | 1253 | // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. |
1202 | PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, shapeData, _pbs, | 1254 | PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, shapeData, BaseShape, |
1203 | null, delegate(BulletBody dBody) | 1255 | null, delegate(BulletBody dBody) |
1204 | { | 1256 | { |
1205 | // Called if the current prim body is about to be destroyed. | 1257 | // Called if the current prim body is about to be destroyed. |
1206 | // Remove all the physical dependencies on the old body. | 1258 | // Remove all the physical dependencies on the old body. |
1259 | // (Maybe someday make the changing of BSShape an event handled by BSLinkset.) | ||
1207 | needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); | 1260 | needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); |
1208 | }); | 1261 | }); |
1209 | 1262 | ||
@@ -1292,7 +1345,11 @@ public sealed class BSPrim : BSPhysObject | |||
1292 | _acceleration = entprop.Acceleration; | 1345 | _acceleration = entprop.Acceleration; |
1293 | _rotationalVelocity = entprop.RotationalVelocity; | 1346 | _rotationalVelocity = entprop.RotationalVelocity; |
1294 | 1347 | ||
1295 | PositionSanityCheck2(true); | 1348 | // remember the current and last set values |
1349 | LastEntityProperties = CurrentEntityProperties; | ||
1350 | CurrentEntityProperties = entprop; | ||
1351 | |||
1352 | PositionSanityCheck(true); | ||
1296 | 1353 | ||
1297 | DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | 1354 | DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", |
1298 | LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); | 1355 | LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); |
@@ -1304,12 +1361,15 @@ public sealed class BSPrim : BSPhysObject | |||
1304 | /* | 1361 | /* |
1305 | else | 1362 | else |
1306 | { | 1363 | { |
1307 | // For debugging, we can also report the movement of children | 1364 | // For debugging, report the movement of children |
1308 | DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | 1365 | DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", |
1309 | LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, | 1366 | LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, |
1310 | entprop.Acceleration, entprop.RotationalVelocity); | 1367 | entprop.Acceleration, entprop.RotationalVelocity); |
1311 | } | 1368 | } |
1312 | */ | 1369 | */ |
1370 | // The linkset implimentation might want to know about this. | ||
1371 | |||
1372 | Linkset.UpdateProperties(this); | ||
1313 | } | 1373 | } |
1314 | } | 1374 | } |
1315 | } | 1375 | } |