aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules/BulletS
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs30
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs318
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs106
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs4
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs2
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSActors.cs0
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs141
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs323
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs0
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs10
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs4
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs1
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSParam.cs238
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs123
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs157
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs1
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs7
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/BSScene.cs329
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs7
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs10
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs24
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs1
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs10
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs0
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs112
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs6
-rw-r--r--OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs2
-rwxr-xr-xOpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs124
44 files changed, 1297 insertions, 795 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs b/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs
index c4a923c..840e453 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs
@@ -155,8 +155,8 @@ public BSAPIUnman(string paramName, BSScene physScene)
155 155
156// Initialization and simulation 156// Initialization and simulation
157public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, 157public override BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms,
158 int maxCollisions, ref CollisionDesc[] collisionArray, 158 int maxCollisions, ref CollisionDesc[] collisionArray,
159 int maxUpdates, ref EntityProperties[] updateArray 159 int maxUpdates, ref EntityProperties[] updateArray
160 ) 160 )
161{ 161{
162 // Pin down the memory that will be used to pass object collisions and updates back from unmanaged code 162 // Pin down the memory that will be used to pass object collisions and updates back from unmanaged code
@@ -1405,6 +1405,19 @@ public override float GetMargin(BulletShape shape)
1405} 1405}
1406 1406
1407// ===================================================================================== 1407// =====================================================================================
1408// Raycast
1409public override SweepHit ConvexSweepTest2(BulletWorld world, BulletBody sweepObject, Vector3 from, Vector3 to, float margin) {
1410 BulletWorldUnman worldu = world as BulletWorldUnman;
1411 BulletBodyUnman bodyu = sweepObject as BulletBodyUnman;
1412 return BSAPICPP.ConvexSweepTest2(worldu.ptr, bodyu.ptr, from, to, margin);
1413}
1414
1415public override RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask) {
1416 BulletWorldUnman worldu = world as BulletWorldUnman;
1417 return BSAPICPP.RayTest2(worldu.ptr, from, to, filterGroup, filterMask);
1418}
1419
1420// =====================================================================================
1408// Debugging 1421// Debugging
1409public override void DumpRigidBody(BulletWorld world, BulletBody collisionObject) 1422public override void DumpRigidBody(BulletWorld world, BulletBody collisionObject)
1410{ 1423{
@@ -1472,8 +1485,8 @@ public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg
1472// Initialization and simulation 1485// Initialization and simulation
1473[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1486[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1474public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, 1487public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
1475 int maxCollisions, IntPtr collisionArray, 1488 int maxCollisions, IntPtr collisionArray,
1476 int maxUpdates, IntPtr updateArray, 1489 int maxUpdates, IntPtr updateArray,
1477 DebugLogCallback logRoutine); 1490 DebugLogCallback logRoutine);
1478 1491
1479[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1492[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@@ -2084,6 +2097,15 @@ public static extern void SetMargin2(IntPtr shape, float val);
2084[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 2097[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
2085public static extern float GetMargin2(IntPtr shape); 2098public static extern float GetMargin2(IntPtr shape);
2086 2099
2100
2101// =====================================================================================
2102// Raycast
2103[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
2104public static extern SweepHit ConvexSweepTest2(IntPtr sim, IntPtr obj, Vector3 from, Vector3 to, float margin);
2105
2106[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
2107public static extern RaycastHit RayTest2(IntPtr sim, Vector3 from, Vector3 to, uint filterGroup, uint filterMask);
2108
2087// ===================================================================================== 2109// =====================================================================================
2088// Debugging 2110// Debugging
2089[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 2111[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs b/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs
index 887311d..7d58728 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs
@@ -815,161 +815,161 @@ private sealed class BulletConstraintXNA : BulletConstraint
815 public override bool SliderSetLimits(BulletConstraint pConstraint, int lowerUpper, int linAng, float val) 815 public override bool SliderSetLimits(BulletConstraint pConstraint, int lowerUpper, int linAng, float val)
816 { 816 {
817 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint; 817 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
818 switch (lowerUpper) 818 switch (lowerUpper)
819 { 819 {
820 case SLIDER_LOWER_LIMIT: 820 case SLIDER_LOWER_LIMIT:
821 switch (linAng) 821 switch (linAng)
822 { 822 {
823 case SLIDER_LINEAR: 823 case SLIDER_LINEAR:
824 constraint.SetLowerLinLimit(val); 824 constraint.SetLowerLinLimit(val);
825 break; 825 break;
826 case SLIDER_ANGULAR: 826 case SLIDER_ANGULAR:
827 constraint.SetLowerAngLimit(val); 827 constraint.SetLowerAngLimit(val);
828 break; 828 break;
829 } 829 }
830 break; 830 break;
831 case SLIDER_UPPER_LIMIT: 831 case SLIDER_UPPER_LIMIT:
832 switch (linAng) 832 switch (linAng)
833 { 833 {
834 case SLIDER_LINEAR: 834 case SLIDER_LINEAR:
835 constraint.SetUpperLinLimit(val); 835 constraint.SetUpperLinLimit(val);
836 break; 836 break;
837 case SLIDER_ANGULAR: 837 case SLIDER_ANGULAR:
838 constraint.SetUpperAngLimit(val); 838 constraint.SetUpperAngLimit(val);
839 break; 839 break;
840 } 840 }
841 break; 841 break;
842 } 842 }
843 return true; 843 return true;
844 } 844 }
845 public override bool SliderSet(BulletConstraint pConstraint, int softRestDamp, int dirLimOrtho, int linAng, float val) 845 public override bool SliderSet(BulletConstraint pConstraint, int softRestDamp, int dirLimOrtho, int linAng, float val)
846 { 846 {
847 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint; 847 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
848 switch (softRestDamp) 848 switch (softRestDamp)
849 { 849 {
850 case SLIDER_SET_SOFTNESS: 850 case SLIDER_SET_SOFTNESS:
851 switch (dirLimOrtho) 851 switch (dirLimOrtho)
852 { 852 {
853 case SLIDER_SET_DIRECTION: 853 case SLIDER_SET_DIRECTION:
854 switch (linAng) 854 switch (linAng)
855 { 855 {
856 case SLIDER_LINEAR: constraint.SetSoftnessDirLin(val); break; 856 case SLIDER_LINEAR: constraint.SetSoftnessDirLin(val); break;
857 case SLIDER_ANGULAR: constraint.SetSoftnessDirAng(val); break; 857 case SLIDER_ANGULAR: constraint.SetSoftnessDirAng(val); break;
858 } 858 }
859 break; 859 break;
860 case SLIDER_SET_LIMIT: 860 case SLIDER_SET_LIMIT:
861 switch (linAng) 861 switch (linAng)
862 { 862 {
863 case SLIDER_LINEAR: constraint.SetSoftnessLimLin(val); break; 863 case SLIDER_LINEAR: constraint.SetSoftnessLimLin(val); break;
864 case SLIDER_ANGULAR: constraint.SetSoftnessLimAng(val); break; 864 case SLIDER_ANGULAR: constraint.SetSoftnessLimAng(val); break;
865 } 865 }
866 break; 866 break;
867 case SLIDER_SET_ORTHO: 867 case SLIDER_SET_ORTHO:
868 switch (linAng) 868 switch (linAng)
869 { 869 {
870 case SLIDER_LINEAR: constraint.SetSoftnessOrthoLin(val); break; 870 case SLIDER_LINEAR: constraint.SetSoftnessOrthoLin(val); break;
871 case SLIDER_ANGULAR: constraint.SetSoftnessOrthoAng(val); break; 871 case SLIDER_ANGULAR: constraint.SetSoftnessOrthoAng(val); break;
872 } 872 }
873 break; 873 break;
874 } 874 }
875 break; 875 break;
876 case SLIDER_SET_RESTITUTION: 876 case SLIDER_SET_RESTITUTION:
877 switch (dirLimOrtho) 877 switch (dirLimOrtho)
878 { 878 {
879 case SLIDER_SET_DIRECTION: 879 case SLIDER_SET_DIRECTION:
880 switch (linAng) 880 switch (linAng)
881 { 881 {
882 case SLIDER_LINEAR: constraint.SetRestitutionDirLin(val); break; 882 case SLIDER_LINEAR: constraint.SetRestitutionDirLin(val); break;
883 case SLIDER_ANGULAR: constraint.SetRestitutionDirAng(val); break; 883 case SLIDER_ANGULAR: constraint.SetRestitutionDirAng(val); break;
884 } 884 }
885 break; 885 break;
886 case SLIDER_SET_LIMIT: 886 case SLIDER_SET_LIMIT:
887 switch (linAng) 887 switch (linAng)
888 { 888 {
889 case SLIDER_LINEAR: constraint.SetRestitutionLimLin(val); break; 889 case SLIDER_LINEAR: constraint.SetRestitutionLimLin(val); break;
890 case SLIDER_ANGULAR: constraint.SetRestitutionLimAng(val); break; 890 case SLIDER_ANGULAR: constraint.SetRestitutionLimAng(val); break;
891 } 891 }
892 break; 892 break;
893 case SLIDER_SET_ORTHO: 893 case SLIDER_SET_ORTHO:
894 switch (linAng) 894 switch (linAng)
895 { 895 {
896 case SLIDER_LINEAR: constraint.SetRestitutionOrthoLin(val); break; 896 case SLIDER_LINEAR: constraint.SetRestitutionOrthoLin(val); break;
897 case SLIDER_ANGULAR: constraint.SetRestitutionOrthoAng(val); break; 897 case SLIDER_ANGULAR: constraint.SetRestitutionOrthoAng(val); break;
898 } 898 }
899 break; 899 break;
900 } 900 }
901 break; 901 break;
902 case SLIDER_SET_DAMPING: 902 case SLIDER_SET_DAMPING:
903 switch (dirLimOrtho) 903 switch (dirLimOrtho)
904 { 904 {
905 case SLIDER_SET_DIRECTION: 905 case SLIDER_SET_DIRECTION:
906 switch (linAng) 906 switch (linAng)
907 { 907 {
908 case SLIDER_LINEAR: constraint.SetDampingDirLin(val); break; 908 case SLIDER_LINEAR: constraint.SetDampingDirLin(val); break;
909 case SLIDER_ANGULAR: constraint.SetDampingDirAng(val); break; 909 case SLIDER_ANGULAR: constraint.SetDampingDirAng(val); break;
910 } 910 }
911 break; 911 break;
912 case SLIDER_SET_LIMIT: 912 case SLIDER_SET_LIMIT:
913 switch (linAng) 913 switch (linAng)
914 { 914 {
915 case SLIDER_LINEAR: constraint.SetDampingLimLin(val); break; 915 case SLIDER_LINEAR: constraint.SetDampingLimLin(val); break;
916 case SLIDER_ANGULAR: constraint.SetDampingLimAng(val); break; 916 case SLIDER_ANGULAR: constraint.SetDampingLimAng(val); break;
917 } 917 }
918 break; 918 break;
919 case SLIDER_SET_ORTHO: 919 case SLIDER_SET_ORTHO:
920 switch (linAng) 920 switch (linAng)
921 { 921 {
922 case SLIDER_LINEAR: constraint.SetDampingOrthoLin(val); break; 922 case SLIDER_LINEAR: constraint.SetDampingOrthoLin(val); break;
923 case SLIDER_ANGULAR: constraint.SetDampingOrthoAng(val); break; 923 case SLIDER_ANGULAR: constraint.SetDampingOrthoAng(val); break;
924 } 924 }
925 break; 925 break;
926 } 926 }
927 break; 927 break;
928 } 928 }
929 return true; 929 return true;
930 } 930 }
931 public override bool SliderMotorEnable(BulletConstraint pConstraint, int linAng, float numericTrueFalse) 931 public override bool SliderMotorEnable(BulletConstraint pConstraint, int linAng, float numericTrueFalse)
932 { 932 {
933 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint; 933 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
934 switch (linAng) 934 switch (linAng)
935 { 935 {
936 case SLIDER_LINEAR: 936 case SLIDER_LINEAR:
937 constraint.SetPoweredLinMotor(numericTrueFalse == 0.0 ? false : true); 937 constraint.SetPoweredLinMotor(numericTrueFalse == 0.0 ? false : true);
938 break; 938 break;
939 case SLIDER_ANGULAR: 939 case SLIDER_ANGULAR:
940 constraint.SetPoweredAngMotor(numericTrueFalse == 0.0 ? false : true); 940 constraint.SetPoweredAngMotor(numericTrueFalse == 0.0 ? false : true);
941 break; 941 break;
942 } 942 }
943 return true; 943 return true;
944 } 944 }
945 public override bool SliderMotor(BulletConstraint pConstraint, int forceVel, int linAng, float val) 945 public override bool SliderMotor(BulletConstraint pConstraint, int forceVel, int linAng, float val)
946 { 946 {
947 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint; 947 SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
948 switch (forceVel) 948 switch (forceVel)
949 { 949 {
950 case SLIDER_MOTOR_VELOCITY: 950 case SLIDER_MOTOR_VELOCITY:
951 switch (linAng) 951 switch (linAng)
952 { 952 {
953 case SLIDER_LINEAR: 953 case SLIDER_LINEAR:
954 constraint.SetTargetLinMotorVelocity(val); 954 constraint.SetTargetLinMotorVelocity(val);
955 break; 955 break;
956 case SLIDER_ANGULAR: 956 case SLIDER_ANGULAR:
957 constraint.SetTargetAngMotorVelocity(val); 957 constraint.SetTargetAngMotorVelocity(val);
958 break; 958 break;
959 } 959 }
960 break; 960 break;
961 case SLIDER_MAX_MOTOR_FORCE: 961 case SLIDER_MAX_MOTOR_FORCE:
962 switch (linAng) 962 switch (linAng)
963 { 963 {
964 case SLIDER_LINEAR: 964 case SLIDER_LINEAR:
965 constraint.SetMaxLinMotorForce(val); 965 constraint.SetMaxLinMotorForce(val);
966 break; 966 break;
967 case SLIDER_ANGULAR: 967 case SLIDER_ANGULAR:
968 constraint.SetMaxAngMotorForce(val); 968 constraint.SetMaxAngMotorForce(val);
969 break; 969 break;
970 } 970 }
971 break; 971 break;
972 } 972 }
973 return true; 973 return true;
974 } 974 }
975 975
@@ -1197,20 +1197,20 @@ private sealed class BulletConstraintXNA : BulletConstraint
1197 }; 1197 };
1198 /* 1198 /*
1199 m_mass = mass; 1199 m_mass = mass;
1200 m_motionState =motionState; 1200 m_motionState =motionState;
1201 m_collisionShape = collisionShape; 1201 m_collisionShape = collisionShape;
1202 m_localInertia = localInertia; 1202 m_localInertia = localInertia;
1203 m_linearDamping = 0f; 1203 m_linearDamping = 0f;
1204 m_angularDamping = 0f; 1204 m_angularDamping = 0f;
1205 m_friction = 0.5f; 1205 m_friction = 0.5f;
1206 m_restitution = 0f; 1206 m_restitution = 0f;
1207 m_linearSleepingThreshold = 0.8f; 1207 m_linearSleepingThreshold = 0.8f;
1208 m_angularSleepingThreshold = 1f; 1208 m_angularSleepingThreshold = 1f;
1209 m_additionalDamping = false; 1209 m_additionalDamping = false;
1210 m_additionalDampingFactor = 0.005f; 1210 m_additionalDampingFactor = 0.005f;
1211 m_additionalLinearDampingThresholdSqr = 0.01f; 1211 m_additionalLinearDampingThresholdSqr = 0.01f;
1212 m_additionalAngularDampingThresholdSqr = 0.01f; 1212 m_additionalAngularDampingThresholdSqr = 0.01f;
1213 m_additionalAngularDampingFactor = 0.01f; 1213 m_additionalAngularDampingFactor = 0.01f;
1214 m_startWorldTransform = IndexedMatrix.Identity; 1214 m_startWorldTransform = IndexedMatrix.Identity;
1215 */ 1215 */
1216 body.SetUserPointer(pLocalID); 1216 body.SetUserPointer(pLocalID);
@@ -2172,7 +2172,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
2172 } 2172 }
2173 2173
2174 public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, 2174 public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
2175 float scaleFactor, float collisionMargin) 2175 float scaleFactor, float collisionMargin)
2176 { 2176 {
2177 const int upAxis = 2; 2177 const int upAxis = 2;
2178 HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)size.X, (int)size.Y, 2178 HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)size.X, (int)size.Y,
@@ -2459,6 +2459,14 @@ private sealed class BulletConstraintXNA : BulletConstraint
2459 } 2459 }
2460 return false; 2460 return false;
2461 } 2461 }
2462
2463 public override SweepHit ConvexSweepTest2(BulletWorld world, BulletBody obj, Vector3 from, Vector3 to, float margin) {
2464 return new SweepHit();
2465 }
2466
2467 public override RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask) {
2468 return new RaycastHit();
2469 }
2462} 2470}
2463 2471
2464 2472
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs
index 0191893..40c6b98 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs
@@ -47,10 +47,9 @@ public class BSActorAvatarMove : BSActor
47 // The amount the step up is applying. Used to smooth stair walking. 47 // The amount the step up is applying. Used to smooth stair walking.
48 float m_lastStepUp; 48 float m_lastStepUp;
49 49
50 // Jumping happens over several frames. If use applies up force while colliding, start the 50 // There are times the velocity is set but we don't want to inforce stationary until the
51 // jump and allow the jump to continue for this number of frames. 51 // real velocity drops.
52 int m_jumpFrames = 0; 52 bool m_waitingForLowVelocityForStationary = false;
53 float m_jumpVelocity = 0f;
54 53
55 public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) 54 public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName)
56 : base(physicsScene, pObj, actorName) 55 : base(physicsScene, pObj, actorName)
@@ -109,19 +108,23 @@ public class BSActorAvatarMove : BSActor
109 { 108 {
110 if (m_velocityMotor != null) 109 if (m_velocityMotor != null)
111 { 110 {
112// if (targ == OMV.Vector3.Zero)
113// Util.PrintCallStack();
114//
115// Console.WriteLine("SetVelocityAndTarget, {0} {1}", vel, targ);
116 m_velocityMotor.Reset(); 111 m_velocityMotor.Reset();
117 m_velocityMotor.SetTarget(targ); 112 m_velocityMotor.SetTarget(targ);
118 m_velocityMotor.SetCurrent(vel); 113 m_velocityMotor.SetCurrent(vel);
119 m_velocityMotor.Enabled = true; 114 m_velocityMotor.Enabled = true;
115 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}",
116 m_controllingPrim.LocalID, vel, targ);
117 m_waitingForLowVelocityForStationary = false;
120 } 118 }
121 }); 119 });
122 } 120 }
123 121
124 // If a hover motor has not been created, create one and start the hovering. 122 public void SuppressStationayCheckUntilLowVelocity()
123 {
124 m_waitingForLowVelocityForStationary = true;
125 }
126
127 // If a movement motor has not been created, create one and start the movement
125 private void ActivateAvatarMove() 128 private void ActivateAvatarMove()
126 { 129 {
127 if (m_velocityMotor == null) 130 if (m_velocityMotor == null)
@@ -133,13 +136,14 @@ public class BSActorAvatarMove : BSActor
133 1f // efficiency 136 1f // efficiency
134 ); 137 );
135 m_velocityMotor.ErrorZeroThreshold = BSParam.AvatarStopZeroThreshold; 138 m_velocityMotor.ErrorZeroThreshold = BSParam.AvatarStopZeroThreshold;
136 // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. 139 // m_velocityMotor.PhysicsScene = m_controllingPrim.PhysScene; // DEBUG DEBUG so motor will output detail log messages.
137 SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); 140 SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
138 141
139 m_physicsScene.BeforeStep += Mover; 142 m_physicsScene.BeforeStep += Mover;
140 m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty; 143 m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty;
141 144
142 m_walkingUpStairs = 0; 145 m_walkingUpStairs = 0;
146 m_waitingForLowVelocityForStationary = false;
143 } 147 }
144 } 148 }
145 149
@@ -153,7 +157,7 @@ public class BSActorAvatarMove : BSActor
153 } 157 }
154 } 158 }
155 159
156 // Called just before the simulation step. Update the vertical position for hoverness. 160 // Called just before the simulation step.
157 private void Mover(float timeStep) 161 private void Mover(float timeStep)
158 { 162 {
159 // Don't do movement while the object is selected. 163 // Don't do movement while the object is selected.
@@ -187,12 +191,28 @@ public class BSActorAvatarMove : BSActor
187 191
188 if (m_controllingPrim.IsColliding) 192 if (m_controllingPrim.IsColliding)
189 { 193 {
190 // If we are colliding with a stationary object, presume we're standing and don't move around 194 // if colliding with something stationary and we're not doing volume detect .
191 if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect) 195 if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect)
192 { 196 {
193 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); 197 if (m_waitingForLowVelocityForStationary)
194 m_controllingPrim.IsStationary = true; 198 {
195 m_controllingPrim.ZeroMotion(true /* inTaintTime */); 199 // if waiting for velocity to drop and it has finally dropped, we can be stationary
200 if (m_controllingPrim.RawVelocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared)
201 {
202 m_waitingForLowVelocityForStationary = false;
203 }
204 }
205 if (!m_waitingForLowVelocityForStationary)
206 {
207 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
208 m_controllingPrim.IsStationary = true;
209 m_controllingPrim.ZeroMotion(true /* inTaintTime */);
210 }
211 else
212 {
213 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,waitingForLowVel,rawvel={1}",
214 m_controllingPrim.LocalID, m_controllingPrim.RawVelocity.Length());
215 }
196 } 216 }
197 217
198 // Standing has more friction on the ground 218 // Standing has more friction on the ground
@@ -222,8 +242,8 @@ public class BSActorAvatarMove : BSActor
222 } 242 }
223 } 243 }
224 244
225 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", 245 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2},isStationary={3}",
226 m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding); 246 m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding,m_controllingPrim.IsStationary);
227 } 247 }
228 else 248 else
229 { 249 {
@@ -237,50 +257,24 @@ public class BSActorAvatarMove : BSActor
237 m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction); 257 m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
238 } 258 }
239 259
240 if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding) 260 // 'm_velocityMotor is used for walking, flying, and jumping and will thus have the correct values
241 { 261 // for Z. But in come cases it must be over-ridden. Like when falling or jumping.
242 stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
243 }
244 262
245 // Colliding and not flying with an upward force. The avatar must be trying to jump. 263 float realVelocityZ = m_controllingPrim.RawVelocity.Z;
246 if (!m_controllingPrim.Flying && m_controllingPrim.IsColliding && stepVelocity.Z > 0)
247 {
248 // We allow the upward force to happen for this many frames.
249 m_jumpFrames = BSParam.AvatarJumpFrames;
250 m_jumpVelocity = stepVelocity.Z;
251 }
252 264
253 // The case where the avatar is not colliding and is not flying is special. 265 // If not flying and falling, we over-ride the stepping motor so we can fall to the ground
254 // The avatar is either falling or jumping and the user can be applying force to the avatar 266 if (!m_controllingPrim.Flying && realVelocityZ < 0)
255 // (force in some direction or force up or down).
256 // If the avatar has negative Z velocity and is not colliding, presume we're falling and keep the velocity.
257 // If the user is trying to apply upward force but we're not colliding, assume the avatar
258 // is trying to jump and don't apply the upward force if not touching the ground any more.
259 if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
260 { 267 {
261 // If upward velocity is being applied, this must be a jump and only allow that to go on so long 268 // Can't fall faster than this
262 if (m_jumpFrames > 0) 269 if (realVelocityZ < BSParam.AvatarTerminalVelocity)
263 { 270 {
264 // Since not touching the ground, only apply upward force for so long. 271 realVelocityZ = BSParam.AvatarTerminalVelocity;
265 m_jumpFrames--;
266 stepVelocity.Z = m_jumpVelocity;
267 } 272 }
268 else 273
269 { 274 stepVelocity.Z = realVelocityZ;
270
271 // Since we're not affected by anything, the avatar must be falling and we do not want that to be too fast.
272 if (m_controllingPrim.RawVelocity.Z < BSParam.AvatarTerminalVelocity)
273 {
274
275 stepVelocity.Z = BSParam.AvatarTerminalVelocity;
276 }
277 else
278 {
279 stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
280 }
281 }
282 // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
283 } 275 }
276 // m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,DEBUG,motorCurrent={1},realZ={2},flying={3},collid={4},jFrames={5}",
277 // m_controllingPrim.LocalID, m_velocityMotor.CurrentValue, realVelocityZ, m_controllingPrim.Flying, m_controllingPrim.IsColliding, m_jumpFrames);
284 278
285 //Alicia: Maintain minimum height when flying. 279 //Alicia: Maintain minimum height when flying.
286 // SL has a flying effect that keeps the avatar flying above the ground by some margin 280 // SL has a flying effect that keeps the avatar flying above the ground by some margin
@@ -291,6 +285,8 @@ public class BSActorAvatarMove : BSActor
291 285
292 if( m_controllingPrim.Position.Z < hover_height) 286 if( m_controllingPrim.Position.Z < hover_height)
293 { 287 {
288 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,addingUpforceForGroundMargin,height={1},hoverHeight={2}",
289 m_controllingPrim.LocalID, m_controllingPrim.Position.Z, hover_height);
294 stepVelocity.Z += BSParam.AvatarFlyingGroundUpForce; 290 stepVelocity.Z += BSParam.AvatarFlyingGroundUpForce;
295 } 291 }
296 } 292 }
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs
index 7ff171e..7ff171e 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorHover.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs
index 78c1b6a..78c1b6a 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorLockAxis.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs
index 3db8f2c..f2019ae 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorMoveToTarget.cs
@@ -205,13 +205,13 @@ public class BSActorMoveToTarget : BSActor
205 addedForce = correctionVector / timeStep; 205 addedForce = correctionVector / timeStep;
206 // Remove the existing velocity (only the moveToTarget force counts) 206 // Remove the existing velocity (only the moveToTarget force counts)
207 addedForce -= m_controllingPrim.RawVelocity; 207 addedForce -= m_controllingPrim.RawVelocity;
208 // Overcome gravity. 208 // Overcome gravity.
209 addedForce -= m_controllingPrim.Gravity; 209 addedForce -= m_controllingPrim.Gravity;
210 210
211 // Add enough force to overcome the mass of the object 211 // Add enough force to overcome the mass of the object
212 addedForce *= m_controllingPrim.Mass; 212 addedForce *= m_controllingPrim.Mass;
213 213
214 m_controllingPrim.AddForce(addedForce, false /* pushForce */, true /* inTaintTime */); 214 m_controllingPrim.AddForce(true /* inTaintTime */, addedForce);
215 } 215 }
216 m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover3,move,fromPos={1},addedForce={2}", 216 m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover3,move,fromPos={1},addedForce={2}",
217 m_controllingPrim.LocalID, origPosition, addedForce); 217 m_controllingPrim.LocalID, origPosition, addedForce);
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs
index ecb4b7f..ecb4b7f 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorSetForce.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs
index a1cf4db..0261bcb 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorSetTorque.cs
@@ -127,7 +127,7 @@ public class BSActorSetTorque : BSActor
127 m_physicsScene.DetailLog("{0},BSActorSetTorque,preStep,force={1}", m_controllingPrim.LocalID, m_controllingPrim.RawTorque); 127 m_physicsScene.DetailLog("{0},BSActorSetTorque,preStep,force={1}", m_controllingPrim.LocalID, m_controllingPrim.RawTorque);
128 if (m_controllingPrim.PhysBody.HasPhysicalBody) 128 if (m_controllingPrim.PhysBody.HasPhysicalBody)
129 { 129 {
130 m_controllingPrim.AddAngularForce(m_controllingPrim.RawTorque, false, true); 130 m_controllingPrim.AddAngularForce(true /* inTaintTime */, m_controllingPrim.RawTorque);
131 m_controllingPrim.ActivateIfPhysical(false); 131 m_controllingPrim.ActivateIfPhysical(false);
132 } 132 }
133 133
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActors.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActors.cs
index 851347b..851347b 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSActors.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSActors.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs
index 7756b10..a288048 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs
@@ -36,16 +36,16 @@ namespace OpenSim.Region.PhysicsModule.BulletS {
36 // Constraint type values as defined by Bullet 36 // Constraint type values as defined by Bullet
37public enum ConstraintType : int 37public enum ConstraintType : int
38{ 38{
39 POINT2POINT_CONSTRAINT_TYPE = 3, 39 POINT2POINT_CONSTRAINT_TYPE = 3,
40 HINGE_CONSTRAINT_TYPE, 40 HINGE_CONSTRAINT_TYPE,
41 CONETWIST_CONSTRAINT_TYPE, 41 CONETWIST_CONSTRAINT_TYPE,
42 D6_CONSTRAINT_TYPE, 42 D6_CONSTRAINT_TYPE,
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 GEAR_CONSTRAINT_TYPE, // added in Bullet 2.82 46 GEAR_CONSTRAINT_TYPE, // added in Bullet 2.82
47 FIXED_CONSTRAINT_TYPE, // added in Bullet 2.82 47 FIXED_CONSTRAINT_TYPE, // added in Bullet 2.82
48 MAX_CONSTRAINT_TYPE, // last type defined by Bullet 48 MAX_CONSTRAINT_TYPE, // last type defined by Bullet
49 // 49 //
50 BS_FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving 50 BS_FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving
51} 51}
@@ -54,25 +54,25 @@ public enum ConstraintType : int
54[StructLayout(LayoutKind.Sequential)] 54[StructLayout(LayoutKind.Sequential)]
55public struct ConvexHull 55public struct ConvexHull
56{ 56{
57 Vector3 Offset; 57 Vector3 Offset;
58 int VertexCount; 58 int VertexCount;
59 Vector3[] Vertices; 59 Vector3[] Vertices;
60} 60}
61public enum BSPhysicsShapeType 61public enum BSPhysicsShapeType
62{ 62{
63 SHAPE_UNKNOWN = 0, 63 SHAPE_UNKNOWN = 0,
64 SHAPE_CAPSULE = 1, 64 SHAPE_CAPSULE = 1,
65 SHAPE_BOX = 2, 65 SHAPE_BOX = 2,
66 SHAPE_CONE = 3, 66 SHAPE_CONE = 3,
67 SHAPE_CYLINDER = 4, 67 SHAPE_CYLINDER = 4,
68 SHAPE_SPHERE = 5, 68 SHAPE_SPHERE = 5,
69 SHAPE_MESH = 6, 69 SHAPE_MESH = 6,
70 SHAPE_HULL = 7, 70 SHAPE_HULL = 7,
71 // following defined by BulletSim 71 // following defined by BulletSim
72 SHAPE_GROUNDPLANE = 20, 72 SHAPE_GROUNDPLANE = 20,
73 SHAPE_TERRAIN = 21, 73 SHAPE_TERRAIN = 21,
74 SHAPE_COMPOUND = 22, 74 SHAPE_COMPOUND = 22,
75 SHAPE_HEIGHTMAP = 23, 75 SHAPE_HEIGHTMAP = 23,
76 SHAPE_AVATAR = 24, 76 SHAPE_AVATAR = 24,
77 SHAPE_CONVEXHULL= 25, 77 SHAPE_CONVEXHULL= 25,
78 SHAPE_GIMPACT = 26, 78 SHAPE_GIMPACT = 26,
@@ -121,6 +121,14 @@ public struct SweepHit
121 public float Fraction; 121 public float Fraction;
122 public Vector3 Normal; 122 public Vector3 Normal;
123 public Vector3 Point; 123 public Vector3 Point;
124
125 public bool hasHit()
126 {
127 float sum = Fraction
128 + Normal.X + Normal.Y + Normal.Z
129 + Point.X + Point.Y + Point.Z;
130 return (sum != 0) || (ID != 0);
131 }
124} 132}
125[StructLayout(LayoutKind.Sequential)] 133[StructLayout(LayoutKind.Sequential)]
126public struct RaycastHit 134public struct RaycastHit
@@ -128,6 +136,13 @@ public struct RaycastHit
128 public UInt32 ID; 136 public UInt32 ID;
129 public float Fraction; 137 public float Fraction;
130 public Vector3 Normal; 138 public Vector3 Normal;
139 public Vector3 Point;
140
141 public bool hasHit()
142 {
143 float sum = Normal.X + Normal.Y + Normal.Z + Point.X + Point.Y + Point.Z;
144 return (sum != 0);
145 }
131} 146}
132[StructLayout(LayoutKind.Sequential)] 147[StructLayout(LayoutKind.Sequential)]
133public struct CollisionDesc 148public struct CollisionDesc
@@ -180,16 +195,16 @@ public struct ConfigurationParameters
180 public float collisionMargin; 195 public float collisionMargin;
181 public float gravity; 196 public float gravity;
182 197
183 public float maxPersistantManifoldPoolSize; 198 public float maxPersistantManifoldPoolSize;
184 public float maxCollisionAlgorithmPoolSize; 199 public float maxCollisionAlgorithmPoolSize;
185 public float shouldDisableContactPoolDynamicAllocation; 200 public float shouldDisableContactPoolDynamicAllocation;
186 public float shouldForceUpdateAllAabbs; 201 public float shouldForceUpdateAllAabbs;
187 public float shouldRandomizeSolverOrder; 202 public float shouldRandomizeSolverOrder;
188 public float shouldSplitSimulationIslands; 203 public float shouldSplitSimulationIslands;
189 public float shouldEnableFrictionCaching; 204 public float shouldEnableFrictionCaching;
190 public float numberOfSolverIterations; 205 public float numberOfSolverIterations;
191 public float useSingleSidedMeshes; 206 public float useSingleSidedMeshes;
192 public float globalContactBreakingThreshold; 207 public float globalContactBreakingThreshold;
193 208
194 public float physicsLoggingFrames; 209 public float physicsLoggingFrames;
195 210
@@ -202,30 +217,30 @@ public struct ConfigurationParameters
202public struct HACDParams 217public struct HACDParams
203{ 218{
204 // usual default values 219 // usual default values
205 public float maxVerticesPerHull; // 100 220 public float maxVerticesPerHull; // 100
206 public float minClusters; // 2 221 public float minClusters; // 2
207 public float compacityWeight; // 0.1 222 public float compacityWeight; // 0.1
208 public float volumeWeight; // 0.0 223 public float volumeWeight; // 0.0
209 public float concavity; // 100 224 public float concavity; // 100
210 public float addExtraDistPoints; // false 225 public float addExtraDistPoints; // false
211 public float addNeighboursDistPoints; // false 226 public float addNeighboursDistPoints; // false
212 public float addFacesPoints; // false 227 public float addFacesPoints; // false
213 public float shouldAdjustCollisionMargin; // false 228 public float shouldAdjustCollisionMargin; // false
214 // VHACD 229 // VHACD
215 public float whichHACD; // zero if Bullet HACD, non-zero says VHACD 230 public float whichHACD; // zero if Bullet HACD, non-zero says VHACD
216 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html 231 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html
217 public float vHACDresolution; // 100,000 max number of voxels generated during voxelization stage 232 public float vHACDresolution; // 100,000 max number of voxels generated during voxelization stage
218 public float vHACDdepth; // 20 max number of clipping stages 233 public float vHACDdepth; // 20 max number of clipping stages
219 public float vHACDconcavity; // 0.0025 maximum concavity 234 public float vHACDconcavity; // 0.0025 maximum concavity
220 public float vHACDplaneDownsampling; // 4 granularity of search for best clipping plane 235 public float vHACDplaneDownsampling; // 4 granularity of search for best clipping plane
221 public float vHACDconvexHullDownsampling; // 4 precision of hull gen process 236 public float vHACDconvexHullDownsampling; // 4 precision of hull gen process
222 public float vHACDalpha; // 0.05 bias toward clipping along symmetry planes 237 public float vHACDalpha; // 0.05 bias toward clipping along symmetry planes
223 public float vHACDbeta; // 0.05 bias toward clipping along revolution axis 238 public float vHACDbeta; // 0.05 bias toward clipping along revolution axis
224 public float vHACDgamma; // 0.00125 max concavity when merging 239 public float vHACDgamma; // 0.00125 max concavity when merging
225 public float vHACDpca; // 0 on/off normalizing mesh before decomp 240 public float vHACDpca; // 0 on/off normalizing mesh before decomp
226 public float vHACDmode; // 0 0:voxel based, 1: tetrahedron based 241 public float vHACDmode; // 0 0:voxel based, 1: tetrahedron based
227 public float vHACDmaxNumVerticesPerCH; // 64 max triangles per convex hull 242 public float vHACDmaxNumVerticesPerCH; // 64 max triangles per convex hull
228 public float vHACDminVolumePerCH; // 0.0001 sampling of generated convex hulls 243 public float vHACDminVolumePerCH; // 0.0001 sampling of generated convex hulls
229} 244}
230 245
231// The states a bullet collision object can have 246// The states a bullet collision object can have
@@ -322,8 +337,8 @@ public abstract string BulletEngineVersion { get; protected set;}
322 337
323// Initialization and simulation 338// Initialization and simulation
324public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms, 339public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms,
325 int maxCollisions, ref CollisionDesc[] collisionArray, 340 int maxCollisions, ref CollisionDesc[] collisionArray,
326 int maxUpdates, ref EntityProperties[] updateArray 341 int maxUpdates, ref EntityProperties[] updateArray
327 ); 342 );
328 343
329public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, 344public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep,
@@ -398,7 +413,7 @@ public abstract void DestroyObject(BulletWorld sim, BulletBody obj);
398public abstract BulletShape CreateGroundPlaneShape(UInt32 id, float height, float collisionMargin); 413public abstract BulletShape CreateGroundPlaneShape(UInt32 id, float height, float collisionMargin);
399 414
400public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, 415public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
401 float scaleFactor, float collisionMargin); 416 float scaleFactor, float collisionMargin);
402 417
403// ===================================================================================== 418// =====================================================================================
404// Constraint creation and helper routines 419// Constraint creation and helper routines
@@ -742,6 +757,12 @@ public abstract void SetMargin(BulletShape shape, float val);
742public abstract float GetMargin(BulletShape shape); 757public abstract float GetMargin(BulletShape shape);
743 758
744// ===================================================================================== 759// =====================================================================================
760// Raycast
761public abstract SweepHit ConvexSweepTest2(BulletWorld world, BulletBody obj, Vector3 from, Vector3 to, float margin);
762
763public abstract RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask);
764
765// =====================================================================================
745// Debugging 766// Debugging
746public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) { } 767public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) { }
747 768
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
index 83fc3a6..d182c34 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
@@ -40,7 +40,6 @@ public sealed class BSCharacter : BSPhysObject
40 private static readonly string LogHeader = "[BULLETS CHAR]"; 40 private static readonly string LogHeader = "[BULLETS CHAR]";
41 41
42 // private bool _stopped; 42 // private bool _stopped;
43 private OMV.Vector3 _size;
44 private bool _grabbed; 43 private bool _grabbed;
45 private bool _selected; 44 private bool _selected;
46 private float _mass; 45 private float _mass;
@@ -53,19 +52,21 @@ public sealed class BSCharacter : BSPhysObject
53 private bool _setAlwaysRun; 52 private bool _setAlwaysRun;
54 private bool _throttleUpdates; 53 private bool _throttleUpdates;
55 private bool _floatOnWater; 54 private bool _floatOnWater;
56 private OMV.Vector3 _rotationalVelocity;
57 private bool _kinematic; 55 private bool _kinematic;
58 private float _buoyancy; 56 private float _buoyancy;
59 57
58 private OMV.Vector3 _size;
59 private float _footOffset;
60
60 private BSActorAvatarMove m_moveActor; 61 private BSActorAvatarMove m_moveActor;
61 private const string AvatarMoveActorName = "BSCharacter.AvatarMove"; 62 private const string AvatarMoveActorName = "BSCharacter.AvatarMove";
62 63
63 private OMV.Vector3 _PIDTarget; 64 private OMV.Vector3 _PIDTarget;
64 private float _PIDTau; 65 private float _PIDTau;
65 66
66// public override OMV.Vector3 RawVelocity 67// public override OMV.Vector3 RawVelocity
67// { get { return base.RawVelocity; } 68// { get { return base.RawVelocity; }
68// set { 69// set {
69// if (value != base.RawVelocity) 70// if (value != base.RawVelocity)
70// Util.PrintCallStack(); 71// Util.PrintCallStack();
71// Console.WriteLine("Set rawvel to {0}", value); 72// Console.WriteLine("Set rawvel to {0}", value);
@@ -76,12 +77,12 @@ public sealed class BSCharacter : BSPhysObject
76 public override bool IsIncomplete { get { return false; } } 77 public override bool IsIncomplete { get { return false; } }
77 78
78 public BSCharacter( 79 public BSCharacter(
79 uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, bool isFlying) 80 uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, float footOffset, bool isFlying)
80 81
81 : base(parent_scene, localID, avName, "BSCharacter") 82 : base(parent_scene, localID, avName, "BSCharacter")
82 { 83 {
83 _physicsActorType = (int)ActorTypes.Agent; 84 _physicsActorType = (int)ActorTypes.Agent;
84 RawPosition = pos; 85 RawPosition = pos;
85 86
86 _flying = isFlying; 87 _flying = isFlying;
87 RawOrientation = OMV.Quaternion.Identity; 88 RawOrientation = OMV.Quaternion.Identity;
@@ -89,22 +90,15 @@ public sealed class BSCharacter : BSPhysObject
89 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 90 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
90 Friction = BSParam.AvatarStandingFriction; 91 Friction = BSParam.AvatarStandingFriction;
91 Density = BSParam.AvatarDensity; 92 Density = BSParam.AvatarDensity;
93 _isPhysical = true;
92 94
93 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 95 // Adjustments for zero X and Y made in Size()
94 // replace with the default values. 96 // This also computes avatar scale, volume, and mass
95 _size = size; 97 SetAvatarSize(size, footOffset, true /* initializing */);
96 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
97 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;
98
99 // The dimensions of the physical capsule are kept in the scale.
100 // Physics creates a unit capsule which is scaled by the physics engine.
101 Scale = ComputeAvatarScale(_size);
102 // set _avatarVolume and _mass based on capsule size, _density and Scale
103 ComputeAvatarVolumeAndMass();
104 98
105 DetailLog( 99 DetailLog(
106 "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}", 100 "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}",
107 LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos, vel); 101 LocalID, Size, Scale, Density, _avatarVolume, RawMass, pos, vel);
108 102
109 // do actual creation in taint time 103 // do actual creation in taint time
110 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate() 104 PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
@@ -208,45 +202,68 @@ public sealed class BSCharacter : BSPhysObject
208 public override OMV.Vector3 Size { 202 public override OMV.Vector3 Size {
209 get 203 get
210 { 204 {
211 // Avatar capsule size is kept in the scale parameter.
212 return _size; 205 return _size;
213 } 206 }
214 207
215 set { 208 set {
216 // This is how much the avatar size is changing. Positive means getting bigger. 209 setAvatarSize(value, _footOffset);
217 // The avatar altitude must be adjusted for this change. 210 }
218 float heightChange = value.Z - _size.Z; 211 }
212
213 // OpenSim 0.9 introduces a common avatar size computation
214 public override void setAvatarSize(OMV.Vector3 size, float feetOffset)
215 {
216 SetAvatarSize(size, feetOffset, false /* initializing */);
217 }
219 218
220 _size = value; 219 // Internal version that, if initializing, doesn't do all the updating of the physics engine
220 public void SetAvatarSize(OMV.Vector3 size, float feetOffset, bool initializing)
221 {
222 OMV.Vector3 newSize = size;
223 if (newSize.IsFinite())
224 {
221 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 225 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
222 // replace with the default values. 226 // replace with the default values.
223 if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; 227 if (newSize.X == 0f) newSize.X = BSParam.AvatarCapsuleDepth;
224 if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; 228 if (newSize.Y == 0f) newSize.Y = BSParam.AvatarCapsuleWidth;
225 229
226 Scale = ComputeAvatarScale(_size); 230 if (newSize.X < 0.01f) newSize.X = 0.01f;
227 ComputeAvatarVolumeAndMass(); 231 if (newSize.Y < 0.01f) newSize.Y = 0.01f;
228 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", 232 if (newSize.Z < 0.01f) newSize.Z = BSParam.AvatarCapsuleHeight;
229 LocalID, _size, Scale, Density, _avatarVolume, RawMass); 233 }
234 else
235 {
236 newSize = new OMV.Vector3(BSParam.AvatarCapsuleDepth, BSParam.AvatarCapsuleWidth, BSParam.AvatarCapsuleHeight);
237 }
230 238
231 PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate() 239 // This is how much the avatar size is changing. Positive means getting bigger.
232 { 240 // The avatar altitude must be adjusted for this change.
233 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape) 241 float heightChange = newSize.Z - Size.Z;
234 {
235 PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
236 UpdatePhysicalMassProperties(RawMass, true);
237 242
238 // Adjust the avatar's position to account for the increase/decrease in size 243 _size = newSize;
239 ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f);
240 244
241 // Make sure this change appears as a property update event 245 Scale = ComputeAvatarScale(Size);
242 PhysScene.PE.PushUpdate(PhysBody); 246 ComputeAvatarVolumeAndMass();
243 } 247 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
244 }); 248 LocalID, _size, Scale, Density, _avatarVolume, RawMass);
245 249
246 } 250 PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate()
251 {
252 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
253 {
254 PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
255 UpdatePhysicalMassProperties(RawMass, true);
256
257 // Adjust the avatar's position to account for the increase/decrease in size
258 ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f);
259
260 // Make sure this change appears as a property update event
261 PhysScene.PE.PushUpdate(PhysBody);
262 }
263 });
247 } 264 }
248 265
249 public override PrimitiveBaseShape Shape 266 public override PrimitiveBaseShape Shape
250 { 267 {
251 set { BaseShape = value; } 268 set { BaseShape = value; }
252 } 269 }
@@ -273,7 +290,7 @@ public sealed class BSCharacter : BSPhysObject
273 { 290 {
274 RawVelocity = OMV.Vector3.Zero; 291 RawVelocity = OMV.Vector3.Zero;
275 _acceleration = OMV.Vector3.Zero; 292 _acceleration = OMV.Vector3.Zero;
276 _rotationalVelocity = OMV.Vector3.Zero; 293 RawRotationalVelocity = OMV.Vector3.Zero;
277 294
278 // Zero some other properties directly into the physics engine 295 // Zero some other properties directly into the physics engine
279 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate() 296 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
@@ -285,7 +302,7 @@ public sealed class BSCharacter : BSPhysObject
285 302
286 public override void ZeroAngularMotion(bool inTaintTime) 303 public override void ZeroAngularMotion(bool inTaintTime)
287 { 304 {
288 _rotationalVelocity = OMV.Vector3.Zero; 305 RawRotationalVelocity = OMV.Vector3.Zero;
289 306
290 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate() 307 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
291 { 308 {
@@ -300,7 +317,7 @@ public sealed class BSCharacter : BSPhysObject
300 } 317 }
301 318
302 319
303 public override void LockAngularMotion(OMV.Vector3 axis) { return; } 320 public override void LockAngularMotion(byte axislocks) { return; }
304 321
305 public override OMV.Vector3 Position { 322 public override OMV.Vector3 Position {
306 get { 323 get {
@@ -333,7 +350,6 @@ public sealed class BSCharacter : BSPhysObject
333 } 350 }
334 } 351 }
335 352
336
337 // Check that the current position is sane and, if not, modify the position to make it so. 353 // Check that the current position is sane and, if not, modify the position to make it so.
338 // Check for being below terrain or on water. 354 // Check for being below terrain or on water.
339 // Returns 'true' of the position was made sane by some action. 355 // Returns 'true' of the position was made sane by some action.
@@ -433,6 +449,7 @@ public sealed class BSCharacter : BSPhysObject
433 public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } 449 public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } }
434 public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } 450 public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }
435 451
452 // PhysicsActor.TargetVelocity
436 // Sets the target in the motor. This starts the changing of the avatar's velocity. 453 // Sets the target in the motor. This starts the changing of the avatar's velocity.
437 public override OMV.Vector3 TargetVelocity 454 public override OMV.Vector3 TargetVelocity
438 { 455 {
@@ -443,43 +460,51 @@ public sealed class BSCharacter : BSPhysObject
443 set 460 set
444 { 461 {
445 DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); 462 DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value);
446 m_targetVelocity = value;
447 OMV.Vector3 targetVel = value; 463 OMV.Vector3 targetVel = value;
448 if (_setAlwaysRun && !_flying) 464 if (!_flying)
449 targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 1f); 465 {
466 if (_setAlwaysRun)
467 targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 1f);
468 else
469 if (BSParam.AvatarWalkVelocityFactor != 1f)
470 targetVel *= new OMV.Vector3(BSParam.AvatarWalkVelocityFactor, BSParam.AvatarWalkVelocityFactor, 1f);
471 }
472 base.m_targetVelocity = targetVel;
450 473
451 if (m_moveActor != null) 474 if (m_moveActor != null)
452 m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */); 475 m_moveActor.SetVelocityAndTarget(RawVelocity, base.m_targetVelocity, false /* inTaintTime */);
453 } 476 }
454 } 477 }
455 // Directly setting velocity means this is what the user really wants now. 478 // Directly setting velocity means this is what the user really wants now.
456 public override OMV.Vector3 Velocity { 479 public override OMV.Vector3 Velocity {
457 get { return RawVelocity; } 480 get { return RawVelocity; }
458 set { 481 set {
459 RawVelocity = value; 482 if (m_moveActor != null)
460 OMV.Vector3 vel = RawVelocity;
461
462 DetailLog("{0}: set Velocity = {1}", LocalID, value);
463
464 PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate()
465 { 483 {
466 if (m_moveActor != null) 484 // m_moveActor.SetVelocityAndTarget(OMV.Vector3.Zero, OMV.Vector3.Zero, false /* inTaintTime */);
467 m_moveActor.SetVelocityAndTarget(vel, vel, true /* inTaintTime */); 485 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false /* inTaintTime */);
486 }
487 base.Velocity = value;
488 }
489 }
468 490
469 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, vel); 491 // SetMomentum just sets the velocity without a target. We need to stop the movement actor if a character.
470 ForceVelocity = vel; 492 public override void SetMomentum(OMV.Vector3 momentum)
471 }); 493 {
494 if (m_moveActor != null)
495 {
496 // m_moveActor.SetVelocityAndTarget(OMV.Vector3.Zero, OMV.Vector3.Zero, false /* inTaintTime */);
497 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false /* inTaintTime */);
472 } 498 }
499 base.SetMomentum(momentum);
473 } 500 }
474 501
475 public override OMV.Vector3 ForceVelocity { 502 public override OMV.Vector3 ForceVelocity {
476 get { return RawVelocity; } 503 get { return RawVelocity; }
477 set { 504 set {
478 PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); 505 DetailLog("{0},BSCharacter.ForceVelocity.set={1}", LocalID, value);
479// Util.PrintCallStack();
480 DetailLog("{0}: set ForceVelocity = {1}", LocalID, value);
481 506
482 RawVelocity = value; 507 RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
483 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); 508 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
484 PhysScene.PE.Activate(PhysBody, true); 509 PhysScene.PE.Activate(PhysBody, true);
485 } 510 }
@@ -600,14 +625,6 @@ public sealed class BSCharacter : BSPhysObject
600 }); 625 });
601 } 626 }
602 } 627 }
603 public override OMV.Vector3 RotationalVelocity {
604 get { return _rotationalVelocity; }
605 set { _rotationalVelocity = value; }
606 }
607 public override OMV.Vector3 ForceRotationalVelocity {
608 get { return _rotationalVelocity; }
609 set { _rotationalVelocity = value; }
610 }
611 public override bool Kinematic { 628 public override bool Kinematic {
612 get { return _kinematic; } 629 get { return _kinematic; }
613 set { _kinematic = value; } 630 set { _kinematic = value; }
@@ -626,8 +643,6 @@ public sealed class BSCharacter : BSPhysObject
626 public override float ForceBuoyancy { 643 public override float ForceBuoyancy {
627 get { return _buoyancy; } 644 get { return _buoyancy; }
628 set { 645 set {
629 PhysScene.AssertInTaintTime("BSCharacter.ForceBuoyancy");
630
631 _buoyancy = value; 646 _buoyancy = value;
632 DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 647 DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
633 // Buoyancy is faked by changing the gravity applied to the object 648 // Buoyancy is faked by changing the gravity applied to the object
@@ -652,14 +667,24 @@ public sealed class BSCharacter : BSPhysObject
652 public override void AddForce(OMV.Vector3 force, bool pushforce) 667 public override void AddForce(OMV.Vector3 force, bool pushforce)
653 { 668 {
654 // Since this force is being applied in only one step, make this a force per second. 669 // Since this force is being applied in only one step, make this a force per second.
655 OMV.Vector3 addForce = force / PhysScene.LastTimeStep; 670 OMV.Vector3 addForce = force;
656 AddForce(addForce, pushforce, false); 671
672 // The interaction of this force with the simulator rate and collision occurance is tricky.
673 // ODE multiplies the force by 100
674 // ubODE multiplies the force by 5.3
675 // BulletSim, after much in-world testing, thinks it gets a similar effect by multiplying mass*0.315f
676 // This number could be a feature of friction or timing, but it seems to move avatars the same as ubODE
677 addForce *= Mass * BSParam.AvatarAddForcePushFactor;
678
679 DetailLog("{0},BSCharacter.addForce,call,force={1},addForce={2},push={3},mass={4}", LocalID, force, addForce, pushforce, Mass);
680 AddForce(false, addForce);
657 } 681 }
658 public override void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 682
683 public override void AddForce(bool inTaintTime, OMV.Vector3 force) {
659 if (force.IsFinite()) 684 if (force.IsFinite())
660 { 685 {
661 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); 686 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
662 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); 687 // DetailLog("{0},BSCharacter.addForce,call,force={1},push={2},inTaint={3}", LocalID, addForce, pushforce, inTaintTime);
663 688
664 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate() 689 PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate()
665 { 690 {
@@ -667,7 +692,15 @@ public sealed class BSCharacter : BSPhysObject
667 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); 692 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
668 if (PhysBody.HasPhysicalBody) 693 if (PhysBody.HasPhysicalBody)
669 { 694 {
695 // Bullet adds this central force to the total force for this tick.
696 // Deep down in Bullet:
697 // linearVelocity += totalForce / mass * timeStep;
670 PhysScene.PE.ApplyCentralForce(PhysBody, addForce); 698 PhysScene.PE.ApplyCentralForce(PhysBody, addForce);
699 PhysScene.PE.Activate(PhysBody, true);
700 }
701 if (m_moveActor != null)
702 {
703 m_moveActor.SuppressStationayCheckUntilLowVelocity();
671 } 704 }
672 }); 705 });
673 } 706 }
@@ -678,65 +711,74 @@ public sealed class BSCharacter : BSPhysObject
678 } 711 }
679 } 712 }
680 713
681 public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 714 public override void AddAngularForce(bool inTaintTime, OMV.Vector3 force) {
682 }
683 public override void SetMomentum(OMV.Vector3 momentum) {
684 } 715 }
685 716
717 // The avatar's physical shape (whether capsule or cube) is unit sized. BulletSim sets
718 // the scale of that unit shape to create the avatars full size.
686 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) 719 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
687 { 720 {
688 OMV.Vector3 newScale = size; 721 OMV.Vector3 newScale = size;
689 722
690 // Bullet's capsule total height is the "passed height + radius * 2"; 723 if (BSParam.AvatarUseBefore09SizeComputation)
691 // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1) 724 {
692 // The number we pass in for 'scaling' is the multiplier to get that base
693 // shape to be the size desired.
694 // So, when creating the scale for the avatar height, we take the passed height
695 // (size.Z) and remove the caps.
696 // An oddity of the Bullet capsule implementation is that it presumes the Y
697 // dimension is the radius of the capsule. Even though some of the code allows
698 // for a asymmetrical capsule, other parts of the code presume it is cylindrical.
699 725
700 // Scale is multiplier of radius with one of "0.5" 726 // Bullet's capsule total height is the "passed height + radius * 2";
727 // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1)
728 // The number we pass in for 'scaling' is the multiplier to get that base
729 // shape to be the size desired.
730 // So, when creating the scale for the avatar height, we take the passed height
731 // (size.Z) and remove the caps.
732 // An oddity of the Bullet capsule implementation is that it presumes the Y
733 // dimension is the radius of the capsule. Even though some of the code allows
734 // for a asymmetrical capsule, other parts of the code presume it is cylindrical.
701 735
702 float heightAdjust = BSParam.AvatarHeightMidFudge; 736 // Scale is multiplier of radius with one of "0.5"
703 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f) 737
704 { 738 float heightAdjust = BSParam.AvatarHeightMidFudge;
705 const float AVATAR_LOW = 1.1f; 739 if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
706 const float AVATAR_MID = 1.775f; // 1.87f
707 const float AVATAR_HI = 2.45f;
708 // An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
709 float midHeightOffset = size.Z - AVATAR_MID;
710 if (midHeightOffset < 0f)
711 { 740 {
712 // Small avatar. Add the adjustment based on the distance from midheight 741 const float AVATAR_LOW = 1.1f;
713 heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge; 742 const float AVATAR_MID = 1.775f; // 1.87f
743 const float AVATAR_HI = 2.45f;
744 // An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
745 float midHeightOffset = size.Z - AVATAR_MID;
746 if (midHeightOffset < 0f)
747 {
748 // Small avatar. Add the adjustment based on the distance from midheight
749 heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge;
750 }
751 else
752 {
753 // Large avatar. Add the adjustment based on the distance from midheight
754 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
755 }
756 }
757 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
758 {
759 newScale.X = size.X / 2f;
760 newScale.Y = size.Y / 2f;
761 // The total scale height is the central cylindar plus the caps on the two ends.
762 newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f;
714 } 763 }
715 else 764 else
716 { 765 {
717 // Large avatar. Add the adjustment based on the distance from midheight 766 newScale.Z = size.Z + heightAdjust;
718 heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
719 } 767 }
720 } 768 // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);
721 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule) 769
722 { 770 // If smaller than the endcaps, just fake like we're almost that small
723 newScale.X = size.X / 2f; 771 if (newScale.Z < 0)
724 newScale.Y = size.Y / 2f; 772 newScale.Z = 0.1f;
725 // The total scale height is the central cylindar plus the caps on the two ends. 773
726 newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f; 774 DetailLog("{0},BSCharacter.ComputeAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
775 LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
727 } 776 }
728 else 777 else
729 { 778 {
730 newScale.Z = size.Z + heightAdjust; 779 newScale.Z = size.Z + _footOffset;
780 DetailLog("{0},BSCharacter.ComputeAvatarScale,using newScale={1}, footOffset={2}", LocalID, newScale, _footOffset);
731 } 781 }
732 // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);
733
734 // If smaller than the endcaps, just fake like we're almost that small
735 if (newScale.Z < 0)
736 newScale.Z = 0.1f;
737
738 DetailLog("{0},BSCharacter.ComputerAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
739 LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
740 782
741 return newScale; 783 return newScale;
742 } 784 }
@@ -744,17 +786,24 @@ public sealed class BSCharacter : BSPhysObject
744 // set _avatarVolume and _mass based on capsule size, _density and Scale 786 // set _avatarVolume and _mass based on capsule size, _density and Scale
745 private void ComputeAvatarVolumeAndMass() 787 private void ComputeAvatarVolumeAndMass()
746 { 788 {
747 _avatarVolume = (float)( 789 if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule)
748 Math.PI 790 {
749 * Size.X / 2f 791 _avatarVolume = (float)(
750 * Size.Y / 2f // the area of capsule cylinder 792 Math.PI
751 * Size.Z // times height of capsule cylinder 793 * Size.X / 2f
752 + 1.33333333f 794 * Size.Y / 2f // the area of capsule cylinder
753 * Math.PI 795 * Size.Z // times height of capsule cylinder
754 * Size.X / 2f 796 + 1.33333333f
755 * Math.Min(Size.X, Size.Y) / 2 797 * Math.PI
756 * Size.Y / 2f // plus the volume of the capsule end caps 798 * Size.X / 2f
757 ); 799 * Math.Min(Size.X, Size.Y) / 2
800 * Size.Y / 2f // plus the volume of the capsule end caps
801 );
802 }
803 else
804 {
805 _avatarVolume = Size.X * Size.Y * Size.Z;
806 }
758 _mass = Density * BSParam.DensityScaleFactor * _avatarVolume; 807 _mass = Density * BSParam.DensityScaleFactor * _avatarVolume;
759 } 808 }
760 809
@@ -773,7 +822,7 @@ public sealed class BSCharacter : BSPhysObject
773 // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many 822 // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many
774 // extra updates. 823 // extra updates.
775 // 824 //
776 // XXX: Contrary to the above comment, setting an update threshold here above 0.4 actually introduces jitter to 825 // XXX: Contrary to the above comment, setting an update threshold here above 0.4 actually introduces jitter to
777 // avatar movement rather than removes it. The larger the threshold, the bigger the jitter. 826 // avatar movement rather than removes it. The larger the threshold, the bigger the jitter.
778 // This is most noticeable in level flight and can be seen with 827 // This is most noticeable in level flight and can be seen with
779 // the "show updates" option in a viewer. With an update threshold, the RawVelocity cycles between a lower 828 // the "show updates" option in a viewer. With an update threshold, the RawVelocity cycles between a lower
@@ -787,7 +836,7 @@ public sealed class BSCharacter : BSPhysObject
787 RawVelocity = entprop.Velocity; 836 RawVelocity = entprop.Velocity;
788 837
789 _acceleration = entprop.Acceleration; 838 _acceleration = entprop.Acceleration;
790 _rotationalVelocity = entprop.RotationalVelocity; 839 RawRotationalVelocity = entprop.RotationalVelocity;
791 840
792 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 841 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
793 if (PositionSanityCheck(true)) 842 if (PositionSanityCheck(true))
@@ -807,7 +856,7 @@ public sealed class BSCharacter : BSPhysObject
807 // PhysScene.PostUpdate(this); 856 // PhysScene.PostUpdate(this);
808 857
809 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 858 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
810 LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity); 859 LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, RawRotationalVelocity);
811 } 860 }
812} 861}
813} 862}
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs
index e42e868..e42e868 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraint.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs
index 4bcde2b..4bcde2b 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraint6Dof.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs
index 5746ac1..5746ac1 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintCollection.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs
index e7566a8..e7566a8 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintConeTwist.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs
index d20538d..d20538d 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintHinge.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs
index 83d42af..83d42af 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSlider.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs
index 563a1b1..563a1b1 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSConstraintSpring.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs b/OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs
index 0fc5577..c4ccdbe 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSDynamics.cs
@@ -125,8 +125,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS
125 125
126 // Just some recomputed constants: 126 // Just some recomputed constants:
127#pragma warning disable 414 127#pragma warning disable 414
128 static readonly float TwoPI = ((float)Math.PI) * 2f; 128 static readonly float TwoPI = ((float)Math.PI) * 2f;
129 static readonly float FourPI = ((float)Math.PI) * 4f; 129 static readonly float FourPI = ((float)Math.PI) * 4f;
130 static readonly float PIOverFour = ((float)Math.PI) / 4f; 130 static readonly float PIOverFour = ((float)Math.PI) / 4f;
131 static readonly float PIOverTwo = ((float)Math.PI) / 2f; 131 static readonly float PIOverTwo = ((float)Math.PI) / 2f;
132#pragma warning restore 414 132#pragma warning restore 414
@@ -768,7 +768,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
768 } 768 }
769 769
770 if ((m_knownChanged & m_knownChangedForce) != 0) 770 if ((m_knownChanged & m_knownChangedForce) != 0)
771 ControllingPrim.AddForce((Vector3)m_knownForce, false /*pushForce*/, true /*inTaintTime*/); 771 ControllingPrim.AddForce(false /* inTaintTime */, (Vector3)m_knownForce);
772 772
773 if ((m_knownChanged & m_knownChangedForceImpulse) != 0) 773 if ((m_knownChanged & m_knownChangedForceImpulse) != 0)
774 ControllingPrim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/); 774 ControllingPrim.AddForceImpulse((Vector3)m_knownForceImpulse, false /*pushforce*/, true /*inTaintTime*/);
@@ -784,7 +784,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
784 784
785 if ((m_knownChanged & m_knownChangedRotationalForce) != 0) 785 if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
786 { 786 {
787 ControllingPrim.AddAngularForce((Vector3)m_knownRotationalForce, false /*pushForce*/, true /*inTaintTime*/); 787 ControllingPrim.AddAngularForce(true /* inTaintTime */, (Vector3)m_knownRotationalForce);
788 } 788 }
789 789
790 // If we set one of the values (ie, the physics engine didn't do it) we must force 790 // If we set one of the values (ie, the physics engine didn't do it) we must force
@@ -1595,7 +1595,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1595 // in that direction. 1595 // in that direction.
1596 // TODO: implement reference frame. 1596 // TODO: implement reference frame.
1597 public void ComputeAngularDeflection() 1597 public void ComputeAngularDeflection()
1598 { 1598 {
1599 1599
1600 if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) 1600 if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
1601 { 1601 {
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs b/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs
index 8312239..13c1361 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs
@@ -257,7 +257,7 @@ public abstract class BSLinkset
257 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have 257 // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have
258 // anything to add for the collision and it should be passed through normal processing. 258 // anything to add for the collision and it should be passed through normal processing.
259 // Default processing for a linkset. 259 // Default processing for a linkset.
260 public virtual bool HandleCollide(uint collidingWith, BSPhysObject collidee, 260 public virtual bool HandleCollide(BSPhysObject collider, BSPhysObject collidee,
261 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 261 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
262 { 262 {
263 bool ret = false; 263 bool ret = false;
@@ -319,7 +319,7 @@ public abstract class BSLinkset
319 public virtual bool AllPartsComplete 319 public virtual bool AllPartsComplete
320 { 320 {
321 get { 321 get {
322 bool ret = true; 322 bool ret = true;
323 this.ForEachMember((member) => 323 this.ForEachMember((member) =>
324 { 324 {
325 if ((!member.IsInitialized) || member.IsIncomplete || member.PrimAssetState == BSPhysObject.PrimAssetCondition.Waiting) 325 if ((!member.IsInitialized) || member.IsIncomplete || member.PrimAssetState == BSPhysObject.PrimAssetCondition.Waiting)
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs
index 953ddee..dc390b2 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs
@@ -450,6 +450,7 @@ public sealed class BSLinksetCompound : BSLinkset
450 m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody); 450 m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody);
451 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}", 451 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}",
452 LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape); 452 LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape);
453 m_physicsScene.PE.ResetBroadphasePool(m_physicsScene.World); // DEBUG DEBUG
453 454
454 // With all of the linkset packed into the root prim, it has the mass of everyone. 455 // With all of the linkset packed into the root prim, it has the mass of everyone.
455 LinksetMass = ComputeLinksetMass(); 456 LinksetMass = ComputeLinksetMass();
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs
index c4b4c86..c4b4c86 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetConstraints.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs b/OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs
index 0e44d03..0e44d03 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSMaterials.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs b/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
index 2faf2d4..2faf2d4 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
index c296008..495f752 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
@@ -90,8 +90,8 @@ public static class BSParam
90 public static float DeactivationTime { get; private set; } 90 public static float DeactivationTime { get; private set; }
91 public static float LinearSleepingThreshold { get; private set; } 91 public static float LinearSleepingThreshold { get; private set; }
92 public static float AngularSleepingThreshold { get; private set; } 92 public static float AngularSleepingThreshold { get; private set; }
93 public static float CcdMotionThreshold { get; private set; } 93 public static float CcdMotionThreshold { get; private set; }
94 public static float CcdSweptSphereRadius { get; private set; } 94 public static float CcdSweptSphereRadius { get; private set; }
95 public static float ContactProcessingThreshold { get; private set; } 95 public static float ContactProcessingThreshold { get; private set; }
96 96
97 public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed 97 public static bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed
@@ -119,14 +119,14 @@ public static class BSParam
119 public static float Gravity { get; private set; } 119 public static float Gravity { get; private set; }
120 120
121 // Physics Engine operation 121 // Physics Engine operation
122 public static float MaxPersistantManifoldPoolSize { get; private set; } 122 public static float MaxPersistantManifoldPoolSize { get; private set; }
123 public static float MaxCollisionAlgorithmPoolSize { get; private set; } 123 public static float MaxCollisionAlgorithmPoolSize { get; private set; }
124 public static bool ShouldDisableContactPoolDynamicAllocation { get; private set; } 124 public static bool ShouldDisableContactPoolDynamicAllocation { get; private set; }
125 public static bool ShouldForceUpdateAllAabbs { get; private set; } 125 public static bool ShouldForceUpdateAllAabbs { get; private set; }
126 public static bool ShouldRandomizeSolverOrder { get; private set; } 126 public static bool ShouldRandomizeSolverOrder { get; private set; }
127 public static bool ShouldSplitSimulationIslands { get; private set; } 127 public static bool ShouldSplitSimulationIslands { get; private set; }
128 public static bool ShouldEnableFrictionCaching { get; private set; } 128 public static bool ShouldEnableFrictionCaching { get; private set; }
129 public static float NumberOfSolverIterations { get; private set; } 129 public static float NumberOfSolverIterations { get; private set; }
130 public static bool UseSingleSidedMeshes { get; private set; } 130 public static bool UseSingleSidedMeshes { get; private set; }
131 public static float GlobalContactBreakingThreshold { get; private set; } 131 public static float GlobalContactBreakingThreshold { get; private set; }
132 public static float PhysicsUnmanLoggingFrames { get; private set; } 132 public static float PhysicsUnmanLoggingFrames { get; private set; }
@@ -135,6 +135,7 @@ public static class BSParam
135 public static bool AvatarToAvatarCollisionsByDefault { get; private set; } 135 public static bool AvatarToAvatarCollisionsByDefault { get; private set; }
136 public static float AvatarFriction { get; private set; } 136 public static float AvatarFriction { get; private set; }
137 public static float AvatarStandingFriction { get; private set; } 137 public static float AvatarStandingFriction { get; private set; }
138 public static float AvatarWalkVelocityFactor { get; private set; }
138 public static float AvatarAlwaysRunFactor { get; private set; } 139 public static float AvatarAlwaysRunFactor { get; private set; }
139 public static float AvatarDensity { get; private set; } 140 public static float AvatarDensity { get; private set; }
140 public static float AvatarRestitution { get; private set; } 141 public static float AvatarRestitution { get; private set; }
@@ -142,23 +143,26 @@ public static class BSParam
142 public static float AvatarCapsuleWidth { get; private set; } 143 public static float AvatarCapsuleWidth { get; private set; }
143 public static float AvatarCapsuleDepth { get; private set; } 144 public static float AvatarCapsuleDepth { get; private set; }
144 public static float AvatarCapsuleHeight { get; private set; } 145 public static float AvatarCapsuleHeight { get; private set; }
146 public static bool AvatarUseBefore09SizeComputation { get; private set; }
145 public static float AvatarHeightLowFudge { get; private set; } 147 public static float AvatarHeightLowFudge { get; private set; }
146 public static float AvatarHeightMidFudge { get; private set; } 148 public static float AvatarHeightMidFudge { get; private set; }
147 public static float AvatarHeightHighFudge { get; private set; } 149 public static float AvatarHeightHighFudge { get; private set; }
148 public static float AvatarFlyingGroundMargin { get; private set; } 150 public static float AvatarFlyingGroundMargin { get; private set; }
149 public static float AvatarFlyingGroundUpForce { get; private set; } 151 public static float AvatarFlyingGroundUpForce { get; private set; }
150 public static float AvatarTerminalVelocity { get; private set; } 152 public static float AvatarTerminalVelocity { get; private set; }
151 public static float AvatarContactProcessingThreshold { get; private set; } 153 public static float AvatarContactProcessingThreshold { get; private set; }
154 public static float AvatarAddForcePushFactor { get; private set; }
152 public static float AvatarStopZeroThreshold { get; private set; } 155 public static float AvatarStopZeroThreshold { get; private set; }
153 public static int AvatarJumpFrames { get; private set; } 156 public static float AvatarStopZeroThresholdSquared { get; private set; }
154 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; } 157 public static int AvatarJumpFrames { get; private set; }
155 public static float AvatarStepHeight { get; private set; } 158 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
156 public static float AvatarStepAngle { get; private set; } 159 public static float AvatarStepHeight { get; private set; }
157 public static float AvatarStepGroundFudge { get; private set; } 160 public static float AvatarStepAngle { get; private set; }
158 public static float AvatarStepApproachFactor { get; private set; } 161 public static float AvatarStepGroundFudge { get; private set; }
159 public static float AvatarStepForceFactor { get; private set; } 162 public static float AvatarStepApproachFactor { get; private set; }
160 public static float AvatarStepUpCorrectionFactor { get; private set; } 163 public static float AvatarStepForceFactor { get; private set; }
161 public static int AvatarStepSmoothingSteps { get; private set; } 164 public static float AvatarStepUpCorrectionFactor { get; private set; }
165 public static int AvatarStepSmoothingSteps { get; private set; }
162 166
163 // Vehicle parameters 167 // Vehicle parameters
164 public static float VehicleMaxLinearVelocity { get; private set; } 168 public static float VehicleMaxLinearVelocity { get; private set; }
@@ -190,31 +194,31 @@ public static class BSParam
190 public static float CSHullVolumeConservationThresholdPercent { get; private set; } 194 public static float CSHullVolumeConservationThresholdPercent { get; private set; }
191 public static int CSHullMaxVertices { get; private set; } 195 public static int CSHullMaxVertices { get; private set; }
192 public static float CSHullMaxSkinWidth { get; private set; } 196 public static float CSHullMaxSkinWidth { get; private set; }
193 public static float BHullMaxVerticesPerHull { get; private set; } // 100 197 public static float BHullMaxVerticesPerHull { get; private set; } // 100
194 public static float BHullMinClusters { get; private set; } // 2 198 public static float BHullMinClusters { get; private set; } // 2
195 public static float BHullCompacityWeight { get; private set; } // 0.1 199 public static float BHullCompacityWeight { get; private set; } // 0.1
196 public static float BHullVolumeWeight { get; private set; } // 0.0 200 public static float BHullVolumeWeight { get; private set; } // 0.0
197 public static float BHullConcavity { get; private set; } // 100 201 public static float BHullConcavity { get; private set; } // 100
198 public static bool BHullAddExtraDistPoints { get; private set; } // false 202 public static bool BHullAddExtraDistPoints { get; private set; } // false
199 public static bool BHullAddNeighboursDistPoints { get; private set; } // false 203 public static bool BHullAddNeighboursDistPoints { get; private set; } // false
200 public static bool BHullAddFacesPoints { get; private set; } // false 204 public static bool BHullAddFacesPoints { get; private set; } // false
201 public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false 205 public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false
202 public static float WhichHACD { get; private set; } // zero if Bullet HACD, non-zero says VHACD 206 public static float WhichHACD { get; private set; } // zero if Bullet HACD, non-zero says VHACD
203 // Parameters for VHACD 2.0: http://code.google.com/p/v-hacd 207 // Parameters for VHACD 2.0: http://code.google.com/p/v-hacd
204 // To enable, set both ShouldUseBulletHACD=true and WhichHACD=1 208 // To enable, set both ShouldUseBulletHACD=true and WhichHACD=1
205 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html 209 // http://kmamou.blogspot.ca/2014/12/v-hacd-20-parameters-description.html
206 public static float VHACDresolution { get; private set; } // 100,000 max number of voxels generated during voxelization stage 210 public static float VHACDresolution { get; private set; } // 100,000 max number of voxels generated during voxelization stage
207 public static float VHACDdepth { get; private set; } // 20 max number of clipping stages 211 public static float VHACDdepth { get; private set; } // 20 max number of clipping stages
208 public static float VHACDconcavity { get; private set; } // 0.0025 maximum concavity 212 public static float VHACDconcavity { get; private set; } // 0.0025 maximum concavity
209 public static float VHACDplaneDownsampling { get; private set; } // 4 granularity of search for best clipping plane 213 public static float VHACDplaneDownsampling { get; private set; } // 4 granularity of search for best clipping plane
210 public static float VHACDconvexHullDownsampling { get; private set; } // 4 precision of hull gen process 214 public static float VHACDconvexHullDownsampling { get; private set; } // 4 precision of hull gen process
211 public static float VHACDalpha { get; private set; } // 0.05 bias toward clipping along symmetry planes 215 public static float VHACDalpha { get; private set; } // 0.05 bias toward clipping along symmetry planes
212 public static float VHACDbeta { get; private set; } // 0.05 bias toward clipping along revolution axis 216 public static float VHACDbeta { get; private set; } // 0.05 bias toward clipping along revolution axis
213 public static float VHACDgamma { get; private set; } // 0.00125 max concavity when merging 217 public static float VHACDgamma { get; private set; } // 0.00125 max concavity when merging
214 public static float VHACDpca { get; private set; } // 0 on/off normalizing mesh before decomp 218 public static float VHACDpca { get; private set; } // 0 on/off normalizing mesh before decomp
215 public static float VHACDmode { get; private set; } // 0 0:voxel based, 1: tetrahedron based 219 public static float VHACDmode { get; private set; } // 0 0:voxel based, 1: tetrahedron based
216 public static float VHACDmaxNumVerticesPerCH { get; private set; } // 64 max triangles per convex hull 220 public static float VHACDmaxNumVerticesPerCH { get; private set; } // 64 max triangles per convex hull
217 public static float VHACDminVolumePerCH { get; private set; } // 0.0001 sampling of generated convex hulls 221 public static float VHACDminVolumePerCH { get; private set; } // 0.0001 sampling of generated convex hulls
218 222
219 // Linkset implementation parameters 223 // Linkset implementation parameters
220 public static float LinksetImplementation { get; private set; } 224 public static float LinksetImplementation { get; private set; }
@@ -227,9 +231,13 @@ public static class BSParam
227 public static float LinkConstraintCFM { get; private set; } 231 public static float LinkConstraintCFM { get; private set; }
228 public static float LinkConstraintSolverIterations { get; private set; } 232 public static float LinkConstraintSolverIterations { get; private set; }
229 233
234 public static bool UseBulletRaycast { get; private set; }
235
230 public static float PID_D { get; private set; } // derivative 236 public static float PID_D { get; private set; } // derivative
231 public static float PID_P { get; private set; } // proportional 237 public static float PID_P { get; private set; } // proportional
232 238
239 public static float DebugNumber { get; private set; } // A console setable number used for debugging
240
233 // Various constants that come from that other virtual world that shall not be named. 241 // Various constants that come from that other virtual world that shall not be named.
234 public const float MinGravityZ = -1f; 242 public const float MinGravityZ = -1f;
235 public const float MaxGravityZ = 28f; 243 public const float MaxGravityZ = 28f;
@@ -574,7 +582,7 @@ public static class BSParam
574 (s,v) => { ContactProcessingThreshold = v;}, 582 (s,v) => { ContactProcessingThreshold = v;},
575 (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ), 583 (s,o) => { s.PE.SetContactProcessingThreshold(o.PhysBody, ContactProcessingThreshold); } ),
576 584
577 new ParameterDefn<float>("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)", 585 new ParameterDefn<float>("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
578 (float)BSTerrainPhys.TerrainImplementation.Heightmap ), 586 (float)BSTerrainPhys.TerrainImplementation.Heightmap ),
579 new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" , 587 new ParameterDefn<int>("TerrainMeshMagnification", "Number of times the 256x256 heightmap is multiplied to create the terrain mesh" ,
580 2 ), 588 2 ),
@@ -597,11 +605,13 @@ public static class BSParam
597 0.2f ), 605 0.2f ),
598 new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", 606 new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
599 0.95f ), 607 0.95f ),
608 new ParameterDefn<float>("AvatarWalkVelocityFactor", "Speed multiplier if avatar is walking",
609 1.0f ),
600 new ParameterDefn<float>("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run", 610 new ParameterDefn<float>("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run",
601 1.3f ), 611 1.3f ),
602 // For historical reasons, density is reported * 100 612 // For historical reasons, density is reported * 100
603 new ParameterDefn<float>("AvatarDensity", "Density of an avatar. Changed on avatar recreation. Scaled times 100.", 613 new ParameterDefn<float>("AvatarDensity", "Density of an avatar. Changed on avatar recreation. Scaled times 100.",
604 3500f) , // 3.5 * 100 614 350f) , // 3.5 * 100
605 new ParameterDefn<float>("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 615 new ParameterDefn<float>("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
606 0f ), 616 0f ),
607 new ParameterDefn<int>("AvatarShape", "Code for avatar physical shape: 0:capsule, 1:cube, 2:ovoid, 2:mesh", 617 new ParameterDefn<int>("AvatarShape", "Code for avatar physical shape: 0:capsule, 1:cube, 2:ovoid, 2:mesh",
@@ -612,6 +622,8 @@ public static class BSParam
612 0.45f ), 622 0.45f ),
613 new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar", 623 new ParameterDefn<float>("AvatarCapsuleHeight", "Default height of space around avatar",
614 1.5f ), 624 1.5f ),
625 new ParameterDefn<bool>("AvatarUseBefore09SizeComputation", "Use the old fudge method of computing avatar capsule size",
626 true ),
615 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground", 627 new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground",
616 0f ), 628 0f ),
617 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground", 629 new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground",
@@ -624,27 +636,31 @@ public static class BSParam
624 2.0f ), 636 2.0f ),
625 new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar", 637 new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar",
626 -54.0f ), 638 -54.0f ),
627 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 639 new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
628 0.1f ),
629 new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
630 0.1f ), 640 0.1f ),
631 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground", 641 new ParameterDefn<float>("AvatarAddForcePushFactor", "BSCharacter.AddForce is multiplied by this and mass to be like other physics engines",
642 0.315f ),
643 new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
644 0.45f,
645 (s) => { return (float)AvatarStopZeroThreshold; },
646 (s,v) => { AvatarStopZeroThreshold = v; AvatarStopZeroThresholdSquared = v * v; } ),
647 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
632 1.0f ), 648 1.0f ),
633 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.", 649 new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.",
634 4 ), 650 4 ),
635 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction", 651 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction",
636 0.999f ) , 652 0.999f ) ,
637 new ParameterDefn<float>("AvatarStepAngle", "The angle (in radians) for a vertical surface to be considered a step", 653 new ParameterDefn<float>("AvatarStepAngle", "The angle (in radians) for a vertical surface to be considered a step",
638 0.3f ) , 654 0.3f ) ,
639 new ParameterDefn<float>("AvatarStepGroundFudge", "Fudge factor subtracted from avatar base when comparing collision height", 655 new ParameterDefn<float>("AvatarStepGroundFudge", "Fudge factor subtracted from avatar base when comparing collision height",
640 0.1f ) , 656 0.1f ) ,
641 new ParameterDefn<float>("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)", 657 new ParameterDefn<float>("AvatarStepApproachFactor", "Factor to control angle of approach to step (0=straight on)",
642 2f ), 658 2f ),
643 new ParameterDefn<float>("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step", 659 new ParameterDefn<float>("AvatarStepForceFactor", "Controls the amount of force up applied to step up onto a step",
644 0f ), 660 0f ),
645 new ParameterDefn<float>("AvatarStepUpCorrectionFactor", "Multiplied by height of step collision to create up movement at step", 661 new ParameterDefn<float>("AvatarStepUpCorrectionFactor", "Multiplied by height of step collision to create up movement at step",
646 0.8f ), 662 0.8f ),
647 new ParameterDefn<int>("AvatarStepSmoothingSteps", "Number of frames after a step collision that we continue walking up stairs", 663 new ParameterDefn<int>("AvatarStepSmoothingSteps", "Number of frames after a step collision that we continue walking up stairs",
648 1 ), 664 1 ),
649 665
650 new ParameterDefn<float>("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle", 666 new ParameterDefn<float>("VehicleMaxLinearVelocity", "Maximum velocity magnitude that can be assigned to a vehicle",
@@ -688,130 +704,136 @@ public static class BSParam
688 new ParameterDefn<bool>("VehicleEnableAngularBanking", "Turn on/off vehicle angular banking effect", 704 new ParameterDefn<bool>("VehicleEnableAngularBanking", "Turn on/off vehicle angular banking effect",
689 true ), 705 true ),
690 706
691 new ParameterDefn<float>("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 707 new ParameterDefn<float>("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
692 0f, 708 0f,
693 (s) => { return MaxPersistantManifoldPoolSize; }, 709 (s) => { return MaxPersistantManifoldPoolSize; },
694 (s,v) => { MaxPersistantManifoldPoolSize = v; s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ), 710 (s,v) => { MaxPersistantManifoldPoolSize = v; s.UnmanagedParams[0].maxPersistantManifoldPoolSize = v; } ),
695 new ParameterDefn<float>("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)", 711 new ParameterDefn<float>("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
696 0f, 712 0f,
697 (s) => { return MaxCollisionAlgorithmPoolSize; }, 713 (s) => { return MaxCollisionAlgorithmPoolSize; },
698 (s,v) => { MaxCollisionAlgorithmPoolSize = v; s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ), 714 (s,v) => { MaxCollisionAlgorithmPoolSize = v; s.UnmanagedParams[0].maxCollisionAlgorithmPoolSize = v; } ),
699 new ParameterDefn<bool>("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count", 715 new ParameterDefn<bool>("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
700 false, 716 false,
701 (s) => { return ShouldDisableContactPoolDynamicAllocation; }, 717 (s) => { return ShouldDisableContactPoolDynamicAllocation; },
702 (s,v) => { ShouldDisableContactPoolDynamicAllocation = v; 718 (s,v) => { ShouldDisableContactPoolDynamicAllocation = v;
703 s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = NumericBool(v); } ), 719 s.UnmanagedParams[0].shouldDisableContactPoolDynamicAllocation = NumericBool(v); } ),
704 new ParameterDefn<bool>("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step", 720 new ParameterDefn<bool>("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
705 false, 721 false,
706 (s) => { return ShouldForceUpdateAllAabbs; }, 722 (s) => { return ShouldForceUpdateAllAabbs; },
707 (s,v) => { ShouldForceUpdateAllAabbs = v; s.UnmanagedParams[0].shouldForceUpdateAllAabbs = NumericBool(v); } ), 723 (s,v) => { ShouldForceUpdateAllAabbs = v; s.UnmanagedParams[0].shouldForceUpdateAllAabbs = NumericBool(v); } ),
708 new ParameterDefn<bool>("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction", 724 new ParameterDefn<bool>("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction",
709 true, 725 true,
710 (s) => { return ShouldRandomizeSolverOrder; }, 726 (s) => { return ShouldRandomizeSolverOrder; },
711 (s,v) => { ShouldRandomizeSolverOrder = v; s.UnmanagedParams[0].shouldRandomizeSolverOrder = NumericBool(v); } ), 727 (s,v) => { ShouldRandomizeSolverOrder = v; s.UnmanagedParams[0].shouldRandomizeSolverOrder = NumericBool(v); } ),
712 new ParameterDefn<bool>("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands", 728 new ParameterDefn<bool>("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands",
713 true, 729 true,
714 (s) => { return ShouldSplitSimulationIslands; }, 730 (s) => { return ShouldSplitSimulationIslands; },
715 (s,v) => { ShouldSplitSimulationIslands = v; s.UnmanagedParams[0].shouldSplitSimulationIslands = NumericBool(v); } ), 731 (s,v) => { ShouldSplitSimulationIslands = v; s.UnmanagedParams[0].shouldSplitSimulationIslands = NumericBool(v); } ),
716 new ParameterDefn<bool>("ShouldEnableFrictionCaching", "Enable friction computation caching", 732 new ParameterDefn<bool>("ShouldEnableFrictionCaching", "Enable friction computation caching",
717 true, 733 true,
718 (s) => { return ShouldEnableFrictionCaching; }, 734 (s) => { return ShouldEnableFrictionCaching; },
719 (s,v) => { ShouldEnableFrictionCaching = v; s.UnmanagedParams[0].shouldEnableFrictionCaching = NumericBool(v); } ), 735 (s,v) => { ShouldEnableFrictionCaching = v; s.UnmanagedParams[0].shouldEnableFrictionCaching = NumericBool(v); } ),
720 new ParameterDefn<float>("NumberOfSolverIterations", "Number of internal iterations (0 means default)", 736 new ParameterDefn<float>("NumberOfSolverIterations", "Number of internal iterations (0 means default)",
721 0f, // zero says use Bullet default 737 0f, // zero says use Bullet default
722 (s) => { return NumberOfSolverIterations; }, 738 (s) => { return NumberOfSolverIterations; },
723 (s,v) => { NumberOfSolverIterations = v; s.UnmanagedParams[0].numberOfSolverIterations = v; } ), 739 (s,v) => { NumberOfSolverIterations = v; s.UnmanagedParams[0].numberOfSolverIterations = v; } ),
724 new ParameterDefn<bool>("UseSingleSidedMeshes", "Whether to compute collisions based on single sided meshes.", 740 new ParameterDefn<bool>("UseSingleSidedMeshes", "Whether to compute collisions based on single sided meshes.",
725 true, 741 true,
726 (s) => { return UseSingleSidedMeshes; }, 742 (s) => { return UseSingleSidedMeshes; },
727 (s,v) => { UseSingleSidedMeshes = v; s.UnmanagedParams[0].useSingleSidedMeshes = NumericBool(v); } ), 743 (s,v) => { UseSingleSidedMeshes = v; s.UnmanagedParams[0].useSingleSidedMeshes = NumericBool(v); } ),
728 new ParameterDefn<float>("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))", 744 new ParameterDefn<float>("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))",
729 0f, 745 0f,
730 (s) => { return GlobalContactBreakingThreshold; }, 746 (s) => { return GlobalContactBreakingThreshold; },
731 (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), 747 (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ),
732 new ParameterDefn<float>("PhysicsUnmanLoggingFrames", "If non-zero, frames between output of detailed unmanaged physics statistics", 748 new ParameterDefn<float>("PhysicsUnmanLoggingFrames", "If non-zero, frames between output of detailed unmanaged physics statistics",
733 0f, 749 0f,
734 (s) => { return PhysicsUnmanLoggingFrames; }, 750 (s) => { return PhysicsUnmanLoggingFrames; },
735 (s,v) => { PhysicsUnmanLoggingFrames = v; s.UnmanagedParams[0].physicsLoggingFrames = v; } ), 751 (s,v) => { PhysicsUnmanLoggingFrames = v; s.UnmanagedParams[0].physicsLoggingFrames = v; } ),
736 752
737 new ParameterDefn<int>("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy", 753 new ParameterDefn<int>("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy",
738 7 ), 754 7 ),
739 new ParameterDefn<int>("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes", 755 new ParameterDefn<int>("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes",
740 2 ), 756 2 ),
741 new ParameterDefn<float>("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)", 757 new ParameterDefn<float>("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)",
742 5f ), 758 5f ),
743 new ParameterDefn<float>("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)", 759 new ParameterDefn<float>("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)",
744 5f ), 760 5f ),
745 new ParameterDefn<int>("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.", 761 new ParameterDefn<int>("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.",
746 32 ), 762 32 ),
747 new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.", 763 new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.",
748 0f ), 764 0f ),
749 765
750 new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull", 766 new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull",
751 200f ), 767 200f ),
752 new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh", 768 new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh",
753 10f ), 769 10f ),
754 new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls", 770 new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls",
755 20f ), 771 20f ),
756 new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull", 772 new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull",
757 0.1f ), 773 0.1f ),
758 new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be", 774 new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be",
759 10f ), 775 10f ),
760 new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors", 776 new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors",
761 true ), 777 true ),
762 new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls", 778 new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls",
763 true ), 779 true ),
764 new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces", 780 new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces",
765 true ), 781 true ),
766 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin", 782 new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin",
767 false ), 783 false ),
768 784
769 new ParameterDefn<float>("WhichHACD", "zero if Bullet HACD, non-zero says VHACD", 785 new ParameterDefn<float>("WhichHACD", "zero if Bullet HACD, non-zero says VHACD",
770 0f ), 786 0f ),
771 new ParameterDefn<float>("VHACDresolution", "max number of voxels generated during voxelization stage", 787 new ParameterDefn<float>("VHACDresolution", "max number of voxels generated during voxelization stage",
772 100000f ), 788 100000f ),
773 new ParameterDefn<float>("VHACDdepth", "max number of clipping stages", 789 new ParameterDefn<float>("VHACDdepth", "max number of clipping stages",
774 20f ), 790 20f ),
775 new ParameterDefn<float>("VHACDconcavity", "maximum concavity", 791 new ParameterDefn<float>("VHACDconcavity", "maximum concavity",
776 0.0025f ), 792 0.0025f ),
777 new ParameterDefn<float>("VHACDplaneDownsampling", "granularity of search for best clipping plane", 793 new ParameterDefn<float>("VHACDplaneDownsampling", "granularity of search for best clipping plane",
778 4f ), 794 4f ),
779 new ParameterDefn<float>("VHACDconvexHullDownsampling", "precision of hull gen process", 795 new ParameterDefn<float>("VHACDconvexHullDownsampling", "precision of hull gen process",
780 4f ), 796 4f ),
781 new ParameterDefn<float>("VHACDalpha", "bias toward clipping along symmetry planes", 797 new ParameterDefn<float>("VHACDalpha", "bias toward clipping along symmetry planes",
782 0.05f ), 798 0.05f ),
783 new ParameterDefn<float>("VHACDbeta", "bias toward clipping along revolution axis", 799 new ParameterDefn<float>("VHACDbeta", "bias toward clipping along revolution axis",
784 0.05f ), 800 0.05f ),
785 new ParameterDefn<float>("VHACDgamma", "max concavity when merging", 801 new ParameterDefn<float>("VHACDgamma", "max concavity when merging",
786 0.00125f ), 802 0.00125f ),
787 new ParameterDefn<float>("VHACDpca", "on/off normalizing mesh before decomp", 803 new ParameterDefn<float>("VHACDpca", "on/off normalizing mesh before decomp",
788 0f ), 804 0f ),
789 new ParameterDefn<float>("VHACDmode", "0:voxel based, 1: tetrahedron based", 805 new ParameterDefn<float>("VHACDmode", "0:voxel based, 1: tetrahedron based",
790 0f ), 806 0f ),
791 new ParameterDefn<float>("VHACDmaxNumVerticesPerCH", "max triangles per convex hull", 807 new ParameterDefn<float>("VHACDmaxNumVerticesPerCH", "max triangles per convex hull",
792 64f ), 808 64f ),
793 new ParameterDefn<float>("VHACDminVolumePerCH", "sampling of generated convex hulls", 809 new ParameterDefn<float>("VHACDminVolumePerCH", "sampling of generated convex hulls",
794 0.0001f ), 810 0.0001f ),
795 811
796 new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", 812 new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
797 (float)BSLinkset.LinksetImplementation.Compound ), 813 (float)BSLinkset.LinksetImplementation.Compound ),
798 new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same", 814 new ParameterDefn<bool>("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same",
799 true ), 815 true ),
800 new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", 816 new ParameterDefn<bool>("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
801 false ), 817 false ),
802 new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", 818 new ParameterDefn<bool>("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
803 true ), 819 true ),
804 new ParameterDefn<float>("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints", 820 new ParameterDefn<float>("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints",
805 5.0f ), 821 5.0f ),
806 new ParameterDefn<float>("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints", 822 new ParameterDefn<float>("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints",
807 0.1f ), 823 0.1f ),
808 new ParameterDefn<float>("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1", 824 new ParameterDefn<float>("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
809 0.1f ), 825 0.1f ),
810 new ParameterDefn<float>("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2", 826 new ParameterDefn<float>("LinkConstraintERP", "Amount constraint is corrected each tick. 0=none, 1=all. Default = 0.2",
811 0.1f ), 827 0.1f ),
812 new ParameterDefn<float>("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", 828 new ParameterDefn<float>("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
813 40 ), 829 40 ),
814 830
831 new ParameterDefn<bool>("UseBulletRaycast", "If 'true', use the raycast function of the Bullet physics engine",
832 true ),
833
834 new ParameterDefn<float>("DebugNumber", "A console setable number sometimes used for debugging",
835 1.0f ),
836
815 new ParameterDefn<int>("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)", 837 new ParameterDefn<int>("PhysicsMetricFrames", "Frames between outputting detailed phys metrics. (0 is off)",
816 0, 838 0,
817 (s) => { return s.PhysicsMetricDumpFrames; }, 839 (s) => { return s.PhysicsMetricDumpFrames; },
@@ -819,7 +841,7 @@ public static class BSParam
819 new ParameterDefn<float>("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool", 841 new ParameterDefn<float>("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool",
820 0f, 842 0f,
821 (s) => { return 0f; }, 843 (s) => { return 0f; },
822 (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v, false /* inTaintTime */); } ), 844 (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v); } ),
823 new ParameterDefn<float>("ResetConstraintSolver", "Setting this is any value resets the constraint solver", 845 new ParameterDefn<float>("ResetConstraintSolver", "Setting this is any value resets the constraint solver",
824 0f, 846 0f,
825 (s) => { return 0f; }, 847 (s) => { return 0f; },
@@ -905,10 +927,10 @@ public static class BSParam
905 // ===================================================================== 927 // =====================================================================
906 // There are parameters that, when set, cause things to happen in the physics engine. 928 // There are parameters that, when set, cause things to happen in the physics engine.
907 // This causes the broadphase collision cache to be cleared. 929 // This causes the broadphase collision cache to be cleared.
908 private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v, bool inTaintTime) 930 private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v)
909 { 931 {
910 BSScene physScene = pPhysScene; 932 BSScene physScene = pPhysScene;
911 physScene.TaintedObject(inTaintTime, "BSParam.ResetBroadphasePoolTainted", delegate() 933 physScene.TaintedObject(BSScene.DetailLogZero, "BSParam.ResetBroadphasePoolTainted", delegate()
912 { 934 {
913 physScene.PE.ResetBroadphasePool(physScene.World); 935 physScene.PE.ResetBroadphasePool(physScene.World);
914 }); 936 });
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs
index da3fc18..6aa24d5 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs
@@ -230,34 +230,97 @@ public abstract class BSPhysObject : PhysicsActor
230 // Update the physical location and motion of the object. Called with data from Bullet. 230 // Update the physical location and motion of the object. Called with data from Bullet.
231 public abstract void UpdateProperties(EntityProperties entprop); 231 public abstract void UpdateProperties(EntityProperties entprop);
232 232
233 // The position value as known by BulletSim. Does not effect the physics engine.
233 public virtual OMV.Vector3 RawPosition { get; set; } 234 public virtual OMV.Vector3 RawPosition { get; set; }
235 // Set position in BulletSim and the physics engined to a value immediately. Must be called at taint time.
234 public abstract OMV.Vector3 ForcePosition { get; set; } 236 public abstract OMV.Vector3 ForcePosition { get; set; }
235 237
238 // The orientation value as known by BulletSim. Does not effect the physics engine.
236 public virtual OMV.Quaternion RawOrientation { get; set; } 239 public virtual OMV.Quaternion RawOrientation { get; set; }
240 // Set orientation in BulletSim and the physics engine to a value immediately. Must be called at taint time.
237 public abstract OMV.Quaternion ForceOrientation { get; set; } 241 public abstract OMV.Quaternion ForceOrientation { get; set; }
238 242
243 // The velocity value as known by BulletSim. Does not effect the physics engine.
239 public virtual OMV.Vector3 RawVelocity { get; set; } 244 public virtual OMV.Vector3 RawVelocity { get; set; }
245 // Set velocity in BulletSim and the physics engined to a value immediately. Must be called at taint time.
240 public abstract OMV.Vector3 ForceVelocity { get; set; } 246 public abstract OMV.Vector3 ForceVelocity { get; set; }
241 247
248 // The rotational velocity value as known by BulletSim. Does not effect the physics engine.
249 public OMV.Vector3 RawRotationalVelocity { get; set; }
250
251 // RawForce is a constant force applied to object (see Force { set; } )
242 public OMV.Vector3 RawForce { get; set; } 252 public OMV.Vector3 RawForce { get; set; }
243 public OMV.Vector3 RawTorque { get; set; } 253 public OMV.Vector3 RawTorque { get; set; }
254
244 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) 255 public override void AddAngularForce(OMV.Vector3 force, bool pushforce)
245 { 256 {
246 AddAngularForce(force, pushforce, false); 257 AddAngularForce(false, force);
247 } 258 }
248 public abstract void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime); 259 public abstract void AddAngularForce(bool inTaintTime, OMV.Vector3 force);
249 public abstract void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime); 260 public abstract void AddForce(bool inTaintTime, OMV.Vector3 force);
250 261
251 public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } 262 // PhysicsActor.Velocity
263 public override OMV.Vector3 Velocity
264 {
265 get { return RawVelocity; }
266 set
267 {
268 // This sets the velocity now. BSCharacter will override to clear target velocity
269 // before calling this.
270 RawVelocity = value;
271 PhysScene.TaintedObject(LocalID, TypeName + ".SetVelocity", delegate () {
272 // DetailLog("{0},BSPhysObject.Velocity.set,vel={1}", LocalID, RawVelocity);
273 ForceVelocity = RawVelocity;
274 });
275 }
276 }
277
278 // PhysicsActor.SetMomentum
279 // All the physics engines use this as a way of forcing the velocity to something.
280 // BSCharacter overrides this so it can set the target velocity to zero before calling this.
281 public override void SetMomentum(OMV.Vector3 momentum)
282 {
283 this.Velocity = momentum;
284 }
285
286 public override OMV.Vector3 RotationalVelocity {
287 get {
288 return RawRotationalVelocity;
289 }
290 set {
291 RawRotationalVelocity = value;
292 Util.ClampV(RawRotationalVelocity, BSParam.MaxAngularVelocity);
293 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
294 PhysScene.TaintedObject(LocalID, TypeName + ".setRotationalVelocity", delegate()
295 {
296 ForceRotationalVelocity = RawRotationalVelocity;
297 });
298 }
299 }
300 public OMV.Vector3 ForceRotationalVelocity {
301 get {
302 return RawRotationalVelocity;
303 }
304 set {
305 RawRotationalVelocity = Util.ClampV(value, BSParam.MaxAngularVelocity);
306 if (PhysBody.HasPhysicalBody)
307 {
308 DetailLog("{0},{1}.ForceRotationalVel,taint,rotvel={2}", LocalID, TypeName, RawRotationalVelocity);
309 PhysScene.PE.SetAngularVelocity(PhysBody, RawRotationalVelocity);
310 // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
311 ActivateIfPhysical(false);
312 }
313 }
314 }
252 315
253 public abstract float ForceBuoyancy { get; set; } 316 public abstract float ForceBuoyancy { get; set; }
254 317
255 public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; } 318 public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
256 319
257 public override bool PIDActive 320 public override bool PIDActive
258 { 321 {
259 get { return MoveToTargetActive; } 322 get { return MoveToTargetActive; }
260 set { MoveToTargetActive = value; } 323 set { MoveToTargetActive = value; }
261 } 324 }
262 325
263 public override OMV.Vector3 PIDTarget { set { MoveToTargetTarget = value; } } 326 public override OMV.Vector3 PIDTarget { set { MoveToTargetTarget = value; } }
@@ -268,7 +331,7 @@ public abstract class BSPhysObject : PhysicsActor
268 public float MoveToTargetTau { get; set; } 331 public float MoveToTargetTau { get; set; }
269 332
270 // Used for llSetHoverHeight and maybe vehicle height. Hover Height will override MoveTo target's Z 333 // Used for llSetHoverHeight and maybe vehicle height. Hover Height will override MoveTo target's Z
271 public override bool PIDHoverActive { set { HoverActive = value; } } 334 public override bool PIDHoverActive {get {return HoverActive;} set { HoverActive = value; } }
272 public override float PIDHoverHeight { set { HoverHeight = value; } } 335 public override float PIDHoverHeight { set { HoverHeight = value; } }
273 public override PIDHoverType PIDHoverType { set { HoverType = value; } } 336 public override PIDHoverType PIDHoverType { set { HoverType = value; } }
274 public override float PIDHoverTau { set { HoverTau = value; } } 337 public override float PIDHoverTau { set { HoverTau = value; } }
@@ -452,18 +515,24 @@ public abstract class BSPhysObject : PhysicsActor
452 private long CollisionsLastTickStep = -1; 515 private long CollisionsLastTickStep = -1;
453 516
454 // The simulation step is telling this object about a collision. 517 // The simulation step is telling this object about a collision.
518 // I'm the 'collider', the thing I'm colliding with is the 'collidee'.
455 // Return 'true' if a collision was processed and should be sent up. 519 // Return 'true' if a collision was processed and should be sent up.
456 // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision. 520 // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision.
457 // Called at taint time from within the Step() function 521 // Called at taint time from within the Step() function
458 public delegate bool CollideCall(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth); 522 public virtual bool Collide(BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
459 public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
460 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
461 { 523 {
462 bool ret = false; 524 bool ret = false;
463 525
526 // if 'collidee' is null, that means it is terrain
527 uint collideeLocalID = (collidee == null) ? BSScene.TERRAIN_ID : collidee.LocalID;
528 // All terrain goes by the TERRAIN_ID id when passed up as a collision
529 if (collideeLocalID <= PhysScene.TerrainManager.HighestTerrainID) {
530 collideeLocalID = BSScene.TERRAIN_ID;
531 }
532
464 // The following lines make IsColliding(), CollidingGround() and CollidingObj work 533 // The following lines make IsColliding(), CollidingGround() and CollidingObj work
465 CollidingStep = PhysScene.SimulationStep; 534 CollidingStep = PhysScene.SimulationStep;
466 if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID) 535 if (collideeLocalID == BSScene.TERRAIN_ID)
467 { 536 {
468 CollidingGroundStep = PhysScene.SimulationStep; 537 CollidingGroundStep = PhysScene.SimulationStep;
469 } 538 }
@@ -474,10 +543,13 @@ public abstract class BSPhysObject : PhysicsActor
474 543
475 CollisionAccumulation++; 544 CollisionAccumulation++;
476 545
477 // For movement tests, remember if we are colliding with an object that is moving. 546 // For movement tests, if the collider is me, remember if we are colliding with an object that is moving.
478 ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; 547 // Here the 'collider'/'collidee' thing gets messed up. In the larger context, when something is checking
548 // if the thing it is colliding with is moving, for instance, it asks if the its collider is moving.
549 ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero || collidee.RotationalVelocity != OMV.Vector3.Zero) : false;
479 ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false; 550 ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false;
480 551
552
481 // Make a collection of the collisions that happened the last simulation tick. 553 // Make a collection of the collisions that happened the last simulation tick.
482 // This is different than the collection created for sending up to the simulator as it is cleared every tick. 554 // This is different than the collection created for sending up to the simulator as it is cleared every tick.
483 if (CollisionsLastTickStep != PhysScene.SimulationStep) 555 if (CollisionsLastTickStep != PhysScene.SimulationStep)
@@ -485,16 +557,29 @@ public abstract class BSPhysObject : PhysicsActor
485 CollisionsLastTick = new CollisionEventUpdate(); 557 CollisionsLastTick = new CollisionEventUpdate();
486 CollisionsLastTickStep = PhysScene.SimulationStep; 558 CollisionsLastTickStep = PhysScene.SimulationStep;
487 } 559 }
488 CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 560 CollisionsLastTick.AddCollider(collideeLocalID, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
489 561
490 // If someone has subscribed for collision events log the collision so it will be reported up 562 // If someone has subscribed for collision events log the collision so it will be reported up
491 if (SubscribedEvents()) { 563 if (SubscribedEvents()) {
564 ContactPoint newContact = new ContactPoint(contactPoint, contactNormal, pentrationDepth);
565
566 // Collision sound requires a velocity to know it should happen. This is a lot of computation for a little used feature.
567 OMV.Vector3 relvel = OMV.Vector3.Zero;
568 if (IsPhysical)
569 relvel = RawVelocity;
570 if (collidee != null && collidee.IsPhysical)
571 relvel -= collidee.RawVelocity;
572 newContact.RelativeSpeed = -OMV.Vector3.Dot(relvel, contactNormal);
573 // DetailLog("{0},{1}.Collision.AddCollider,vel={2},contee.vel={3},relvel={4},relspeed={5}",
574 // LocalID, TypeName, RawVelocity, (collidee == null ? OMV.Vector3.Zero : collidee.RawVelocity), relvel, newContact.RelativeSpeed);
575
492 lock (PhysScene.CollisionLock) 576 lock (PhysScene.CollisionLock)
493 { 577 {
494 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 578 CollisionCollection.AddCollider(collideeLocalID, newContact);
495 } 579 }
496 DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}", 580 DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},speed={6},colliderMoving={7}",
497 LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); 581 LocalID, TypeName, collideeLocalID, contactPoint, contactNormal, pentrationDepth,
582 newContact.RelativeSpeed, ColliderIsMoving);
498 583
499 ret = true; 584 ret = true;
500 } 585 }
@@ -555,7 +640,11 @@ public abstract class BSPhysObject : PhysicsActor
555 PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate() 640 PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate()
556 { 641 {
557 if (PhysBody.HasPhysicalBody) 642 if (PhysBody.HasPhysicalBody)
643 {
558 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 644 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
645 DetailLog("{0},{1}.SubscribeEvents,setting collision. ms={2}, collisionFlags={3:x}",
646 LocalID, TypeName, SubscribedEventsMs, CurrentCollisionFlags);
647 }
559 }); 648 });
560 } 649 }
561 else 650 else
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs
index 6f27ac7..f085d70 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs
@@ -33,7 +33,7 @@ using log4net;
33using OMV = OpenMetaverse; 33using OMV = OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.PhysicsModules.SharedBase; 35using OpenSim.Region.PhysicsModules.SharedBase;
36using OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet; 36using OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet;
37 37
38namespace OpenSim.Region.PhysicsModule.BulletS 38namespace OpenSim.Region.PhysicsModule.BulletS
39{ 39{
@@ -59,7 +59,6 @@ public class BSPrim : BSPhysObject
59 private bool _setAlwaysRun; 59 private bool _setAlwaysRun;
60 private bool _throttleUpdates; 60 private bool _throttleUpdates;
61 private bool _floatOnWater; 61 private bool _floatOnWater;
62 private OMV.Vector3 _rotationalVelocity;
63 private bool _kinematic; 62 private bool _kinematic;
64 private float _buoyancy; 63 private float _buoyancy;
65 64
@@ -90,7 +89,7 @@ public class BSPrim : BSPhysObject
90 RawOrientation = rotation; 89 RawOrientation = rotation;
91 _buoyancy = 0f; 90 _buoyancy = 0f;
92 RawVelocity = OMV.Vector3.Zero; 91 RawVelocity = OMV.Vector3.Zero;
93 _rotationalVelocity = OMV.Vector3.Zero; 92 RawRotationalVelocity = OMV.Vector3.Zero;
94 BaseShape = pbs; 93 BaseShape = pbs;
95 _isPhysical = pisPhysical; 94 _isPhysical = pisPhysical;
96 _isVolumeDetect = false; 95 _isVolumeDetect = false;
@@ -256,7 +255,7 @@ public class BSPrim : BSPhysObject
256 { 255 {
257 RawVelocity = OMV.Vector3.Zero; 256 RawVelocity = OMV.Vector3.Zero;
258 _acceleration = OMV.Vector3.Zero; 257 _acceleration = OMV.Vector3.Zero;
259 _rotationalVelocity = OMV.Vector3.Zero; 258 RawRotationalVelocity = OMV.Vector3.Zero;
260 259
261 // Zero some other properties in the physics engine 260 // Zero some other properties in the physics engine
262 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate() 261 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
@@ -267,33 +266,33 @@ public class BSPrim : BSPhysObject
267 } 266 }
268 public override void ZeroAngularMotion(bool inTaintTime) 267 public override void ZeroAngularMotion(bool inTaintTime)
269 { 268 {
270 _rotationalVelocity = OMV.Vector3.Zero; 269 RawRotationalVelocity = OMV.Vector3.Zero;
271 // Zero some other properties in the physics engine 270 // Zero some other properties in the physics engine
272 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate() 271 PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
273 { 272 {
274 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); 273 // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
275 if (PhysBody.HasPhysicalBody) 274 if (PhysBody.HasPhysicalBody)
276 { 275 {
277 PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); 276 PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, RawRotationalVelocity);
278 PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); 277 PhysScene.PE.SetAngularVelocity(PhysBody, RawRotationalVelocity);
279 } 278 }
280 }); 279 });
281 } 280 }
282 281
283 public override void LockAngularMotion(OMV.Vector3 axis) 282 public override void LockAngularMotion(byte axislocks)
284 { 283 {
285 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 284 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axislocks);
286 285
287 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f); 286 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_UNLOCK_ANGULAR, 0f, 0f);
288 if (axis.X != 1) 287 if ((axislocks & 0x02) != 0)
289 { 288 {
290 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f); 289 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_X, 0f, 0f);
291 } 290 }
292 if (axis.Y != 1) 291 if ((axislocks & 0x04) != 0)
293 { 292 {
294 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f); 293 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Y, 0f, 0f);
295 } 294 }
296 if (axis.Z != 1) 295 if ((axislocks & 0x08) != 0)
297 { 296 {
298 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f); 297 ApplyAxisLimits(ExtendedPhysics.PHYS_AXIS_LOCK_ANGULAR_Z, 0f, 0f);
299 } 298 }
@@ -394,7 +393,7 @@ public class BSPrim : BSPhysObject
394 // Apply upforce and overcome gravity. 393 // Apply upforce and overcome gravity.
395 OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity; 394 OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity;
396 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, RawPosition, upForce, correctionForce); 395 DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, RawPosition, upForce, correctionForce);
397 AddForce(correctionForce, false, inTaintTime); 396 AddForce(inTaintTime, correctionForce);
398 ret = true; 397 ret = true;
399 } 398 }
400 } 399 }
@@ -426,9 +425,9 @@ public class BSPrim : BSPhysObject
426 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity); 425 RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity);
427 ret = true; 426 ret = true;
428 } 427 }
429 if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared) 428 if (RawRotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared)
430 { 429 {
431 _rotationalVelocity = Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); 430 RawRotationalVelocity = Util.ClampV(RawRotationalVelocity, BSParam.MaxAngularVelocity);
432 ret = true; 431 ret = true;
433 } 432 }
434 433
@@ -647,6 +646,59 @@ public class BSPrim : BSPhysObject
647 }); 646 });
648 } 647 }
649 648
649 public override void SetVehicle(object pvdata)
650 {
651 PhysScene.TaintedObject(LocalID, "BSPrim.SetVehicle", delegate ()
652 {
653 BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
654 if (vehicleActor != null && (pvdata is VehicleData) )
655 {
656 VehicleData vdata = (VehicleData)pvdata;
657 // vehicleActor.ProcessSetVehicle((VehicleData)vdata);
658
659 vehicleActor.ProcessTypeChange(vdata.m_type);
660 vehicleActor.ProcessVehicleFlags(-1, false);
661 vehicleActor.ProcessVehicleFlags((int)vdata.m_flags, false);
662
663 // Linear properties
664 vehicleActor.ProcessVectorVehicleParam(Vehicle.LINEAR_MOTOR_DIRECTION, vdata.m_linearMotorDirection);
665 vehicleActor.ProcessVectorVehicleParam(Vehicle.LINEAR_FRICTION_TIMESCALE, vdata.m_linearFrictionTimescale);
666 vehicleActor.ProcessFloatVehicleParam(Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE, vdata.m_linearMotorDecayTimescale);
667 vehicleActor.ProcessFloatVehicleParam(Vehicle.LINEAR_MOTOR_TIMESCALE, vdata.m_linearMotorTimescale);
668 vehicleActor.ProcessVectorVehicleParam(Vehicle.LINEAR_MOTOR_OFFSET, vdata.m_linearMotorOffset);
669
670 //Angular properties
671 vehicleActor.ProcessVectorVehicleParam(Vehicle.ANGULAR_MOTOR_DIRECTION, vdata.m_angularMotorDirection);
672 vehicleActor.ProcessFloatVehicleParam(Vehicle.ANGULAR_MOTOR_TIMESCALE, vdata.m_angularMotorTimescale);
673 vehicleActor.ProcessFloatVehicleParam(Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE, vdata.m_angularMotorDecayTimescale);
674 vehicleActor.ProcessVectorVehicleParam(Vehicle.ANGULAR_FRICTION_TIMESCALE, vdata.m_angularFrictionTimescale);
675
676 //Deflection properties
677 vehicleActor.ProcessFloatVehicleParam(Vehicle.ANGULAR_DEFLECTION_EFFICIENCY, vdata.m_angularDeflectionEfficiency);
678 vehicleActor.ProcessFloatVehicleParam(Vehicle.ANGULAR_DEFLECTION_TIMESCALE, vdata.m_angularDeflectionTimescale);
679 vehicleActor.ProcessFloatVehicleParam(Vehicle.LINEAR_DEFLECTION_EFFICIENCY, vdata.m_linearDeflectionEfficiency);
680 vehicleActor.ProcessFloatVehicleParam(Vehicle.LINEAR_DEFLECTION_TIMESCALE, vdata.m_linearDeflectionTimescale);
681
682 //Banking properties
683 vehicleActor.ProcessFloatVehicleParam(Vehicle.BANKING_EFFICIENCY, vdata.m_bankingEfficiency);
684 vehicleActor.ProcessFloatVehicleParam(Vehicle.BANKING_MIX, vdata.m_bankingMix);
685 vehicleActor.ProcessFloatVehicleParam(Vehicle.BANKING_TIMESCALE, vdata.m_bankingTimescale);
686
687 //Hover and Buoyancy properties
688 vehicleActor.ProcessFloatVehicleParam(Vehicle.HOVER_HEIGHT, vdata.m_VhoverHeight);
689 vehicleActor.ProcessFloatVehicleParam(Vehicle.HOVER_EFFICIENCY, vdata.m_VhoverEfficiency);
690 vehicleActor.ProcessFloatVehicleParam(Vehicle.HOVER_TIMESCALE, vdata.m_VhoverTimescale);
691 vehicleActor.ProcessFloatVehicleParam(Vehicle.BUOYANCY, vdata.m_VehicleBuoyancy);
692
693 //Attractor properties
694 vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, vdata.m_verticalAttractionEfficiency);
695 vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, vdata.m_verticalAttractionTimescale);
696
697 vehicleActor.ProcessRotationVehicleParam(Vehicle.REFERENCE_FRAME, vdata.m_referenceFrame);
698 }
699 });
700 }
701
650 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more 702 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
651 public override void SetVolumeDetect(int param) { 703 public override void SetVolumeDetect(int param) {
652 bool newValue = (param != 0); 704 bool newValue = (param != 0);
@@ -735,22 +787,9 @@ public class BSPrim : BSPhysObject
735 } 787 }
736 } 788 }
737 } 789 }
738 public override OMV.Vector3 Velocity {
739 get { return RawVelocity; }
740 set {
741 RawVelocity = value;
742 PhysScene.TaintedObject(LocalID, "BSPrim.setVelocity", delegate()
743 {
744 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
745 ForceVelocity = RawVelocity;
746 });
747 }
748 }
749 public override OMV.Vector3 ForceVelocity { 790 public override OMV.Vector3 ForceVelocity {
750 get { return RawVelocity; } 791 get { return RawVelocity; }
751 set { 792 set {
752 PhysScene.AssertInTaintTime("BSPrim.ForceVelocity");
753
754 RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); 793 RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
755 if (PhysBody.HasPhysicalBody) 794 if (PhysBody.HasPhysicalBody)
756 { 795 {
@@ -955,7 +994,7 @@ public class BSPrim : BSPhysObject
955 // For good measure, make sure the transform is set through to the motion state 994 // For good measure, make sure the transform is set through to the motion state
956 ForcePosition = RawPosition; 995 ForcePosition = RawPosition;
957 ForceVelocity = RawVelocity; 996 ForceVelocity = RawVelocity;
958 ForceRotationalVelocity = _rotationalVelocity; 997 ForceRotationalVelocity = RawRotationalVelocity;
959 998
960 // A dynamic object has mass 999 // A dynamic object has mass
961 UpdatePhysicalMassProperties(RawMass, false); 1000 UpdatePhysicalMassProperties(RawMass, false);
@@ -1075,35 +1114,6 @@ public class BSPrim : BSPhysObject
1075 }); 1114 });
1076 } 1115 }
1077 } 1116 }
1078 public override OMV.Vector3 RotationalVelocity {
1079 get {
1080 return _rotationalVelocity;
1081 }
1082 set {
1083 _rotationalVelocity = value;
1084 Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity);
1085 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
1086 PhysScene.TaintedObject(LocalID, "BSPrim.setRotationalVelocity", delegate()
1087 {
1088 ForceRotationalVelocity = _rotationalVelocity;
1089 });
1090 }
1091 }
1092 public override OMV.Vector3 ForceRotationalVelocity {
1093 get {
1094 return _rotationalVelocity;
1095 }
1096 set {
1097 _rotationalVelocity = Util.ClampV(value, BSParam.MaxAngularVelocity);
1098 if (PhysBody.HasPhysicalBody)
1099 {
1100 DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
1101 PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
1102 // PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
1103 ActivateIfPhysical(false);
1104 }
1105 }
1106 }
1107 public override bool Kinematic { 1117 public override bool Kinematic {
1108 get { return _kinematic; } 1118 get { return _kinematic; }
1109 set { _kinematic = value; 1119 set { _kinematic = value;
@@ -1132,14 +1142,14 @@ public class BSPrim : BSPhysObject
1132 } 1142 }
1133 } 1143 }
1134 1144
1135 public override bool PIDActive 1145 public override bool PIDActive
1136 { 1146 {
1137 get 1147 get
1138 { 1148 {
1139 return MoveToTargetActive; 1149 return MoveToTargetActive;
1140 } 1150 }
1141 1151
1142 set 1152 set
1143 { 1153 {
1144 MoveToTargetActive = value; 1154 MoveToTargetActive = value;
1145 1155
@@ -1167,12 +1177,16 @@ public class BSPrim : BSPhysObject
1167 // if the actor exists, tell it to refresh its values. 1177 // if the actor exists, tell it to refresh its values.
1168 actor.Refresh(); 1178 actor.Refresh();
1169 } 1179 }
1170 1180
1171 } 1181 }
1172 } 1182 }
1173 // Used for llSetHoverHeight and maybe vehicle height 1183 // Used for llSetHoverHeight and maybe vehicle height
1174 // Hover Height will override MoveTo target's Z 1184 // Hover Height will override MoveTo target's Z
1175 public override bool PIDHoverActive { 1185 public override bool PIDHoverActive {
1186 get
1187 {
1188 return base.HoverActive;
1189 }
1176 set { 1190 set {
1177 base.HoverActive = value; 1191 base.HoverActive = value;
1178 EnableActor(HoverActive, HoverActorName, delegate() 1192 EnableActor(HoverActive, HoverActorName, delegate()
@@ -1192,14 +1206,18 @@ public class BSPrim : BSPhysObject
1192 // Per documentation, max force is limited. 1206 // Per documentation, max force is limited.
1193 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude); 1207 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
1194 1208
1195 // Since this force is being applied in only one step, make this a force per second. 1209 // Push forces seem to be scaled differently (follow pattern in ubODE)
1196 addForce /= PhysScene.LastTimeStep; 1210 if (!pushforce) {
1197 AddForce(addForce, pushforce, false /* inTaintTime */); 1211 // Since this force is being applied in only one step, make this a force per second.
1212 addForce /= PhysScene.LastTimeStep;
1213 }
1214
1215 AddForce(false /* inTaintTime */, addForce);
1198 } 1216 }
1199 1217
1200 // Applying a force just adds this to the total force on the object. 1218 // Applying a force just adds this to the total force on the object.
1201 // This added force will only last the next simulation tick. 1219 // This added force will only last the next simulation tick.
1202 public override void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 1220 public override void AddForce(bool inTaintTime, OMV.Vector3 force) {
1203 // for an object, doesn't matter if force is a pushforce or not 1221 // for an object, doesn't matter if force is a pushforce or not
1204 if (IsPhysicallyActive) 1222 if (IsPhysicallyActive)
1205 { 1223 {
@@ -1258,7 +1276,7 @@ public class BSPrim : BSPhysObject
1258 } 1276 }
1259 1277
1260 // BSPhysObject.AddAngularForce() 1278 // BSPhysObject.AddAngularForce()
1261 public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) 1279 public override void AddAngularForce(bool inTaintTime, OMV.Vector3 force)
1262 { 1280 {
1263 if (force.IsFinite()) 1281 if (force.IsFinite())
1264 { 1282 {
@@ -1297,9 +1315,6 @@ public class BSPrim : BSPhysObject
1297 }); 1315 });
1298 } 1316 }
1299 1317
1300 public override void SetMomentum(OMV.Vector3 momentum) {
1301 // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
1302 }
1303 #region Mass Calculation 1318 #region Mass Calculation
1304 1319
1305 private float CalculateMass() 1320 private float CalculateMass()
@@ -1869,7 +1884,7 @@ public class BSPrim : BSPhysObject
1869 if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold)) 1884 if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
1870 RawVelocity = entprop.Velocity; 1885 RawVelocity = entprop.Velocity;
1871 _acceleration = entprop.Acceleration; 1886 _acceleration = entprop.Acceleration;
1872 _rotationalVelocity = entprop.RotationalVelocity; 1887 RawRotationalVelocity = entprop.RotationalVelocity;
1873 1888
1874 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG 1889 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1875 1890
@@ -1878,7 +1893,7 @@ public class BSPrim : BSPhysObject
1878 { 1893 {
1879 entprop.Position = RawPosition; 1894 entprop.Position = RawPosition;
1880 entprop.Velocity = RawVelocity; 1895 entprop.Velocity = RawVelocity;
1881 entprop.RotationalVelocity = _rotationalVelocity; 1896 entprop.RotationalVelocity = RawRotationalVelocity;
1882 entprop.Acceleration = _acceleration; 1897 entprop.Acceleration = _acceleration;
1883 } 1898 }
1884 1899
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs
index d8ed56b..3f90fc5 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs
@@ -81,7 +81,6 @@ public class BSPrimDisplaced : BSPrim
81 // Called at taint time. 81 // Called at taint time.
82 public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) 82 public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement)
83 { 83 {
84 PhysScene.AssertInTaintTime("BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement");
85 Vector3 comDisp; 84 Vector3 comDisp;
86 if (UserSetCenterOfMassDisplacement.HasValue) 85 if (UserSetCenterOfMassDisplacement.HasValue)
87 comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; 86 comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement;
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs
index 55b5da0..563dcfa 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs
@@ -203,15 +203,14 @@ public class BSPrimLinkable : BSPrimDisplaced
203 // Called after a simulation step to post a collision with this object. 203 // Called after a simulation step to post a collision with this object.
204 // This returns 'true' if the collision has been queued and the SendCollisions call must 204 // This returns 'true' if the collision has been queued and the SendCollisions call must
205 // be made at the end of the simulation step. 205 // be made at the end of the simulation step.
206 public override bool Collide(uint collidingWith, BSPhysObject collidee, 206 public override bool Collide(BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
207 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
208 { 207 {
209 bool ret = false; 208 bool ret = false;
210 // Ask the linkset if it wants to handle the collision 209 // Ask the linkset if it wants to handle the collision
211 if (!Linkset.HandleCollide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth)) 210 if (!Linkset.HandleCollide(this, collidee, contactPoint, contactNormal, pentrationDepth))
212 { 211 {
213 // The linkset didn't handle it so pass the collision through normal processing 212 // The linkset didn't handle it so pass the collision through normal processing
214 ret = base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth); 213 ret = base.Collide(collidee, contactPoint, contactNormal, pentrationDepth);
215 } 214 }
216 return ret; 215 return ret;
217 } 216 }
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
index 452ce55..163efaa 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs
@@ -124,9 +124,10 @@ namespace OpenSim.Region.PhysicsModule.BulletS
124 // True if initialized and ready to do simulation steps 124 // True if initialized and ready to do simulation steps
125 private bool m_initialized = false; 125 private bool m_initialized = false;
126 126
127 // Flag which is true when processing taints. 127 // Object locked whenever execution is inside the physics engine
128 // Not guaranteed to be correct all the time (don't depend on this) but good for debugging. 128 public Object PhysicsEngineLock = new object();
129 public bool InTaintTime { get; private set; } 129 // Flag that is true when the simulator is active and shouldn't be touched
130 public bool InSimulationTime { get; private set; }
130 131
131 // Pinned memory used to pass step information between managed and unmanaged 132 // Pinned memory used to pass step information between managed and unmanaged
132 internal int m_maxCollisionsPerFrame; 133 internal int m_maxCollisionsPerFrame;
@@ -212,6 +213,11 @@ namespace OpenSim.Region.PhysicsModule.BulletS
212 get { return "BulletSim"; } 213 get { return "BulletSim"; }
213 } 214 }
214 215
216 public string Version
217 {
218 get { return "1.0"; }
219 }
220
215 public Type ReplaceableInterface 221 public Type ReplaceableInterface
216 { 222 {
217 get { return null; } 223 get { return null; }
@@ -245,6 +251,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
245 EngineType = Name; 251 EngineType = Name;
246 RegionName = scene.RegionInfo.RegionName; 252 RegionName = scene.RegionInfo.RegionName;
247 PhysicsSceneName = EngineType + "/" + RegionName; 253 PhysicsSceneName = EngineType + "/" + RegionName;
254 EngineName = Name + " " + Version;
248 255
249 scene.RegisterModuleInterface<PhysicsScene>(this); 256 scene.RegisterModuleInterface<PhysicsScene>(this);
250 Vector3 extent = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, scene.RegionInfo.RegionSizeZ); 257 Vector3 extent = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, scene.RegionInfo.RegionSizeZ);
@@ -338,19 +345,19 @@ namespace OpenSim.Region.PhysicsModule.BulletS
338 // Put some informational messages into the log file. 345 // Put some informational messages into the log file.
339 m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation); 346 m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation);
340 347
341 InTaintTime = false; 348 InSimulationTime = false;
342 m_initialized = true; 349 m_initialized = true;
343 350
344 // If the physics engine runs on its own thread, start same. 351 // If the physics engine runs on its own thread, start same.
345 if (BSParam.UseSeparatePhysicsThread) 352 if (BSParam.UseSeparatePhysicsThread)
346 { 353 {
347 // The physics simulation should happen independently of the heartbeat loop 354 // The physics simulation should happen independently of the heartbeat loop
348 m_physicsThread 355 m_physicsThread
349 = WorkManager.StartThread( 356 = WorkManager.StartThread(
350 BulletSPluginPhysicsThread, 357 BulletSPluginPhysicsThread,
351 string.Format("{0} ({1})", BulletEngineName, RegionName), 358 string.Format("{0} ({1})", BulletEngineName, RegionName),
352 ThreadPriority.Normal, 359 ThreadPriority.Normal,
353 true, 360 true,
354 true); 361 true);
355 } 362 }
356 } 363 }
@@ -523,13 +530,13 @@ namespace OpenSim.Region.PhysicsModule.BulletS
523 return null; 530 return null;
524 } 531 }
525 532
526 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) 533 public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float footOffset, bool isFlying)
527 { 534 {
528 // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName); 535 // m_log.DebugFormat("{0}: AddAvatar: {1}", LogHeader, avName);
529 536
530 if (!m_initialized) return null; 537 if (!m_initialized) return null;
531 538
532 BSCharacter actor = new BSCharacter(localID, avName, this, position, velocity, size, isFlying); 539 BSCharacter actor = new BSCharacter(localID, avName, this, position, Vector3.Zero, size, footOffset, isFlying);
533 lock (PhysObjects) 540 lock (PhysObjects)
534 PhysObjects.Add(localID, actor); 541 PhysObjects.Add(localID, actor);
535 542
@@ -651,49 +658,57 @@ namespace OpenSim.Region.PhysicsModule.BulletS
651 658
652 int beforeTime = Util.EnvironmentTickCount(); 659 int beforeTime = Util.EnvironmentTickCount();
653 int simTime = 0; 660 int simTime = 0;
661 int numTaints = 0;
662 int numSubSteps = 0;
654 663
655 int numTaints = _taintOperations.Count; 664 lock (PhysicsEngineLock)
656 InTaintTime = true; // Only used for debugging so locking is not necessary. 665 {
666 InSimulationTime = true;
667 // update the prim states while we know the physics engine is not busy
668 numTaints += ProcessTaints();
657 669
658 // update the prim states while we know the physics engine is not busy 670 // Some of the physical objects requre individual, pre-step calls
659 ProcessTaints(); 671 // (vehicles and avatar movement, in particular)
672 TriggerPreStepEvent(timeStep);
660 673
661 // Some of the physical objects requre individual, pre-step calls 674 // the prestep actions might have added taints
662 // (vehicles and avatar movement, in particular) 675 numTaints += ProcessTaints();
663 TriggerPreStepEvent(timeStep);
664 676
665 // the prestep actions might have added taints 677 // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
666 numTaints += _taintOperations.Count; 678 // Only enable this in a limited test world with few objects.
667 ProcessTaints(); 679 if (m_physicsPhysicalDumpEnabled)
680 PE.DumpAllInfo(World);
668 681
669 InTaintTime = false; // Only used for debugging so locking is not necessary. 682 // step the physical world one interval
683 m_simulationStep++;
684 try
685 {
686 numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
687 }
688 catch (Exception e)
689 {
690 m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
691 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
692 DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
693 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
694 updatedEntityCount = 0;
695 collidersCount = 0;
696 }
670 697
671 // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. 698 // Make the physics engine dump useful statistics periodically
672 // Only enable this in a limited test world with few objects. 699 if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0))
673 if (m_physicsPhysicalDumpEnabled) 700 PE.DumpPhysicsStatistics(World);
674 PE.DumpAllInfo(World);
675 701
676 // step the physical world one interval 702 InSimulationTime = false;
677 m_simulationStep++;
678 int numSubSteps = 0;
679 try
680 {
681 numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
682 703
683 } 704 // Some actors want to know when the simulation step is complete.
684 catch (Exception e) 705 TriggerPostStepEvent(timeStep);
685 { 706
686 m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}", 707 // In case there were any parameter updates that happened during the simulation step
687 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e); 708 numTaints += ProcessTaints();
688 DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
689 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
690 updatedEntityCount = 0;
691 collidersCount = 0;
692 }
693 709
694 // Make the physics engine dump useful statistics periodically 710 InSimulationTime = false;
695 if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0)) 711 }
696 PE.DumpPhysicsStatistics(World);
697 712
698 // Get a value for 'now' so all the collision and update routines don't have to get their own. 713 // Get a value for 'now' so all the collision and update routines don't have to get their own.
699 SimulationNowTime = Util.EnvironmentTickCount(); 714 SimulationNowTime = Util.EnvironmentTickCount();
@@ -743,9 +758,6 @@ namespace OpenSim.Region.PhysicsModule.BulletS
743 } 758 }
744 } 759 }
745 760
746 // Some actors want to know when the simulation step is complete.
747 TriggerPostStepEvent(timeStep);
748
749 simTime = Util.EnvironmentTickCountSubtract(beforeTime); 761 simTime = Util.EnvironmentTickCountSubtract(beforeTime);
750 if (PhysicsLogging.Enabled) 762 if (PhysicsLogging.Enabled)
751 { 763 {
@@ -762,7 +774,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS
762 // The physics engine returns the number of milliseconds it simulated this call. 774 // The physics engine returns the number of milliseconds it simulated this call.
763 // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS. 775 // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
764 // Multiply by a fixed nominal frame rate to give a rate similar to the simulator (usually 55). 776 // Multiply by a fixed nominal frame rate to give a rate similar to the simulator (usually 55).
765 m_simulatedTime += (float)numSubSteps * m_fixedTimeStep * 1000f * NominalFrameRate; 777// m_simulatedTime += (float)numSubSteps * m_fixedTimeStep * 1000f * NominalFrameRate;
778 m_simulatedTime += (float)numSubSteps * m_fixedTimeStep;
766 } 779 }
767 780
768 // Called by a BSPhysObject to note that it has changed properties and this information 781 // Called by a BSPhysObject to note that it has changed properties and this information
@@ -849,7 +862,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
849 862
850 // Return the framerate simulated to give the above returned results. 863 // Return the framerate simulated to give the above returned results.
851 // (Race condition here but this is just bookkeeping so rare mistakes do not merit a lock). 864 // (Race condition here but this is just bookkeeping so rare mistakes do not merit a lock).
852 float simTime = m_simulatedTime; 865 float simTime = m_simulatedTime / timeStep;
853 m_simulatedTime = 0f; 866 m_simulatedTime = 0f;
854 return simTime; 867 return simTime;
855 } 868 }
@@ -879,7 +892,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
879 892
880 if (collider.IsInitialized) 893 if (collider.IsInitialized)
881 { 894 {
882 if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) 895 if (collider.Collide(collidee, collidePoint, collideNormal, penetration))
883 { 896 {
884 // If a collision was 'good', remember to send it to the simulator 897 // If a collision was 'good', remember to send it to the simulator
885 lock (CollisionLock) 898 lock (CollisionLock)
@@ -948,26 +961,150 @@ namespace OpenSim.Region.PhysicsModule.BulletS
948 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); 961 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
949 } 962 }
950 963
951 // Although no one seems to check this, I do support combining. 964 #endregion // Terrain
952 public override bool SupportsCombining() 965
966 #region Raycast
967
968 public override bool SupportsRayCast()
953 { 969 {
954 return TerrainManager.SupportsCombining(); 970 return BSParam.UseBulletRaycast;
955 } 971 }
956 // This call says I am a child to region zero in a mega-region. 'pScene' is that 972
957 // of region zero, 'offset' is my offset from regions zero's origin, and 973 public override bool SupportsRaycastWorldFiltered()
958 // 'extents' is the largest XY that is handled in my region.
959 public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
960 { 974 {
961 TerrainManager.Combine(pScene, offset, extents); 975 return BSParam.UseBulletRaycast;
962 } 976 }
963 977
964 // Unhook all the combining that I know about. 978
965 public override void UnCombine(PhysicsScene pScene) 979 /// <summary>
980 /// Queue a raycast against the physics scene.
981 /// The provided callback method will be called when the raycast is complete
982 ///
983 /// Many physics engines don't support collision testing at the same time as
984 /// manipulating the physics scene, so we queue the request up and callback
985 /// a custom method when the raycast is complete.
986 /// This allows physics engines that give an immediate result to callback immediately
987 /// and ones that don't, to callback when it gets a result back.
988 /// public delegate void RayCallback(List<ContactResult> list);
989 ///
990 /// ODE for example will not allow you to change the scene while collision testing or
991 /// it asserts, 'opteration not valid for locked space'. This includes adding a ray to the scene.
992 ///
993 /// This is named RayCastWorld to not conflict with modrex's Raycast method.
994 /// </summary>
995 /// <param name="position">Origin of the ray</param>
996 /// <param name="direction">Direction of the ray</param>
997 /// <param name="length">Length of ray in meters</param>
998 /// <param name="retMethod">Method to call when the raycast is complete</param>
999 public override void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
966 { 1000 {
967 TerrainManager.UnCombine(pScene); 1001 if (retMethod != null)
1002 {
1003 if (BSParam.UseBulletRaycast)
1004 {
1005 Vector3 posFrom = position;
1006 Vector3 posTo = Vector3.Normalize(direction) * length + position;
1007
1008 TaintedObject(DetailLogZero, "BSScene.RaycastWorld1", delegate ()
1009 {
1010 RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, 0xffff, 0xffff);
1011 retMethod(true, hitInfo.Point, hitInfo.ID, hitInfo.Fraction, hitInfo.Normal);
1012 });
1013 }
1014 else
1015 {
1016 retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero);
1017 }
1018 }
968 } 1019 }
969 1020
970 #endregion // Terrain 1021 public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
1022 {
1023 if (retMethod != null)
1024 {
1025 if (BSParam.UseBulletRaycast)
1026 {
1027 List<ContactResult> hitInfo = RaycastWorld(position, direction, length, count);
1028 retMethod(hitInfo);
1029 }
1030 else
1031 {
1032 retMethod(new List<ContactResult>());
1033 }
1034 }
1035 }
1036
1037 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int count)
1038 {
1039 return (List<ContactResult>)RaycastWorld(position, direction, length, count, RayFilterFlags.All);
1040 }
1041
1042 public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayFilterFlags filter)
1043 {
1044 List<ContactResult> ret = new List<ContactResult>();
1045 if (BSParam.UseBulletRaycast)
1046 {
1047 uint collisionFilter = 0;
1048 uint collisionMask = 0;
1049 if ((filter & RayFilterFlags.land) != 0)
1050 {
1051 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Terrain].group;
1052 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Terrain].mask;
1053 }
1054 if ((filter & RayFilterFlags.agent) != 0)
1055 {
1056 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Avatar].group;
1057 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Avatar].mask;
1058 }
1059 if ((filter & RayFilterFlags.nonphysical) != 0)
1060 {
1061 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Static].group;
1062 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Static].mask;
1063 }
1064 if ((filter & RayFilterFlags.physical) != 0)
1065 {
1066 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Dynamic].group;
1067 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Dynamic].mask;
1068 }
1069 // if ((filter & RayFilterFlags.phantom) != 0)
1070 // {
1071 // collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].group;
1072 // collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].mask;
1073 // }
1074 if ((filter & RayFilterFlags.volumedtc) != 0)
1075 {
1076 collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].group;
1077 collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].mask;
1078 }
1079 DetailLog("{0},RaycastWorld,pos={1},dir={2},len={3},count={4},filter={5},filter={6},mask={7}",
1080 DetailLogZero, position, direction, length, count, filter, collisionFilter, collisionMask);
1081 // NOTE: locking ensures the physics engine is not executing.
1082 // The caller might have to wait for the physics engine to finish.
1083 lock (PhysicsEngineLock)
1084 {
1085 Vector3 posFrom = position;
1086 Vector3 posTo = Vector3.Normalize(direction) * length + position;
1087 DetailLog("{0},RaycastWorld,RayTest2,from={1},to={2}",
1088 DetailLogZero, posFrom, posTo);
1089 RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, collisionFilter, collisionMask);
1090 if (hitInfo.hasHit())
1091 {
1092 ContactResult result = new ContactResult();
1093 result.Pos = hitInfo.Point;
1094 result.Normal = hitInfo.Normal;
1095 result.ConsumerID = hitInfo.ID;
1096 result.Depth = hitInfo.Fraction;
1097 ret.Add(result);
1098 DetailLog("{0},RaycastWorld,hit,pos={1},norm={2},depth={3},id={4}",
1099 DetailLogZero, result.Pos, result.Normal, result.Depth, result.ConsumerID);
1100 }
1101 }
1102 }
1103 return ret;
1104 }
1105
1106 #endregion Raycast
1107
971 1108
972 public override Dictionary<uint, float> GetTopColliders() 1109 public override Dictionary<uint, float> GetTopColliders()
973 { 1110 {
@@ -1081,32 +1218,35 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1081 // Calls to the PhysicsActors can't directly call into the physics engine 1218 // Calls to the PhysicsActors can't directly call into the physics engine
1082 // because it might be busy. We delay changes to a known time. 1219 // because it might be busy. We delay changes to a known time.
1083 // We rely on C#'s closure to save and restore the context for the delegate. 1220 // We rely on C#'s closure to save and restore the context for the delegate.
1084 public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback) 1221 // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed.
1222 // public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
1223 // {
1224 // TaintedObject(BSScene.DetailLogZero, pIdent, pCallback);
1225 // }
1226 // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed.
1227 public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
1085 { 1228 {
1086 TaintedObject(false /*inTaintTime*/, pOriginator, pIdent, pCallback); 1229 TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1087 } 1230 }
1088 public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback) 1231 public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback)
1089 { 1232 {
1090 TaintedObject(false /*inTaintTime*/, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); 1233 TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1091 }
1092 public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
1093 {
1094 TaintedObject(inTaintTime, BSScene.DetailLogZero, pIdent, pCallback);
1095 }
1096 public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
1097 {
1098 TaintedObject(inTaintTime, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
1099 } 1234 }
1100 // Sometimes a potentially tainted operation can be used in and out of taint time. 1235 // Sometimes a potentially tainted operation can be used in and out of taint time.
1101 // This routine executes the command immediately if in taint-time otherwise it is queued. 1236 // This routine executes the command immediately if in taint-time otherwise it is queued.
1102 public void TaintedObject(bool inTaintTime, string pOriginator, string pIdent, TaintCallback pCallback) 1237 public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback)
1103 { 1238 {
1104 if (!m_initialized) return; 1239 if (!m_initialized) return;
1105 1240
1106 if (inTaintTime) 1241 if (Monitor.TryEnter(PhysicsEngineLock))
1242 {
1243 // If we can get exclusive access to the physics engine, just do the operation
1107 pCallback(); 1244 pCallback();
1245 Monitor.Exit(PhysicsEngineLock);
1246 }
1108 else 1247 else
1109 { 1248 {
1249 // The physics engine is busy, queue the operation
1110 lock (_taintLock) 1250 lock (_taintLock)
1111 { 1251 {
1112 _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback)); 1252 _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
@@ -1133,14 +1273,21 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1133 // When someone tries to change a property on a BSPrim or BSCharacter, the object queues 1273 // When someone tries to change a property on a BSPrim or BSCharacter, the object queues
1134 // a callback into itself to do the actual property change. That callback is called 1274 // a callback into itself to do the actual property change. That callback is called
1135 // here just before the physics engine is called to step the simulation. 1275 // here just before the physics engine is called to step the simulation.
1136 public void ProcessTaints() 1276 // Returns the number of taints processed
1277 // NOTE: Called while PhysicsEngineLock is locked
1278 public int ProcessTaints()
1137 { 1279 {
1138 ProcessRegularTaints(); 1280 int ret = 0;
1139 ProcessPostTaintTaints(); 1281 ret += ProcessRegularTaints();
1282 ret += ProcessPostTaintTaints();
1283 return ret;
1140 } 1284 }
1141 1285
1142 private void ProcessRegularTaints() 1286 // Returns the number of taints processed
1287 // NOTE: Called while PhysicsEngineLock is locked
1288 private int ProcessRegularTaints()
1143 { 1289 {
1290 int ret = 0;
1144 if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process 1291 if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process
1145 { 1292 {
1146 // swizzle a new list into the list location so we can process what's there 1293 // swizzle a new list into the list location so we can process what's there
@@ -1157,6 +1304,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1157 { 1304 {
1158 DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG 1305 DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG
1159 tcbe.callback(); 1306 tcbe.callback();
1307 ret++;
1160 } 1308 }
1161 catch (Exception e) 1309 catch (Exception e)
1162 { 1310 {
@@ -1165,6 +1313,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1165 } 1313 }
1166 oldList.Clear(); 1314 oldList.Clear();
1167 } 1315 }
1316 return ret;
1168 } 1317 }
1169 1318
1170 // Schedule an update to happen after all the regular taints are processed. 1319 // Schedule an update to happen after all the regular taints are processed.
@@ -1183,8 +1332,11 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1183 } 1332 }
1184 1333
1185 // Taints that happen after the normal taint processing but before the simulation step. 1334 // Taints that happen after the normal taint processing but before the simulation step.
1186 private void ProcessPostTaintTaints() 1335 // Returns the number of taints processed
1336 // NOTE: Called while PhysicsEngineLock is locked
1337 private int ProcessPostTaintTaints()
1187 { 1338 {
1339 int ret = 0;
1188 if (m_initialized && _postTaintOperations.Count > 0) 1340 if (m_initialized && _postTaintOperations.Count > 0)
1189 { 1341 {
1190 Dictionary<string, TaintCallbackEntry> oldList; 1342 Dictionary<string, TaintCallbackEntry> oldList;
@@ -1200,6 +1352,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1200 { 1352 {
1201 DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG 1353 DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG
1202 kvp.Value.callback(); 1354 kvp.Value.callback();
1355 ret++;
1203 } 1356 }
1204 catch (Exception e) 1357 catch (Exception e)
1205 { 1358 {
@@ -1208,20 +1361,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS
1208 } 1361 }
1209 oldList.Clear(); 1362 oldList.Clear();
1210 } 1363 }
1364 return ret;
1211 } 1365 }
1212
1213 // Only used for debugging. Does not change state of anything so locking is not necessary.
1214 public bool AssertInTaintTime(string whereFrom)
1215 {
1216 if (!InTaintTime)
1217 {
1218 DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
1219 m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
1220 // Util.PrintCallStack(DetailLog);
1221 }
1222 return InTaintTime;
1223 }
1224
1225 #endregion // Taints 1366 #endregion // Taints
1226 1367
1227 #region IPhysicsParameters 1368 #region IPhysicsParameters
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs
index b100273..86bf23f 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs
@@ -30,7 +30,6 @@ using System.Text;
30using OMV = OpenMetaverse; 30using OMV = OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.PhysicsModules.SharedBase; 32using OpenSim.Region.PhysicsModules.SharedBase;
33using OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet;
34 33
35namespace OpenSim.Region.PhysicsModule.BulletS 34namespace OpenSim.Region.PhysicsModule.BulletS
36{ 35{
@@ -76,8 +75,6 @@ public sealed class BSShapeCollection : IDisposable
76 // Called at taint-time. 75 // Called at taint-time.
77 public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback) 76 public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback)
78 { 77 {
79 m_physicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape");
80
81 bool ret = false; 78 bool ret = false;
82 79
83 // This lock could probably be pushed down lower but building shouldn't take long 80 // This lock could probably be pushed down lower but building shouldn't take long
@@ -230,6 +227,8 @@ public sealed class BSShapeCollection : IDisposable
230 ret = CreateGeomMeshOrHull(prim, shapeCallback); 227 ret = CreateGeomMeshOrHull(prim, shapeCallback);
231 } 228 }
232 229
230 m_physicsScene.PE.ResetBroadphasePool(m_physicsScene.World); // DEBUG DEBUG
231
233 return ret; 232 return ret;
234 } 233 }
235 234
@@ -345,8 +344,6 @@ public sealed class BSShapeCollection : IDisposable
345 if (!body.HasPhysicalBody) 344 if (!body.HasPhysicalBody)
346 return; 345 return;
347 346
348 m_physicsScene.AssertInTaintTime("BSShapeCollection.DereferenceBody");
349
350 lock (m_collectionActivityLock) 347 lock (m_collectionActivityLock)
351 { 348 {
352 if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.ID, body); 349 if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.ID, body);
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs b/OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs
index 086a412..e791b27 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSShapes.cs
@@ -31,8 +31,8 @@ using System.Text;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.PhysicsModules.SharedBase; 33using OpenSim.Region.PhysicsModules.SharedBase;
34using OpenSim.Region.PhysicsModules.Meshing; 34using OpenSim.Region.PhysicsModule.Meshing;
35using OpenSim.Region.PhysicsModule.ConvexDecompositionDotNet; 35using OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet;
36 36
37using OMV = OpenMetaverse; 37using OMV = OpenMetaverse;
38 38
@@ -555,7 +555,9 @@ public class BSShapeMesh : BSShape
555 { 555 {
556 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, 556 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
557 false, // say it is not physical so a bounding box is not built 557 false, // say it is not physical so a bounding box is not built
558 false // do not cache the mesh and do not use previously built versions 558 false, // do not cache the mesh and do not use previously built versions
559 false,
560 false
559 ); 561 );
560 } 562 }
561 563
@@ -712,7 +714,7 @@ public class BSShapeHull : BSShape
712 lock (physicsScene.mesher) 714 lock (physicsScene.mesher)
713 { 715 {
714 // Pass true for physicalness as this prevents the creation of bounding box which is not needed 716 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
715 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); 717 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
716 718
717 // If we should use the asset's hull info, fetch it out of the locked mesher 719 // If we should use the asset's hull info, fetch it out of the locked mesher
718 if (meshData != null && BSParam.ShouldUseAssetHulls) 720 if (meshData != null && BSParam.ShouldUseAssetHulls)
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
index 42fc11b..f72ad28 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
@@ -141,14 +141,30 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
141 } 141 }
142 142
143 // The passed position is relative to the base of the region. 143 // The passed position is relative to the base of the region.
144 // There are many assumptions herein that the heightmap increment is 1.
144 public override float GetTerrainHeightAtXYZ(Vector3 pos) 145 public override float GetTerrainHeightAtXYZ(Vector3 pos)
145 { 146 {
146 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; 147 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
147 148
148 int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; 149 try {
149 try 150 int baseX = (int)pos.X;
150 { 151 int baseY = (int)pos.Y;
151 ret = m_mapInfo.heightMap[mapIndex]; 152 int maxX = (int)m_mapInfo.sizeX;
153 int maxY = (int)m_mapInfo.sizeY;
154 float diffX = pos.X - (float)baseX;
155 float diffY = pos.Y - (float)baseY;
156
157 float mapHeight1 = m_mapInfo.heightMap[baseY * maxY + baseX];
158 float mapHeight2 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + baseX];
159 float mapHeight3 = m_mapInfo.heightMap[baseY * maxY + Math.Min(baseX + 1, maxX - 1)];
160 float mapHeight4 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + Math.Min(baseX + 1, maxX - 1)];
161
162 float Xrise = (mapHeight4 - mapHeight3) * diffX;
163 float Yrise = (mapHeight2 - mapHeight1) * diffY;
164
165 ret = mapHeight1 + ((Xrise + Yrise) / 2f);
166 // m_physicsScene.DetailLog("{0},BSTerrainHeightMap,GetTerrainHeightAtXYZ,pos={1},{2}/{3}/{4}/{5},ret={6}",
167 // BSScene.DetailLogZero, pos, mapHeight1, mapHeight2, mapHeight3, mapHeight4, ret);
152 } 168 }
153 catch 169 catch
154 { 170 {
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs
index d11baa6..d11baa6 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainManager.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs
index cd59b65..cd59b65 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainMesh.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs b/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs
index 3329395..308769b 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs
@@ -100,6 +100,7 @@ public class BulletBody
100 } 100 }
101} 101}
102 102
103// Handle to btCollisionObject - a shape that can be added to a btRidgidBody
103public class BulletShape 104public class BulletShape
104{ 105{
105 public BulletShape() 106 public BulletShape()
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt b/OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt
index 0453376..0453376 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt
+++ b/OpenSim/Region/PhysicsModules/BulletS/BulletSimTODO.txt
diff --git a/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs b/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
index 2ba3c5a..ab5d4849 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS
136 136
137 return; 137 return;
138 } 138 }
139 139
140 // Register as LSL functions all the [ScriptInvocation] marked methods. 140 // Register as LSL functions all the [ScriptInvocation] marked methods.
141 Comms.RegisterScriptInvocations(this); 141 Comms.RegisterScriptInvocations(this);
142 Comms.RegisterConstants(this); 142 Comms.RegisterConstants(this);
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs b/OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs
index 698be39..91ce468 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Properties/AssemblyInfo.cs
@@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices; 3using System.Runtime.InteropServices;
4using Mono.Addins; 4using Mono.Addins;
5 5
6// General Information about an assembly is controlled through the following 6// General Information about an assembly is controlled through the following
7// set of attributes. Change these attribute values to modify the information 7// set of attributes. Change these attribute values to modify the information
8// associated with an assembly. 8// associated with an assembly.
9[assembly: AssemblyTitle("OpenSim.Region.Physics.BulletSPlugin")] 9[assembly: AssemblyTitle("OpenSim.Region.Physics.BulletSPlugin")]
@@ -15,8 +15,8 @@ using Mono.Addins;
15[assembly: AssemblyTrademark("")] 15[assembly: AssemblyTrademark("")]
16[assembly: AssemblyCulture("")] 16[assembly: AssemblyCulture("")]
17 17
18// Setting ComVisible to false makes the types in this assembly not visible 18// Setting ComVisible to false makes the types in this assembly not visible
19// to COM components. If you need to access a type in this assembly from 19// to COM components. If you need to access a type in this assembly from
20// COM, set the ComVisible attribute to true on that type. 20// COM, set the ComVisible attribute to true on that type.
21[assembly: ComVisible(false)] 21[assembly: ComVisible(false)]
22 22
@@ -26,11 +26,11 @@ using Mono.Addins;
26// Version information for an assembly consists of the following four values: 26// Version information for an assembly consists of the following four values:
27// 27//
28// Major Version 28// Major Version
29// Minor Version 29// Minor Version
30// Build Number 30// Build Number
31// Revision 31// Revision
32// 32//
33[assembly: AssemblyVersion("0.8.3.*")] 33[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
34 34
35[assembly: Addin("OpenSim.Region.PhysicsModule.BulletS", OpenSim.VersionInfo.VersionNumber)] 35[assembly: Addin("OpenSim.Region.PhysicsModule.BulletS", OpenSim.VersionInfo.VersionNumber)]
36[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] 36[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs
index 35eba29..35eba29 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/BasicVehicles.cs
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs
index 0be1f4c..14d0bdc 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTests.cs
@@ -1,56 +1,56 @@
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 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq; 30using System.Linq;
31using System.Text; 31using System.Text;
32 32
33using NUnit.Framework; 33using NUnit.Framework;
34using log4net; 34using log4net;
35 35
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37 37
38namespace OpenSim.Region.PhysicsModule.BulletS.Tests 38namespace OpenSim.Region.PhysicsModule.BulletS.Tests
39{ 39{
40[TestFixture] 40[TestFixture]
41public class BulletSimTests : OpenSimTestCase 41public class BulletSimTests : OpenSimTestCase
42{ 42{
43 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 43 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
44 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 44 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
45 45
46 [TestFixtureSetUp] 46 [TestFixtureSetUp]
47 public void Init() 47 public void Init()
48 { 48 {
49 } 49 }
50 50
51 [TestFixtureTearDown] 51 [TestFixtureTearDown]
52 public void TearDown() 52 public void TearDown()
53 { 53 {
54 } 54 }
55} 55}
56} 56}
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs
index 4eeea4d..3e8c1cd 100644..100755
--- a/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/BulletSimTestsUtil.cs
@@ -34,7 +34,7 @@ using Nini.Config;
34 34
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.PhysicsModules.SharedBase; 36using OpenSim.Region.PhysicsModules.SharedBase;
37using OpenSim.Region.PhysicsModules.Meshing; 37using OpenSim.Region.PhysicsModule.Meshing;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39 39
40using OpenMetaverse; 40using OpenMetaverse;
@@ -80,13 +80,13 @@ public static class BulletSimTestsUtil
80 } 80 }
81 81
82 Vector3 regionExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); 82 Vector3 regionExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
83 83
84 RegionInfo info = new RegionInfo(); 84 RegionInfo info = new RegionInfo();
85 info.RegionName = "BSTestRegion"; 85 info.RegionName = "BSTestRegion";
86 info.RegionSizeX = info.RegionSizeY = info.RegionSizeZ = Constants.RegionSize; 86 info.RegionSizeX = info.RegionSizeY = info.RegionSizeZ = Constants.RegionSize;
87 OpenSim.Region.Framework.Scenes.Scene scene = new OpenSim.Region.Framework.Scenes.Scene(info); 87 OpenSim.Region.Framework.Scenes.Scene scene = new OpenSim.Region.Framework.Scenes.Scene(info);
88 88
89 IMesher mesher = new OpenSim.Region.PhysicsModules.Meshing.Meshmerizer(); 89 IMesher mesher = new OpenSim.Region.PhysicsModule.Meshing.Meshmerizer();
90 INonSharedRegionModule mod = mesher as INonSharedRegionModule; 90 INonSharedRegionModule mod = mesher as INonSharedRegionModule;
91 mod.Initialise(openSimINI); 91 mod.Initialise(openSimINI);
92 mod.AddRegion(scene); 92 mod.AddRegion(scene);
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs
index c0cf19a..c2be568 100644
--- a/OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/HullCreation.cs
@@ -146,7 +146,7 @@ public class HullCreation : OpenSimTestCase
146 uint torusLocalID = 125; 146 uint torusLocalID = 125;
147 PhysicsScene.AddPrimShape("testTorus", pbs, pos, size, rot, isPhys, torusLocalID); 147 PhysicsScene.AddPrimShape("testTorus", pbs, pos, size, rot, isPhys, torusLocalID);
148 BSPrim primTypeTorus = (BSPrim)PhysicsScene.PhysObjects[torusLocalID]; 148 BSPrim primTypeTorus = (BSPrim)PhysicsScene.PhysObjects[torusLocalID];
149 149
150 // The actual prim shape creation happens at taint time 150 // The actual prim shape creation happens at taint time
151 PhysicsScene.ProcessTaints(); 151 PhysicsScene.ProcessTaints();
152 152
diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs
new file mode 100755
index 0000000..bfa95c1
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs
@@ -0,0 +1,124 @@
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 copyright
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 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33using NUnit.Framework;
34using log4net;
35
36using OpenSim.Framework;
37using OpenSim.Region.PhysicsModule.BulletS;
38using OpenSim.Region.PhysicsModules.SharedBase;
39using OpenSim.Tests.Common;
40
41using OpenMetaverse;
42
43namespace OpenSim.Region.PhysicsModule.BulletS.Tests
44{
45 [TestFixture]
46 public class BulletSimRaycast : OpenSimTestCase
47 {
48 // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
49 // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
50
51 BSScene _physicsScene { get; set; }
52 BSPrim _targetSphere { get; set; }
53 Vector3 _targetSpherePosition { get; set; }
54 float _simulationTimeStep = 0.089f;
55
56 uint _targetLocalID = 123;
57
58 [TestFixtureSetUp]
59 public void Init()
60 {
61 Dictionary<string, string> engineParams = new Dictionary<string, string>();
62 engineParams.Add("UseBulletRaycast", "true");
63 _physicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
64
65 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere();
66 Vector3 pos = new Vector3(100.0f, 100.0f, 50f);
67 _targetSpherePosition = pos;
68 Vector3 size = new Vector3(10f, 10f, 10f);
69 pbs.Scale = size;
70 Quaternion rot = Quaternion.Identity;
71 bool isPhys = false;
72
73 _physicsScene.AddPrimShape("TargetSphere", pbs, pos, size, rot, isPhys, _targetLocalID);
74 _targetSphere = (BSPrim)_physicsScene.PhysObjects[_targetLocalID];
75 // The actual prim shape creation happens at taint time
76 _physicsScene.ProcessTaints();
77
78 }
79
80 [TestFixtureTearDown]
81 public void TearDown()
82 {
83 if (_physicsScene != null)
84 {
85 // The Dispose() will also free any physical objects in the scene
86 _physicsScene.Dispose();
87 _physicsScene = null;
88 }
89 }
90
91 // There is a 10x10x10 sphere at <100,100,50>
92 // Shoot rays around the sphere and verify it hits and doesn't hit
93 // TestCase parameters are <x,y,z> of start and <x,y,z> of end and expected result
94 [TestCase(100f, 50f, 50f, 100f, 150f, 50f, true, "Pass through sphere from front")]
95 [TestCase(50f, 100f, 50f, 150f, 100f, 50f, true, "Pass through sphere from side")]
96 [TestCase(50f, 50f, 50f, 150f, 150f, 50f, true, "Pass through sphere diaginally")]
97 [TestCase(100f, 100f, 100f, 100f, 100f, 20f, true, "Pass through sphere from above")]
98 [TestCase(20f, 20f, 50f, 80f, 80f, 50f, false, "Not reach sphere")]
99 [TestCase(50f, 50f, 65f, 150f, 150f, 65f, false, "Passed over sphere")]
100 public void RaycastAroundObject(float fromX, float fromY, float fromZ, float toX, float toY, float toZ, bool expected, string msg) {
101 Vector3 fromPos = new Vector3(fromX, fromY, fromZ);
102 Vector3 toPos = new Vector3(toX, toY, toZ);
103 Vector3 direction = toPos - fromPos;
104 float len = Vector3.Distance(fromPos, toPos);
105
106 List<ContactResult> results = _physicsScene.RaycastWorld(fromPos, direction, len, 1);
107
108 if (expected) {
109 // The test coordinates should generate a hit
110 Assert.True(results.Count != 0, msg + ": Did not return a hit but expected to.");
111 Assert.True(results.Count == 1, msg + ": Raycast returned not just one hit result.");
112 Assert.True(results[0].ConsumerID == _targetLocalID, msg + ": Raycast returned a collision object other than the target");
113 }
114 else
115 {
116 // The test coordinates should not generate a hit
117 if (results.Count > 0)
118 {
119 Assert.False(results.Count > 0, msg + ": Returned a hit at " + results[0].Pos.ToString());
120 }
121 }
122 }
123 }
124} \ No newline at end of file