diff options
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r-- | OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 471 |
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 | ||