aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/PrimMesher.cs
diff options
context:
space:
mode:
authorDahlia Trimble2008-09-05 16:38:51 +0000
committerDahlia Trimble2008-09-05 16:38:51 +0000
commit0fc618e7b2c9e24d8f05e235bc3dd5c77c2bc062 (patch)
treed6b2fd2a7a34c1012ab247fdcddbf3ffe941f620 /OpenSim/Region/Physics/Meshing/PrimMesher.cs
parentcreate a "nant test" target to make it very simple to run the nunit (diff)
downloadopensim-SC-0fc618e7b2c9e24d8f05e235bc3dd5c77c2bc062.zip
opensim-SC-0fc618e7b2c9e24d8f05e235bc3dd5c77c2bc062.tar.gz
opensim-SC-0fc618e7b2c9e24d8f05e235bc3dd5c77c2bc062.tar.bz2
opensim-SC-0fc618e7b2c9e24d8f05e235bc3dd5c77c2bc062.tar.xz
Replaced a lot of trig calls with lookup tables for common prim types in an attempt to improve meshing speed.
Added a new between points interpolation method to improve accuracy of profile cuts in triangle and square profile prims.
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/PrimMesher.cs')
-rw-r--r--OpenSim/Region/Physics/Meshing/PrimMesher.cs245
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 /*
88angles3 = [
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
94angles4 = [
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
101angles24 = [
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
128angles24 = [
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 }