aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing
diff options
context:
space:
mode:
authorTeravus Ovares2008-05-29 20:20:50 +0000
committerTeravus Ovares2008-05-29 20:20:50 +0000
commit918f887c0c10fda33633548f3601bdf07d74edfd (patch)
tree2db5459288f52117a071fcc51c7f2d1d7a19a3b3 /OpenSim/Region/Physics/Meshing
parentMantis#1416. Thank you very much, Melanie for a patch that: (diff)
downloadopensim-SC-918f887c0c10fda33633548f3601bdf07d74edfd.zip
opensim-SC-918f887c0c10fda33633548f3601bdf07d74edfd.tar.gz
opensim-SC-918f887c0c10fda33633548f3601bdf07d74edfd.tar.bz2
opensim-SC-918f887c0c10fda33633548f3601bdf07d74edfd.tar.xz
* Applying Dahlia's interim path curve patch. it adds initial support for some tori/ring parameters. Thanks Dahlia!
* Some situations do not match the client's render of the tori, we know and are working on it. This is an initial support patch, so expect it to not be exact. * Some tapers are acting slightly odd. Will fix.
Diffstat (limited to 'OpenSim/Region/Physics/Meshing')
-rw-r--r--OpenSim/Region/Physics/Meshing/Extruder.cs211
-rw-r--r--OpenSim/Region/Physics/Meshing/HelperTypes.cs36
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs450
3 files changed, 650 insertions, 47 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Extruder.cs b/OpenSim/Region/Physics/Meshing/Extruder.cs
index c7dcf33..480ffda 100644
--- a/OpenSim/Region/Physics/Meshing/Extruder.cs
+++ b/OpenSim/Region/Physics/Meshing/Extruder.cs
@@ -47,6 +47,21 @@ namespace OpenSim.Region.Physics.Meshing
47 public float twistTop = 0; 47 public float twistTop = 0;
48 public float twistBot = 0; 48 public float twistBot = 0;
49 public float twistMid = 0; 49 public float twistMid = 0;
50 public float pathScaleX = 1.0f;
51 public float pathScaleY = 0.5f;
52 public float skew = 0.0f;
53 public float radius = 0.0f;
54 public float revolutions = 1.0f;
55
56 public float pathCutBegin = 0.0f;
57 public float pathCutEnd = 1.0f;
58
59 public ushort pathBegin = 0;
60 public ushort pathEnd = 0;
61
62 public float pathTaperX = 0.0f;
63 public float pathTaperY = 0.0f;
64
50 65
51 public Mesh Extrude(Mesh m) 66 public Mesh Extrude(Mesh m)
52 { 67 {
@@ -230,5 +245,201 @@ namespace OpenSim.Region.Physics.Meshing
230 } 245 }
231 return result; 246 return result;
232 } 247 }
248 public Mesh ExtrudeCircularPath(Mesh m)
249 {
250 //startParameter = float.MinValue;
251 //stopParameter = float.MaxValue;
252 // Currently only works for iSteps=1;
253 Mesh result = new Mesh();
254
255 Quaternion tt = new Quaternion();
256 Vertex v2 = new Vertex(0, 0, 0);
257
258 Mesh newLayer;
259 Mesh lastLayer = null;
260
261 int start = 0;
262 int step;
263 int steps = 24;
264
265 float twistTotal = twistTop - twistBot;
266 if (System.Math.Abs(twistTotal) > (float)System.Math.PI * 1.5) steps *= 2;
267 if (System.Math.Abs(twistTotal) > (float)System.Math.PI * 3.0) steps *= 2;
268
269 double percentOfPathMultiplier = 1.0 / steps;
270 double angleStepMultiplier = System.Math.PI * 2.0 / steps;
271
272 //System.Console.WriteLine("twistTop: " + twistTop.ToString() + " twistbot: " + twistBot.ToString() + " twisttotal: " + twistTotal.ToString());
273
274 float yPathScale = pathScaleY * 0.5f;
275 float skewStart = -skew;
276 float skewOffset = 0.0f;
277 float totalSkew = skew * 2.0f;
278
279
280 float startAngle = (float)(System.Math.PI * 2.0 * pathCutBegin * revolutions);
281 float endAngle = (float)(System.Math.PI * 2.0 * pathCutEnd * revolutions);
282 float stepSize = (float)0.2617993878; // 2*PI / 24 segments
283 step = (int)(startAngle / stepSize);
284 float angle = startAngle;
285
286 float xProfileScale = 1.0f;
287 float yProfileScale = 1.0f;
288
289 //System.Console.WriteLine("startAngle: " + startAngle.ToString() + " endAngle: " + endAngle.ToString() + " step: " + step.ToString());
290 bool done = false;
291
292 //System.Console.WriteLine(" PathScaleX: " + pathScaleX.ToString() + " pathScaleY: " + pathScaleY.ToString());
293
294 //System.Console.WriteLine("taperBotFactorX: " + taperBotFactorX.ToString() + " taperBotFactorY: " + taperBotFactorY.ToString()
295 // + " taperTopFactorX: " + taperTopFactorX.ToString() + " taperTopFactorY: " + taperTopFactorY.ToString());
296
297
298
299 do
300 {
301 float percentOfPath = 1.0f;
302
303 percentOfPath = (angle - startAngle) / (endAngle - startAngle); // endAngle should always be larger than startAngle
304
305 // System.Console.WriteLine("angle: " + angle.ToString() + " percentOfPath: " + percentOfPath.ToString());
306
307 if (pathTaperX > 0.001f) // can't really compare to 0.0f as the value passed is never exactly zero
308 xProfileScale = 1.0f - percentOfPath * pathTaperX;
309 else if (pathTaperX < -0.001f)
310 xProfileScale = 1.0f + (1.0f - percentOfPath) * pathTaperX;
311 else xProfileScale = 1.0f;
312
313 if (pathTaperY > 0.001f)
314 yProfileScale = 1.0f - percentOfPath * pathTaperY;
315 else if (pathTaperY < -0.001f)
316 yProfileScale = 1.0f + (1.0f - percentOfPath) * pathTaperY;
317 else yProfileScale = 1.0f;
318
319 float radiusScale;
320
321 if (radius > 0.001f)
322 radiusScale = 1.0f - radius * percentOfPath;
323 else if (radius < 0.001f)
324 radiusScale = 1.0f + radius * (1.0f - percentOfPath);
325 else radiusScale = 1.0f;
326
327 //radiusScale = 1.0f;
328
329 //System.Console.WriteLine("Extruder: radius: " + radius.ToString() + " radiusScale: " + radiusScale.ToString());
330
331
332
333
334
335 float twist = twistBot + (twistTotal * (float)percentOfPath);
336
337 float zOffset = (float)(System.Math.Sin(angle) * (0.5f - yPathScale)) * radiusScale;
338 float yOffset = (float)(System.Math.Cos(angle) * (0.5f - yPathScale)) * radiusScale;
339 float xOffset = 0.5f * (skewStart + totalSkew * (float)percentOfPath);
340
341 newLayer = m.Clone();
342
343 Vertex vTemp = new Vertex(0.0f, 0.0f, 0.0f);
344
345 if (twistTotal != 0.0f || twistBot != 0.0f)
346 {
347 Quaternion profileRot = new Quaternion(new Vertex(0.0f, 0.0f, -1.0f), twist);
348 foreach (Vertex v in newLayer.vertices)
349 {
350 if (v != null)
351 {
352 vTemp = v * profileRot;
353 v.X = vTemp.X;
354 v.Y = vTemp.Y;
355 v.Z = vTemp.Z;
356 }
357 }
358 }
359
360 Quaternion layerRot = new Quaternion(new Vertex(-1.0f, 0.0f, 0.0f), (float)angle);
361 foreach (Vertex v in newLayer.vertices)
362 {
363 if (v != null)
364 {
365 vTemp = v * layerRot;
366 v.X = xProfileScale * vTemp.X + xOffset;
367 v.Y = yProfileScale * vTemp.Y + yOffset;
368 v.Z = vTemp.Z + zOffset;
369 }
370 }
371
372 if (angle == startAngle) // last layer, invert normals
373 foreach (Triangle t in newLayer.triangles)
374 {
375 t.invertNormal();
376 }
377
378 result.Append(newLayer);
379
380 int iLastNull = 0;
381
382 if (lastLayer != null)
383 {
384 int i, count = newLayer.vertices.Count;
385
386 for (i = 0; i < count; i++)
387 {
388 int iNext = (i + 1);
389
390 if (lastLayer.vertices[i] == null) // cant make a simplex here
391 iLastNull = i + 1;
392 else
393 {
394 if (i == count - 1) // End of list
395 iNext = iLastNull;
396
397 if (lastLayer.vertices[iNext] == null) // Null means wrap to begin of last segment
398 iNext = iLastNull;
399
400 result.Add(new Triangle(newLayer.vertices[i], lastLayer.vertices[i], newLayer.vertices[iNext]));
401 result.Add(new Triangle(newLayer.vertices[iNext], lastLayer.vertices[i], lastLayer.vertices[iNext]));
402 }
403 }
404 }
405 lastLayer = newLayer;
406
407
408
409
410
411
412
413
414 // calc next angle
415
416 if (angle >= endAngle)
417 done = true;
418 else
419 {
420 angle = stepSize * ++step;
421 if (angle > endAngle)
422 angle = endAngle;
423 }
424 }
425 while (!done);
426
427
428
429 // scale the mesh to the desired size
430 float xScale = size.X;
431 float yScale = size.Y;
432 float zScale = size.Z;
433
434 foreach (Vertex v in result.vertices)
435 if (v != null)
436 {
437 v.X *= xScale;
438 v.Y *= yScale;
439 v.Z *= zScale;
440 }
441
442 return result;
443 }
233 } 444 }
234} 445}
diff --git a/OpenSim/Region/Physics/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
index 584133c..f031fb6 100644
--- a/OpenSim/Region/Physics/Meshing/HelperTypes.cs
+++ b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
@@ -51,9 +51,13 @@ public class Quaternion
51 { 51 {
52 // using (* 0.5) instead of (/2) 52 // using (* 0.5) instead of (/2)
53 w = (float)Math.Cos(angle * 0.5f); 53 w = (float)Math.Cos(angle * 0.5f);
54 x = axis.X * (float)Math.Sin(angle * 0.5f); 54 float sin = (float)Math.Sin(angle * 0.5f);
55 y = axis.Y * (float)Math.Sin(angle * 0.5f); 55 //x = axis.X * (float)Math.Sin(angle * 0.5f);
56 z = axis.Z * (float)Math.Sin(angle * 0.5f); 56 //y = axis.Y * (float)Math.Sin(angle * 0.5f);
57 //z = axis.Z * (float)Math.Sin(angle * 0.5f);
58 x = axis.X * sin;
59 y = axis.Y * sin;
60 z = axis.Z * sin;
57 normalize(); 61 normalize();
58 } 62 }
59 public static Quaternion operator *(Quaternion a, Quaternion b) 63 public static Quaternion operator *(Quaternion a, Quaternion b)
@@ -73,12 +77,18 @@ public class Quaternion
73 } 77 }
74 public void normalize() 78 public void normalize()
75 { 79 {
76 float mag = length(); 80 //float mag = length();
77 81
78 w /= mag; 82 //w /= mag;
79 x /= mag; 83 //x /= mag;
80 y /= mag; 84 //y /= mag;
81 z /= mag; 85 //z /= mag;
86 float iMag = 1.0f / length();
87
88 w *= iMag;
89 x *= iMag;
90 y *= iMag;
91 z *= iMag;
82 } 92 }
83 public float length() 93 public float length()
84 { 94 {
@@ -169,7 +179,8 @@ public class Vertex : PhysicsVector, IComparable<Vertex>
169 float tlength = length(); 179 float tlength = length();
170 if (tlength != 0) 180 if (tlength != 0)
171 { 181 {
172 return new Vertex(X / tlength, Y / tlength, Z / tlength); 182 float mul = 1.0f / tlength;
183 return new Vertex(X * mul, Y * mul, Z * mul);
173 } 184 }
174 else 185 else
175 { 186 {
@@ -230,9 +241,10 @@ public class Vertex : PhysicsVector, IComparable<Vertex>
230 { 241 {
231 return new Vertex(0f,0f,0f); 242 return new Vertex(0f,0f,0f);
232 } 243 }
233 v1.X /= am; 244 float mul = 1.0f / am;
234 v1.Y /= am; 245 v1.X *= mul;
235 v1.Z /= am; 246 v1.Y *= mul;
247 v1.Z *= mul;
236 return v1; 248 return v1;
237 } 249 }
238 250
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index ba4f941..5ef392c 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenSim.Framework; 30using OpenSim.Framework;
31using OpenSim.Region.Physics.Manager; 31using OpenSim.Region.Physics.Manager;
32using libsecondlife;
32 33
33namespace OpenSim.Region.Physics.Meshing 34namespace OpenSim.Region.Physics.Meshing
34{ 35{
@@ -253,7 +254,8 @@ namespace OpenSim.Region.Physics.Meshing
253 holeHull.AddVertex(IPP); 254 holeHull.AddVertex(IPP);
254 holeHull.AddVertex(IPM); 255 holeHull.AddVertex(IPM);
255 } 256 }
256 if (hshape == HollowShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight) 257 //if (hshape == HollowShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
258 if ( hshape == HollowShape.Circle )
257 { 259 {
258 float hollowFactorF = (float)fhollowFactor / (float)50000; 260 float hollowFactorF = (float)fhollowFactor / (float)50000;
259 261
@@ -576,7 +578,6 @@ namespace OpenSim.Region.Physics.Meshing
576 } 578 }
577 } 579 }
578 580
579
580 if (pathShearX != 0) 581 if (pathShearX != 0)
581 { 582 {
582 if (pathShearX > 50) 583 if (pathShearX > 50)
@@ -647,7 +648,7 @@ namespace OpenSim.Region.Physics.Meshing
647 return result; 648 return result;
648 } 649 }
649 650
650 private static Mesh CreateCyllinderMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) 651 private static Mesh CreateCylinderMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
651 // Builds the z (+ and -) surfaces of a box shaped prim 652 // Builds the z (+ and -) surfaces of a box shaped prim
652 { 653 {
653 654
@@ -1318,6 +1319,317 @@ namespace OpenSim.Region.Physics.Meshing
1318 return sm; 1319 return sm;
1319 1320
1320 } 1321 }
1322
1323 private static Mesh CreateCircularProfileMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
1324 {
1325
1326 UInt16 hollowFactor = primShape.ProfileHollow;
1327 UInt16 profileBegin = primShape.ProfileBegin;
1328 UInt16 profileEnd = primShape.ProfileEnd;
1329 UInt16 taperX = primShape.PathScaleX;
1330 UInt16 taperY = primShape.PathScaleY;
1331 UInt16 pathShearX = primShape.PathShearX;
1332 UInt16 pathShearY = primShape.PathShearY;
1333 Int16 twistBot = primShape.PathTwist;
1334 Int16 twistTop = primShape.PathTwistBegin;
1335 HollowShape hollowShape = primShape.HollowShape;
1336
1337 //Console.WriteLine("pathTwist: " + primShape.PathTwist.ToString() + " pathTwistBegin: " + primShape.PathTwistBegin.ToString());
1338
1339 SimpleHull outerHull = new SimpleHull();
1340
1341 //Console.WriteLine("primShape.ProfileCurve & 0x07: " + Convert.ToString(primShape.ProfileCurve & 0x07));
1342
1343 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
1344
1345 //if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle
1346 // || (primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Square)
1347 {
1348 //Console.WriteLine("Meshmerizer thinks " + primName + " is a TORUS");
1349 if ( hollowShape == HollowShape.Same )
1350 hollowShape = HollowShape.Circle;
1351
1352 // build the profile shape
1353 // counter-clockwise around the quadrants, start at 45 degrees
1354
1355 outerHull.AddVertex(new Vertex(0.353553f, 0.353553f, 0.0f)); // 45 degrees
1356 outerHull.AddVertex(new Vertex(0.250000f, 0.433013f, 0.0f)); // 60 degrees
1357 outerHull.AddVertex(new Vertex(0.129410f, 0.482963f, 0.0f)); // 75 degrees
1358 outerHull.AddVertex(new Vertex(0.000000f, 0.500000f, 0.0f)); // 90 degrees
1359 outerHull.AddVertex(new Vertex(-0.129410f, 0.482963f, 0.0f)); // 105 degrees
1360 outerHull.AddVertex(new Vertex(-0.250000f, 0.433013f, 0.0f)); // 120 degrees
1361 outerHull.AddVertex(new Vertex(-0.353553f, 0.353553f, 0.0f)); // 135 degrees
1362 outerHull.AddVertex(new Vertex(-0.433013f, 0.250000f, 0.0f)); // 150 degrees
1363 outerHull.AddVertex(new Vertex(-0.482963f, 0.129410f, 0.0f)); // 165 degrees
1364 outerHull.AddVertex(new Vertex(-0.500000f, 0.000000f, 0.0f)); // 180 degrees
1365 outerHull.AddVertex(new Vertex(-0.482963f, -0.129410f, 0.0f)); // 195 degrees
1366 outerHull.AddVertex(new Vertex(-0.433013f, -0.250000f, 0.0f)); // 210 degrees
1367 outerHull.AddVertex(new Vertex(-0.353553f, -0.353553f, 0.0f)); // 225 degrees
1368 outerHull.AddVertex(new Vertex(-0.250000f, -0.433013f, 0.0f)); // 240 degrees
1369 outerHull.AddVertex(new Vertex(-0.129410f, -0.482963f, 0.0f)); // 255 degrees
1370 outerHull.AddVertex(new Vertex(0.000000f, -0.500000f, 0.0f)); // 270 degrees
1371 outerHull.AddVertex(new Vertex(0.129410f, -0.482963f, 0.0f)); // 285 degrees
1372 outerHull.AddVertex(new Vertex(0.250000f, -0.433013f, 0.0f)); // 300 degrees
1373 outerHull.AddVertex(new Vertex(0.353553f, -0.353553f, 0.0f)); // 315 degrees
1374 outerHull.AddVertex(new Vertex(0.433013f, -0.250000f, 0.0f)); // 330 degrees
1375 outerHull.AddVertex(new Vertex(0.482963f, -0.129410f, 0.0f)); // 345 degrees
1376 outerHull.AddVertex(new Vertex(0.500000f, 0.000000f, 0.0f)); // 0 degrees
1377 outerHull.AddVertex(new Vertex(0.482963f, 0.129410f, 0.0f)); // 15 degrees
1378 outerHull.AddVertex(new Vertex(0.433013f, 0.250000f, 0.0f)); // 30 degrees
1379 }
1380
1381 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Square) // a ring
1382 {
1383 //Console.WriteLine("Meshmerizer thinks " + primName + " is a TUBE");
1384 if ( hollowShape == HollowShape.Same )
1385 hollowShape = HollowShape.Square;
1386
1387 outerHull.AddVertex(new Vertex(+0.5f, +0.5f, 0.0f));
1388 outerHull.AddVertex(new Vertex(-0.5f, +0.5f, 0.0f));
1389 outerHull.AddVertex(new Vertex(-0.5f, -0.5f, 0.0f));
1390 outerHull.AddVertex(new Vertex(+0.5f, -0.5f, 0.0f));
1391 }
1392
1393 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
1394 {
1395 //Console.WriteLine("Meshmerizer thinks " + primName + " is a RING");
1396 if ( hollowShape == HollowShape.Same )
1397 hollowShape = HollowShape.Triangle;
1398
1399 outerHull.AddVertex(new Vertex(+0.255f, -0.375f, 0.0f));
1400 outerHull.AddVertex(new Vertex(+0.25f, +0.375f, 0.0f));
1401 outerHull.AddVertex(new Vertex(-0.5f, +0.0f, 0.0f));
1402
1403 }
1404
1405 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
1406 {
1407 //Console.WriteLine("Meshmerizer thinks " + primName + " is a SPHERE");
1408 if (hollowShape == HollowShape.Same)
1409 hollowShape = HollowShape.Circle;
1410
1411 // not implemented here, use old routine
1412 return CreateSphereMesh(primName, primShape, size);
1413 }
1414
1415 // Deal with cuts now
1416 if ((profileBegin != 0) || (profileEnd != 0))
1417 {
1418 double fProfileBeginAngle = profileBegin / 50000.0 * 360.0;
1419 // In degree, for easier debugging and understanding
1420 //fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
1421 double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
1422 //fProfileEndAngle -= (90.0 + 45.0);
1423 if (fProfileBeginAngle < fProfileEndAngle)
1424 fProfileEndAngle -= 360.0;
1425
1426 // Note, that we don't want to cut out a triangle, even if this is a
1427 // good approximation for small cuts. Indeed we want to cut out an arc
1428 // and we approximate this arc by a polygon chain
1429 // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
1430 // So it can easily be subtracted from the outer hull
1431 int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5);
1432 // how many steps do we need with approximately 45 degree
1433 double dStepWidth = (fProfileBeginAngle - fProfileEndAngle) / iSteps;
1434
1435 Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
1436
1437 // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
1438 SimpleHull cutHull = new SimpleHull();
1439 cutHull.AddVertex(origin);
1440 for (int i = 0; i < iSteps; i++)
1441 {
1442 double angle = fProfileBeginAngle - i * dStepWidth; // we count against the angle orientation!!!!
1443 Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
1444 cutHull.AddVertex(v);
1445 }
1446 Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0);
1447 // Calculated separately to avoid errors
1448 cutHull.AddVertex(legEnd);
1449
1450 // m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
1451 SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
1452
1453 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
1454 {
1455 Quaternion zFlip = new Quaternion(new Vertex(0.0f, 0.0f, 1.0f), (float)Math.PI);
1456 Vertex vTmp = new Vertex(0.0f, 0.0f, 0.0f);
1457 foreach (Vertex v in cuttedHull.getVertices())
1458 if (v != null)
1459 {
1460 vTmp = v * zFlip;
1461 v.X = vTmp.X;
1462 v.Y = vTmp.Y;
1463 v.Z = vTmp.Z;
1464 }
1465 }
1466
1467 outerHull = cuttedHull;
1468 }
1469
1470 // Deal with the hole here
1471 if (hollowFactor > 0)
1472 {
1473 SimpleHull holeHull;
1474
1475 if (hollowShape == HollowShape.Triangle)
1476 {
1477 holeHull = new SimpleHull();
1478
1479 float hollowFactorF = (float) hollowFactor / 50000.0f;
1480
1481 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
1482 {
1483 holeHull.AddVertex(new Vertex(+0.125f * hollowFactorF, -0.1875f * hollowFactorF, 0.0f));
1484 holeHull.AddVertex(new Vertex(-0.25f * hollowFactorF, -0f * hollowFactorF, 0.0f));
1485 holeHull.AddVertex(new Vertex(+0.125f * hollowFactorF, +0.1875f * hollowFactorF, 0.0f));
1486 }
1487 else
1488 {
1489 holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f));
1490 holeHull.AddVertex(new Vertex(-0.5f * hollowFactorF, -0f * hollowFactorF, 0.0f));
1491 holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f));
1492
1493 ////holeHull.AddVertex(new Vertex(-0.5f * hollowFactorF, -0f * hollowFactorF, 0.0f));
1494
1495 ////holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f));
1496
1497 ////holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f));
1498
1499 //holeHull.AddVertex(new Vertex(-0.5f * hollowFactorF, +0f * hollowFactorF, 0.0f));
1500 //holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f));
1501 //holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f));
1502 ////holeHull.AddVertex(new Vertex(-0.5f * hollowFactorF, +0f * hollowFactorF, 0.0f));
1503 }
1504 }
1505 else
1506 {
1507 holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
1508 }
1509
1510 if (holeHull != null)
1511 {
1512 SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
1513
1514 outerHull = hollowedHull;
1515 }
1516 }
1517
1518 Mesh m = new Mesh();
1519
1520 Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
1521 Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
1522 Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
1523
1524 m.Add(Seed1);
1525 m.Add(Seed2);
1526 m.Add(Seed3);
1527
1528 m.Add(new Triangle(Seed1, Seed2, Seed3));
1529 m.Add(outerHull.getVertices());
1530
1531 InsertVertices(m.vertices, 3, m.triangles);
1532 m.DumpRaw(baseDir, primName, "Proto first Mesh");
1533
1534 m.Remove(Seed1);
1535 m.Remove(Seed2);
1536 m.Remove(Seed3);
1537 m.DumpRaw(baseDir, primName, "Proto seeds removed");
1538
1539 m.RemoveTrianglesOutside(outerHull);
1540 m.DumpRaw(baseDir, primName, "Proto outsides removed");
1541
1542 foreach (Triangle t in m.triangles)
1543 t.invertNormal();
1544
1545 Vertex vTemp = new Vertex(0.0f, 0.0f, 0.0f);
1546
1547 //Console.WriteLine("primShape.PathScaleX: " + primShape.PathScaleX.ToString() + " primShape.PathScaleY: " + primShape.PathScaleY.ToString());
1548 //Console.WriteLine("primShape.PathSkew: " + primShape.PathSkew.ToString() + " primShape.PathRadiusOffset: " + primShape.PathRadiusOffset.ToString() + " primShape.pathRevolutions: " + primShape.PathRevolutions.ToString());
1549
1550 float skew = primShape.PathSkew * 0.01f;
1551 float pathScaleX = (float)(200 - primShape.PathScaleX) * 0.01f;
1552 float pathScaleY = (float)(200 - primShape.PathScaleY) * 0.01f;
1553 //Console.WriteLine("PathScaleX: " + pathScaleX.ToString() + " pathScaleY: " + pathScaleY.ToString());
1554
1555 float profileXComp = pathScaleX * (1.0f - Math.Abs(skew));
1556 foreach (Vertex v in m.vertices)
1557 if (v != null)
1558 {
1559 v.X *= profileXComp;
1560 v.Y *= pathScaleY;
1561 //v.Y *= 0.5f; // torus profile is scaled in y axis
1562 }
1563
1564 Extruder extr = new Extruder();
1565
1566 extr.size = size;
1567 extr.pathScaleX = pathScaleX;
1568 extr.pathScaleY = pathScaleY;
1569 extr.pathCutBegin = 0.00002f * primShape.PathBegin;
1570 extr.pathCutEnd = 0.00002f * (50000 - primShape.PathEnd);
1571 extr.pathBegin = primShape.PathBegin;
1572 extr.pathEnd = primShape.PathEnd;
1573 extr.skew = skew;
1574 extr.revolutions = 1.0f + (float)primShape.PathRevolutions * 3.0f / 200.0f;
1575
1576 //System.Console.WriteLine("primShape.PathBegin: " + primShape.PathBegin.ToString() + " primShape.PathEnd: " + primShape.PathEnd.ToString());
1577 //System.Console.WriteLine("extr.pathCutBegin: " + extr.pathCutBegin.ToString() + " extr.pathCutEnd: " + extr.pathCutEnd.ToString());
1578 //System.Console.WriteLine("extr.revolutions: " + extr.revolutions.ToString());
1579
1580 //System.Console.WriteLine("primShape.PathTaperX: " + primShape.PathTaperX.ToString());
1581 //System.Console.WriteLine("primShape.PathTaperY: " + primShape.PathTaperY.ToString());
1582
1583 extr.pathTaperX = 0.01f * (float)primShape.PathTaperX;
1584 extr.pathTaperY = 0.01f * (float)primShape.PathTaperY;
1585
1586 extr.radius = 0.01f * (float)primShape.PathRadiusOffset;
1587 //System.Console.WriteLine("primShape.PathRadiusOffset: " + primShape.PathRadiusOffset.ToString());
1588
1589
1590
1591
1592
1593 if (pathShearX != 0)
1594 {
1595 if (pathShearX > 50)
1596 {
1597 // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
1598 extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
1599 //m_log.Warn("pushX: " + extr.pushX);
1600 }
1601 else
1602 {
1603 extr.pushX = (float)pathShearX / 100;
1604 //m_log.Warn("pushX: " + extr.pushX);
1605 }
1606 }
1607
1608 if (pathShearY != 0)
1609 {
1610 if (pathShearY > 50)
1611 {
1612 // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
1613 extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
1614 //m_log.Warn("pushY: " + extr.pushY);
1615 }
1616 else
1617 {
1618 extr.pushY = (float)pathShearY / 100;
1619 //m_log.Warn("pushY: " + extr.pushY);
1620 }
1621
1622 }
1623
1624 extr.twistTop = (float)primShape.PathTwist * (float)Math.PI * 0.02f;
1625 extr.twistBot = (float)primShape.PathTwistBegin * (float)Math.PI * 0.02f;
1626
1627 //System.Console.WriteLine("[MESH]: twistTop = " + twistTop.ToString() + "|" + extr.twistTop.ToString() + ", twistMid = " + twistMid.ToString() + "|" + extr.twistMid.ToString() + ", twistbot = " + twistBot.ToString() + "|" + extr.twistBot.ToString());
1628 Mesh result = extr.ExtrudeCircularPath(m);
1629 result.DumpRaw(baseDir, primName, "Z extruded");
1630 return result;
1631 }
1632
1321 public static void CalcNormals(Mesh mesh) 1633 public static void CalcNormals(Mesh mesh)
1322 { 1634 {
1323 int iTriangles = mesh.triangles.Count; 1635 int iTriangles = mesh.triangles.Count;
@@ -1432,43 +1744,111 @@ namespace OpenSim.Region.Physics.Meshing
1432 mesh = (Mesh)smesh; 1744 mesh = (Mesh)smesh;
1433 CalcNormals(mesh); 1745 CalcNormals(mesh);
1434 } 1746 }
1435 else 1747 else if ((primShape.ProfileCurve & (byte)ProfileShape.Square) == (byte)ProfileShape.Square)
1748 {
1749 if (primShape.PathCurve == (byte)LLObject.PathCurve.Line)
1750 { // its a box
1751 mesh = CreateBoxMesh(primName, primShape, size);
1752 CalcNormals(mesh);
1753 }
1754 else if (primShape.PathCurve == (byte)LLObject.PathCurve.Circle)
1755 { // tube
1756 // do a cylinder for now
1757 //mesh = CreateCylinderMesh(primName, primShape, size);
1758 mesh = CreateCircularProfileMesh(primName, primShape, size);
1759 CalcNormals(mesh);
1760 }
1761 }
1762 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
1436 { 1763 {
1437 switch (primShape.ProfileShape) 1764 if (primShape.PathCurve == (byte)Extrusion.Straight)
1438 { 1765 {
1439 case ProfileShape.Square: 1766 mesh = CreateCylinderMesh(primName, primShape, size);
1440 mesh = CreateBoxMesh(primName, primShape, size); 1767 CalcNormals(mesh);
1441 CalcNormals(mesh); 1768 }
1442 break;
1443 case ProfileShape.Circle:
1444 if (primShape.PathCurve == (byte)Extrusion.Straight)
1445 {
1446 mesh = CreateCyllinderMesh(primName, primShape, size);
1447 CalcNormals(mesh);
1448 }
1449 break;
1450 case ProfileShape.HalfCircle:
1451 if (primShape.PathCurve == (byte)Extrusion.Curve1)
1452 {
1453 mesh = CreateSphereMesh(primName, primShape, size);
1454 CalcNormals(mesh);
1455 }
1456 break;
1457
1458 case ProfileShape.EquilateralTriangle:
1459 mesh = CreatePrismMesh(primName, primShape, size);
1460 CalcNormals(mesh);
1461 break;
1462 1769
1463 default: 1770 // look at LLObject.cs in libsecondlife for how to know the prim type
1464 mesh = CreateBoxMesh(primName, primShape, size); 1771 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
1465 CalcNormals(mesh); 1772 else if (primShape.PathCurve == (byte) Extrusion.Curve1 && LLObject.UnpackPathScale(primShape.PathScaleY) <= 0.75f)
1466 //Set default mesh to cube otherwise it'll return 1773 { // dahlia's favorite, a torus :)
1467 // null and crash on the 'setMesh' method in the physics plugins. 1774 mesh = CreateCircularProfileMesh(primName, primShape, size);
1468 //mesh = null; 1775 CalcNormals(mesh);
1469 break;
1470 } 1776 }
1471 } 1777 }
1778 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
1779 {
1780 if (primShape.PathCurve == (byte)Extrusion.Curve1 || primShape.PathCurve == (byte) Extrusion.Curve2)
1781 {
1782 mesh = CreateSphereMesh(primName, primShape, size);
1783 CalcNormals(mesh);
1784 }
1785 }
1786 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
1787 {
1788 if (primShape.PathCurve == (byte)Extrusion.Straight)
1789 {
1790 mesh = CreatePrismMesh(primName, primShape, size);
1791 CalcNormals(mesh);
1792 }
1793 else if (primShape.PathCurve == (byte) Extrusion.Curve1)
1794 { // a ring - do a cylinder for now
1795 //mesh = CreateCylinderMesh(primName, primShape, size);
1796 mesh = CreateCircularProfileMesh(primName, primShape, size);
1797 CalcNormals(mesh);
1798 }
1799 }
1800 else // just do a box
1801 {
1802 mesh = CreateBoxMesh(primName, primShape, size);
1803 CalcNormals(mesh);
1804 }
1805
1806 //else
1807 //{
1808 // switch (primShape.ProfileShape)
1809 // {
1810 // case ProfileShape.Square:
1811 // mesh = CreateBoxMesh(primName, primShape, size);
1812 // CalcNormals(mesh);
1813 // break;
1814 // case ProfileShape.Circle:
1815 // if (primShape.PathCurve == (byte)Extrusion.Straight)
1816 // {
1817 // mesh = CreateCylinderMesh(primName, primShape, size);
1818 // CalcNormals(mesh);
1819 // }
1820
1821 // // look at LLObject.cs in libsecondlife for how to know the prim type
1822 // // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
1823 // else if ((primShape.ProfileCurve & 0x07) == (byte)LLObject.ProfileCurve.Circle && LLObject.UnpackPathScale(primShape.PathScaleY) <= 0.75f)
1824 // { // dahlia's favorite, a torus :)
1825 // mesh = CreateCylinderMesh(primName, primShape, size);
1826 // CalcNormals(mesh);
1827 // }
1828
1829 // break;
1830 // case ProfileShape.HalfCircle:
1831 // if (primShape.PathCurve == (byte)Extrusion.Curve1)
1832 // {
1833 // mesh = CreateSphereMesh(primName, primShape, size);
1834 // CalcNormals(mesh);
1835 // }
1836 // break;
1837
1838 // case ProfileShape.EquilateralTriangle:
1839 // mesh = CreatePrismMesh(primName, primShape, size);
1840 // CalcNormals(mesh);
1841 // break;
1842
1843 // default:
1844 // mesh = CreateBoxMesh(primName, primShape, size);
1845 // CalcNormals(mesh);
1846 // //Set default mesh to cube otherwise it'll return
1847 // // null and crash on the 'setMesh' method in the physics plugins.
1848 // //mesh = null;
1849 // break;
1850 // }
1851 //}
1472 1852
1473 return mesh; 1853 return mesh;
1474 } 1854 }