diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/PrimMesher.cs | 245 |
1 files changed, 202 insertions, 43 deletions
diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs index e15804e..86bdabc 100644 --- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs | |||
@@ -79,10 +79,137 @@ namespace OpenSim.Region.Physics.Meshing | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | //internal float angles3[][] = [ | ||
83 | //[0.0f, 1.0f, 0.0f], | ||
84 | //[0.33333333333333331f, -0.49999999999999978f, 0.86602540378443871f], | ||
85 | //[0.66666666666666663f, -0.50000000000000044f, -0.86602540378443837f], | ||
86 | //[1.0f, 1.0f, -2.4492127076447545e-016f]]; | ||
87 | /* | ||
88 | angles3 = [ | ||
89 | [0.0, 1.0, 0.0], | ||
90 | [0.33333333333333331, -0.49999999999999978, 0.86602540378443871], | ||
91 | [0.66666666666666663, -0.50000000000000044, -0.86602540378443837], | ||
92 | [1.0, 1.0, -2.4492127076447545e-016]] | ||
93 | |||
94 | angles4 = [ | ||
95 | [0.0, 1.0, 0.0], | ||
96 | [0.25, 0.0, 1.0], | ||
97 | [0.5, -1.0, 0.0], | ||
98 | [0.75, 0.0, -1.0], | ||
99 | [1.0, 1.0, 0.0]] | ||
100 | |||
101 | angles24 = [ | ||
102 | [0.0, 0.5, 0.0], | ||
103 | [0.041666666666666664, 0.48296291314453416, 0.12940952255126037], | ||
104 | [0.083333333333333329, 0.43301270189221935, 0.25], | ||
105 | [0.125, 0.35355339059327379, 0.35355339059327373], | ||
106 | [0.16666666666666666, 0.25, 0.4330127018922193], | ||
107 | [0.20833333333333331, 0.12940952255126048, 0.4829629131445341], | ||
108 | [0.25, 0.0, 0.5], | ||
109 | [0.29166666666666663, -0.12940952255126031, 0.48296291314453416], | ||
110 | [0.33333333333333331, -0.25, 0.43301270189221935], | ||
111 | [0.375, -0.35355339059327373, 0.35355339059327379], | ||
112 | [0.41666666666666663, -0.43301270189221924, 0.25], | ||
113 | [0.45833333333333331, -0.4829629131445341, 0.12940952255126051], | ||
114 | [0.5, -0.5, 0.0], | ||
115 | [0.54166666666666663, -0.48296291314453421, -0.12940952255126018], | ||
116 | [0.58333333333333326, -0.43301270189221941, -0.25], | ||
117 | [0.62499999999999989, -0.35355339059327395, -0.35355339059327356], | ||
118 | [0.66666666666666663, -0.25, -0.43301270189221919], | ||
119 | [0.70833333333333326, -0.12940952255126076, -0.48296291314453405], | ||
120 | [0.75, 0.0, -0.5], | ||
121 | [0.79166666666666663, 0.12940952255126015, -0.48296291314453421], | ||
122 | [0.83333333333333326, 0.25, -0.43301270189221952], | ||
123 | [0.875, 0.35355339059327368, -0.35355339059327384], | ||
124 | [0.91666666666666663, 0.43301270189221919, -0.25], | ||
125 | [0.95833333333333326, 0.48296291314453405, -0.12940952255126079], | ||
126 | [1.0, 0.5, 0.0]] | ||
127 | |||
128 | angles24 = [ | ||
129 | [0.0, 1.0, 0.0], | ||
130 | [0.041666666666666664, 0.96592582628906831, 0.25881904510252074], | ||
131 | [0.083333333333333329, 0.86602540378443871, 0.5], | ||
132 | [0.125, 0.70710678118654757, 0.70710678118654746], | ||
133 | [0.16666666666666667, 0.5, 0.8660254037844386], | ||
134 | [0.20833333333333331, 0.25881904510252096, 0.9659258262890682], | ||
135 | [0.25, 6.1230317691118863e-017, 1.0], | ||
136 | [0.29166666666666663, -0.25881904510252063, 0.96592582628906831], | ||
137 | [0.33333333333333333, -0.5, 0.86602540378443871], | ||
138 | [0.375, -0.70710678118654746, 0.70710678118654757], | ||
139 | [0.41666666666666663, -0.86602540378443849, 0.5], | ||
140 | [0.45833333333333331, -0.9659258262890682, 0.25881904510252102], | ||
141 | [0.5, -1.0, 1.2246063538223773e-016], | ||
142 | [0.54166666666666663, -0.96592582628906842, -0.25881904510252035], | ||
143 | [0.58333333333333326, -0.86602540378443882, -0.5], | ||
144 | [0.62499999999999989, -0.70710678118654791, -0.70710678118654713], | ||
145 | [0.66666666666666667, -0.5, -0.86602540378443837], | ||
146 | [0.70833333333333326, -0.25881904510252152, -0.96592582628906809], | ||
147 | [0.75, -1.8369095307335659e-016, -1.0], | ||
148 | [0.79166666666666663, 0.2588190451025203, -0.96592582628906842], | ||
149 | [0.83333333333333326, 0.5, -0.86602540378443904], | ||
150 | [0.875, 0.70710678118654735, -0.70710678118654768], | ||
151 | [0.91666666666666663, 0.86602540378443837, -0.5], | ||
152 | [0.95833333333333326, 0.96592582628906809, -0.25881904510252157], | ||
153 | [1.0, 1.0, -2.4492127076447545e-016]] | ||
154 | |||
155 | */ | ||
156 | |||
82 | internal class AngleList | 157 | internal class AngleList |
83 | { | 158 | { |
84 | private float iX, iY; // intersection point | 159 | private float iX, iY; // intersection point |
85 | 160 | ||
161 | private Angle[] angles3 = | ||
162 | { | ||
163 | new Angle(0.0f, 1.0f, 0.0f), | ||
164 | new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), | ||
165 | new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), | ||
166 | new Angle(1.0f, 1.0f, 0.0f) | ||
167 | }; | ||
168 | |||
169 | private Angle[] angles4 = | ||
170 | { | ||
171 | new Angle(0.0f, 1.0f, 0.0f), | ||
172 | new Angle(0.25f, 0.0f, 1.0f), | ||
173 | new Angle(0.5f, -1.0f, 0.0f), | ||
174 | new Angle(0.75f, 0.0f, -1.0f), | ||
175 | new Angle(1.0f, 1.0f, 0.0f) | ||
176 | }; | ||
177 | |||
178 | private Angle[] angles24 = | ||
179 | { | ||
180 | new Angle(0.0f, 1.0f, 0.0f), | ||
181 | new Angle(0.041666666666666664f, 0.96592582628906831f, 0.25881904510252074f), | ||
182 | new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f), | ||
183 | new Angle(0.125f, 0.70710678118654757f, 0.70710678118654746f), | ||
184 | new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), | ||
185 | new Angle(0.20833333333333331f, 0.25881904510252096f, 0.9659258262890682f), | ||
186 | new Angle(0.25f, 0.0f, 1.0f), | ||
187 | new Angle(0.29166666666666663f, -0.25881904510252063f, 0.96592582628906831f), | ||
188 | new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), | ||
189 | new Angle(0.375f, -0.70710678118654746f, 0.70710678118654757f), | ||
190 | new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f), | ||
191 | new Angle(0.45833333333333331f, -0.9659258262890682f, 0.25881904510252102f), | ||
192 | new Angle(0.5f, -1.0f, 0.0f), | ||
193 | new Angle(0.54166666666666663f, -0.96592582628906842f, -0.25881904510252035f), | ||
194 | new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f), | ||
195 | new Angle(0.62499999999999989f, -0.70710678118654791f, -0.70710678118654713f), | ||
196 | new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), | ||
197 | new Angle(0.70833333333333326f, -0.25881904510252152f, -0.96592582628906809f), | ||
198 | new Angle(0.75f, 0.0f, -1.0f), | ||
199 | new Angle(0.79166666666666663f, 0.2588190451025203f, -0.96592582628906842f), | ||
200 | new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), | ||
201 | new Angle(0.875f, 0.70710678118654735f, -0.70710678118654768f), | ||
202 | new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f), | ||
203 | new Angle(0.95833333333333326f, 0.96592582628906809f, -0.25881904510252157f), | ||
204 | new Angle(1.0f, 1.0f, 0.0f) | ||
205 | }; | ||
206 | |||
207 | private Angle interpolatePoints(float newPoint, Angle p1, Angle p2) | ||
208 | { | ||
209 | float m = (newPoint - p1.angle) / (p2.angle - p1.angle); | ||
210 | return new Angle(newPoint, p1.X + m * (p2.X - p1.X), p1.Y + m * (p2.Y - p1.Y)); | ||
211 | } | ||
212 | |||
86 | private void intersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) | 213 | private void intersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) |
87 | { // ref: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ | 214 | { // ref: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ |
88 | double denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); | 215 | double denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); |
@@ -98,64 +225,96 @@ namespace OpenSim.Region.Physics.Meshing | |||
98 | 225 | ||
99 | internal List<Angle> angles; | 226 | internal List<Angle> angles; |
100 | 227 | ||
101 | // this class should have a table of most commonly computed values | ||
102 | // instead of all the trig function calls | ||
103 | // most common would be for sides = 3, 4, or 24 | ||
104 | internal void makeAngles( int sides, float startAngle, float stopAngle ) | 228 | internal void makeAngles( int sides, float startAngle, float stopAngle ) |
105 | { | 229 | { |
106 | angles = new List<Angle>(); | 230 | angles = new List<Angle>(); |
107 | double twoPi = System.Math.PI * 2.0; | 231 | double twoPi = System.Math.PI * 2.0; |
232 | float twoPiInv = 1.0f / (float)twoPi; | ||
108 | 233 | ||
109 | if (sides < 1) | 234 | if (sides < 1) |
110 | throw new Exception("number of sides not greater than zero"); | 235 | throw new Exception("number of sides not greater than zero"); |
111 | if (stopAngle <= startAngle) | 236 | if (stopAngle <= startAngle) |
112 | throw new Exception("stopAngle not greater than startAngle"); | 237 | throw new Exception("stopAngle not greater than startAngle"); |
113 | 238 | ||
114 | double stepSize = twoPi / sides; | 239 | if ((sides == 3 || sides == 4 || sides == 24)) |
115 | |||
116 | int startStep = (int) (startAngle / stepSize); | ||
117 | double angle = stepSize * startStep; | ||
118 | int step = startStep; | ||
119 | double stopAngleTest = stopAngle; | ||
120 | if (stopAngle < twoPi) | ||
121 | { | 240 | { |
122 | stopAngleTest = stepSize * ((int)(stopAngle / stepSize) + 1); | 241 | startAngle *= twoPiInv; |
123 | if (stopAngleTest < stopAngle) | 242 | stopAngle *= twoPiInv; |
124 | stopAngleTest += stepSize; | 243 | |
125 | if (stopAngleTest > twoPi) | 244 | Angle[] sourceAngles; |
126 | stopAngleTest = twoPi; | 245 | if (sides == 3) |
246 | sourceAngles = angles3; | ||
247 | else if (sides == 4) | ||
248 | sourceAngles = angles4; | ||
249 | else sourceAngles = angles24; | ||
250 | |||
251 | int startAngleIndex = (int)(startAngle * sides); | ||
252 | int endAngleIndex = sourceAngles.Length - 1; | ||
253 | if (stopAngle < 1.0f) | ||
254 | endAngleIndex = (int)(stopAngle * sides) + 1; | ||
255 | if (endAngleIndex == startAngleIndex) | ||
256 | endAngleIndex++; | ||
257 | |||
258 | for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) | ||
259 | angles.Add(sourceAngles[angleIndex]); | ||
260 | |||
261 | if (startAngle > 0.0f) | ||
262 | angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); | ||
263 | |||
264 | if (stopAngle < 1.0f) | ||
265 | { | ||
266 | int lastAngleIndex = angles.Count - 1; | ||
267 | angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); | ||
268 | } | ||
127 | } | 269 | } |
128 | 270 | else | |
129 | while (angle <= stopAngleTest) | ||
130 | { | 271 | { |
131 | Angle newAngle; | 272 | double stepSize = twoPi / sides; |
132 | newAngle.angle = (float) angle; | ||
133 | newAngle.X = (float) System.Math.Cos(angle); | ||
134 | newAngle.Y = (float) System.Math.Sin(angle); | ||
135 | angles.Add(newAngle); | ||
136 | step += 1; | ||
137 | angle = stepSize * step; | ||
138 | } | ||
139 | 273 | ||
140 | if (startAngle > angles[0].angle) | 274 | int startStep = (int)(startAngle / stepSize); |
141 | { | 275 | double angle = stepSize * startStep; |
142 | Angle newAngle; | 276 | int step = startStep; |
143 | intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, 0.0f, 0.0f, (float)Math.Cos(startAngle), (float)Math.Sin(startAngle)); | 277 | double stopAngleTest = stopAngle; |
144 | newAngle.angle = startAngle; | 278 | if (stopAngle < twoPi) |
145 | newAngle.X = iX; | 279 | { |
146 | newAngle.Y = iY; | 280 | stopAngleTest = stepSize * ((int)(stopAngle / stepSize) + 1); |
147 | angles[0] = newAngle; | 281 | if (stopAngleTest < stopAngle) |
148 | } | 282 | stopAngleTest += stepSize; |
283 | if (stopAngleTest > twoPi) | ||
284 | stopAngleTest = twoPi; | ||
285 | } | ||
149 | 286 | ||
150 | int index = angles.Count - 1; | 287 | while (angle <= stopAngleTest) |
151 | if (stopAngle < angles[index].angle) | 288 | { |
152 | { | 289 | Angle newAngle; |
153 | Angle newAngle; | 290 | newAngle.angle = (float)angle; |
154 | intersection(angles[index - 1].X, angles[index - 1].Y, angles[index].X, angles[index].Y, 0.0f, 0.0f, (float)Math.Cos(stopAngle), (float)Math.Sin(stopAngle)); | 291 | newAngle.X = (float)System.Math.Cos(angle); |
155 | newAngle.angle = stopAngle; | 292 | newAngle.Y = (float)System.Math.Sin(angle); |
156 | newAngle.X = iX; | 293 | angles.Add(newAngle); |
157 | newAngle.Y = iY; | 294 | step += 1; |
158 | angles[index] = newAngle; | 295 | angle = stepSize * step; |
296 | } | ||
297 | |||
298 | if (startAngle > angles[0].angle) | ||
299 | { | ||
300 | Angle newAngle; | ||
301 | intersection(angles[0].X, angles[0].Y, angles[1].X, angles[1].Y, 0.0f, 0.0f, (float)Math.Cos(startAngle), (float)Math.Sin(startAngle)); | ||
302 | newAngle.angle = startAngle; | ||
303 | newAngle.X = iX; | ||
304 | newAngle.Y = iY; | ||
305 | angles[0] = newAngle; | ||
306 | } | ||
307 | |||
308 | int index = angles.Count - 1; | ||
309 | if (stopAngle < angles[index].angle) | ||
310 | { | ||
311 | Angle newAngle; | ||
312 | intersection(angles[index - 1].X, angles[index - 1].Y, angles[index].X, angles[index].Y, 0.0f, 0.0f, (float)Math.Cos(stopAngle), (float)Math.Sin(stopAngle)); | ||
313 | newAngle.angle = stopAngle; | ||
314 | newAngle.X = iX; | ||
315 | newAngle.Y = iY; | ||
316 | angles[index] = newAngle; | ||
317 | } | ||
159 | } | 318 | } |
160 | } | 319 | } |
161 | } | 320 | } |