aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs91
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs221
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs4
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs40
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs41
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs6
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs25
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraintConeTwist.cs54
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraintSlider.cs55
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs103
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs43
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs31
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs494
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs25
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs21
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs91
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs94
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs71
18 files changed, 1313 insertions, 197 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
index 12a0c17..3bd81d4 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs
@@ -596,6 +596,60 @@ public override bool SetBreakingImpulseThreshold(BulletConstraint constrain, flo
596 return BSAPICPP.SetBreakingImpulseThreshold2(constrainu.ptr, threshold); 596 return BSAPICPP.SetBreakingImpulseThreshold2(constrainu.ptr, threshold);
597} 597}
598 598
599public override bool HingeSetLimits(BulletConstraint constrain, float low, float high, float softness, float bias, float relaxation)
600{
601 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
602 return BSAPICPP.HingeSetLimits2(constrainu.ptr, low, high, softness, bias, relaxation);
603}
604
605public override bool SpringEnable(BulletConstraint constrain, int index, float numericTrueFalse)
606{
607 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
608 return BSAPICPP.ConstraintSpringEnable2(constrainu.ptr, index, numericTrueFalse);
609}
610
611public override bool SpringSetEquilibriumPoint(BulletConstraint constrain, int index, float equilibriumPoint)
612{
613 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
614 return BSAPICPP.ConstraintSpringSetEquilibriumPoint2(constrainu.ptr, index, equilibriumPoint);
615}
616
617public override bool SpringSetStiffness(BulletConstraint constrain, int index, float stiffnesss)
618{
619 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
620 return BSAPICPP.ConstraintSpringSetStiffness2(constrainu.ptr, index, stiffnesss);
621}
622
623public override bool SpringSetDamping(BulletConstraint constrain, int index, float damping)
624{
625 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
626 return BSAPICPP.ConstraintSpringSetDamping2(constrainu.ptr, index, damping);
627}
628
629public override bool SliderSetLimits(BulletConstraint constrain, int lowerUpper, int linAng, float val)
630{
631 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
632 return BSAPICPP.SliderSetLimits2(constrainu.ptr, lowerUpper, linAng, val);
633}
634
635public override bool SliderSet(BulletConstraint constrain, int softRestDamp, int dirLimOrtho, int linAng, float val)
636{
637 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
638 return BSAPICPP.SliderSet2(constrainu.ptr, softRestDamp, dirLimOrtho, linAng, val);
639}
640
641public override bool SliderMotorEnable(BulletConstraint constrain, int linAng, float numericTrueFalse)
642{
643 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
644 return BSAPICPP.SliderMotorEnable2(constrainu.ptr, linAng, numericTrueFalse);
645}
646
647public override bool SliderMotor(BulletConstraint constrain, int forceVel, int linAng, float val)
648{
649 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
650 return BSAPICPP.SliderMotor2(constrainu.ptr, forceVel, linAng, val);
651}
652
599public override bool CalculateTransforms(BulletConstraint constrain) 653public override bool CalculateTransforms(BulletConstraint constrain)
600{ 654{
601 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman; 655 BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
@@ -671,6 +725,13 @@ public override bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj)
671 return BSAPICPP.RemoveObjectFromWorld2(worldu.ptr, bodyu.ptr); 725 return BSAPICPP.RemoveObjectFromWorld2(worldu.ptr, bodyu.ptr);
672} 726}
673 727
728public override bool ClearCollisionProxyCache(BulletWorld world, BulletBody obj)
729{
730 BulletWorldUnman worldu = world as BulletWorldUnman;
731 BulletBodyUnman bodyu = obj as BulletBodyUnman;
732 return BSAPICPP.ClearCollisionProxyCache2(worldu.ptr, bodyu.ptr);
733}
734
674public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects) 735public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects)
675{ 736{
676 BulletWorldUnman worldu = world as BulletWorldUnman; 737 BulletWorldUnman worldu = world as BulletWorldUnman;
@@ -1601,6 +1662,33 @@ public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enabl
1601public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold); 1662public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold);
1602 1663
1603[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1664[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1665public static extern bool HingeSetLimits2(IntPtr constrain, float low, float high, float softness, float bias, float relaxation);
1666
1667[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1668public static extern bool ConstraintSpringEnable2(IntPtr constrain, int index, float numericTrueFalse);
1669
1670[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1671public static extern bool ConstraintSpringSetEquilibriumPoint2(IntPtr constrain, int index, float equilibriumPoint);
1672
1673[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1674public static extern bool ConstraintSpringSetStiffness2(IntPtr constrain, int index, float stiffness);
1675
1676[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1677public static extern bool ConstraintSpringSetDamping2(IntPtr constrain, int index, float damping);
1678
1679[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1680public static extern bool SliderSetLimits2(IntPtr constrain, int lowerUpper, int linAng, float val);
1681
1682[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1683public static extern bool SliderSet2(IntPtr constrain, int softRestDamp, int dirLimOrtho, int linAng, float val);
1684
1685[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1686public static extern bool SliderMotorEnable2(IntPtr constrain, int linAng, float numericTrueFalse);
1687
1688[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1689public static extern bool SliderMotor2(IntPtr constrain, int forceVel, int linAng, float val);
1690
1691[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1604public static extern bool CalculateTransforms2(IntPtr constrain); 1692public static extern bool CalculateTransforms2(IntPtr constrain);
1605 1693
1606[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1694[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@@ -1632,6 +1720,9 @@ public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
1632public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj); 1720public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
1633 1721
1634[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1722[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1723public static extern bool ClearCollisionProxyCache2(IntPtr world, IntPtr obj);
1724
1725[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1635public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects); 1726public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects);
1636 1727
1637[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1728[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
index 2a820be..17ebed2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
@@ -169,6 +169,19 @@ private sealed class BulletConstraintXNA : BulletConstraint
169 return true; 169 return true;
170 } 170 }
171 171
172 public override bool ClearCollisionProxyCache(BulletWorld pWorld, BulletBody pBody)
173 {
174 DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
175 RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
176 CollisionObject collisionObject = ((BulletBodyXNA)pBody).body;
177 if (body != null && collisionObject != null && collisionObject.GetBroadphaseHandle() != null)
178 {
179 world.RemoveCollisionObject(collisionObject);
180 world.AddCollisionObject(collisionObject);
181 }
182 return true;
183 }
184
172 public override bool AddConstraintToWorld(BulletWorld pWorld, BulletConstraint pConstraint, bool pDisableCollisionsBetweenLinkedObjects) 185 public override bool AddConstraintToWorld(BulletWorld pWorld, BulletConstraint pConstraint, bool pDisableCollisionsBetweenLinkedObjects)
173 { 186 {
174 DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world; 187 DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
@@ -752,6 +765,214 @@ private sealed class BulletConstraintXNA : BulletConstraint
752 constraint.SetBreakingImpulseThreshold(threshold); 765 constraint.SetBreakingImpulseThreshold(threshold);
753 return true; 766 return true;
754 } 767 }
768 public override bool HingeSetLimits(BulletConstraint pConstraint, float low, float high, float softness, float bias, float relaxation)
769 {
770 HingeConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as HingeConstraint;
771 if (softness == HINGE_NOT_SPECIFIED)
772 constraint.SetLimit(low, high);
773 else
774 constraint.SetLimit(low, high, softness, bias, relaxation);
775 return true;
776 }
777 public override bool SpringEnable(BulletConstraint pConstraint, int index, float numericTrueFalse)
778 {
779 Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
780 constraint.EnableSpring(index, (numericTrueFalse == 0f ? false : true));
781 return true;
782 }
783
784 public override bool SpringSetEquilibriumPoint(BulletConstraint pConstraint, int index, float equilibriumPoint)
785 {
786 Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
787 if (index == SPRING_NOT_SPECIFIED)
788 {
789 constraint.SetEquilibriumPoint();
790 }
791 else
792 {
793 if (equilibriumPoint == SPRING_NOT_SPECIFIED)
794 constraint.SetEquilibriumPoint(index);
795 else
796 constraint.SetEquilibriumPoint(index, equilibriumPoint);
797 }
798 return true;
799 }
800
801 public override bool SpringSetStiffness(BulletConstraint pConstraint, int index, float stiffness)
802 {
803 Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
804 constraint.SetStiffness(index, stiffness);
805 return true;
806 }
807
808 public override bool SpringSetDamping(BulletConstraint pConstraint, int index, float damping)
809 {
810 Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
811 constraint.SetDamping(index, damping);
812 return true;
813 }
814
815 public override bool SliderSetLimits(BulletConstraint pConstraint, int lowerUpper, int linAng, float val)
816 {
817 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
818 switch (lowerUpper)
819 {
820 case SLIDER_LOWER_LIMIT:
821 switch (linAng)
822 {
823 case SLIDER_LINEAR:
824 constraint.SetLowerLinLimit(val);
825 break;
826 case SLIDER_ANGULAR:
827 constraint.SetLowerAngLimit(val);
828 break;
829 }
830 break;
831 case SLIDER_UPPER_LIMIT:
832 switch (linAng)
833 {
834 case SLIDER_LINEAR:
835 constraint.SetUpperLinLimit(val);
836 break;
837 case SLIDER_ANGULAR:
838 constraint.SetUpperAngLimit(val);
839 break;
840 }
841 break;
842 }
843 return true;
844 }
845 public override bool SliderSet(BulletConstraint pConstraint, int softRestDamp, int dirLimOrtho, int linAng, float val)
846 {
847 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
848 switch (softRestDamp)
849 {
850 case SLIDER_SET_SOFTNESS:
851 switch (dirLimOrtho)
852 {
853 case SLIDER_SET_DIRECTION:
854 switch (linAng)
855 {
856 case SLIDER_LINEAR: constraint.SetSoftnessDirLin(val); break;
857 case SLIDER_ANGULAR: constraint.SetSoftnessDirAng(val); break;
858 }
859 break;
860 case SLIDER_SET_LIMIT:
861 switch (linAng)
862 {
863 case SLIDER_LINEAR: constraint.SetSoftnessLimLin(val); break;
864 case SLIDER_ANGULAR: constraint.SetSoftnessLimAng(val); break;
865 }
866 break;
867 case SLIDER_SET_ORTHO:
868 switch (linAng)
869 {
870 case SLIDER_LINEAR: constraint.SetSoftnessOrthoLin(val); break;
871 case SLIDER_ANGULAR: constraint.SetSoftnessOrthoAng(val); break;
872 }
873 break;
874 }
875 break;
876 case SLIDER_SET_RESTITUTION:
877 switch (dirLimOrtho)
878 {
879 case SLIDER_SET_DIRECTION:
880 switch (linAng)
881 {
882 case SLIDER_LINEAR: constraint.SetRestitutionDirLin(val); break;
883 case SLIDER_ANGULAR: constraint.SetRestitutionDirAng(val); break;
884 }
885 break;
886 case SLIDER_SET_LIMIT:
887 switch (linAng)
888 {
889 case SLIDER_LINEAR: constraint.SetRestitutionLimLin(val); break;
890 case SLIDER_ANGULAR: constraint.SetRestitutionLimAng(val); break;
891 }
892 break;
893 case SLIDER_SET_ORTHO:
894 switch (linAng)
895 {
896 case SLIDER_LINEAR: constraint.SetRestitutionOrthoLin(val); break;
897 case SLIDER_ANGULAR: constraint.SetRestitutionOrthoAng(val); break;
898 }
899 break;
900 }
901 break;
902 case SLIDER_SET_DAMPING:
903 switch (dirLimOrtho)
904 {
905 case SLIDER_SET_DIRECTION:
906 switch (linAng)
907 {
908 case SLIDER_LINEAR: constraint.SetDampingDirLin(val); break;
909 case SLIDER_ANGULAR: constraint.SetDampingDirAng(val); break;
910 }
911 break;
912 case SLIDER_SET_LIMIT:
913 switch (linAng)
914 {
915 case SLIDER_LINEAR: constraint.SetDampingLimLin(val); break;
916 case SLIDER_ANGULAR: constraint.SetDampingLimAng(val); break;
917 }
918 break;
919 case SLIDER_SET_ORTHO:
920 switch (linAng)
921 {
922 case SLIDER_LINEAR: constraint.SetDampingOrthoLin(val); break;
923 case SLIDER_ANGULAR: constraint.SetDampingOrthoAng(val); break;
924 }
925 break;
926 }
927 break;
928 }
929 return true;
930 }
931 public override bool SliderMotorEnable(BulletConstraint pConstraint, int linAng, float numericTrueFalse)
932 {
933 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
934 switch (linAng)
935 {
936 case SLIDER_LINEAR:
937 constraint.SetPoweredLinMotor(numericTrueFalse == 0.0 ? false : true);
938 break;
939 case SLIDER_ANGULAR:
940 constraint.SetPoweredAngMotor(numericTrueFalse == 0.0 ? false : true);
941 break;
942 }
943 return true;
944 }
945 public override bool SliderMotor(BulletConstraint pConstraint, int forceVel, int linAng, float val)
946 {
947 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
948 switch (forceVel)
949 {
950 case SLIDER_MOTOR_VELOCITY:
951 switch (linAng)
952 {
953 case SLIDER_LINEAR:
954 constraint.SetTargetLinMotorVelocity(val);
955 break;
956 case SLIDER_ANGULAR:
957 constraint.SetTargetAngMotorVelocity(val);
958 break;
959 }
960 break;
961 case SLIDER_MAX_MOTOR_FORCE:
962 switch (linAng)
963 {
964 case SLIDER_LINEAR:
965 constraint.SetMaxLinMotorForce(val);
966 break;
967 case SLIDER_ANGULAR:
968 constraint.SetMaxAngMotorForce(val);
969 break;
970 }
971 break;
972 }
973 return true;
974 }
975
755 //BulletSimAPI.SetAngularDamping(Prim.PhysBody.ptr, angularDamping); 976 //BulletSimAPI.SetAngularDamping(Prim.PhysBody.ptr, angularDamping);
756 public override void SetAngularDamping(BulletBody pBody, float angularDamping) 977 public override void SetAngularDamping(BulletBody pBody, float angularDamping)
757 { 978 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
index 68bc1b9..1bcf879 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs
@@ -105,7 +105,7 @@ public class BSActorAvatarMove : BSActor
105 // into the movement motor. 105 // into the movement motor.
106 public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime) 106 public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime)
107 { 107 {
108 m_physicsScene.TaintedObject(inTaintTime, "BSActorAvatarMove.setVelocityAndTarget", delegate() 108 m_physicsScene.TaintedObject(inTaintTime, m_controllingPrim.LocalID, "BSActorAvatarMove.setVelocityAndTarget", delegate()
109 { 109 {
110 if (m_velocityMotor != null) 110 if (m_velocityMotor != null)
111 { 111 {
@@ -128,6 +128,7 @@ public class BSActorAvatarMove : BSActor
128 BSMotor.Infinite, // decay time scale 128 BSMotor.Infinite, // decay time scale
129 1f // efficiency 129 1f // efficiency
130 ); 130 );
131 m_velocityMotor.ErrorZeroThreshold = BSParam.AvatarStopZeroThreshold;
131 // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. 132 // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
132 SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); 133 SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
133 134
@@ -278,6 +279,7 @@ public class BSActorAvatarMove : BSActor
278 if (m_controllingPrim.IsStationary) 279 if (m_controllingPrim.IsStationary)
279 { 280 {
280 entprop.Position = m_controllingPrim.RawPosition; 281 entprop.Position = m_controllingPrim.RawPosition;
282 entprop.Velocity = OMV.Vector3.Zero;
281 m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation); 283 m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation);
282 } 284 }
283 285
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
index 6cdc112..f7dd158 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
@@ -43,7 +43,9 @@ public enum ConstraintType : int
43 SLIDER_CONSTRAINT_TYPE, 43 SLIDER_CONSTRAINT_TYPE,
44 CONTACT_CONSTRAINT_TYPE, 44 CONTACT_CONSTRAINT_TYPE,
45 D6_SPRING_CONSTRAINT_TYPE, 45 D6_SPRING_CONSTRAINT_TYPE,
46 MAX_CONSTRAINT_TYPE 46 MAX_CONSTRAINT_TYPE, // last type defined by Bullet
47 //
48 FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving
47} 49}
48 50
49// =============================================================================== 51// ===============================================================================
@@ -290,7 +292,7 @@ public enum ConstraintParamAxis : int
290 AXIS_ANGULAR_X, 292 AXIS_ANGULAR_X,
291 AXIS_ANGULAR_Y, 293 AXIS_ANGULAR_Y,
292 AXIS_ANGULAR_Z, 294 AXIS_ANGULAR_Z,
293 AXIS_LINEAR_ALL = 20, // these last three added by BulletSim so we don't have to do zillions of calls 295 AXIS_LINEAR_ALL = 20, // added by BulletSim so we don't have to do zillions of calls
294 AXIS_ANGULAR_ALL, 296 AXIS_ANGULAR_ALL,
295 AXIS_ALL 297 AXIS_ALL
296}; 298};
@@ -441,6 +443,38 @@ public abstract bool TranslationalLimitMotor(BulletConstraint constrain, float e
441 443
442public abstract bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold); 444public abstract bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold);
443 445
446public const int HINGE_NOT_SPECIFIED = -1;
447public abstract bool HingeSetLimits(BulletConstraint constrain, float low, float high, float softness, float bias, float relaxation);
448
449public abstract bool SpringEnable(BulletConstraint constrain, int index, float numericTrueFalse);
450
451public const int SPRING_NOT_SPECIFIED = -1;
452public abstract bool SpringSetEquilibriumPoint(BulletConstraint constrain, int index, float equilibriumPoint);
453
454public abstract bool SpringSetStiffness(BulletConstraint constrain, int index, float stiffnesss);
455
456public abstract bool SpringSetDamping(BulletConstraint constrain, int index, float damping);
457
458public const int SLIDER_LOWER_LIMIT = 0;
459public const int SLIDER_UPPER_LIMIT = 1;
460public const int SLIDER_LINEAR = 2;
461public const int SLIDER_ANGULAR = 3;
462public abstract bool SliderSetLimits(BulletConstraint constrain, int lowerUpper, int linAng, float val);
463
464public const int SLIDER_SET_SOFTNESS = 4;
465public const int SLIDER_SET_RESTITUTION = 5;
466public const int SLIDER_SET_DAMPING = 6;
467public const int SLIDER_SET_DIRECTION = 7;
468public const int SLIDER_SET_LIMIT = 8;
469public const int SLIDER_SET_ORTHO = 9;
470public abstract bool SliderSet(BulletConstraint constrain, int softRestDamp, int dirLimOrtho, int linAng, float val);
471
472public abstract bool SliderMotorEnable(BulletConstraint constrain, int linAng, float numericTrueFalse);
473
474public const int SLIDER_MOTOR_VELOCITY = 10;
475public const int SLIDER_MAX_MOTOR_FORCE = 11;
476public abstract bool SliderMotor(BulletConstraint constrain, int forceVel, int linAng, float val);
477
444public abstract bool CalculateTransforms(BulletConstraint constrain); 478public abstract bool CalculateTransforms(BulletConstraint constrain);
445 479
446public abstract bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis); 480public abstract bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis);
@@ -464,6 +498,8 @@ public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj);
464 498
465public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj); 499public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj);
466 500
501public abstract bool ClearCollisionProxyCache(BulletWorld world, BulletBody obj);
502
467public abstract bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects); 503public abstract bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects);
468 504
469public abstract bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain); 505public abstract bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 291dfcd..fc18960 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -93,7 +93,7 @@ public sealed class BSCharacter : BSPhysObject
93 LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos); 93 LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos);
94 94
95 // do actual creation in taint time 95 // do actual creation in taint time
96 PhysScene.TaintedObject("BSCharacter.create", delegate() 96 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
97 { 97 {
98 DetailLog("{0},BSCharacter.create,taint", LocalID); 98 DetailLog("{0},BSCharacter.create,taint", LocalID);
99 // New body and shape into PhysBody and PhysShape 99 // New body and shape into PhysBody and PhysShape
@@ -121,7 +121,7 @@ public sealed class BSCharacter : BSPhysObject
121 base.Destroy(); 121 base.Destroy();
122 122
123 DetailLog("{0},BSCharacter.Destroy", LocalID); 123 DetailLog("{0},BSCharacter.Destroy", LocalID);
124 PhysScene.TaintedObject("BSCharacter.destroy", delegate() 124 PhysScene.TaintedObject(LocalID, "BSCharacter.destroy", delegate()
125 { 125 {
126 PhysScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */); 126 PhysScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */);
127 PhysBody.Clear(); 127 PhysBody.Clear();
@@ -209,7 +209,7 @@ public sealed class BSCharacter : BSPhysObject
209 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", 209 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
210 LocalID, _size, Scale, Density, _avatarVolume, RawMass); 210 LocalID, _size, Scale, Density, _avatarVolume, RawMass);
211 211
212 PhysScene.TaintedObject("BSCharacter.setSize", delegate() 212 PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate()
213 { 213 {
214 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape) 214 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
215 { 215 {
@@ -257,7 +257,7 @@ public sealed class BSCharacter : BSPhysObject
257 _rotationalVelocity = OMV.Vector3.Zero; 257 _rotationalVelocity = OMV.Vector3.Zero;
258 258
259 // Zero some other properties directly into the physics engine 259 // Zero some other properties directly into the physics engine
260 PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() 260 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
261 { 261 {
262 if (PhysBody.HasPhysicalBody) 262 if (PhysBody.HasPhysicalBody)
263 PhysScene.PE.ClearAllForces(PhysBody); 263 PhysScene.PE.ClearAllForces(PhysBody);
@@ -267,7 +267,7 @@ public sealed class BSCharacter : BSPhysObject
267 { 267 {
268 _rotationalVelocity = OMV.Vector3.Zero; 268 _rotationalVelocity = OMV.Vector3.Zero;
269 269
270 PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() 270 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
271 { 271 {
272 if (PhysBody.HasPhysicalBody) 272 if (PhysBody.HasPhysicalBody)
273 { 273 {
@@ -291,7 +291,7 @@ public sealed class BSCharacter : BSPhysObject
291 set { 291 set {
292 RawPosition = value; 292 RawPosition = value;
293 293
294 PhysScene.TaintedObject("BSCharacter.setPosition", delegate() 294 PhysScene.TaintedObject(LocalID, "BSCharacter.setPosition", delegate()
295 { 295 {
296 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); 296 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
297 PositionSanityCheck(); 297 PositionSanityCheck();
@@ -363,7 +363,7 @@ public sealed class BSCharacter : BSPhysObject
363 { 363 {
364 // The new position value must be pushed into the physics engine but we can't 364 // The new position value must be pushed into the physics engine but we can't
365 // just assign to "Position" because of potential call loops. 365 // just assign to "Position" because of potential call loops.
366 PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() 366 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.PositionSanityCheck", delegate()
367 { 367 {
368 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); 368 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
369 ForcePosition = RawPosition; 369 ForcePosition = RawPosition;
@@ -390,7 +390,7 @@ public sealed class BSCharacter : BSPhysObject
390 set { 390 set {
391 RawForce = value; 391 RawForce = value;
392 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); 392 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
393 PhysScene.TaintedObject("BSCharacter.SetForce", delegate() 393 PhysScene.TaintedObject(LocalID, "BSCharacter.SetForce", delegate()
394 { 394 {
395 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce); 395 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce);
396 if (PhysBody.HasPhysicalBody) 396 if (PhysBody.HasPhysicalBody)
@@ -438,7 +438,7 @@ public sealed class BSCharacter : BSPhysObject
438 set { 438 set {
439 RawVelocity = value; 439 RawVelocity = value;
440 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity); 440 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity);
441 PhysScene.TaintedObject("BSCharacter.setVelocity", delegate() 441 PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate()
442 { 442 {
443 if (m_moveActor != null) 443 if (m_moveActor != null)
444 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */); 444 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */);
@@ -480,7 +480,7 @@ public sealed class BSCharacter : BSPhysObject
480 if (RawOrientation != value) 480 if (RawOrientation != value)
481 { 481 {
482 RawOrientation = value; 482 RawOrientation = value;
483 PhysScene.TaintedObject("BSCharacter.setOrientation", delegate() 483 PhysScene.TaintedObject(LocalID, "BSCharacter.setOrientation", delegate()
484 { 484 {
485 // Bullet assumes we know what we are doing when forcing orientation 485 // Bullet assumes we know what we are doing when forcing orientation
486 // so it lets us go against all the rules and just compensates for them later. 486 // so it lets us go against all the rules and just compensates for them later.
@@ -560,7 +560,7 @@ public sealed class BSCharacter : BSPhysObject
560 public override bool FloatOnWater { 560 public override bool FloatOnWater {
561 set { 561 set {
562 _floatOnWater = value; 562 _floatOnWater = value;
563 PhysScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() 563 PhysScene.TaintedObject(LocalID, "BSCharacter.setFloatOnWater", delegate()
564 { 564 {
565 if (PhysBody.HasPhysicalBody) 565 if (PhysBody.HasPhysicalBody)
566 { 566 {
@@ -588,7 +588,7 @@ public sealed class BSCharacter : BSPhysObject
588 public override float Buoyancy { 588 public override float Buoyancy {
589 get { return _buoyancy; } 589 get { return _buoyancy; }
590 set { _buoyancy = value; 590 set { _buoyancy = value;
591 PhysScene.TaintedObject("BSCharacter.setBuoyancy", delegate() 591 PhysScene.TaintedObject(LocalID, "BSCharacter.setBuoyancy", delegate()
592 { 592 {
593 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 593 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
594 ForceBuoyancy = _buoyancy; 594 ForceBuoyancy = _buoyancy;
@@ -633,7 +633,7 @@ public sealed class BSCharacter : BSPhysObject
633 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); 633 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
634 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); 634 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
635 635
636 PhysScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() 636 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate()
637 { 637 {
638 // Bullet adds this central force to the total force for this tick 638 // Bullet adds this central force to the total force for this tick
639 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); 639 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
@@ -676,18 +676,20 @@ public sealed class BSCharacter : BSPhysObject
676 float heightAdjust = BSParam.AvatarHeightMidFudge; 676 float heightAdjust = BSParam.AvatarHeightMidFudge;
677 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f) 677 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
678 { 678 {
679 // An avatar is between 1.61 and 2.12 meters. Midpoint is 1.87m. 679 const float AVATAR_LOW = 1.1f;
680 // The "times 4" relies on the fact that the difference from the midpoint to the extremes is exactly 0.25 680 const float AVATAR_MID = 1.775f; // 1.87f
681 float midHeightOffset = size.Z - 1.87f; 681 const float AVATAR_HI = 2.45f;
682 // An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
683 float midHeightOffset = size.Z - AVATAR_MID;
682 if (midHeightOffset < 0f) 684 if (midHeightOffset < 0f)
683 { 685 {
684 // Small avatar. Add the adjustment based on the distance from midheight 686 // Small avatar. Add the adjustment based on the distance from midheight
685 heightAdjust += -1f * midHeightOffset * 4f * BSParam.AvatarHeightLowFudge; 687 heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge;
686 } 688 }
687 else 689 else
688 { 690 {
689 // Large avatar. Add the adjustment based on the distance from midheight 691 // Large avatar. Add the adjustment based on the distance from midheight
690 heightAdjust += midHeightOffset * 4f * BSParam.AvatarHeightHighFudge; 692 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
691 } 693 }
692 } 694 }
693 // The total scale height is the central cylindar plus the caps on the two ends. 695 // The total scale height is the central cylindar plus the caps on the two ends.
@@ -698,6 +700,9 @@ public sealed class BSCharacter : BSPhysObject
698 if (newScale.Z < 0) 700 if (newScale.Z < 0)
699 newScale.Z = 0.1f; 701 newScale.Z = 0.1f;
700 702
703 DetailLog("{0},BSCharacter.ComputerAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
704 LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
705
701 return newScale; 706 return newScale;
702 } 707 }
703 708
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index 42b5c49..b47e9a8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -64,7 +64,7 @@ public abstract class BSConstraint : IDisposable
64 { 64 {
65 bool success = PhysicsScene.PE.DestroyConstraint(m_world, m_constraint); 65 bool success = PhysicsScene.PE.DestroyConstraint(m_world, m_constraint);
66 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}", 66 m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}",
67 BSScene.DetailLogZero, 67 m_body1.ID,
68 m_body1.ID, m_body1.AddrString, 68 m_body1.ID, m_body1.AddrString,
69 m_body2.ID, m_body2.AddrString, 69 m_body2.ID, m_body2.AddrString,
70 success); 70 success);
@@ -77,7 +77,10 @@ public abstract class BSConstraint : IDisposable
77 { 77 {
78 bool ret = false; 78 bool ret = false;
79 if (m_enabled) 79 if (m_enabled)
80 {
81 m_world.physicsScene.DetailLog("{0},BSConstraint.SetLinearLimits,taint,low={1},high={2}", m_body1.ID, low, high);
80 ret = PhysicsScene.PE.SetLinearLimits(m_constraint, low, high); 82 ret = PhysicsScene.PE.SetLinearLimits(m_constraint, low, high);
83 }
81 return ret; 84 return ret;
82 } 85 }
83 86
@@ -86,6 +89,7 @@ public abstract class BSConstraint : IDisposable
86 bool ret = false; 89 bool ret = false;
87 if (m_enabled) 90 if (m_enabled)
88 { 91 {
92 m_world.physicsScene.DetailLog("{0},BSConstraint.SetAngularLimits,taint,low={1},high={2}", m_body1.ID, low, high);
89 ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high); 93 ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high);
90 } 94 }
91 return ret; 95 return ret;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
index d0949f5..7fcb75c 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint6Dof.cs
@@ -32,12 +32,19 @@ using OpenMetaverse;
32namespace OpenSim.Region.Physics.BulletSPlugin 32namespace OpenSim.Region.Physics.BulletSPlugin
33{ 33{
34 34
35public sealed class BSConstraint6Dof : BSConstraint 35public class BSConstraint6Dof : BSConstraint
36{ 36{
37 private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]"; 37 private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]";
38 38
39 public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } } 39 public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } }
40 40
41 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2) :base(world)
42 {
43 m_body1 = obj1;
44 m_body2 = obj2;
45 m_enabled = false;
46 }
47
41 // Create a btGeneric6DofConstraint 48 // Create a btGeneric6DofConstraint
42 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2, 49 public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
43 Vector3 frame1, Quaternion frame1rot, 50 Vector3 frame1, Quaternion frame1rot,
@@ -52,9 +59,11 @@ public sealed class BSConstraint6Dof : BSConstraint
52 frame2, frame2rot, 59 frame2, frame2rot,
53 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); 60 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
54 m_enabled = true; 61 m_enabled = true;
55 world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}", 62 PhysicsScene.DetailLog("{0},BS6DofConstraint,create,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
56 BSScene.DetailLogZero, world.worldID, 63 m_body1.ID, world.worldID,
57 obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString); 64 obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
65 PhysicsScene.DetailLog("{0},BS6DofConstraint,create, f1Loc={1},f1Rot={2},f2Loc={3},f2Rot={4},usefA={5},disCol={6}",
66 m_body1.ID, frame1, frame1rot, frame2, frame2rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
58 } 67 }
59 68
60 // 6 Dof constraint based on a midpoint between the two constrained bodies 69 // 6 Dof constraint based on a midpoint between the two constrained bodies
@@ -79,9 +88,11 @@ public sealed class BSConstraint6Dof : BSConstraint
79 m_constraint = PhysicsScene.PE.Create6DofConstraintToPoint(m_world, m_body1, m_body2, 88 m_constraint = PhysicsScene.PE.Create6DofConstraintToPoint(m_world, m_body1, m_body2,
80 joinPoint, 89 joinPoint,
81 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies); 90 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
91
82 PhysicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}", 92 PhysicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
83 BSScene.DetailLogZero, world.worldID, m_constraint.AddrString, 93 m_body1.ID, world.worldID, m_constraint.AddrString,
84 obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString); 94 obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
95
85 if (!m_constraint.HasPhysicalConstraint) 96 if (!m_constraint.HasPhysicalConstraint)
86 { 97 {
87 world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}", 98 world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}",
@@ -106,8 +117,10 @@ public sealed class BSConstraint6Dof : BSConstraint
106 frameInBloc, frameInBrot, 117 frameInBloc, frameInBrot,
107 useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies); 118 useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies);
108 m_enabled = true; 119 m_enabled = true;
109 world.physicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}", 120 PhysicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}",
110 BSScene.DetailLogZero, world.worldID, obj1.ID, obj1.AddrString); 121 m_body1.ID, world.worldID, obj1.ID, obj1.AddrString);
122 PhysicsScene.DetailLog("{0},BS6DofConstraint,createFixed, fBLoc={1},fBRot={2},usefA={3},disCol={4}",
123 m_body1.ID, frameInBloc, frameInBrot, useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies);
111 } 124 }
112 125
113 public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot) 126 public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintConeTwist.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintConeTwist.cs
new file mode 100755
index 0000000..7a76a9a
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintConeTwist.cs
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Physics.BulletSPlugin
33{
34
35public sealed class BSConstraintConeTwist : BSConstraint
36{
37 public override ConstraintType Type { get { return ConstraintType.CONETWIST_CONSTRAINT_TYPE; } }
38
39 public BSConstraintConeTwist(BulletWorld world, BulletBody obj1, BulletBody obj2,
40 Vector3 frameInAloc, Quaternion frameInArot,
41 Vector3 frameInBloc, Quaternion frameInBrot,
42 bool disableCollisionsBetweenLinkedBodies)
43 : base(world)
44 {
45 m_body1 = obj1;
46 m_body2 = obj2;
47 m_constraint = PhysicsScene.PE.CreateConeTwistConstraint(world, obj1, obj2,
48 frameInAloc, frameInArot, frameInBloc, frameInBrot,
49 disableCollisionsBetweenLinkedBodies);
50 m_enabled = true;
51 }
52}
53
54}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSlider.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSlider.cs
new file mode 100755
index 0000000..37cfa07
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSlider.cs
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Physics.BulletSPlugin
33{
34
35public sealed class BSConstraintSlider : BSConstraint
36{
37 public override ConstraintType Type { get { return ConstraintType.SLIDER_CONSTRAINT_TYPE; } }
38
39 public BSConstraintSlider(BulletWorld world, BulletBody obj1, BulletBody obj2,
40 Vector3 frameInAloc, Quaternion frameInArot,
41 Vector3 frameInBloc, Quaternion frameInBrot,
42 bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
43 : base(world)
44 {
45 m_body1 = obj1;
46 m_body2 = obj2;
47 m_constraint = PhysicsScene.PE.CreateSliderConstraint(world, obj1, obj2,
48 frameInAloc, frameInArot, frameInBloc, frameInBrot,
49 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
50 m_enabled = true;
51 }
52
53}
54
55}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs
new file mode 100755
index 0000000..8e7ddff
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintSpring.cs
@@ -0,0 +1,103 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Physics.BulletSPlugin
33{
34
35public sealed class BSConstraintSpring : BSConstraint6Dof
36{
37 public override ConstraintType Type { get { return ConstraintType.D6_SPRING_CONSTRAINT_TYPE; } }
38
39 public BSConstraintSpring(BulletWorld world, BulletBody obj1, BulletBody obj2,
40 Vector3 frame1Loc, Quaternion frame1Rot,
41 Vector3 frame2Loc, Quaternion frame2Rot,
42 bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
43 :base(world, obj1, obj2)
44 {
45 m_constraint = PhysicsScene.PE.Create6DofSpringConstraint(world, obj1, obj2,
46 frame1Loc, frame1Rot, frame2Loc, frame2Rot,
47 useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
48 m_enabled = true;
49
50 PhysicsScene.DetailLog("{0},BSConstraintSpring,create,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
51 obj1.ID, world.worldID, obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
52 PhysicsScene.DetailLog("{0},BSConstraintSpring,create, f1Loc={1},f1Rot={2},f2Loc={3},f2Rot={4},usefA={5},disCol={6}",
53 m_body1.ID, frame1Loc, frame1Rot, frame2Loc, frame2Rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
54 }
55
56 public bool SetAxisEnable(int pIndex, bool pAxisEnable)
57 {
58 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEnable,obj1ID={1},obj2ID={2},indx={3},enable={4}",
59 m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pAxisEnable);
60 PhysicsScene.PE.SpringEnable(m_constraint, pIndex, BSParam.NumericBool(pAxisEnable));
61 return true;
62 }
63
64 public bool SetStiffness(int pIndex, float pStiffness)
65 {
66 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetStiffness,obj1ID={1},obj2ID={2},indx={3},stiff={4}",
67 m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pStiffness);
68 PhysicsScene.PE.SpringSetStiffness(m_constraint, pIndex, pStiffness);
69 return true;
70 }
71
72 public bool SetDamping(int pIndex, float pDamping)
73 {
74 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetDamping,obj1ID={1},obj2ID={2},indx={3},damp={4}",
75 m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pDamping);
76 PhysicsScene.PE.SpringSetDamping(m_constraint, pIndex, pDamping);
77 return true;
78 }
79
80 public bool SetEquilibriumPoint(int pIndex, float pEqPoint)
81 {
82 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEquilibriumPoint,obj1ID={1},obj2ID={2},indx={3},eqPoint={4}",
83 m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pEqPoint);
84 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, pIndex, pEqPoint);
85 return true;
86 }
87
88 public bool SetEquilibriumPoint(Vector3 linearEq, Vector3 angularEq)
89 {
90 PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEquilibriumPoint,obj1ID={1},obj2ID={2},linearEq={3},angularEq={4}",
91 m_body1.ID, m_body1.ID, m_body2.ID, linearEq, angularEq);
92 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 0, linearEq.X);
93 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 1, linearEq.Y);
94 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 2, linearEq.Z);
95 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 3, angularEq.X);
96 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 4, angularEq.Y);
97 PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 5, angularEq.Z);
98 return true;
99 }
100
101}
102
103} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 3afd52e..77f69a5 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -77,6 +77,10 @@ public abstract class BSLinkset
77 { 77 {
78 member = pMember; 78 member = pMember;
79 } 79 }
80 public virtual void ResetLink() { }
81 public virtual void SetLinkParameters(BSConstraint constrain) { }
82 // Returns 'true' if physical property updates from the child should be reported to the simulator
83 public virtual bool ShouldUpdateChildProperties() { return false; }
80 } 84 }
81 85
82 public LinksetImplementation LinksetImpl { get; protected set; } 86 public LinksetImplementation LinksetImpl { get; protected set; }
@@ -148,7 +152,7 @@ public abstract class BSLinkset
148 // Returns a new linkset for the child which is a linkset of one (just the 152 // Returns a new linkset for the child which is a linkset of one (just the
149 // orphened child). 153 // orphened child).
150 // Called at runtime. 154 // Called at runtime.
151 public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child) 155 public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child, bool inTaintTime)
152 { 156 {
153 lock (m_linksetActivityLock) 157 lock (m_linksetActivityLock)
154 { 158 {
@@ -157,7 +161,7 @@ public abstract class BSLinkset
157 // Cannot remove the root from a linkset. 161 // Cannot remove the root from a linkset.
158 return this; 162 return this;
159 } 163 }
160 RemoveChildFromLinkset(child); 164 RemoveChildFromLinkset(child, inTaintTime);
161 LinksetMass = ComputeLinksetMass(); 165 LinksetMass = ComputeLinksetMass();
162 } 166 }
163 167
@@ -205,6 +209,17 @@ public abstract class BSLinkset
205 return ret; 209 return ret;
206 } 210 }
207 211
212 public bool TryGetLinkInfo(BSPrimLinkable child, out BSLinkInfo foundInfo)
213 {
214 bool ret = false;
215 BSLinkInfo found = null;
216 lock (m_linksetActivityLock)
217 {
218 ret = m_children.TryGetValue(child, out found);
219 }
220 foundInfo = found;
221 return ret;
222 }
208 // Perform an action on each member of the linkset including root prim. 223 // Perform an action on each member of the linkset including root prim.
209 // Depends on the action on whether this should be done at taint time. 224 // Depends on the action on whether this should be done at taint time.
210 public delegate bool ForEachLinkInfoAction(BSLinkInfo obj); 225 public delegate bool ForEachLinkInfoAction(BSLinkInfo obj);
@@ -222,6 +237,21 @@ public abstract class BSLinkset
222 return ret; 237 return ret;
223 } 238 }
224 239
240 // Check the type of the link and return 'true' if the link is flexible and the
241 // updates from the child should be sent to the simulator so things change.
242 public virtual bool ShouldReportPropertyUpdates(BSPrimLinkable child)
243 {
244 bool ret = false;
245
246 BSLinkInfo linkInfo;
247 if (m_children.TryGetValue(child, out linkInfo))
248 {
249 ret = linkInfo.ShouldUpdateChildProperties();
250 }
251
252 return ret;
253 }
254
225 // Called after a simulation step to post a collision with this object. 255 // Called after a simulation step to post a collision with this object.
226 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have 256 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have
227 // anything to add for the collision and it should be passed through normal processing. 257 // anything to add for the collision and it should be passed through normal processing.
@@ -255,7 +285,7 @@ public abstract class BSLinkset
255 285
256 // I am the root of a linkset and one of my children is being removed. 286 // I am the root of a linkset and one of my children is being removed.
257 // Safe to call even if the child is not really in my linkset. 287 // Safe to call even if the child is not really in my linkset.
258 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child); 288 protected abstract void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime);
259 289
260 // When physical properties are changed the linkset needs to recalculate 290 // When physical properties are changed the linkset needs to recalculate
261 // its internal properties. 291 // its internal properties.
@@ -430,6 +460,13 @@ public abstract class BSLinkset
430 return com; 460 return com;
431 } 461 }
432 462
463 #region Extension
464 public virtual object Extension(string pFunct, params object[] pParams)
465 {
466 return null;
467 }
468 #endregion // Extension
469
433 // Invoke the detailed logger and output something if it's enabled. 470 // Invoke the detailed logger and output something if it's enabled.
434 protected void DetailLog(string msg, params Object[] args) 471 protected void DetailLog(string msg, params Object[] args)
435 { 472 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 085d195..8f12189 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -90,10 +90,9 @@ public sealed class BSLinksetCompound : BSLinkset
90 // its internal properties. 90 // its internal properties.
91 public override void Refresh(BSPrimLinkable requestor) 91 public override void Refresh(BSPrimLinkable requestor)
92 { 92 {
93 base.Refresh(requestor);
94
95 // Something changed so do the rebuilding thing 93 // Something changed so do the rebuilding thing
96 // ScheduleRebuild(); 94 ScheduleRebuild(requestor);
95 base.Refresh(requestor);
97 } 96 }
98 97
99 // Schedule a refresh to happen after all the other taint processing. 98 // Schedule a refresh to happen after all the other taint processing.
@@ -127,7 +126,7 @@ public sealed class BSLinksetCompound : BSLinkset
127 if (IsRoot(child)) 126 if (IsRoot(child))
128 { 127 {
129 // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly. 128 // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly.
130 ScheduleRebuild(LinksetRoot); 129 Refresh(LinksetRoot);
131 } 130 }
132 return ret; 131 return ret;
133 } 132 }
@@ -144,7 +143,7 @@ public sealed class BSLinksetCompound : BSLinkset
144 if (IsRoot(child)) 143 if (IsRoot(child))
145 { 144 {
146 // Schedule a rebuild to verify that the root shape is set to the real shape. 145 // Schedule a rebuild to verify that the root shape is set to the real shape.
147 ScheduleRebuild(LinksetRoot); 146 Refresh(LinksetRoot);
148 } 147 }
149 return ret; 148 return ret;
150 } 149 }
@@ -227,7 +226,7 @@ public sealed class BSLinksetCompound : BSLinkset
227 // there will already be a rebuild scheduled. 226 // there will already be a rebuild scheduled.
228 DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}", 227 DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}",
229 updated.LocalID, whichUpdated); 228 updated.LocalID, whichUpdated);
230 ScheduleRebuild(updated); 229 Refresh(updated);
231 } 230 }
232 } 231 }
233 } 232 }
@@ -242,10 +241,10 @@ public sealed class BSLinksetCompound : BSLinkset
242 { 241 {
243 bool ret = false; 242 bool ret = false;
244 243
245 DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}", 244 DetailLog("{0},BSLinksetCompound.RemoveDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}",
246 child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child)); 245 child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child));
247 246
248 ScheduleRebuild(child); 247 Refresh(child);
249 248
250 return ret; 249 return ret;
251 } 250 }
@@ -263,14 +262,14 @@ public sealed class BSLinksetCompound : BSLinkset
263 DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 262 DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
264 263
265 // Rebuild the compound shape with the new child shape included 264 // Rebuild the compound shape with the new child shape included
266 ScheduleRebuild(child); 265 Refresh(child);
267 } 266 }
268 return; 267 return;
269 } 268 }
270 269
271 // Remove the specified child from the linkset. 270 // Remove the specified child from the linkset.
272 // Safe to call even if the child is not really in the linkset. 271 // Safe to call even if the child is not really in the linkset.
273 protected override void RemoveChildFromLinkset(BSPrimLinkable child) 272 protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
274 { 273 {
275 child.ClearDisplacement(); 274 child.ClearDisplacement();
276 275
@@ -282,17 +281,17 @@ public sealed class BSLinksetCompound : BSLinkset
282 child.LocalID, child.PhysBody.AddrString); 281 child.LocalID, child.PhysBody.AddrString);
283 282
284 // Cause the child's body to be rebuilt and thus restored to normal operation 283 // Cause the child's body to be rebuilt and thus restored to normal operation
285 child.ForceBodyShapeRebuild(false); 284 child.ForceBodyShapeRebuild(inTaintTime);
286 285
287 if (!HasAnyChildren) 286 if (!HasAnyChildren)
288 { 287 {
289 // The linkset is now empty. The root needs rebuilding. 288 // The linkset is now empty. The root needs rebuilding.
290 LinksetRoot.ForceBodyShapeRebuild(false); 289 LinksetRoot.ForceBodyShapeRebuild(inTaintTime);
291 } 290 }
292 else 291 else
293 { 292 {
294 // Rebuild the compound shape with the child removed 293 // Rebuild the compound shape with the child removed
295 ScheduleRebuild(LinksetRoot); 294 Refresh(LinksetRoot);
296 } 295 }
297 } 296 }
298 return; 297 return;
@@ -318,10 +317,10 @@ public sealed class BSLinksetCompound : BSLinkset
318 // being destructed and going non-physical. 317 // being destructed and going non-physical.
319 LinksetRoot.ForceBodyShapeRebuild(true); 318 LinksetRoot.ForceBodyShapeRebuild(true);
320 319
321 // There is no reason to build all this physical stuff for a non-physical linkset. 320 // There is no reason to build all this physical stuff for a non-physical or empty linkset.
322 if (!LinksetRoot.IsPhysicallyActive) 321 if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
323 { 322 {
324 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); 323 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
325 return; // Note the 'finally' clause at the botton which will get executed. 324 return; // Note the 'finally' clause at the botton which will get executed.
326 } 325 }
327 326
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index 4bac222..aaf92c8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -28,6 +28,8 @@ using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Text; 29using System.Text;
30 30
31using OpenSim.Region.OptionalModules.Scripting;
32
31using OMV = OpenMetaverse; 33using OMV = OpenMetaverse;
32 34
33namespace OpenSim.Region.Physics.BulletSPlugin 35namespace OpenSim.Region.Physics.BulletSPlugin
@@ -51,18 +53,32 @@ public sealed class BSLinksetConstraints : BSLinkset
51 public float cfm; 53 public float cfm;
52 public float erp; 54 public float erp;
53 public float solverIterations; 55 public float solverIterations;
56 //
57 public OMV.Vector3 frameInAloc;
58 public OMV.Quaternion frameInArot;
59 public OMV.Vector3 frameInBloc;
60 public OMV.Quaternion frameInBrot;
61 public bool useLinearReferenceFrameA;
62 // Spring
63 public bool[] springAxisEnable;
64 public float[] springDamping;
65 public float[] springStiffness;
66 public OMV.Vector3 springLinearEquilibriumPoint;
67 public OMV.Vector3 springAngularEquilibriumPoint;
54 68
55 public BSLinkInfoConstraint(BSPrimLinkable pMember) 69 public BSLinkInfoConstraint(BSPrimLinkable pMember)
56 : base(pMember) 70 : base(pMember)
57 { 71 {
58 constraint = null; 72 constraint = null;
59 ResetToFixedConstraint(); 73 ResetLink();
74 member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.creation", member.LocalID);
60 } 75 }
61 76
62 // Set all the parameters for this constraint to a fixed, non-movable constraint. 77 // Set all the parameters for this constraint to a fixed, non-movable constraint.
63 public void ResetToFixedConstraint() 78 public override void ResetLink()
64 { 79 {
65 constraintType = ConstraintType.D6_CONSTRAINT_TYPE; 80 // constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
81 constraintType = ConstraintType.FIXED_CONSTRAINT_TYPE;
66 linearLimitLow = OMV.Vector3.Zero; 82 linearLimitLow = OMV.Vector3.Zero;
67 linearLimitHigh = OMV.Vector3.Zero; 83 linearLimitHigh = OMV.Vector3.Zero;
68 angularLimitLow = OMV.Vector3.Zero; 84 angularLimitLow = OMV.Vector3.Zero;
@@ -74,17 +90,37 @@ public sealed class BSLinksetConstraints : BSLinkset
74 cfm = BSParam.LinkConstraintCFM; 90 cfm = BSParam.LinkConstraintCFM;
75 erp = BSParam.LinkConstraintERP; 91 erp = BSParam.LinkConstraintERP;
76 solverIterations = BSParam.LinkConstraintSolverIterations; 92 solverIterations = BSParam.LinkConstraintSolverIterations;
93 frameInAloc = OMV.Vector3.Zero;
94 frameInArot = OMV.Quaternion.Identity;
95 frameInBloc = OMV.Vector3.Zero;
96 frameInBrot = OMV.Quaternion.Identity;
97 useLinearReferenceFrameA = true;
98 springAxisEnable = new bool[6];
99 springDamping = new float[6];
100 springStiffness = new float[6];
101 for (int ii = 0; ii < springAxisEnable.Length; ii++)
102 {
103 springAxisEnable[ii] = false;
104 springDamping[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
105 springStiffness[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
106 }
107 springLinearEquilibriumPoint = OMV.Vector3.Zero;
108 springAngularEquilibriumPoint = OMV.Vector3.Zero;
109 member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.ResetLink", member.LocalID);
77 } 110 }
78 111
79 // Given a constraint, apply the current constraint parameters to same. 112 // Given a constraint, apply the current constraint parameters to same.
80 public void SetConstraintParameters(BSConstraint constrain) 113 public override void SetLinkParameters(BSConstraint constrain)
81 { 114 {
115 member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.SetLinkParameters,type={1}", member.LocalID, constraintType);
82 switch (constraintType) 116 switch (constraintType)
83 { 117 {
118 case ConstraintType.FIXED_CONSTRAINT_TYPE:
84 case ConstraintType.D6_CONSTRAINT_TYPE: 119 case ConstraintType.D6_CONSTRAINT_TYPE:
85 BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof; 120 BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof;
86 if (constrain6dof != null) 121 if (constrain6dof != null)
87 { 122 {
123 // NOTE: D6_SPRING_CONSTRAINT_TYPE should be updated if you change any of this code.
88 // zero linear and angular limits makes the objects unable to move in relation to each other 124 // zero linear and angular limits makes the objects unable to move in relation to each other
89 constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh); 125 constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh);
90 constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh); 126 constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh);
@@ -99,10 +135,55 @@ public sealed class BSLinksetConstraints : BSLinkset
99 } 135 }
100 } 136 }
101 break; 137 break;
138 case ConstraintType.D6_SPRING_CONSTRAINT_TYPE:
139 BSConstraintSpring constrainSpring = constrain as BSConstraintSpring;
140 if (constrainSpring != null)
141 {
142 // zero linear and angular limits makes the objects unable to move in relation to each other
143 constrainSpring.SetLinearLimits(linearLimitLow, linearLimitHigh);
144 constrainSpring.SetAngularLimits(angularLimitLow, angularLimitHigh);
145
146 // tweek the constraint to increase stability
147 constrainSpring.UseFrameOffset(useFrameOffset);
148 constrainSpring.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce);
149 constrainSpring.SetCFMAndERP(cfm, erp);
150 if (solverIterations != 0f)
151 {
152 constrainSpring.SetSolverIterations(solverIterations);
153 }
154 for (int ii = 0; ii < springAxisEnable.Length; ii++)
155 {
156 constrainSpring.SetAxisEnable(ii, springAxisEnable[ii]);
157 if (springDamping[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED)
158 constrainSpring.SetDamping(ii, springDamping[ii]);
159 if (springStiffness[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED)
160 constrainSpring.SetStiffness(ii, springStiffness[ii]);
161 }
162 constrainSpring.CalculateTransforms();
163
164 if (springLinearEquilibriumPoint != OMV.Vector3.Zero)
165 constrainSpring.SetEquilibriumPoint(springLinearEquilibriumPoint, springAngularEquilibriumPoint);
166 else
167 constrainSpring.SetEquilibriumPoint(BSAPITemplate.SPRING_NOT_SPECIFIED, BSAPITemplate.SPRING_NOT_SPECIFIED);
168 }
169 break;
102 default: 170 default:
103 break; 171 break;
104 } 172 }
105 } 173 }
174
175 // Return 'true' if the property updates from the physics engine should be reported
176 // to the simulator.
177 // If the constraint is fixed, we don't need to report as the simulator and viewer will
178 // report the right things.
179 public override bool ShouldUpdateChildProperties()
180 {
181 bool ret = true;
182 if (constraintType == ConstraintType.FIXED_CONSTRAINT_TYPE)
183 ret = false;
184
185 return ret;
186 }
106 } 187 }
107 188
108 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent) 189 public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
@@ -110,12 +191,15 @@ public sealed class BSLinksetConstraints : BSLinkset
110 LinksetImpl = LinksetImplementation.Constraint; 191 LinksetImpl = LinksetImplementation.Constraint;
111 } 192 }
112 193
194 private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINT]";
195
113 // When physical properties are changed the linkset needs to recalculate 196 // When physical properties are changed the linkset needs to recalculate
114 // its internal properties. 197 // its internal properties.
115 // This is queued in the 'post taint' queue so the 198 // This is queued in the 'post taint' queue so the
116 // refresh will happen once after all the other taints are applied. 199 // refresh will happen once after all the other taints are applied.
117 public override void Refresh(BSPrimLinkable requestor) 200 public override void Refresh(BSPrimLinkable requestor)
118 { 201 {
202 ScheduleRebuild(requestor);
119 base.Refresh(requestor); 203 base.Refresh(requestor);
120 204
121 } 205 }
@@ -132,10 +216,16 @@ public sealed class BSLinksetConstraints : BSLinkset
132 { 216 {
133 // Queue to happen after all the other taint processing 217 // Queue to happen after all the other taint processing
134 m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() 218 m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
219 {
220 if (HasAnyChildren)
135 { 221 {
136 if (HasAnyChildren) 222 // Constraints that have not been changed are not rebuild but make sure
137 RecomputeLinksetConstraints(); 223 // the constraint of the requestor is rebuilt.
138 }); 224 PhysicallyUnlinkAChildFromRoot(LinksetRoot, requestor);
225 // Rebuild the linkset and all its constraints.
226 RecomputeLinksetConstraints();
227 }
228 });
139 } 229 }
140 } 230 }
141 231
@@ -152,7 +242,7 @@ public sealed class BSLinksetConstraints : BSLinkset
152 if (IsRoot(child)) 242 if (IsRoot(child))
153 { 243 {
154 // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly. 244 // The root is going dynamic. Rebuild the linkset so parts and mass get computed properly.
155 ScheduleRebuild(LinksetRoot); 245 Refresh(LinksetRoot);
156 } 246 }
157 return ret; 247 return ret;
158 } 248 }
@@ -171,7 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset
171 if (IsRoot(child)) 261 if (IsRoot(child))
172 { 262 {
173 // Schedule a rebuild to verify that the root shape is set to the real shape. 263 // Schedule a rebuild to verify that the root shape is set to the real shape.
174 ScheduleRebuild(LinksetRoot); 264 Refresh(LinksetRoot);
175 } 265 }
176 return ret; 266 return ret;
177 } 267 }
@@ -199,7 +289,7 @@ public sealed class BSLinksetConstraints : BSLinkset
199 // Just undo all the constraints for this linkset. Rebuild at the end of the step. 289 // Just undo all the constraints for this linkset. Rebuild at the end of the step.
200 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot); 290 ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
201 // Cause the constraints, et al to be rebuilt before the next simulation step. 291 // Cause the constraints, et al to be rebuilt before the next simulation step.
202 ScheduleRebuild(LinksetRoot); 292 Refresh(LinksetRoot);
203 } 293 }
204 return ret; 294 return ret;
205 } 295 }
@@ -217,14 +307,14 @@ public sealed class BSLinksetConstraints : BSLinkset
217 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); 307 DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
218 308
219 // Cause constraints and assorted properties to be recomputed before the next simulation step. 309 // Cause constraints and assorted properties to be recomputed before the next simulation step.
220 ScheduleRebuild(LinksetRoot); 310 Refresh(LinksetRoot);
221 } 311 }
222 return; 312 return;
223 } 313 }
224 314
225 // Remove the specified child from the linkset. 315 // Remove the specified child from the linkset.
226 // Safe to call even if the child is not really in my linkset. 316 // Safe to call even if the child is not really in my linkset.
227 protected override void RemoveChildFromLinkset(BSPrimLinkable child) 317 protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
228 { 318 {
229 if (m_children.Remove(child)) 319 if (m_children.Remove(child))
230 { 320 {
@@ -236,12 +326,12 @@ public sealed class BSLinksetConstraints : BSLinkset
236 rootx.LocalID, rootx.PhysBody.AddrString, 326 rootx.LocalID, rootx.PhysBody.AddrString,
237 childx.LocalID, childx.PhysBody.AddrString); 327 childx.LocalID, childx.PhysBody.AddrString);
238 328
239 m_physicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate() 329 m_physicsScene.TaintedObject(inTaintTime, childx.LocalID, "BSLinksetConstraints.RemoveChildFromLinkset", delegate()
240 { 330 {
241 PhysicallyUnlinkAChildFromRoot(rootx, childx); 331 PhysicallyUnlinkAChildFromRoot(rootx, childx);
242 }); 332 });
243 // See that the linkset parameters are recomputed at the end of the taint time. 333 // See that the linkset parameters are recomputed at the end of the taint time.
244 ScheduleRebuild(LinksetRoot); 334 Refresh(LinksetRoot);
245 } 335 }
246 else 336 else
247 { 337 {
@@ -262,8 +352,8 @@ public sealed class BSLinksetConstraints : BSLinkset
262 // Create a static constraint between the two passed objects 352 // Create a static constraint between the two passed objects
263 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li) 353 private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li)
264 { 354 {
265 BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint; 355 BSLinkInfoConstraint linkInfo = li as BSLinkInfoConstraint;
266 if (liConstraint == null) 356 if (linkInfo == null)
267 return null; 357 return null;
268 358
269 // Zero motion for children so they don't interpolate 359 // Zero motion for children so they don't interpolate
@@ -271,27 +361,26 @@ public sealed class BSLinksetConstraints : BSLinkset
271 361
272 BSConstraint constrain = null; 362 BSConstraint constrain = null;
273 363
274 switch (liConstraint.constraintType) 364 switch (linkInfo.constraintType)
275 { 365 {
366 case ConstraintType.FIXED_CONSTRAINT_TYPE:
276 case ConstraintType.D6_CONSTRAINT_TYPE: 367 case ConstraintType.D6_CONSTRAINT_TYPE:
277 // Relative position normalized to the root prim 368 // Relative position normalized to the root prim
278 // Essentually a vector pointing from center of rootPrim to center of li.member 369 // Essentually a vector pointing from center of rootPrim to center of li.member
279 OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position; 370 OMV.Vector3 childRelativePosition = linkInfo.member.Position - rootPrim.Position;
280 371
281 // real world coordinate of midpoint between the two objects 372 // real world coordinate of midpoint between the two objects
282 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2); 373 OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
283 374
284 DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}", 375 DetailLog("{0},BSLinksetConstraint.BuildConstraint,6Dof,rBody={1},cBody={2},rLoc={3},cLoc={4},midLoc={5}",
285 rootPrim.LocalID, 376 rootPrim.LocalID, rootPrim.PhysBody, linkInfo.member.PhysBody,
286 rootPrim.LocalID, rootPrim.PhysBody.AddrString, 377 rootPrim.Position, linkInfo.member.Position, midPoint);
287 liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString,
288 rootPrim.Position, liConstraint.member.Position, midPoint);
289 378
290 // create a constraint that allows no freedom of movement between the two objects 379 // create a constraint that allows no freedom of movement between the two objects
291 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 380 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
292 381
293 constrain = new BSConstraint6Dof( 382 constrain = new BSConstraint6Dof(
294 m_physicsScene.World, rootPrim.PhysBody, liConstraint.member.PhysBody, midPoint, true, true ); 383 m_physicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody, midPoint, true, true );
295 384
296 /* NOTE: below is an attempt to build constraint with full frame computation, etc. 385 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
297 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms 386 * Using the midpoint is easier since it lets the Bullet code manipulate the transforms
@@ -320,11 +409,23 @@ public sealed class BSLinksetConstraints : BSLinkset
320 */ 409 */
321 410
322 break; 411 break;
412 case ConstraintType.D6_SPRING_CONSTRAINT_TYPE:
413 constrain = new BSConstraintSpring(m_physicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody,
414 linkInfo.frameInAloc, linkInfo.frameInArot, linkInfo.frameInBloc, linkInfo.frameInBrot,
415 linkInfo.useLinearReferenceFrameA,
416 true /*disableCollisionsBetweenLinkedBodies*/);
417 DetailLog("{0},BSLinksetConstraint.BuildConstraint,spring,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6}",
418 rootPrim.LocalID,
419 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
420 linkInfo.member.LocalID, linkInfo.member.PhysBody.AddrString,
421 rootPrim.Position, linkInfo.member.Position);
422
423 break;
323 default: 424 default:
324 break; 425 break;
325 } 426 }
326 427
327 liConstraint.SetConstraintParameters(constrain); 428 linkInfo.SetLinkParameters(constrain);
328 429
329 m_physicsScene.Constraints.AddConstraint(constrain); 430 m_physicsScene.Constraints.AddConstraint(constrain);
330 431
@@ -343,13 +444,22 @@ public sealed class BSLinksetConstraints : BSLinkset
343 rootPrim.LocalID, rootPrim.PhysBody.AddrString, 444 rootPrim.LocalID, rootPrim.PhysBody.AddrString,
344 childPrim.LocalID, childPrim.PhysBody.AddrString); 445 childPrim.LocalID, childPrim.PhysBody.AddrString);
345 446
346 // Find the constraint for this link and get rid of it from the overall collection and from my list 447 // If asked to unlink root from root, just remove all the constraints
347 if (m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody)) 448 if (rootPrim == childPrim || childPrim == LinksetRoot)
348 { 449 {
349 // Make the child refresh its location 450 PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
350 m_physicsScene.PE.PushUpdate(childPrim.PhysBody);
351 ret = true; 451 ret = true;
352 } 452 }
453 else
454 {
455 // Find the constraint for this link and get rid of it from the overall collection and from my list
456 if (m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
457 {
458 // Make the child refresh its location
459 m_physicsScene.PE.PushUpdate(childPrim.PhysBody);
460 ret = true;
461 }
462 }
353 463
354 return ret; 464 return ret;
355 } 465 }
@@ -382,9 +492,9 @@ public sealed class BSLinksetConstraints : BSLinkset
382 Rebuilding = true; 492 Rebuilding = true;
383 493
384 // There is no reason to build all this physical stuff for a non-physical linkset. 494 // There is no reason to build all this physical stuff for a non-physical linkset.
385 if (!LinksetRoot.IsPhysicallyActive) 495 if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
386 { 496 {
387 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); 497 DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
388 return; // Note the 'finally' clause at the botton which will get executed. 498 return; // Note the 'finally' clause at the botton which will get executed.
389 } 499 }
390 500
@@ -401,6 +511,7 @@ public sealed class BSLinksetConstraints : BSLinkset
401 // If constraint doesn't exist yet, create it. 511 // If constraint doesn't exist yet, create it.
402 constrain = BuildConstraint(LinksetRoot, li); 512 constrain = BuildConstraint(LinksetRoot, li);
403 } 513 }
514 li.SetLinkParameters(constrain);
404 constrain.RecomputeConstraintVariables(linksetMass); 515 constrain.RecomputeConstraintVariables(linksetMass);
405 516
406 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG 517 // PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
@@ -412,5 +523,324 @@ public sealed class BSLinksetConstraints : BSLinkset
412 Rebuilding = false; 523 Rebuilding = false;
413 } 524 }
414 } 525 }
526
527 #region Extension
528 public override object Extension(string pFunct, params object[] pParams)
529 {
530 object ret = null;
531 switch (pFunct)
532 {
533 // pParams = [ BSPhysObject root, BSPhysObject child, integer linkType ]
534 case ExtendedPhysics.PhysFunctChangeLinkType:
535 if (pParams.Length > 2)
536 {
537 int requestedType = (int)pParams[2];
538 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,requestedType={1}", LinksetRoot.LocalID, requestedType);
539 if (requestedType == (int)ConstraintType.FIXED_CONSTRAINT_TYPE
540 || requestedType == (int)ConstraintType.D6_CONSTRAINT_TYPE
541 || requestedType == (int)ConstraintType.D6_SPRING_CONSTRAINT_TYPE
542 || requestedType == (int)ConstraintType.HINGE_CONSTRAINT_TYPE
543 || requestedType == (int)ConstraintType.CONETWIST_CONSTRAINT_TYPE
544 || requestedType == (int)ConstraintType.SLIDER_CONSTRAINT_TYPE)
545 {
546 BSPrimLinkable child = pParams[1] as BSPrimLinkable;
547 if (child != null)
548 {
549 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,rootID={1},childID={2},type={3}",
550 LinksetRoot.LocalID, LinksetRoot.LocalID, child.LocalID, requestedType);
551 m_physicsScene.TaintedObject(child.LocalID, "BSLinksetConstraint.PhysFunctChangeLinkType", delegate()
552 {
553 // Pick up all the constraints currently created.
554 RemoveDependencies(child);
555
556 BSLinkInfo linkInfo = null;
557 if (TryGetLinkInfo(child, out linkInfo))
558 {
559 BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
560 if (linkInfoC != null)
561 {
562 linkInfoC.constraintType = (ConstraintType)requestedType;
563 ret = (object)true;
564 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,link={1},type={2}",
565 linkInfo.member.LocalID, linkInfo.member.LocalID, linkInfoC.constraintType);
566 }
567 else
568 {
569 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,linkInfoNotConstraint,childID={1}", LinksetRoot.LocalID, child.LocalID);
570 }
571 }
572 else
573 {
574 DetailLog("{0},BSLinksetConstraint.ChangeLinkType,noLinkInfoForChild,childID={1}", LinksetRoot.LocalID, child.LocalID);
575 }
576 // Cause the whole linkset to be rebuilt in post-taint time.
577 Refresh(child);
578 });
579 }
580 else
581 {
582 DetailLog("{0},BSLinksetConstraint.SetLinkType,childNotBSPrimLinkable", LinksetRoot.LocalID);
583 }
584 }
585 else
586 {
587 DetailLog("{0},BSLinksetConstraint.SetLinkType,illegalRequestedType,reqested={1},spring={2}",
588 LinksetRoot.LocalID, requestedType, ((int)ConstraintType.D6_SPRING_CONSTRAINT_TYPE));
589 }
590 }
591 break;
592 // pParams = [ BSPhysObject root, BSPhysObject child ]
593 case ExtendedPhysics.PhysFunctGetLinkType:
594 if (pParams.Length > 0)
595 {
596 BSPrimLinkable child = pParams[1] as BSPrimLinkable;
597 if (child != null)
598 {
599 BSLinkInfo linkInfo = null;
600 if (TryGetLinkInfo(child, out linkInfo))
601 {
602 BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
603 if (linkInfoC != null)
604 {
605 ret = (object)(int)linkInfoC.constraintType;
606 DetailLog("{0},BSLinksetConstraint.GetLinkType,link={1},type={2}",
607 linkInfo.member.LocalID, linkInfo.member.LocalID, linkInfoC.constraintType);
608
609 }
610 }
611 }
612 }
613 break;
614 // pParams = [ BSPhysObject root, BSPhysObject child, int op, object opParams, int op, object opParams, ... ]
615 case ExtendedPhysics.PhysFunctChangeLinkParams:
616 // There should be two parameters: the childActor and a list of parameters to set
617 if (pParams.Length > 2)
618 {
619 BSPrimLinkable child = pParams[1] as BSPrimLinkable;
620 BSLinkInfo baseLinkInfo = null;
621 if (TryGetLinkInfo(child, out baseLinkInfo))
622 {
623 BSLinkInfoConstraint linkInfo = baseLinkInfo as BSLinkInfoConstraint;
624 if (linkInfo != null)
625 {
626 int valueInt;
627 float valueFloat;
628 bool valueBool;
629 OMV.Vector3 valueVector;
630 OMV.Vector3 valueVector2;
631 OMV.Quaternion valueQuaternion;
632 int axisLow, axisHigh;
633
634 int opIndex = 2;
635 while (opIndex < pParams.Length)
636 {
637 int thisOp = 0;
638 string errMsg = "";
639 try
640 {
641 thisOp = (int)pParams[opIndex];
642 DetailLog("{0},BSLinksetConstraint.ChangeLinkParams2,op={1},val={2}",
643 linkInfo.member.LocalID, thisOp, pParams[opIndex + 1]);
644 switch (thisOp)
645 {
646 case ExtendedPhysics.PHYS_PARAM_LINK_TYPE:
647 valueInt = (int)pParams[opIndex + 1];
648 ConstraintType valueType = (ConstraintType)valueInt;
649 if (valueType == ConstraintType.FIXED_CONSTRAINT_TYPE
650 || valueType == ConstraintType.D6_CONSTRAINT_TYPE
651 || valueType == ConstraintType.D6_SPRING_CONSTRAINT_TYPE
652 || valueType == ConstraintType.HINGE_CONSTRAINT_TYPE
653 || valueType == ConstraintType.CONETWIST_CONSTRAINT_TYPE
654 || valueType == ConstraintType.SLIDER_CONSTRAINT_TYPE)
655 {
656 linkInfo.constraintType = valueType;
657 }
658 opIndex += 2;
659 break;
660 case ExtendedPhysics.PHYS_PARAM_FRAMEINA_LOC:
661 errMsg = "PHYS_PARAM_FRAMEINA_LOC takes one parameter of type vector";
662 valueVector = (OMV.Vector3)pParams[opIndex + 1];
663 linkInfo.frameInAloc = valueVector;
664 opIndex += 2;
665 break;
666 case ExtendedPhysics.PHYS_PARAM_FRAMEINA_ROT:
667 errMsg = "PHYS_PARAM_FRAMEINA_ROT takes one parameter of type rotation";
668 valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1];
669 linkInfo.frameInArot = valueQuaternion;
670 opIndex += 2;
671 break;
672 case ExtendedPhysics.PHYS_PARAM_FRAMEINB_LOC:
673 errMsg = "PHYS_PARAM_FRAMEINB_LOC takes one parameter of type vector";
674 valueVector = (OMV.Vector3)pParams[opIndex + 1];
675 linkInfo.frameInBloc = valueVector;
676 opIndex += 2;
677 break;
678 case ExtendedPhysics.PHYS_PARAM_FRAMEINB_ROT:
679 errMsg = "PHYS_PARAM_FRAMEINB_ROT takes one parameter of type rotation";
680 valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1];
681 linkInfo.frameInBrot = valueQuaternion;
682 opIndex += 2;
683 break;
684 case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_LOW:
685 errMsg = "PHYS_PARAM_LINEAR_LIMIT_LOW takes one parameter of type vector";
686 valueVector = (OMV.Vector3)pParams[opIndex + 1];
687 linkInfo.linearLimitLow = valueVector;
688 opIndex += 2;
689 break;
690 case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_HIGH:
691 errMsg = "PHYS_PARAM_LINEAR_LIMIT_HIGH takes one parameter of type vector";
692 valueVector = (OMV.Vector3)pParams[opIndex + 1];
693 linkInfo.linearLimitHigh = valueVector;
694 opIndex += 2;
695 break;
696 case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_LOW:
697 errMsg = "PHYS_PARAM_ANGULAR_LIMIT_LOW takes one parameter of type vector";
698 valueVector = (OMV.Vector3)pParams[opIndex + 1];
699 linkInfo.angularLimitLow = valueVector;
700 opIndex += 2;
701 break;
702 case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_HIGH:
703 errMsg = "PHYS_PARAM_ANGULAR_LIMIT_HIGH takes one parameter of type vector";
704 valueVector = (OMV.Vector3)pParams[opIndex + 1];
705 linkInfo.angularLimitHigh = valueVector;
706 opIndex += 2;
707 break;
708 case ExtendedPhysics.PHYS_PARAM_USE_FRAME_OFFSET:
709 errMsg = "PHYS_PARAM_USE_FRAME_OFFSET takes one parameter of type integer (bool)";
710 valueBool = ((int)pParams[opIndex + 1]) != 0;
711 linkInfo.useFrameOffset = valueBool;
712 opIndex += 2;
713 break;
714 case ExtendedPhysics.PHYS_PARAM_ENABLE_TRANSMOTOR:
715 errMsg = "PHYS_PARAM_ENABLE_TRANSMOTOR takes one parameter of type integer (bool)";
716 valueBool = ((int)pParams[opIndex + 1]) != 0;
717 linkInfo.enableTransMotor = valueBool;
718 opIndex += 2;
719 break;
720 case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXVEL:
721 errMsg = "PHYS_PARAM_TRANSMOTOR_MAXVEL takes one parameter of type float";
722 valueFloat = (float)pParams[opIndex + 1];
723 linkInfo.transMotorMaxVel = valueFloat;
724 opIndex += 2;
725 break;
726 case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXFORCE:
727 errMsg = "PHYS_PARAM_TRANSMOTOR_MAXFORCE takes one parameter of type float";
728 valueFloat = (float)pParams[opIndex + 1];
729 linkInfo.transMotorMaxForce = valueFloat;
730 opIndex += 2;
731 break;
732 case ExtendedPhysics.PHYS_PARAM_CFM:
733 errMsg = "PHYS_PARAM_CFM takes one parameter of type float";
734 valueFloat = (float)pParams[opIndex + 1];
735 linkInfo.cfm = valueFloat;
736 opIndex += 2;
737 break;
738 case ExtendedPhysics.PHYS_PARAM_ERP:
739 errMsg = "PHYS_PARAM_ERP takes one parameter of type float";
740 valueFloat = (float)pParams[opIndex + 1];
741 linkInfo.erp = valueFloat;
742 opIndex += 2;
743 break;
744 case ExtendedPhysics.PHYS_PARAM_SOLVER_ITERATIONS:
745 errMsg = "PHYS_PARAM_SOLVER_ITERATIONS takes one parameter of type float";
746 valueFloat = (float)pParams[opIndex + 1];
747 linkInfo.solverIterations = valueFloat;
748 opIndex += 2;
749 break;
750 case ExtendedPhysics.PHYS_PARAM_SPRING_AXIS_ENABLE:
751 errMsg = "PHYS_PARAM_SPRING_AXIS_ENABLE takes two parameters of types integer and integer (bool)";
752 valueInt = (int)pParams[opIndex + 1];
753 valueBool = ((int)pParams[opIndex + 2]) != 0;
754 GetAxisRange(valueInt, out axisLow, out axisHigh);
755 for (int ii = axisLow; ii <= axisHigh; ii++)
756 linkInfo.springAxisEnable[ii] = valueBool;
757 opIndex += 3;
758 break;
759 case ExtendedPhysics.PHYS_PARAM_SPRING_DAMPING:
760 errMsg = "PHYS_PARAM_SPRING_DAMPING takes two parameters of types integer and float";
761 valueInt = (int)pParams[opIndex + 1];
762 valueFloat = (float)pParams[opIndex + 2];
763 GetAxisRange(valueInt, out axisLow, out axisHigh);
764 for (int ii = axisLow; ii <= axisHigh; ii++)
765 linkInfo.springDamping[ii] = valueFloat;
766 opIndex += 3;
767 break;
768 case ExtendedPhysics.PHYS_PARAM_SPRING_STIFFNESS:
769 errMsg = "PHYS_PARAM_SPRING_STIFFNESS takes two parameters of types integer and float";
770 valueInt = (int)pParams[opIndex + 1];
771 valueFloat = (float)pParams[opIndex + 2];
772 GetAxisRange(valueInt, out axisLow, out axisHigh);
773 for (int ii = axisLow; ii <= axisHigh; ii++)
774 linkInfo.springStiffness[ii] = valueFloat;
775 opIndex += 3;
776 break;
777 case ExtendedPhysics.PHYS_PARAM_SPRING_EQUILIBRIUM_POINT:
778 errMsg = "PHYS_PARAM_SPRING_EQUILIBRIUM_POINT takes two parameters of type vector";
779 valueVector = (OMV.Vector3)pParams[opIndex + 1];
780 valueVector2 = (OMV.Vector3)pParams[opIndex + 2];
781 linkInfo.springLinearEquilibriumPoint = valueVector;
782 linkInfo.springAngularEquilibriumPoint = valueVector2;
783 opIndex += 3;
784 break;
785 case ExtendedPhysics.PHYS_PARAM_USE_LINEAR_FRAMEA:
786 errMsg = "PHYS_PARAM_USE_LINEAR_FRAMEA takes one parameter of type integer (bool)";
787 valueBool = ((int)pParams[opIndex + 1]) != 0;
788 linkInfo.useLinearReferenceFrameA = valueBool;
789 opIndex += 2;
790 break;
791 default:
792 break;
793 }
794 }
795 catch (InvalidCastException e)
796 {
797 m_physicsScene.Logger.WarnFormat("{0} value of wrong type in physSetLinksetParams: {1}, err={2}",
798 LogHeader, errMsg, e);
799 }
800 catch (Exception e)
801 {
802 m_physicsScene.Logger.WarnFormat("{0} bad parameters in physSetLinksetParams: {1}", LogHeader, e);
803 }
804 }
805 }
806 // Something changed so a rebuild is in order
807 Refresh(child);
808 }
809 }
810 break;
811 default:
812 ret = base.Extension(pFunct, pParams);
813 break;
814 }
815 return ret;
816 }
817
818 // Bullet constraints keep some limit parameters for each linear and angular axis.
819 // Setting same is easier if there is an easy way to see all or types.
820 // This routine returns the array limits for the set of axis.
821 private void GetAxisRange(int rangeSpec, out int low, out int high)
822 {
823 switch (rangeSpec)
824 {
825 case ExtendedPhysics.PHYS_AXIS_LINEAR_ALL:
826 low = 0;
827 high = 2;
828 break;
829 case ExtendedPhysics.PHYS_AXIS_ANGULAR_ALL:
830 low = 3;
831 high = 5;
832 break;
833 case ExtendedPhysics.PHYS_AXIS_ALL:
834 low = 0;
835 high = 5;
836 break;
837 default:
838 low = high = rangeSpec;
839 break;
840 }
841 return;
842 }
843 #endregion // Extension
844
415} 845}
416} 846}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index fcb892a..43aa63e 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -134,6 +134,7 @@ public static class BSParam
134 public static float AvatarHeightMidFudge { get; private set; } 134 public static float AvatarHeightMidFudge { get; private set; }
135 public static float AvatarHeightHighFudge { get; private set; } 135 public static float AvatarHeightHighFudge { get; private set; }
136 public static float AvatarContactProcessingThreshold { get; private set; } 136 public static float AvatarContactProcessingThreshold { get; private set; }
137 public static float AvatarStopZeroThreshold { get; private set; }
137 public static int AvatarJumpFrames { get; private set; } 138 public static int AvatarJumpFrames { get; private set; }
138 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; } 139 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
139 public static float AvatarStepHeight { get; private set; } 140 public static float AvatarStepHeight { get; private set; }
@@ -570,11 +571,13 @@ public static class BSParam
570 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", 571 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground",
571 -0.2f ), 572 -0.2f ),
572 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", 573 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground",
573 0.2f ), 574 0.1f ),
574 new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground", 575 new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground",
575 0.2f ), 576 0.1f ),
576 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 577 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
577 0.1f ), 578 0.1f ),
579 new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
580 0.1f ),
578 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", 581 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
579 1.0f ), 582 1.0f ),
580 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.", 583 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.",
@@ -683,21 +686,21 @@ public static class BSParam
683 0f ), 686 0f ),
684 687
685 new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull", 688 new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull",
686 100f ), 689 200f ),
687 new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh", 690 new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh",
688 2f ), 691 10f ),
689 new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls", 692 new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls",
690 0.1f ), 693 20f ),
691 new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull", 694 new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull",
692 0f ), 695 0.1f ),
693 new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be", 696 new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be",
694 100f ), 697 10f ),
695 new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors", 698 new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors",
696 false ), 699 true ),
697 new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls", 700 new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls",
698 false ), 701 true ),
699 new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces", 702 new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces",
700 false ), 703 true ),
701 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin", 704 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin",
702 false ), 705 false ),
703 706
@@ -826,7 +829,7 @@ public static class BSParam
826 private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v) 829 private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v)
827 { 830 {
828 BSScene physScene = pPhysScene; 831 BSScene physScene = pPhysScene;
829 physScene.TaintedObject("BSParam.ResetConstraintSolver", delegate() 832 physScene.TaintedObject(BSScene.DetailLogZero, "BSParam.ResetConstraintSolver", delegate()
830 { 833 {
831 physScene.PE.ResetConstraintSolver(physScene.World); 834 physScene.PE.ResetConstraintSolver(physScene.World);
832 }); 835 });
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 9dc52d5..f89b376 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -121,7 +121,7 @@ public abstract class BSPhysObject : PhysicsActor
121 public virtual void Destroy() 121 public virtual void Destroy()
122 { 122 {
123 PhysicalActors.Enable(false); 123 PhysicalActors.Enable(false);
124 PhysScene.TaintedObject("BSPhysObject.Destroy", delegate() 124 PhysScene.TaintedObject(LocalID, "BSPhysObject.Destroy", delegate()
125 { 125 {
126 PhysicalActors.Dispose(); 126 PhysicalActors.Dispose();
127 }); 127 });
@@ -300,8 +300,19 @@ public abstract class BSPhysObject : PhysicsActor
300 // Called in taint-time!! 300 // Called in taint-time!!
301 public void ActivateIfPhysical(bool forceIt) 301 public void ActivateIfPhysical(bool forceIt)
302 { 302 {
303 if (IsPhysical && PhysBody.HasPhysicalBody) 303 if (PhysBody.HasPhysicalBody)
304 PhysScene.PE.Activate(PhysBody, forceIt); 304 {
305 if (IsPhysical)
306 {
307 // Physical objects might need activating
308 PhysScene.PE.Activate(PhysBody, forceIt);
309 }
310 else
311 {
312 // Clear the collision cache since we've changed some properties.
313 PhysScene.PE.ClearCollisionProxyCache(PhysScene.World, PhysBody);
314 }
315 }
305 } 316 }
306 317
307 // 'actors' act on the physical object to change or constrain its motion. These can range from 318 // 'actors' act on the physical object to change or constrain its motion. These can range from
@@ -509,7 +520,7 @@ public abstract class BSPhysObject : PhysicsActor
509 // make sure first collision happens 520 // make sure first collision happens
510 NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs); 521 NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs);
511 522
512 PhysScene.TaintedObject(TypeName+".SubscribeEvents", delegate() 523 PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate()
513 { 524 {
514 if (PhysBody.HasPhysicalBody) 525 if (PhysBody.HasPhysicalBody)
515 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 526 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
@@ -524,7 +535,7 @@ public abstract class BSPhysObject : PhysicsActor
524 public override void UnSubscribeEvents() { 535 public override void UnSubscribeEvents() {
525 // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName); 536 // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName);
526 SubscribedEventsMs = 0; 537 SubscribedEventsMs = 0;
527 PhysScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() 538 PhysScene.TaintedObject(LocalID, TypeName+".UnSubscribeEvents", delegate()
528 { 539 {
529 // Make sure there is a body there because sometimes destruction happens in an un-ideal order. 540 // Make sure there is a body there because sometimes destruction happens in an un-ideal order.
530 if (PhysBody.HasPhysicalBody) 541 if (PhysBody.HasPhysicalBody)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index d5b999d..15b7090 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -41,7 +41,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
41 [Serializable] 41 [Serializable]
42public class BSPrim : BSPhysObject 42public class BSPrim : BSPhysObject
43{ 43{
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
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.
@@ -102,7 +102,7 @@ public class BSPrim : BSPhysObject
102 102
103 // DetailLog("{0},BSPrim.constructor,call", LocalID); 103 // DetailLog("{0},BSPrim.constructor,call", LocalID);
104 // do the actual object creation at taint time 104 // do the actual object creation at taint time
105 PhysScene.TaintedObject("BSPrim.create", delegate() 105 PhysScene.TaintedObject(LocalID, "BSPrim.create", delegate()
106 { 106 {
107 // Make sure the object is being created with some sanity. 107 // Make sure the object is being created with some sanity.
108 ExtremeSanityCheck(true /* inTaintTime */); 108 ExtremeSanityCheck(true /* inTaintTime */);
@@ -126,7 +126,7 @@ public class BSPrim : BSPhysObject
126 // Undo any vehicle properties 126 // Undo any vehicle properties
127 this.VehicleType = (int)Vehicle.TYPE_NONE; 127 this.VehicleType = (int)Vehicle.TYPE_NONE;
128 128
129 PhysScene.TaintedObject("BSPrim.Destroy", delegate() 129 PhysScene.TaintedObject(LocalID, "BSPrim.Destroy", delegate()
130 { 130 {
131 DetailLog("{0},BSPrim.Destroy,taint,", LocalID); 131 DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
132 // If there are physical body and shape, release my use of same. 132 // If there are physical body and shape, release my use of same.
@@ -161,7 +161,7 @@ public class BSPrim : BSPhysObject
161 } 161 }
162 public override bool ForceBodyShapeRebuild(bool inTaintTime) 162 public override bool ForceBodyShapeRebuild(bool inTaintTime)
163 { 163 {
164 PhysScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate() 164 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ForceBodyShapeRebuild", delegate()
165 { 165 {
166 _mass = CalculateMass(); // changing the shape changes the mass 166 _mass = CalculateMass(); // changing the shape changes the mass
167 CreateGeomAndObject(true); 167 CreateGeomAndObject(true);
@@ -178,7 +178,7 @@ public class BSPrim : BSPhysObject
178 if (value != _isSelected) 178 if (value != _isSelected)
179 { 179 {
180 _isSelected = value; 180 _isSelected = value;
181 PhysScene.TaintedObject("BSPrim.setSelected", delegate() 181 PhysScene.TaintedObject(LocalID, "BSPrim.setSelected", delegate()
182 { 182 {
183 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected); 183 DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
184 SetObjectDynamic(false); 184 SetObjectDynamic(false);
@@ -224,7 +224,7 @@ public class BSPrim : BSPhysObject
224 _rotationalVelocity = OMV.Vector3.Zero; 224 _rotationalVelocity = OMV.Vector3.Zero;
225 225
226 // Zero some other properties in the physics engine 226 // Zero some other properties in the physics engine
227 PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 227 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
228 { 228 {
229 if (PhysBody.HasPhysicalBody) 229 if (PhysBody.HasPhysicalBody)
230 PhysScene.PE.ClearAllForces(PhysBody); 230 PhysScene.PE.ClearAllForces(PhysBody);
@@ -234,7 +234,7 @@ public class BSPrim : BSPhysObject
234 { 234 {
235 _rotationalVelocity = OMV.Vector3.Zero; 235 _rotationalVelocity = OMV.Vector3.Zero;
236 // Zero some other properties in the physics engine 236 // Zero some other properties in the physics engine
237 PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate() 237 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
238 { 238 {
239 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); 239 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
240 if (PhysBody.HasPhysicalBody) 240 if (PhysBody.HasPhysicalBody)
@@ -262,7 +262,7 @@ public class BSPrim : BSPhysObject
262 }); 262 });
263 263
264 // Update parameters so the new actor's Refresh() action is called at the right time. 264 // Update parameters so the new actor's Refresh() action is called at the right time.
265 PhysScene.TaintedObject("BSPrim.LockAngularMotion", delegate() 265 PhysScene.TaintedObject(LocalID, "BSPrim.LockAngularMotion", delegate()
266 { 266 {
267 UpdatePhysicalParameters(); 267 UpdatePhysicalParameters();
268 }); 268 });
@@ -287,7 +287,7 @@ public class BSPrim : BSPhysObject
287 RawPosition = value; 287 RawPosition = value;
288 PositionSanityCheck(false); 288 PositionSanityCheck(false);
289 289
290 PhysScene.TaintedObject("BSPrim.setPosition", delegate() 290 PhysScene.TaintedObject(LocalID, "BSPrim.setPosition", delegate()
291 { 291 {
292 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); 292 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
293 ForcePosition = RawPosition; 293 ForcePosition = RawPosition;
@@ -531,7 +531,7 @@ public class BSPrim : BSPhysObject
531 set { 531 set {
532 Vehicle type = (Vehicle)value; 532 Vehicle type = (Vehicle)value;
533 533
534 PhysScene.TaintedObject("setVehicleType", delegate() 534 PhysScene.TaintedObject(LocalID, "setVehicleType", delegate()
535 { 535 {
536 // Some vehicle scripts change vehicle type on the fly as an easy way to 536 // Some vehicle scripts change vehicle type on the fly as an easy way to
537 // change all the parameters. Like a plane changing to CAR when on the 537 // change all the parameters. Like a plane changing to CAR when on the
@@ -561,7 +561,7 @@ public class BSPrim : BSPhysObject
561 } 561 }
562 public override void VehicleFloatParam(int param, float value) 562 public override void VehicleFloatParam(int param, float value)
563 { 563 {
564 PhysScene.TaintedObject("BSPrim.VehicleFloatParam", delegate() 564 PhysScene.TaintedObject(LocalID, "BSPrim.VehicleFloatParam", delegate()
565 { 565 {
566 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */); 566 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
567 if (vehicleActor != null) 567 if (vehicleActor != null)
@@ -573,7 +573,7 @@ public class BSPrim : BSPhysObject
573 } 573 }
574 public override void VehicleVectorParam(int param, OMV.Vector3 value) 574 public override void VehicleVectorParam(int param, OMV.Vector3 value)
575 { 575 {
576 PhysScene.TaintedObject("BSPrim.VehicleVectorParam", delegate() 576 PhysScene.TaintedObject(LocalID, "BSPrim.VehicleVectorParam", delegate()
577 { 577 {
578 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */); 578 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
579 if (vehicleActor != null) 579 if (vehicleActor != null)
@@ -585,7 +585,7 @@ public class BSPrim : BSPhysObject
585 } 585 }
586 public override void VehicleRotationParam(int param, OMV.Quaternion rotation) 586 public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
587 { 587 {
588 PhysScene.TaintedObject("BSPrim.VehicleRotationParam", delegate() 588 PhysScene.TaintedObject(LocalID, "BSPrim.VehicleRotationParam", delegate()
589 { 589 {
590 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */); 590 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
591 if (vehicleActor != null) 591 if (vehicleActor != null)
@@ -597,7 +597,7 @@ public class BSPrim : BSPhysObject
597 } 597 }
598 public override void VehicleFlags(int param, bool remove) 598 public override void VehicleFlags(int param, bool remove)
599 { 599 {
600 PhysScene.TaintedObject("BSPrim.VehicleFlags", delegate() 600 PhysScene.TaintedObject(LocalID, "BSPrim.VehicleFlags", delegate()
601 { 601 {
602 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */); 602 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
603 if (vehicleActor != null) 603 if (vehicleActor != null)
@@ -613,7 +613,7 @@ public class BSPrim : BSPhysObject
613 if (_isVolumeDetect != newValue) 613 if (_isVolumeDetect != newValue)
614 { 614 {
615 _isVolumeDetect = newValue; 615 _isVolumeDetect = newValue;
616 PhysScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() 616 PhysScene.TaintedObject(LocalID, "BSPrim.SetVolumeDetect", delegate()
617 { 617 {
618 // DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); 618 // DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect);
619 SetObjectDynamic(true); 619 SetObjectDynamic(true);
@@ -628,7 +628,7 @@ public class BSPrim : BSPhysObject
628 public override void SetMaterial(int material) 628 public override void SetMaterial(int material)
629 { 629 {
630 base.SetMaterial(material); 630 base.SetMaterial(material);
631 PhysScene.TaintedObject("BSPrim.SetMaterial", delegate() 631 PhysScene.TaintedObject(LocalID, "BSPrim.SetMaterial", delegate()
632 { 632 {
633 UpdatePhysicalParameters(); 633 UpdatePhysicalParameters();
634 }); 634 });
@@ -641,7 +641,7 @@ public class BSPrim : BSPhysObject
641 if (base.Friction != value) 641 if (base.Friction != value)
642 { 642 {
643 base.Friction = value; 643 base.Friction = value;
644 PhysScene.TaintedObject("BSPrim.setFriction", delegate() 644 PhysScene.TaintedObject(LocalID, "BSPrim.setFriction", delegate()
645 { 645 {
646 UpdatePhysicalParameters(); 646 UpdatePhysicalParameters();
647 }); 647 });
@@ -656,7 +656,7 @@ public class BSPrim : BSPhysObject
656 if (base.Restitution != value) 656 if (base.Restitution != value)
657 { 657 {
658 base.Restitution = value; 658 base.Restitution = value;
659 PhysScene.TaintedObject("BSPrim.setRestitution", delegate() 659 PhysScene.TaintedObject(LocalID, "BSPrim.setRestitution", delegate()
660 { 660 {
661 UpdatePhysicalParameters(); 661 UpdatePhysicalParameters();
662 }); 662 });
@@ -673,7 +673,7 @@ public class BSPrim : BSPhysObject
673 if (base.Density != value) 673 if (base.Density != value)
674 { 674 {
675 base.Density = value; 675 base.Density = value;
676 PhysScene.TaintedObject("BSPrim.setDensity", delegate() 676 PhysScene.TaintedObject(LocalID, "BSPrim.setDensity", delegate()
677 { 677 {
678 UpdatePhysicalParameters(); 678 UpdatePhysicalParameters();
679 }); 679 });
@@ -688,7 +688,7 @@ public class BSPrim : BSPhysObject
688 if (base.GravModifier != value) 688 if (base.GravModifier != value)
689 { 689 {
690 base.GravModifier = value; 690 base.GravModifier = value;
691 PhysScene.TaintedObject("BSPrim.setGravityModifier", delegate() 691 PhysScene.TaintedObject(LocalID, "BSPrim.setGravityModifier", delegate()
692 { 692 {
693 UpdatePhysicalParameters(); 693 UpdatePhysicalParameters();
694 }); 694 });
@@ -699,7 +699,7 @@ public class BSPrim : BSPhysObject
699 get { return RawVelocity; } 699 get { return RawVelocity; }
700 set { 700 set {
701 RawVelocity = value; 701 RawVelocity = value;
702 PhysScene.TaintedObject("BSPrim.setVelocity", delegate() 702 PhysScene.TaintedObject(LocalID, "BSPrim.setVelocity", delegate()
703 { 703 {
704 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity); 704 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
705 ForceVelocity = RawVelocity; 705 ForceVelocity = RawVelocity;
@@ -745,7 +745,7 @@ public class BSPrim : BSPhysObject
745 return; 745 return;
746 RawOrientation = value; 746 RawOrientation = value;
747 747
748 PhysScene.TaintedObject("BSPrim.setOrientation", delegate() 748 PhysScene.TaintedObject(LocalID, "BSPrim.setOrientation", delegate()
749 { 749 {
750 ForceOrientation = RawOrientation; 750 ForceOrientation = RawOrientation;
751 }); 751 });
@@ -776,7 +776,7 @@ public class BSPrim : BSPhysObject
776 if (_isPhysical != value) 776 if (_isPhysical != value)
777 { 777 {
778 _isPhysical = value; 778 _isPhysical = value;
779 PhysScene.TaintedObject("BSPrim.setIsPhysical", delegate() 779 PhysScene.TaintedObject(LocalID, "BSPrim.setIsPhysical", delegate()
780 { 780 {
781 DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); 781 DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
782 SetObjectDynamic(true); 782 SetObjectDynamic(true);
@@ -1020,7 +1020,7 @@ public class BSPrim : BSPhysObject
1020 public override bool FloatOnWater { 1020 public override bool FloatOnWater {
1021 set { 1021 set {
1022 _floatOnWater = value; 1022 _floatOnWater = value;
1023 PhysScene.TaintedObject("BSPrim.setFloatOnWater", delegate() 1023 PhysScene.TaintedObject(LocalID, "BSPrim.setFloatOnWater", delegate()
1024 { 1024 {
1025 if (_floatOnWater) 1025 if (_floatOnWater)
1026 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); 1026 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
@@ -1037,7 +1037,7 @@ public class BSPrim : BSPhysObject
1037 _rotationalVelocity = value; 1037 _rotationalVelocity = value;
1038 Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); 1038 Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity);
1039 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 1039 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
1040 PhysScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 1040 PhysScene.TaintedObject(LocalID, "BSPrim.setRotationalVelocity", delegate()
1041 { 1041 {
1042 ForceRotationalVelocity = _rotationalVelocity; 1042 ForceRotationalVelocity = _rotationalVelocity;
1043 }); 1043 });
@@ -1068,7 +1068,7 @@ public class BSPrim : BSPhysObject
1068 get { return _buoyancy; } 1068 get { return _buoyancy; }
1069 set { 1069 set {
1070 _buoyancy = value; 1070 _buoyancy = value;
1071 PhysScene.TaintedObject("BSPrim.setBuoyancy", delegate() 1071 PhysScene.TaintedObject(LocalID, "BSPrim.setBuoyancy", delegate()
1072 { 1072 {
1073 ForceBuoyancy = _buoyancy; 1073 ForceBuoyancy = _buoyancy;
1074 }); 1074 });
@@ -1142,7 +1142,7 @@ public class BSPrim : BSPhysObject
1142 // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce); 1142 // DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
1143 1143
1144 OMV.Vector3 addForce = force; 1144 OMV.Vector3 addForce = force;
1145 PhysScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() 1145 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.AddForce", delegate()
1146 { 1146 {
1147 // Bullet adds this central force to the total force for this tick. 1147 // Bullet adds this central force to the total force for this tick.
1148 // Deep down in Bullet: 1148 // Deep down in Bullet:
@@ -1172,7 +1172,7 @@ public class BSPrim : BSPhysObject
1172 OMV.Vector3 addImpulse = Util.ClampV(impulse, BSParam.MaxAddForceMagnitude); 1172 OMV.Vector3 addImpulse = Util.ClampV(impulse, BSParam.MaxAddForceMagnitude);
1173 // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse); 1173 // DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse);
1174 1174
1175 PhysScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate() 1175 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.AddImpulse", delegate()
1176 { 1176 {
1177 // Bullet adds this impulse immediately to the velocity 1177 // Bullet adds this impulse immediately to the velocity
1178 DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse); 1178 DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse);
@@ -1197,7 +1197,7 @@ public class BSPrim : BSPhysObject
1197 if (force.IsFinite()) 1197 if (force.IsFinite())
1198 { 1198 {
1199 OMV.Vector3 angForce = force; 1199 OMV.Vector3 angForce = force;
1200 PhysScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate() 1200 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.AddAngularForce", delegate()
1201 { 1201 {
1202 if (PhysBody.HasPhysicalBody) 1202 if (PhysBody.HasPhysicalBody)
1203 { 1203 {
@@ -1221,7 +1221,7 @@ public class BSPrim : BSPhysObject
1221 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime) 1221 public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
1222 { 1222 {
1223 OMV.Vector3 applyImpulse = impulse; 1223 OMV.Vector3 applyImpulse = impulse;
1224 PhysScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() 1224 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ApplyTorqueImpulse", delegate()
1225 { 1225 {
1226 if (PhysBody.HasPhysicalBody) 1226 if (PhysBody.HasPhysicalBody)
1227 { 1227 {
@@ -1552,39 +1552,10 @@ public class BSPrim : BSPhysObject
1552 #region Extension 1552 #region Extension
1553 public override object Extension(string pFunct, params object[] pParams) 1553 public override object Extension(string pFunct, params object[] pParams)
1554 { 1554 {
1555 DetailLog("{0} BSPrim.Extension,op={1}", LocalID, pFunct);
1555 object ret = null; 1556 object ret = null;
1556 switch (pFunct) 1557 switch (pFunct)
1557 { 1558 {
1558 case BSScene.PhysFunctGetLinksetType:
1559 {
1560 BSPrimLinkable myHandle = this as BSPrimLinkable;
1561 if (myHandle != null)
1562 {
1563 ret = (object)myHandle.LinksetType;
1564 }
1565 m_log.DebugFormat("{0} Extension.physGetLinksetType, type={1}", LogHeader, ret);
1566 break;
1567 }
1568 case BSScene.PhysFunctSetLinksetType:
1569 {
1570 if (pParams.Length > 0)
1571 {
1572 BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[0];
1573 BSPrimLinkable myHandle = this as BSPrimLinkable;
1574 if (myHandle != null && myHandle.Linkset.IsRoot(myHandle))
1575 {
1576 PhysScene.TaintedObject("BSPrim.PhysFunctSetLinksetType", delegate()
1577 {
1578 // Cause the linkset type to change
1579 m_log.DebugFormat("{0} Extension.physSetLinksetType, oldType={1}, newType={2}",
1580 LogHeader, myHandle.Linkset.LinksetImpl, linksetType);
1581 myHandle.ConvertLinkset(linksetType);
1582 });
1583 }
1584 ret = (object)(int)linksetType;
1585 }
1586 break;
1587 }
1588 default: 1559 default:
1589 ret = base.Extension(pFunct, pParams); 1560 ret = base.Extension(pFunct, pParams);
1590 break; 1561 break;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
index 7179a6d..126b146 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs
@@ -30,6 +30,7 @@ using System.Linq;
30using System.Text; 30using System.Text;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.OptionalModules.Scripting;
33 34
34using OMV = OpenMetaverse; 35using OMV = OpenMetaverse;
35 36
@@ -41,6 +42,8 @@ public class BSPrimLinkable : BSPrimDisplaced
41 // operations necessary for keeping the linkset created and, additionally, this 42 // operations necessary for keeping the linkset created and, additionally, this
42 // calls the linkset implementation for its creation and management. 43 // calls the linkset implementation for its creation and management.
43 44
45 private static readonly string LogHeader = "[BULLETS PRIMLINKABLE]";
46
44 // This adds the overrides for link() and delink() so the prim is linkable. 47 // This adds the overrides for link() and delink() so the prim is linkable.
45 48
46 public BSLinkset Linkset { get; set; } 49 public BSLinkset Linkset { get; set; }
@@ -58,15 +61,12 @@ public class BSPrimLinkable : BSPrimDisplaced
58 61
59 Linkset = BSLinkset.Factory(PhysScene, this); 62 Linkset = BSLinkset.Factory(PhysScene, this);
60 63
61 PhysScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate() 64 Linkset.Refresh(this);
62 {
63 Linkset.Refresh(this);
64 });
65 } 65 }
66 66
67 public override void Destroy() 67 public override void Destroy()
68 { 68 {
69 Linkset = Linkset.RemoveMeFromLinkset(this); 69 Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime */);
70 base.Destroy(); 70 base.Destroy();
71 } 71 }
72 72
@@ -80,7 +80,7 @@ public class BSPrimLinkable : BSPrimDisplaced
80 80
81 Linkset = parent.Linkset.AddMeToLinkset(this); 81 Linkset = parent.Linkset.AddMeToLinkset(this);
82 82
83 DetailLog("{0},BSPrimLinkset.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", 83 DetailLog("{0},BSPrimLinkable.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
84 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); 84 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
85 } 85 }
86 return; 86 return;
@@ -94,9 +94,9 @@ public class BSPrimLinkable : BSPrimDisplaced
94 BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG 94 BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG
95 int childrenBefore = Linkset.NumberOfChildren; // DEBUG 95 int childrenBefore = Linkset.NumberOfChildren; // DEBUG
96 96
97 Linkset = Linkset.RemoveMeFromLinkset(this); 97 Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime*/);
98 98
99 DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", 99 DetailLog("{0},BSPrimLinkable.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
100 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren); 100 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
101 return; 101 return;
102 } 102 }
@@ -108,7 +108,7 @@ public class BSPrimLinkable : BSPrimDisplaced
108 set 108 set
109 { 109 {
110 base.Position = value; 110 base.Position = value;
111 PhysScene.TaintedObject("BSPrimLinkset.setPosition", delegate() 111 PhysScene.TaintedObject(LocalID, "BSPrimLinkable.setPosition", delegate()
112 { 112 {
113 Linkset.UpdateProperties(UpdatedProperties.Position, this); 113 Linkset.UpdateProperties(UpdatedProperties.Position, this);
114 }); 114 });
@@ -122,7 +122,7 @@ public class BSPrimLinkable : BSPrimDisplaced
122 set 122 set
123 { 123 {
124 base.Orientation = value; 124 base.Orientation = value;
125 PhysScene.TaintedObject("BSPrimLinkset.setOrientation", delegate() 125 PhysScene.TaintedObject(LocalID, "BSPrimLinkable.setOrientation", delegate()
126 { 126 {
127 Linkset.UpdateProperties(UpdatedProperties.Orientation, this); 127 Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
128 }); 128 });
@@ -180,7 +180,7 @@ public class BSPrimLinkable : BSPrimDisplaced
180 // Do any filtering/modification needed for linksets. 180 // Do any filtering/modification needed for linksets.
181 public override void UpdateProperties(EntityProperties entprop) 181 public override void UpdateProperties(EntityProperties entprop)
182 { 182 {
183 if (Linkset.IsRoot(this)) 183 if (Linkset.IsRoot(this) || Linkset.ShouldReportPropertyUpdates(this))
184 { 184 {
185 // Properties are only updated for the roots of a linkset. 185 // Properties are only updated for the roots of a linkset.
186 // TODO: this will have to change when linksets are articulated. 186 // TODO: this will have to change when linksets are articulated.
@@ -240,6 +240,8 @@ public class BSPrimLinkable : BSPrimDisplaced
240 bool ret = false; 240 bool ret = false;
241 if (LinksetType != newType) 241 if (LinksetType != newType)
242 { 242 {
243 DetailLog("{0},BSPrimLinkable.ConvertLinkset,oldT={1},newT={2}", LocalID, LinksetType, newType);
244
243 // Set the implementation type first so the call to BSLinkset.Factory gets the new type. 245 // Set the implementation type first so the call to BSLinkset.Factory gets the new type.
244 this.LinksetType = newType; 246 this.LinksetType = newType;
245 247
@@ -263,7 +265,10 @@ public class BSPrimLinkable : BSPrimDisplaced
263 // Remove the children from the old linkset and add to the new (will be a new instance from the factory) 265 // Remove the children from the old linkset and add to the new (will be a new instance from the factory)
264 foreach (BSPrimLinkable child in children) 266 foreach (BSPrimLinkable child in children)
265 { 267 {
266 oldLinkset.RemoveMeFromLinkset(child); 268 oldLinkset.RemoveMeFromLinkset(child, true /*inTaintTime*/);
269 }
270 foreach (BSPrimLinkable child in children)
271 {
267 newLinkset.AddMeToLinkset(child); 272 newLinkset.AddMeToLinkset(child);
268 child.Linkset = newLinkset; 273 child.Linkset = newLinkset;
269 } 274 }
@@ -274,5 +279,70 @@ public class BSPrimLinkable : BSPrimDisplaced
274 } 279 }
275 return ret; 280 return ret;
276 } 281 }
282
283 #region Extension
284 public override object Extension(string pFunct, params object[] pParams)
285 {
286 DetailLog("{0} BSPrimLinkable.Extension,op={1},nParam={2}", LocalID, pFunct, pParams.Length);
287 object ret = null;
288 switch (pFunct)
289 {
290 // physGetLinksetType();
291 // pParams = [ BSPhysObject root, null ]
292 case ExtendedPhysics.PhysFunctGetLinksetType:
293 {
294 ret = (object)LinksetType;
295 DetailLog("{0},BSPrimLinkable.Extension.physGetLinksetType,type={1}", LocalID, ret);
296 break;
297 }
298 // physSetLinksetType(type);
299 // pParams = [ BSPhysObject root, null, integer type ]
300 case ExtendedPhysics.PhysFunctSetLinksetType:
301 {
302 if (pParams.Length > 2)
303 {
304 BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[2];
305 if (Linkset.IsRoot(this))
306 {
307 PhysScene.TaintedObject(LocalID, "BSPrim.PhysFunctSetLinksetType", delegate()
308 {
309 // Cause the linkset type to change
310 DetailLog("{0},BSPrimLinkable.Extension.physSetLinksetType, oldType={1},newType={2}",
311 LocalID, Linkset.LinksetImpl, linksetType);
312 ConvertLinkset(linksetType);
313 });
314 }
315 ret = (object)(int)linksetType;
316 }
317 break;
318 }
319 // physChangeLinkType(linknum, typeCode);
320 // pParams = [ BSPhysObject root, BSPhysObject child, integer linkType ]
321 case ExtendedPhysics.PhysFunctChangeLinkType:
322 {
323 ret = Linkset.Extension(pFunct, pParams);
324 break;
325 }
326 // physGetLinkType(linknum);
327 // pParams = [ BSPhysObject root, BSPhysObject child ]
328 case ExtendedPhysics.PhysFunctGetLinkType:
329 {
330 ret = Linkset.Extension(pFunct, pParams);
331 break;
332 }
333 // physChangeLinkParams(linknum, [code, value, code, value, ...]);
334 // pParams = [ BSPhysObject root, BSPhysObject child, object[] [ string op, object opParam, string op, object opParam, ... ] ]
335 case ExtendedPhysics.PhysFunctChangeLinkParams:
336 {
337 ret = Linkset.Extension(pFunct, pParams);
338 break;
339 }
340 default:
341 ret = base.Extension(pFunct, pParams);
342 break;
343 }
344 return ret;
345 }
346 #endregion // Extension
277} 347}
278} 348}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index c92c9b9..b3dfa41 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -157,12 +157,20 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
157 public delegate void TaintCallback(); 157 public delegate void TaintCallback();
158 private struct TaintCallbackEntry 158 private struct TaintCallbackEntry
159 { 159 {
160 public String originator;
160 public String ident; 161 public String ident;
161 public TaintCallback callback; 162 public TaintCallback callback;
162 public TaintCallbackEntry(string i, TaintCallback c) 163 public TaintCallbackEntry(string pIdent, TaintCallback pCallBack)
163 { 164 {
164 ident = i; 165 originator = BSScene.DetailLogZero;
165 callback = c; 166 ident = pIdent;
167 callback = pCallBack;
168 }
169 public TaintCallbackEntry(string pOrigin, string pIdent, TaintCallback pCallBack)
170 {
171 originator = pOrigin;
172 ident = pIdent;
173 callback = pCallBack;
166 } 174 }
167 } 175 }
168 private Object _taintLock = new Object(); // lock for using the next object 176 private Object _taintLock = new Object(); // lock for using the next object
@@ -867,18 +875,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
867 public override bool IsThreaded { get { return false; } } 875 public override bool IsThreaded { get { return false; } }
868 876
869 #region Extensions 877 #region Extensions
870 // =============================================================
871 // Per scene functions. See below.
872
873 // Per avatar functions. See BSCharacter.
874
875 // Per prim functions. See BSPrim.
876 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
877 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
878 // =============================================================
879
880 public override object Extension(string pFunct, params object[] pParams) 878 public override object Extension(string pFunct, params object[] pParams)
881 { 879 {
880 DetailLog("{0} BSScene.Extension,op={1}", DetailLogZero, pFunct);
882 return base.Extension(pFunct, pParams); 881 return base.Extension(pFunct, pParams);
883 } 882 }
884 #endregion // Extensions 883 #endregion // Extensions
@@ -897,26 +896,37 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
897 // Calls to the PhysicsActors can't directly call into the physics engine 896 // Calls to the PhysicsActors can't directly call into the physics engine
898 // because it might be busy. We delay changes to a known time. 897 // because it might be busy. We delay changes to a known time.
899 // We rely on C#'s closure to save and restore the context for the delegate. 898 // We rely on C#'s closure to save and restore the context for the delegate.
900 public void TaintedObject(String ident, TaintCallback callback) 899 public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback)
901 { 900 {
902 if (!m_initialized) return; 901 TaintedObject(false /*inTaintTime*/, pOriginator, pIdent, pCallback);
903 902 }
904 lock (_taintLock) 903 public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback)
905 { 904 {
906 _taintOperations.Add(new TaintCallbackEntry(ident, callback)); 905 TaintedObject(false /*inTaintTime*/, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
907 } 906 }
908 907 public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
909 return; 908 {
909 TaintedObject(inTaintTime, BSScene.DetailLogZero, pIdent, pCallback);
910 }
911 public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
912 {
913 TaintedObject(inTaintTime, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
910 } 914 }
911
912 // Sometimes a potentially tainted operation can be used in and out of taint time. 915 // Sometimes a potentially tainted operation can be used in and out of taint time.
913 // This routine executes the command immediately if in taint-time otherwise it is queued. 916 // This routine executes the command immediately if in taint-time otherwise it is queued.
914 public void TaintedObject(bool inTaintTime, string ident, TaintCallback callback) 917 public void TaintedObject(bool inTaintTime, string pOriginator, string pIdent, TaintCallback pCallback)
915 { 918 {
919 if (!m_initialized) return;
920
916 if (inTaintTime) 921 if (inTaintTime)
917 callback(); 922 pCallback();
918 else 923 else
919 TaintedObject(ident, callback); 924 {
925 lock (_taintLock)
926 {
927 _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
928 }
929 }
920 } 930 }
921 931
922 private void TriggerPreStepEvent(float timeStep) 932 private void TriggerPreStepEvent(float timeStep)
@@ -960,7 +970,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
960 { 970 {
961 try 971 try
962 { 972 {
963 DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG 973 DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG
964 tcbe.callback(); 974 tcbe.callback();
965 } 975 }
966 catch (Exception e) 976 catch (Exception e)
@@ -977,10 +987,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
977 // will replace any previous operation by the same object. 987 // will replace any previous operation by the same object.
978 public void PostTaintObject(String ident, uint ID, TaintCallback callback) 988 public void PostTaintObject(String ident, uint ID, TaintCallback callback)
979 { 989 {
980 string uniqueIdent = ident + "-" + ID.ToString(); 990 string IDAsString = ID.ToString();
991 string uniqueIdent = ident + "-" + IDAsString;
981 lock (_taintLock) 992 lock (_taintLock)
982 { 993 {
983 _postTaintOperations[uniqueIdent] = new TaintCallbackEntry(uniqueIdent, callback); 994 _postTaintOperations[uniqueIdent] = new TaintCallbackEntry(IDAsString, uniqueIdent, callback);
984 } 995 }
985 996
986 return; 997 return;
@@ -1090,7 +1101,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1090 string xval = val; 1101 string xval = val;
1091 List<uint> xlIDs = lIDs; 1102 List<uint> xlIDs = lIDs;
1092 string xparm = parm; 1103 string xparm = parm;
1093 TaintedObject("BSScene.UpdateParameterSet", delegate() { 1104 TaintedObject(DetailLogZero, "BSScene.UpdateParameterSet", delegate() {
1094 BSParam.ParameterDefnBase thisParam; 1105 BSParam.ParameterDefnBase thisParam;
1095 if (BSParam.TryGetParameter(xparm, out thisParam)) 1106 if (BSParam.TryGetParameter(xparm, out thisParam))
1096 { 1107 {