aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
diff options
context:
space:
mode:
authorMelanie2010-10-02 00:18:52 +0200
committerMelanie2010-10-02 00:18:52 +0200
commit9f7f266f583cfd47f3c66aa56b0ba26e634e8d91 (patch)
tree83b2c16487efc0b36443f9b37a17fbad48b7b7ed /OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
parentEnforce region agent limit as set in estate tools (diff)
downloadopensim-SC-9f7f266f583cfd47f3c66aa56b0ba26e634e8d91.zip
opensim-SC-9f7f266f583cfd47f3c66aa56b0ba26e634e8d91.tar.gz
opensim-SC-9f7f266f583cfd47f3c66aa56b0ba26e634e8d91.tar.bz2
opensim-SC-9f7f266f583cfd47f3c66aa56b0ba26e634e8d91.tar.xz
Replace CalculateMass with a better, contributed version
Diffstat (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs')
-rw-r--r--OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs471
1 files changed, 228 insertions, 243 deletions
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
index 2105be1..793774a 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
@@ -884,300 +884,285 @@ namespace OpenSim.Region.Physics.OdePlugin
884 884
885 private float CalculateMass() 885 private float CalculateMass()
886 { 886 {
887 float volume = 0; 887 float volume = _size.X * _size.Y * _size.Z; // default
888 888 float tmp;
889 // No material is passed to the physics engines yet.. soo..
890 // we're using the m_density constant in the class definition
891 889
892 float returnMass = 0; 890 float returnMass = 0;
893 891 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
892 float hollowVolume = hollowAmount * hollowAmount;
893
894 switch (_pbs.ProfileShape) 894 switch (_pbs.ProfileShape)
895 { 895 {
896 case ProfileShape.Square: 896 case ProfileShape.Square:
897 // Profile Volume 897 // default box
898
899 if (_pbs.PathCurve == (byte)Extrusion.Straight)
900 {
901 if (hollowAmount > 0.0)
902 {
903 switch (_pbs.HollowShape)
904 {
905 case HollowShape.Square:
906 case HollowShape.Same:
907 break;
898 908
899 volume = _size.X*_size.Y*_size.Z; 909 case HollowShape.Circle:
900 910
901 // If the user has 'hollowed out' 911 hollowVolume *= 0.78539816339f;
902 // ProfileHollow is one of those 0 to 50000 values :P 912 break;
903 // we like percentages better.. so turning into a percentage
904 913
905 if (((float) _pbs.ProfileHollow/50000f) > 0.0) 914 case HollowShape.Triangle:
906 { 915
907 float hollowAmount = (float) _pbs.ProfileHollow/50000f; 916 hollowVolume *= (0.5f * .5f);
917 break;
918
919 default:
920 hollowVolume = 0;
921 break;
922 }
923 volume *= (1.0f - hollowVolume);
924 }
925 }
908 926
909 // calculate the hollow volume by it's shape compared to the prim shape 927 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
910 float hollowVolume = 0;
911 switch (_pbs.HollowShape)
912 { 928 {
913 case HollowShape.Square: 929 //a tube
914 case HollowShape.Same: 930
915 // Cube Hollow volume calculation 931 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
916 float hollowsizex = _size.X*hollowAmount; 932 tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY);
917 float hollowsizey = _size.Y*hollowAmount; 933 volume -= volume*tmp*tmp;
918 float hollowsizez = _size.Z*hollowAmount; 934
919 hollowVolume = hollowsizex*hollowsizey*hollowsizez; 935 if (hollowAmount > 0.0)
920 break; 936 {
921 937 hollowVolume *= hollowAmount;
922 case HollowShape.Circle: 938
923 // Hollow shape is a perfect cyllinder in respect to the cube's scale 939 switch (_pbs.HollowShape)
924 // Cyllinder hollow volume calculation 940 {
925 float hRadius = _size.X/2; 941 case HollowShape.Square:
926 float hLength = _size.Z; 942 case HollowShape.Same:
927 943 break;
928 // pi * r2 * h 944
929 hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount); 945 case HollowShape.Circle:
930 break; 946 hollowVolume *= 0.78539816339f;;
931 947 break;
932 case HollowShape.Triangle: 948
933 // Equilateral Triangular Prism volume hollow calculation 949 case HollowShape.Triangle:
934 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y 950 hollowVolume *= 0.5f * 0.5f;
935 951 break;
936 float aLength = _size.Y; 952 default:
937 // 1/2 abh 953 hollowVolume = 0;
938 hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount); 954 break;
939 break; 955 }
940 956 volume *= (1.0f - hollowVolume);
941 default: 957 }
942 hollowVolume = 0;
943 break;
944 } 958 }
945 volume = volume - hollowVolume;
946 }
947 959
948 break; 960 break;
961
949 case ProfileShape.Circle: 962 case ProfileShape.Circle:
950 if (_pbs.PathCurve == (byte)Extrusion.Straight)
951 {
952 // Cylinder
953 float volume1 = (float)(Math.PI * Math.Pow(_size.X/2, 2) * _size.Z);
954 float volume2 = (float)(Math.PI * Math.Pow(_size.Y/2, 2) * _size.Z);
955 963
956 // Approximating the cylinder's irregularity. 964 if (_pbs.PathCurve == (byte)Extrusion.Straight)
957 if (volume1 > volume2)
958 {
959 volume = (float)volume1 - (volume1 - volume2);
960 }
961 else if (volume2 > volume1)
962 { 965 {
963 volume = (float)volume2 - (volume2 - volume1); 966 volume *= 0.78539816339f; // elipse base
967
968 if (hollowAmount > 0.0)
969 {
970 switch (_pbs.HollowShape)
971 {
972 case HollowShape.Same:
973 case HollowShape.Circle:
974 break;
975
976 case HollowShape.Square:
977 hollowVolume *= 0.5f * 2.5984480504799f;
978 break;
979
980 case HollowShape.Triangle:
981 hollowVolume *= .5f * 1.27323954473516f;
982 break;
983
984 default:
985 hollowVolume = 0;
986 break;
987 }
988 volume *= (1.0f - hollowVolume);
989 }
964 } 990 }
965 else 991
992 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
966 { 993 {
967 // Regular cylinder 994 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
968 volume = volume1; 995 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
969 } 996 volume *= (1.0f - tmp * tmp);
970 } 997
971 else 998 if (hollowAmount > 0.0)
972 { 999 {
973 // We don't know what the shape is yet, so use default
974 volume = _size.X * _size.Y * _size.Z;
975 }
976 // If the user has 'hollowed out'
977 // ProfileHollow is one of those 0 to 50000 values :P
978 // we like percentages better.. so turning into a percentage
979 1000
980 if (((float)_pbs.ProfileHollow / 50000f) > 0.0) 1001 // calculate the hollow volume by it's shape compared to the prim shape
981 { 1002 hollowVolume *= hollowAmount;
982 float hollowAmount = (float)_pbs.ProfileHollow / 50000f;
983 1003
984 // calculate the hollow volume by it's shape compared to the prim shape 1004 switch (_pbs.HollowShape)
985 float hollowVolume = 0; 1005 {
986 switch (_pbs.HollowShape) 1006 case HollowShape.Same:
987 { 1007 case HollowShape.Circle:
988 case HollowShape.Same: 1008 break;
989 case HollowShape.Circle: 1009
990 // Hollow shape is a perfect cyllinder in respect to the cube's scale 1010 case HollowShape.Square:
991 // Cyllinder hollow volume calculation 1011 hollowVolume *= 0.5f * 2.5984480504799f;
992 float hRadius = _size.X / 2; 1012 break;
993 float hLength = _size.Z; 1013
994 1014 case HollowShape.Triangle:
995 // pi * r2 * h 1015 hollowVolume *= .5f * 1.27323954473516f;
996 hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount); 1016 break;
997 break; 1017
998 1018 default:
999 case HollowShape.Square: 1019 hollowVolume = 0;
1000 // Cube Hollow volume calculation 1020 break;
1001 float hollowsizex = _size.X * hollowAmount; 1021 }
1002 float hollowsizey = _size.Y * hollowAmount; 1022 volume *= (1.0f - hollowVolume);
1003 float hollowsizez = _size.Z * hollowAmount; 1023 }
1004 hollowVolume = hollowsizex * hollowsizey * hollowsizez;
1005 break;
1006
1007 case HollowShape.Triangle:
1008 // Equilateral Triangular Prism volume hollow calculation
1009 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
1010
1011 float aLength = _size.Y;
1012 // 1/2 abh
1013 hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
1014 break;
1015
1016 default:
1017 hollowVolume = 0;
1018 break;
1019 } 1024 }
1020 volume = volume - hollowVolume;
1021 }
1022 break; 1025 break;
1023 1026
1024 case ProfileShape.HalfCircle: 1027 case ProfileShape.HalfCircle:
1025 if (_pbs.PathCurve == (byte)Extrusion.Curve1) 1028 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
1026 { 1029 {
1027 if (_size.X == _size.Y && _size.Y == _size.Z) 1030 volume *= 0.52359877559829887307710723054658f;
1028 {
1029 // regular sphere
1030 // v = 4/3 * pi * r^3
1031 float sradius3 = (float)Math.Pow((_size.X / 2), 3);
1032 volume = (float)((4f / 3f) * Math.PI * sradius3);
1033 }
1034 else
1035 {
1036 // we treat this as a box currently
1037 volume = _size.X * _size.Y * _size.Z;
1038 }
1039 }
1040 else
1041 {
1042 // We don't know what the shape is yet, so use default
1043 volume = _size.X * _size.Y * _size.Z;
1044 } 1031 }
1045 break; 1032 break;
1046 1033
1047 case ProfileShape.EquilateralTriangle: 1034 case ProfileShape.EquilateralTriangle:
1048 /*
1049 v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h
1050 1035
1051 // seed mesh 1036 if (_pbs.PathCurve == (byte)Extrusion.Straight)
1052 Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f); 1037 {
1053 Vertex PM = new Vertex(+0.5f, 0f, 0.0f); 1038 volume *= 0.32475953f;
1054 Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
1055 */
1056 float xA = -0.25f * _size.X;
1057 float yA = -0.45f * _size.Y;
1058 1039
1059 float xB = 0.5f * _size.X; 1040 if (hollowAmount > 0.0)
1060 float yB = 0; 1041 {
1061 1042
1062 float xC = -0.25f * _size.X; 1043 // calculate the hollow volume by it's shape compared to the prim shape
1063 float yC = 0.45f * _size.Y; 1044 switch (_pbs.HollowShape)
1045 {
1046 case HollowShape.Same:
1047 case HollowShape.Triangle:
1048 hollowVolume *= .25f;
1049 break;
1064 1050
1065 volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z); 1051 case HollowShape.Square:
1052 hollowVolume *= 0.499849f * 3.07920140172638f;
1053 break;
1066 1054
1067 // If the user has 'hollowed out' 1055 case HollowShape.Circle:
1068 // ProfileHollow is one of those 0 to 50000 values :P 1056 // Hollow shape is a perfect cyllinder in respect to the cube's scale
1069 // we like percentages better.. so turning into a percentage 1057 // Cyllinder hollow volume calculation
1070 float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f);
1071 if (((float)fhollowFactor / 50000f) > 0.0)
1072 {
1073 float hollowAmount = (float)fhollowFactor / 50000f;
1074 1058
1075 // calculate the hollow volume by it's shape compared to the prim shape 1059 hollowVolume *= 0.1963495f * 3.07920140172638f;
1076 float hollowVolume = 0; 1060 break;
1077 switch (_pbs.HollowShape) 1061
1078 { 1062 default:
1079 case HollowShape.Same: 1063 hollowVolume = 0;
1080 case HollowShape.Triangle: 1064 break;
1081 // Equilateral Triangular Prism volume hollow calculation 1065 }
1082 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y 1066 volume *= (1.0f - hollowVolume);
1083 1067 }
1084 float aLength = _size.Y;
1085 // 1/2 abh
1086 hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
1087 break;
1088
1089 case HollowShape.Square:
1090 // Cube Hollow volume calculation
1091 float hollowsizex = _size.X * hollowAmount;
1092 float hollowsizey = _size.Y * hollowAmount;
1093 float hollowsizez = _size.Z * hollowAmount;
1094 hollowVolume = hollowsizex * hollowsizey * hollowsizez;
1095 break;
1096
1097 case HollowShape.Circle:
1098 // Hollow shape is a perfect cyllinder in respect to the cube's scale
1099 // Cyllinder hollow volume calculation
1100 float hRadius = _size.X / 2;
1101 float hLength = _size.Z;
1102
1103 // pi * r2 * h
1104 hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount);
1105 break;
1106
1107 default:
1108 hollowVolume = 0;
1109 break;
1110 } 1068 }
1111 volume = volume - hollowVolume; 1069 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
1112 } 1070 {
1113 break; 1071 volume *= 0.32475953f;
1072 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
1073 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
1074 volume *= (1.0f - tmp * tmp);
1114 1075
1115 default: 1076 if (hollowAmount > 0.0)
1116 // we don't have all of the volume formulas yet so 1077 {
1117 // use the common volume formula for all
1118 volume = _size.X*_size.Y*_size.Z;
1119 break;
1120 }
1121 1078
1122 // Calculate Path cut effect on volume 1079 hollowVolume *= hollowAmount;
1123 // Not exact, in the triangle hollow example
1124 // They should never be zero or less then zero..
1125 // we'll ignore it if it's less then zero
1126 1080
1127 // ProfileEnd and ProfileBegin are values 1081 switch (_pbs.HollowShape)
1128 // from 0 to 50000 1082 {
1083 case HollowShape.Same:
1084 case HollowShape.Triangle:
1085 hollowVolume *= .25f;
1086 break;
1129 1087
1130 // Turning them back into percentages so that I can cut that percentage off the volume 1088 case HollowShape.Square:
1089 hollowVolume *= 0.499849f * 3.07920140172638f;
1090 break;
1131 1091
1132 float PathCutEndAmount = _pbs.ProfileEnd; 1092 case HollowShape.Circle:
1133 float PathCutStartAmount = _pbs.ProfileBegin;
1134 if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f)
1135 {
1136 float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f);
1137 1093
1138 // Check the return amount for sanity 1094 hollowVolume *= 0.1963495f * 3.07920140172638f;
1139 if (pathCutAmount >= 0.99f) 1095 break;
1140 pathCutAmount = 0.99f;
1141 1096
1142 volume = volume - (volume*pathCutAmount); 1097 default:
1143 } 1098 hollowVolume = 0;
1144 UInt16 taperX = _pbs.PathScaleX; 1099 break;
1145 UInt16 taperY = _pbs.PathScaleY; 1100 }
1146 float taperFactorX = 0; 1101 volume *= (1.0f - hollowVolume);
1147 float taperFactorY = 0; 1102 }
1103 }
1104 break;
1148 1105
1149 // Mass = density * volume 1106 default:
1150 if (taperX != 100) 1107 break;
1151 {
1152 if (taperX > 100)
1153 {
1154 taperFactorX = 1.0f - ((float)taperX / 200);
1155 //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
1156 }
1157 else
1158 {
1159 taperFactorX = 1.0f - ((100 - (float)taperX) / 100);
1160 //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
1161 } 1108 }
1162 volume = (float)volume * ((taperFactorX / 3f) + 0.001f);
1163 }
1164 1109
1165 if (taperY != 100) 1110
1166 { 1111
1167 if (taperY > 100) 1112 float taperX1;
1113 float taperY1;
1114 float taperX;
1115 float taperY;
1116 float pathBegin;
1117 float pathEnd;
1118 float profileBegin;
1119 float profileEnd;
1120
1121 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
1168 { 1122 {
1169 taperFactorY = 1.0f - ((float)taperY / 200); 1123 taperX1 = _pbs.PathScaleX * 0.01f;
1170 //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString()); 1124 if (taperX1 > 1.0f)
1125 taperX1 = 2.0f - taperX1;
1126 taperX = 1.0f - taperX1;
1127
1128 taperY1 = _pbs.PathScaleY * 0.01f;
1129 if (taperY1 > 1.0f)
1130 taperY1 = 2.0f - taperY1;
1131 taperY = 1.0f - taperY1;
1171 } 1132 }
1172 else 1133 else
1173 { 1134 {
1174 taperFactorY = 1.0f - ((100 - (float)taperY) / 100); 1135 taperX = _pbs.PathTaperX * 0.01f;
1175 //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString()); 1136 if (taperX < 0.0f)
1137 taperX = -taperX;
1138 taperX1 = 1.0f - taperX;
1139
1140 taperY = _pbs.PathTaperY * 0.01f;
1141 if (taperY < 0.0f)
1142 taperY = -taperY;
1143 taperY1 = 1.0f - taperY;
1144
1176 } 1145 }
1177 volume = (float)volume * ((taperFactorY / 3f) + 0.001f); 1146
1178 } 1147
1179 returnMass = m_density*volume; 1148 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
1180 if (returnMass <= 0) returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. 1149
1150 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
1151 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
1152 volume *= (pathEnd - pathBegin);
1153
1154// this is crude aproximation
1155 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
1156 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
1157 volume *= (profileEnd - profileBegin);
1158
1159 returnMass = m_density * volume;
1160
1161 if (returnMass <= 0)
1162 returnMass = 0.0001f;//ckrinke: Mass must be greater then zero.
1163// else if (returnMass > _parent_scene.maximumMassObject)
1164// returnMass = _parent_scene.maximumMassObject;
1165
1181 1166
1182 1167
1183 1168