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.cs220
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}