aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing
diff options
context:
space:
mode:
Diffstat (limited to '')
-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 }