aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/Extruder.cs
diff options
context:
space:
mode:
authorDahlia Trimble2008-11-29 11:02:14 +0000
committerDahlia Trimble2008-11-29 11:02:14 +0000
commitfdd238833163eb947986bfcdd09da82f6949a5f2 (patch)
tree6b90177758405f6106f4f5d4d75e3b98bf08053c /OpenSim/Region/Physics/Meshing/Extruder.cs
parentComment the ScriptSponsor and restore the indefinite lifetime for (diff)
downloadopensim-SC_OLD-fdd238833163eb947986bfcdd09da82f6949a5f2.zip
opensim-SC_OLD-fdd238833163eb947986bfcdd09da82f6949a5f2.tar.gz
opensim-SC_OLD-fdd238833163eb947986bfcdd09da82f6949a5f2.tar.bz2
opensim-SC_OLD-fdd238833163eb947986bfcdd09da82f6949a5f2.tar.xz
Update meshing code to sync with current PrimMesher.cs on forge.
Migrate sculpt meshing code to primMesher version. This should result in more accurate physical sculpted prim proxies. Remove much obsolete code from Region/Physics/Meshing
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/Extruder.cs')
-rw-r--r--OpenSim/Region/Physics/Meshing/Extruder.cs472
1 files changed, 0 insertions, 472 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Extruder.cs b/OpenSim/Region/Physics/Meshing/Extruder.cs
deleted file mode 100644
index 1fc65e3..0000000
--- a/OpenSim/Region/Physics/Meshing/Extruder.cs
+++ /dev/null
@@ -1,472 +0,0 @@
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 OpenSim 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//#define SPAM
28
29using OpenMetaverse;
30using OpenSim.Region.Physics.Manager;
31
32namespace OpenSim.Region.Physics.Meshing
33{
34 internal class Extruder
35 {
36 //public float startParameter;
37 //public float stopParameter;
38 public PhysicsVector size;
39
40 public float taperTopFactorX = 1f;
41 public float taperTopFactorY = 1f;
42 public float taperBotFactorX = 1f;
43 public float taperBotFactorY = 1f;
44
45 public float pushX = 0f;
46 public float pushY = 0f;
47
48 // twist amount in radians. NOT DEGREES.
49 public float twistTop = 0;
50 public float twistBot = 0;
51 public float twistMid = 0;
52 public float pathScaleX = 1.0f;
53 public float pathScaleY = 0.5f;
54 public float skew = 0.0f;
55 public float radius = 0.0f;
56 public float revolutions = 1.0f;
57
58 public float pathCutBegin = 0.0f;
59 public float pathCutEnd = 1.0f;
60
61 public ushort pathBegin = 0;
62 public ushort pathEnd = 0;
63
64 public float pathTaperX = 0.0f;
65 public float pathTaperY = 0.0f;
66
67 /// <summary>
68 /// Creates an extrusion of a profile along a linear path. Used to create prim types box, cylinder, and prism.
69 /// </summary>
70 /// <param name="m"></param>
71 /// <returns>A mesh of the extruded shape</returns>
72 public Mesh ExtrudeLinearPath(Mesh m)
73 {
74 Mesh result = new Mesh();
75
76 Mesh newLayer;
77 Mesh lastLayer = null;
78
79 int step = 0;
80 int steps = 1;
81
82 float twistTotal = twistTop - twistBot;
83 // if the profile has a lot of twist, add more layers otherwise the layers may overlap
84 // and the resulting mesh may be quite inaccurate. This method is arbitrary and may not
85 // accurately match the viewer
86 float twistTotalAbs = System.Math.Abs(twistTotal);
87 if (twistTotalAbs > 0.01)
88 steps += (int)(twistTotalAbs * 3.66f); // dahlia's magic number ;)
89
90#if SPAM
91 System.Console.WriteLine("ExtrudeLinearPath: twistTotalAbs: " + twistTotalAbs.ToString() + " steps: " + steps.ToString());
92#endif
93
94 double percentOfPathMultiplier = 1.0 / steps;
95
96 float start = -0.5f;
97
98 float stepSize = 1.0f / (float)steps;
99
100 float xProfileScale = 1.0f;
101 float yProfileScale = 1.0f;
102
103 float xOffset = 0.0f;
104 float yOffset = 0.0f;
105 float zOffset = start;
106
107 float xOffsetStepIncrement = pushX / steps;
108 float yOffsetStepIncrement = pushY / steps;
109
110#if SPAM
111 System.Console.WriteLine("Extruder: twistTop: " + twistTop.ToString() + " twistbot: " + twistBot.ToString() + " twisttotal: " + twistTotal.ToString());
112 System.Console.WriteLine("Extruder: taperBotFactorX: " + taperBotFactorX.ToString() + " taperBotFactorY: " + taperBotFactorY.ToString()
113 + " taperTopFactorX: " + taperTopFactorX.ToString() + " taperTopFactorY: " + taperTopFactorY.ToString());
114 System.Console.WriteLine("Extruder: PathScaleX: " + pathScaleX.ToString() + " pathScaleY: " + pathScaleY.ToString());
115#endif
116
117 //float percentOfPath = 0.0f;
118 float percentOfPath = (float)pathBegin * 2.0e-5f;
119 zOffset += percentOfPath;
120 bool done = false;
121 do // loop through the length of the path and add the layers
122 {
123 newLayer = m.Clone();
124
125 if (taperBotFactorX < 1.0f)
126 xProfileScale = 1.0f - (1.0f - percentOfPath) * (1.0f - taperBotFactorX);
127 else if (taperTopFactorX < 1.0f)
128 xProfileScale = 1.0f - percentOfPath * (1.0f - taperTopFactorX);
129 else xProfileScale = 1.0f;
130
131 if (taperBotFactorY < 1.0f)
132 yProfileScale = 1.0f - (1.0f - percentOfPath) * (1.0f - taperBotFactorY);
133 else if (taperTopFactorY < 1.0f)
134 yProfileScale = 1.0f - percentOfPath * (1.0f - taperTopFactorY);
135 else yProfileScale = 1.0f;
136
137#if SPAM
138 //System.Console.WriteLine("xProfileScale: " + xProfileScale.ToString() + " yProfileScale: " + yProfileScale.ToString());
139#endif
140 Vertex vTemp = new Vertex(0.0f, 0.0f, 0.0f);
141
142 // apply the taper to the profile before any rotations
143 if (xProfileScale != 1.0f || yProfileScale != 1.0f)
144 {
145 foreach (Vertex v in newLayer.vertices)
146 {
147 if (v != null)
148 {
149 v.X *= xProfileScale;
150 v.Y *= yProfileScale;
151 }
152 }
153 }
154
155
156 float twist = twistBot + (twistTotal * (float)percentOfPath);
157#if SPAM
158 System.Console.WriteLine("Extruder: percentOfPath: " + percentOfPath.ToString() + " zOffset: " + zOffset.ToString()
159 + " xProfileScale: " + xProfileScale.ToString() + " yProfileScale: " + yProfileScale.ToString());
160#endif
161
162 // apply twist rotation to the profile layer and position the layer in the prim
163
164 Quaternion profileRot = Quaternion.CreateFromAxisAngle(new Vector3(0.0f, 0.0f, 1.0f), twist);
165 foreach (Vertex v in newLayer.vertices)
166 {
167 if (v != null)
168 {
169 vTemp = v * profileRot;
170 v.X = vTemp.X + xOffset;
171 v.Y = vTemp.Y + yOffset;
172 v.Z = vTemp.Z + zOffset;
173 }
174 }
175
176 if (step == 0) // the first layer, invert normals
177 {
178 foreach (Triangle t in newLayer.triangles)
179 {
180 t.invertNormal();
181 }
182 }
183
184 result.Append(newLayer);
185
186 int iLastNull = 0;
187
188 if (lastLayer != null)
189 {
190 int i, count = newLayer.vertices.Count;
191
192 for (i = 0; i < count; i++)
193 {
194 int iNext = (i + 1);
195
196 if (lastLayer.vertices[i] == null) // cant make a simplex here
197 {
198 iLastNull = i + 1;
199 }
200 else
201 {
202 if (i == count - 1) // End of list
203 iNext = iLastNull;
204
205 if (lastLayer.vertices[iNext] == null) // Null means wrap to begin of last segment
206 iNext = iLastNull;
207
208 result.Add(new Triangle(newLayer.vertices[i], lastLayer.vertices[i], newLayer.vertices[iNext]));
209 result.Add(new Triangle(newLayer.vertices[iNext], lastLayer.vertices[i], lastLayer.vertices[iNext]));
210 }
211 }
212 }
213 lastLayer = newLayer;
214
215 // calc the step for the next interation of the loop
216
217 if (step < steps)
218 {
219 step++;
220 percentOfPath += (float)percentOfPathMultiplier;
221
222 xOffset += xOffsetStepIncrement;
223 yOffset += yOffsetStepIncrement;
224 zOffset += stepSize;
225
226 if (percentOfPath > 1.0f - (float)pathEnd * 2.0e-5f)
227 done = true;
228 }
229 else done = true;
230
231 } while (!done); // loop until all the layers in the path are completed
232
233 // scale the mesh to the desired size
234 float xScale = size.X;
235 float yScale = size.Y;
236 float zScale = size.Z;
237
238 foreach (Vertex v in result.vertices)
239 {
240 if (v != null)
241 {
242 v.X *= xScale;
243 v.Y *= yScale;
244 v.Z *= zScale;
245 }
246 }
247
248 return result;
249 }
250
251 /// <summary>
252 /// Extrudes a shape around a circular path. Used to create prim types torus, ring, and tube.
253 /// </summary>
254 /// <param name="m"></param>
255 /// <returns>a mesh of the extruded shape</returns>
256 public Mesh ExtrudeCircularPath(Mesh m)
257 {
258 Mesh result = new Mesh();
259
260 Mesh newLayer;
261 Mesh lastLayer = null;
262
263 int step;
264 int steps = 24;
265
266 float twistTotal = twistTop - twistBot;
267 // if the profile has a lot of twist, add more layers otherwise the layers may overlap
268 // and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't
269 // accurately match the viewer
270 if (System.Math.Abs(twistTotal) > (float)System.Math.PI * 1.5f) steps *= 2;
271 if (System.Math.Abs(twistTotal) > (float)System.Math.PI * 3.0f) steps *= 2;
272
273 // double percentOfPathMultiplier = 1.0 / steps;
274 // double angleStepMultiplier = System.Math.PI * 2.0 / steps;
275
276 float yPathScale = pathScaleY * 0.5f;
277 float pathLength = pathCutEnd - pathCutBegin;
278 float totalSkew = skew * 2.0f * pathLength;
279 float skewStart = (-skew) + pathCutBegin * 2.0f * skew;
280
281 // It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end
282 // angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used
283 // to calculate the sine for generating the path radius appears to approximate it's effects there
284 // too, but there are some subtle differences in the radius which are noticeable as the prim size
285 // increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on
286 // the meshes generated with this technique appear nearly identical in shape to the same prims when
287 // displayed by the viewer.
288
289
290 float startAngle = (float)(System.Math.PI * 2.0 * pathCutBegin * revolutions) - pushY * 0.9f;
291 float endAngle = (float)(System.Math.PI * 2.0 * pathCutEnd * revolutions) - pushY * 0.9f;
292 float stepSize = (float)0.2617993878; // 2*PI / 24 segments per revolution
293
294 step = (int)(startAngle / stepSize);
295 float angle = startAngle;
296
297 float xProfileScale = 1.0f;
298 float yProfileScale = 1.0f;
299
300
301#if SPAM
302 System.Console.WriteLine("Extruder: twistTop: " + twistTop.ToString() + " twistbot: " + twistBot.ToString() + " twisttotal: " + twistTotal.ToString());
303 System.Console.WriteLine("Extruder: startAngle: " + startAngle.ToString() + " endAngle: " + endAngle.ToString() + " step: " + step.ToString());
304 System.Console.WriteLine("Extruder: taperBotFactorX: " + taperBotFactorX.ToString() + " taperBotFactorY: " + taperBotFactorY.ToString()
305 + " taperTopFactorX: " + taperTopFactorX.ToString() + " taperTopFactorY: " + taperTopFactorY.ToString());
306 System.Console.WriteLine("Extruder: PathScaleX: " + pathScaleX.ToString() + " pathScaleY: " + pathScaleY.ToString());
307#endif
308
309 bool done = false;
310 do // loop through the length of the path and add the layers
311 {
312 newLayer = m.Clone();
313
314 float percentOfPath = (angle - startAngle) / (endAngle - startAngle); // endAngle should always be larger than startAngle
315
316 if (pathTaperX > 0.001f) // can't really compare to 0.0f as the value passed is never exactly zero
317 xProfileScale = 1.0f - percentOfPath * pathTaperX;
318 else if (pathTaperX < -0.001f)
319 xProfileScale = 1.0f + (1.0f - percentOfPath) * pathTaperX;
320 else xProfileScale = 1.0f;
321
322 if (pathTaperY > 0.001f)
323 yProfileScale = 1.0f - percentOfPath * pathTaperY;
324 else if (pathTaperY < -0.001f)
325 yProfileScale = 1.0f + (1.0f - percentOfPath) * pathTaperY;
326 else yProfileScale = 1.0f;
327
328#if SPAM
329 //System.Console.WriteLine("xProfileScale: " + xProfileScale.ToString() + " yProfileScale: " + yProfileScale.ToString());
330#endif
331 Vertex vTemp = new Vertex(0.0f, 0.0f, 0.0f);
332
333 // apply the taper to the profile before any rotations
334 if (xProfileScale != 1.0f || yProfileScale != 1.0f)
335 {
336 foreach (Vertex v in newLayer.vertices)
337 {
338 if (v != null)
339 {
340 v.X *= xProfileScale;
341 v.Y *= yProfileScale;
342 }
343 }
344 }
345
346 float radiusScale;
347
348 if (radius > 0.001f)
349 radiusScale = 1.0f - radius * percentOfPath;
350 else if (radius < 0.001f)
351 radiusScale = 1.0f + radius * (1.0f - percentOfPath);
352 else
353 radiusScale = 1.0f;
354
355#if SPAM
356 System.Console.WriteLine("Extruder: angle: " + angle.ToString() + " percentOfPath: " + percentOfPath.ToString()
357 + " radius: " + radius.ToString() + " radiusScale: " + radiusScale.ToString()
358 + " xProfileScale: " + xProfileScale.ToString() + " yProfileScale: " + yProfileScale.ToString());
359#endif
360
361 float twist = twistBot + (twistTotal * (float)percentOfPath);
362
363 float xOffset;
364 float yOffset;
365 float zOffset;
366
367 xOffset = 0.5f * (skewStart + totalSkew * (float)percentOfPath);
368 xOffset += (float) System.Math.Sin(angle) * pushX * 0.45f;
369 yOffset = (float)(System.Math.Cos(angle) * (0.5f - yPathScale)) * radiusScale;
370 zOffset = (float)(System.Math.Sin(angle + pushY * 0.9f) * (0.5f - yPathScale)) * radiusScale;
371
372 // next apply twist rotation to the profile layer
373 if (twistTotal != 0.0f || twistBot != 0.0f)
374 {
375 Quaternion profileRot = new Quaternion(new Vector3(0.0f, 0.0f, 1.0f), twist);
376 foreach (Vertex v in newLayer.vertices)
377 {
378 if (v != null)
379 {
380 vTemp = v * profileRot;
381 v.X = vTemp.X;
382 v.Y = vTemp.Y;
383 v.Z = vTemp.Z;
384 }
385 }
386 }
387
388 // now orient the rotation of the profile layer relative to it's position on the path
389 // adding pushY to the angle used to generate the quat appears to approximate the viewer
390 Quaternion layerRot = Quaternion.CreateFromAxisAngle(new Vector3(1.0f, 0.0f, 0.0f), (float)angle + pushY * 0.9f);
391 foreach (Vertex v in newLayer.vertices)
392 {
393 if (v != null)
394 {
395 vTemp = v * layerRot;
396 v.X = vTemp.X + xOffset;
397 v.Y = vTemp.Y + yOffset;
398 v.Z = vTemp.Z + zOffset;
399 }
400 }
401
402 if (angle == startAngle) // the first layer, invert normals
403 {
404 foreach (Triangle t in newLayer.triangles)
405 {
406 t.invertNormal();
407 }
408 }
409
410 result.Append(newLayer);
411
412 int iLastNull = 0;
413
414 if (lastLayer != null)
415 {
416 int i, count = newLayer.vertices.Count;
417
418 for (i = 0; i < count; i++)
419 {
420 int iNext = (i + 1);
421
422 if (lastLayer.vertices[i] == null) // cant make a simplex here
423 {
424 iLastNull = i + 1;
425 }
426 else
427 {
428 if (i == count - 1) // End of list
429 iNext = iLastNull;
430
431 if (lastLayer.vertices[iNext] == null) // Null means wrap to begin of last segment
432 iNext = iLastNull;
433
434 result.Add(new Triangle(newLayer.vertices[i], lastLayer.vertices[i], newLayer.vertices[iNext]));
435 result.Add(new Triangle(newLayer.vertices[iNext], lastLayer.vertices[i], lastLayer.vertices[iNext]));
436 }
437 }
438 }
439 lastLayer = newLayer;
440
441 // calc the angle for the next interation of the loop
442 if (angle >= endAngle)
443 {
444 done = true;
445 }
446 else
447 {
448 angle = stepSize * ++step;
449 if (angle > endAngle)
450 angle = endAngle;
451 }
452 } while (!done); // loop until all the layers in the path are completed
453
454 // scale the mesh to the desired size
455 float xScale = size.X;
456 float yScale = size.Y;
457 float zScale = size.Z;
458
459 foreach (Vertex v in result.vertices)
460 {
461 if (v != null)
462 {
463 v.X *= xScale;
464 v.Y *= yScale;
465 v.Z *= zScale;
466 }
467 }
468
469 return result;
470 }
471 }
472}