diff options
Diffstat (limited to 'OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs')
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs | 1230 |
1 files changed, 307 insertions, 923 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs b/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs index 4049ee1..8eb136b 100644 --- a/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs | |||
@@ -225,26 +225,6 @@ namespace PrimMesher | |||
225 | } | 225 | } |
226 | } | 226 | } |
227 | 227 | ||
228 | public struct UVCoord | ||
229 | { | ||
230 | public float U; | ||
231 | public float V; | ||
232 | |||
233 | |||
234 | public UVCoord(float u, float v) | ||
235 | { | ||
236 | this.U = u; | ||
237 | this.V = v; | ||
238 | } | ||
239 | |||
240 | public UVCoord Flip() | ||
241 | { | ||
242 | this.U = 1.0f - this.U; | ||
243 | this.V = 1.0f - this.V; | ||
244 | return this; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | public struct Face | 228 | public struct Face |
249 | { | 229 | { |
250 | public int primFace; | 230 | public int primFace; |
@@ -254,16 +234,6 @@ namespace PrimMesher | |||
254 | public int v2; | 234 | public int v2; |
255 | public int v3; | 235 | public int v3; |
256 | 236 | ||
257 | //normals | ||
258 | public int n1; | ||
259 | public int n2; | ||
260 | public int n3; | ||
261 | |||
262 | // uvs | ||
263 | public int uv1; | ||
264 | public int uv2; | ||
265 | public int uv3; | ||
266 | |||
267 | public Face(int v1, int v2, int v3) | 237 | public Face(int v1, int v2, int v3) |
268 | { | 238 | { |
269 | primFace = 0; | 239 | primFace = 0; |
@@ -272,31 +242,6 @@ namespace PrimMesher | |||
272 | this.v2 = v2; | 242 | this.v2 = v2; |
273 | this.v3 = v3; | 243 | this.v3 = v3; |
274 | 244 | ||
275 | this.n1 = 0; | ||
276 | this.n2 = 0; | ||
277 | this.n3 = 0; | ||
278 | |||
279 | this.uv1 = 0; | ||
280 | this.uv2 = 0; | ||
281 | this.uv3 = 0; | ||
282 | |||
283 | } | ||
284 | |||
285 | public Face(int v1, int v2, int v3, int n1, int n2, int n3) | ||
286 | { | ||
287 | primFace = 0; | ||
288 | |||
289 | this.v1 = v1; | ||
290 | this.v2 = v2; | ||
291 | this.v3 = v3; | ||
292 | |||
293 | this.n1 = n1; | ||
294 | this.n2 = n2; | ||
295 | this.n3 = n3; | ||
296 | |||
297 | this.uv1 = 0; | ||
298 | this.uv2 = 0; | ||
299 | this.uv3 = 0; | ||
300 | } | 245 | } |
301 | 246 | ||
302 | public Coord SurfaceNormal(List<Coord> coordList) | 247 | public Coord SurfaceNormal(List<Coord> coordList) |
@@ -312,96 +257,6 @@ namespace PrimMesher | |||
312 | } | 257 | } |
313 | } | 258 | } |
314 | 259 | ||
315 | public struct ViewerFace | ||
316 | { | ||
317 | public int primFaceNumber; | ||
318 | |||
319 | public Coord v1; | ||
320 | public Coord v2; | ||
321 | public Coord v3; | ||
322 | |||
323 | public int coordIndex1; | ||
324 | public int coordIndex2; | ||
325 | public int coordIndex3; | ||
326 | |||
327 | public Coord n1; | ||
328 | public Coord n2; | ||
329 | public Coord n3; | ||
330 | |||
331 | public UVCoord uv1; | ||
332 | public UVCoord uv2; | ||
333 | public UVCoord uv3; | ||
334 | |||
335 | public ViewerFace(int primFaceNumber) | ||
336 | { | ||
337 | this.primFaceNumber = primFaceNumber; | ||
338 | |||
339 | this.v1 = new Coord(); | ||
340 | this.v2 = new Coord(); | ||
341 | this.v3 = new Coord(); | ||
342 | |||
343 | this.coordIndex1 = this.coordIndex2 = this.coordIndex3 = -1; // -1 means not assigned yet | ||
344 | |||
345 | this.n1 = new Coord(); | ||
346 | this.n2 = new Coord(); | ||
347 | this.n3 = new Coord(); | ||
348 | |||
349 | this.uv1 = new UVCoord(); | ||
350 | this.uv2 = new UVCoord(); | ||
351 | this.uv3 = new UVCoord(); | ||
352 | } | ||
353 | |||
354 | public void Scale(float x, float y, float z) | ||
355 | { | ||
356 | this.v1.X *= x; | ||
357 | this.v1.Y *= y; | ||
358 | this.v1.Z *= z; | ||
359 | |||
360 | this.v2.X *= x; | ||
361 | this.v2.Y *= y; | ||
362 | this.v2.Z *= z; | ||
363 | |||
364 | this.v3.X *= x; | ||
365 | this.v3.Y *= y; | ||
366 | this.v3.Z *= z; | ||
367 | } | ||
368 | |||
369 | public void AddPos(float x, float y, float z) | ||
370 | { | ||
371 | this.v1.X += x; | ||
372 | this.v2.X += x; | ||
373 | this.v3.X += x; | ||
374 | |||
375 | this.v1.Y += y; | ||
376 | this.v2.Y += y; | ||
377 | this.v3.Y += y; | ||
378 | |||
379 | this.v1.Z += z; | ||
380 | this.v2.Z += z; | ||
381 | this.v3.Z += z; | ||
382 | } | ||
383 | |||
384 | public void AddRot(Quat q) | ||
385 | { | ||
386 | this.v1 *= q; | ||
387 | this.v2 *= q; | ||
388 | this.v3 *= q; | ||
389 | |||
390 | this.n1 *= q; | ||
391 | this.n2 *= q; | ||
392 | this.n3 *= q; | ||
393 | } | ||
394 | |||
395 | public void CalcSurfaceNormal() | ||
396 | { | ||
397 | |||
398 | Coord edge1 = new Coord(this.v2.X - this.v1.X, this.v2.Y - this.v1.Y, this.v2.Z - this.v1.Z); | ||
399 | Coord edge2 = new Coord(this.v3.X - this.v1.X, this.v3.Y - this.v1.Y, this.v3.Z - this.v1.Z); | ||
400 | |||
401 | this.n1 = this.n2 = this.n3 = Coord.Cross(edge1, edge2).Normalize(); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | internal struct Angle | 260 | internal struct Angle |
406 | { | 261 | { |
407 | internal float angle; | 262 | internal float angle; |
@@ -428,14 +283,6 @@ namespace PrimMesher | |||
428 | new Angle(1.0f, 1.0f, 0.0f) | 283 | new Angle(1.0f, 1.0f, 0.0f) |
429 | }; | 284 | }; |
430 | 285 | ||
431 | private static Coord[] normals3 = | ||
432 | { | ||
433 | new Coord(0.25f, 0.4330127019f, 0.0f).Normalize(), | ||
434 | new Coord(-0.5f, 0.0f, 0.0f).Normalize(), | ||
435 | new Coord(0.25f, -0.4330127019f, 0.0f).Normalize(), | ||
436 | new Coord(0.25f, 0.4330127019f, 0.0f).Normalize() | ||
437 | }; | ||
438 | |||
439 | private static Angle[] angles4 = | 286 | private static Angle[] angles4 = |
440 | { | 287 | { |
441 | new Angle(0.0f, 1.0f, 0.0f), | 288 | new Angle(0.0f, 1.0f, 0.0f), |
@@ -445,13 +292,32 @@ namespace PrimMesher | |||
445 | new Angle(1.0f, 1.0f, 0.0f) | 292 | new Angle(1.0f, 1.0f, 0.0f) |
446 | }; | 293 | }; |
447 | 294 | ||
448 | private static Coord[] normals4 = | 295 | private static Angle[] angles6 = |
449 | { | 296 | { |
450 | new Coord(0.5f, 0.5f, 0.0f).Normalize(), | 297 | new Angle(0.0f, 1.0f, 0.0f), |
451 | new Coord(-0.5f, 0.5f, 0.0f).Normalize(), | 298 | new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), |
452 | new Coord(-0.5f, -0.5f, 0.0f).Normalize(), | 299 | new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), |
453 | new Coord(0.5f, -0.5f, 0.0f).Normalize(), | 300 | new Angle(0.5f, -1.0f, 0.0f), |
454 | new Coord(0.5f, 0.5f, 0.0f).Normalize() | 301 | new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), |
302 | new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), | ||
303 | new Angle(1.0f, 1.0f, 0.0f) | ||
304 | }; | ||
305 | |||
306 | private static Angle[] angles12 = | ||
307 | { | ||
308 | new Angle(0.0f, 1.0f, 0.0f), | ||
309 | new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f), | ||
310 | new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), | ||
311 | new Angle(0.25f, 0.0f, 1.0f), | ||
312 | new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), | ||
313 | new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f), | ||
314 | new Angle(0.5f, -1.0f, 0.0f), | ||
315 | new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f), | ||
316 | new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), | ||
317 | new Angle(0.75f, 0.0f, -1.0f), | ||
318 | new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), | ||
319 | new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f), | ||
320 | new Angle(1.0f, 1.0f, 0.0f) | ||
455 | }; | 321 | }; |
456 | 322 | ||
457 | private static Angle[] angles24 = | 323 | private static Angle[] angles24 = |
@@ -503,56 +369,72 @@ namespace PrimMesher | |||
503 | } | 369 | } |
504 | 370 | ||
505 | internal List<Angle> angles; | 371 | internal List<Angle> angles; |
506 | internal List<Coord> normals; | ||
507 | 372 | ||
508 | internal void makeAngles(int sides, float startAngle, float stopAngle) | 373 | internal void makeAngles(int sides, float startAngle, float stopAngle, bool hasCut) |
509 | { | 374 | { |
510 | angles = new List<Angle>(); | 375 | angles = new List<Angle>(); |
511 | normals = new List<Coord>(); | ||
512 | 376 | ||
513 | double twoPi = System.Math.PI * 2.0; | 377 | const double twoPi = System.Math.PI * 2.0; |
514 | float twoPiInv = 1.0f / (float)twoPi; | 378 | const float twoPiInv = (float)(1.0d / twoPi); |
515 | 379 | ||
516 | if (sides < 1) | 380 | if (sides < 1) |
517 | throw new Exception("number of sides not greater than zero"); | 381 | throw new Exception("number of sides not greater than zero"); |
518 | if (stopAngle <= startAngle) | 382 | if (stopAngle <= startAngle) |
519 | throw new Exception("stopAngle not greater than startAngle"); | 383 | throw new Exception("stopAngle not greater than startAngle"); |
520 | 384 | ||
521 | if ((sides == 3 || sides == 4 || sides == 24)) | 385 | if ((sides == 3 || sides == 4 || sides == 6 || sides == 12 || sides == 24)) |
522 | { | 386 | { |
523 | startAngle *= twoPiInv; | 387 | startAngle *= twoPiInv; |
524 | stopAngle *= twoPiInv; | 388 | stopAngle *= twoPiInv; |
525 | 389 | ||
526 | Angle[] sourceAngles; | 390 | Angle[] sourceAngles; |
527 | if (sides == 3) | 391 | switch (sides) |
528 | sourceAngles = angles3; | 392 | { |
529 | else if (sides == 4) | 393 | case 3: |
530 | sourceAngles = angles4; | 394 | sourceAngles = angles3; |
531 | else sourceAngles = angles24; | 395 | break; |
396 | case 4: | ||
397 | sourceAngles = angles4; | ||
398 | break; | ||
399 | case 6: | ||
400 | sourceAngles = angles6; | ||
401 | break; | ||
402 | case 12: | ||
403 | sourceAngles = angles12; | ||
404 | break; | ||
405 | default: | ||
406 | sourceAngles = angles24; | ||
407 | break; | ||
408 | } | ||
532 | 409 | ||
533 | int startAngleIndex = (int)(startAngle * sides); | 410 | int startAngleIndex = (int)(startAngle * sides); |
534 | int endAngleIndex = sourceAngles.Length - 1; | 411 | int endAngleIndex = sourceAngles.Length - 1; |
535 | if (stopAngle < 1.0f) | ||
536 | endAngleIndex = (int)(stopAngle * sides) + 1; | ||
537 | if (endAngleIndex == startAngleIndex) | ||
538 | endAngleIndex++; | ||
539 | 412 | ||
540 | for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) | 413 | if (hasCut) |
541 | { | 414 | { |
542 | angles.Add(sourceAngles[angleIndex]); | 415 | if (stopAngle < 1.0f) |
543 | if (sides == 3) | 416 | endAngleIndex = (int)(stopAngle * sides) + 1; |
544 | normals.Add(normals3[angleIndex]); | 417 | if (endAngleIndex == startAngleIndex) |
545 | else if (sides == 4) | 418 | endAngleIndex++; |
546 | normals.Add(normals4[angleIndex]); | 419 | |
547 | } | 420 | for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) |
421 | { | ||
422 | angles.Add(sourceAngles[angleIndex]); | ||
423 | } | ||
548 | 424 | ||
549 | if (startAngle > 0.0f) | 425 | if (startAngle > 0.0f) |
550 | angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); | 426 | angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); |
551 | 427 | ||
552 | if (stopAngle < 1.0f) | 428 | if (stopAngle < 1.0f) |
429 | { | ||
430 | int lastAngleIndex = angles.Count - 1; | ||
431 | angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); | ||
432 | } | ||
433 | } | ||
434 | else | ||
553 | { | 435 | { |
554 | int lastAngleIndex = angles.Count - 1; | 436 | for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex; angleIndex++) |
555 | angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); | 437 | angles.Add(sourceAngles[angleIndex]); |
556 | } | 438 | } |
557 | } | 439 | } |
558 | else | 440 | else |
@@ -618,20 +500,10 @@ namespace PrimMesher | |||
618 | 500 | ||
619 | public List<Coord> coords; | 501 | public List<Coord> coords; |
620 | public List<Face> faces; | 502 | public List<Face> faces; |
621 | public List<Coord> vertexNormals; | ||
622 | public List<float> us; | ||
623 | public List<UVCoord> faceUVs; | ||
624 | public List<int> faceNumbers; | ||
625 | 503 | ||
626 | // use these for making individual meshes for each prim face | 504 | // use these for making individual meshes for each prim face |
627 | public List<int> outerCoordIndices = null; | 505 | public List<int> outerCoordIndices = null; |
628 | public List<int> hollowCoordIndices = null; | 506 | public List<int> hollowCoordIndices = null; |
629 | public List<int> cut1CoordIndices = null; | ||
630 | public List<int> cut2CoordIndices = null; | ||
631 | |||
632 | public Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); | ||
633 | public Coord cutNormal1 = new Coord(); | ||
634 | public Coord cutNormal2 = new Coord(); | ||
635 | 507 | ||
636 | public int numOuterVerts = 0; | 508 | public int numOuterVerts = 0; |
637 | public int numHollowVerts = 0; | 509 | public int numHollowVerts = 0; |
@@ -639,7 +511,6 @@ namespace PrimMesher | |||
639 | public int outerFaceNumber = -1; | 511 | public int outerFaceNumber = -1; |
640 | public int hollowFaceNumber = -1; | 512 | public int hollowFaceNumber = -1; |
641 | 513 | ||
642 | public bool calcVertexNormals = false; | ||
643 | public int bottomFaceNumber = 0; | 514 | public int bottomFaceNumber = 0; |
644 | public int numPrimFaces = 0; | 515 | public int numPrimFaces = 0; |
645 | 516 | ||
@@ -647,40 +518,19 @@ namespace PrimMesher | |||
647 | { | 518 | { |
648 | this.coords = new List<Coord>(); | 519 | this.coords = new List<Coord>(); |
649 | this.faces = new List<Face>(); | 520 | this.faces = new List<Face>(); |
650 | this.vertexNormals = new List<Coord>(); | ||
651 | this.us = new List<float>(); | ||
652 | this.faceUVs = new List<UVCoord>(); | ||
653 | this.faceNumbers = new List<int>(); | ||
654 | } | 521 | } |
655 | 522 | ||
656 | public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) | 523 | public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool hasProfileCut, bool createFaces) |
657 | { | 524 | { |
658 | this.calcVertexNormals = calcVertexNormals; | 525 | const float halfSqr2 = 0.7071067811866f; |
526 | |||
659 | this.coords = new List<Coord>(); | 527 | this.coords = new List<Coord>(); |
660 | this.faces = new List<Face>(); | 528 | this.faces = new List<Face>(); |
661 | this.vertexNormals = new List<Coord>(); | ||
662 | this.us = new List<float>(); | ||
663 | this.faceUVs = new List<UVCoord>(); | ||
664 | this.faceNumbers = new List<int>(); | ||
665 | |||
666 | Coord center = new Coord(0.0f, 0.0f, 0.0f); | ||
667 | 529 | ||
668 | List<Coord> hollowCoords = new List<Coord>(); | 530 | List<Coord> hollowCoords = new List<Coord>(); |
669 | List<Coord> hollowNormals = new List<Coord>(); | ||
670 | List<float> hollowUs = new List<float>(); | ||
671 | |||
672 | if (calcVertexNormals) | ||
673 | { | ||
674 | this.outerCoordIndices = new List<int>(); | ||
675 | this.hollowCoordIndices = new List<int>(); | ||
676 | this.cut1CoordIndices = new List<int>(); | ||
677 | this.cut2CoordIndices = new List<int>(); | ||
678 | } | ||
679 | 531 | ||
680 | bool hasHollow = (hollow > 0.0f); | 532 | bool hasHollow = (hollow > 0.0f); |
681 | 533 | ||
682 | bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f); | ||
683 | |||
684 | AngleList angles = new AngleList(); | 534 | AngleList angles = new AngleList(); |
685 | AngleList hollowAngles = new AngleList(); | 535 | AngleList hollowAngles = new AngleList(); |
686 | 536 | ||
@@ -688,14 +538,14 @@ namespace PrimMesher | |||
688 | float yScale = 0.5f; | 538 | float yScale = 0.5f; |
689 | if (sides == 4) // corners of a square are sqrt(2) from center | 539 | if (sides == 4) // corners of a square are sqrt(2) from center |
690 | { | 540 | { |
691 | xScale = 0.707107f; | 541 | xScale = halfSqr2; |
692 | yScale = 0.707107f; | 542 | yScale = halfSqr2; |
693 | } | 543 | } |
694 | 544 | ||
695 | float startAngle = profileStart * twoPi; | 545 | float startAngle = profileStart * twoPi; |
696 | float stopAngle = profileEnd * twoPi; | 546 | float stopAngle = profileEnd * twoPi; |
697 | 547 | ||
698 | try { angles.makeAngles(sides, startAngle, stopAngle); } | 548 | try { angles.makeAngles(sides, startAngle, stopAngle,hasProfileCut); } |
699 | catch (Exception ex) | 549 | catch (Exception ex) |
700 | { | 550 | { |
701 | 551 | ||
@@ -707,6 +557,9 @@ namespace PrimMesher | |||
707 | 557 | ||
708 | this.numOuterVerts = angles.angles.Count; | 558 | this.numOuterVerts = angles.angles.Count; |
709 | 559 | ||
560 | Angle angle; | ||
561 | Coord newVert = new Coord(); | ||
562 | |||
710 | // flag to create as few triangles as possible for 3 or 4 side profile | 563 | // flag to create as few triangles as possible for 3 or 4 side profile |
711 | bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); | 564 | bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); |
712 | 565 | ||
@@ -716,7 +569,7 @@ namespace PrimMesher | |||
716 | hollowAngles = angles; | 569 | hollowAngles = angles; |
717 | else | 570 | else |
718 | { | 571 | { |
719 | try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle); } | 572 | try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle, hasProfileCut); } |
720 | catch (Exception ex) | 573 | catch (Exception ex) |
721 | { | 574 | { |
722 | errorMessage = "makeAngles failed: Exception: " + ex.ToString() | 575 | errorMessage = "makeAngles failed: Exception: " + ex.ToString() |
@@ -724,116 +577,48 @@ namespace PrimMesher | |||
724 | 577 | ||
725 | return; | 578 | return; |
726 | } | 579 | } |
580 | |||
581 | int numHollowAngles = hollowAngles.angles.Count; | ||
582 | for (int i = 0; i < numHollowAngles; i++) | ||
583 | { | ||
584 | angle = hollowAngles.angles[i]; | ||
585 | newVert.X = hollow * xScale * angle.X; | ||
586 | newVert.Y = hollow * yScale * angle.Y; | ||
587 | newVert.Z = 0.0f; | ||
588 | |||
589 | hollowCoords.Add(newVert); | ||
590 | } | ||
727 | } | 591 | } |
728 | this.numHollowVerts = hollowAngles.angles.Count; | 592 | this.numHollowVerts = hollowAngles.angles.Count; |
729 | } | 593 | } |
730 | else if (!simpleFace) | 594 | else if (!simpleFace) |
731 | { | 595 | { |
596 | Coord center = new Coord(0.0f, 0.0f, 0.0f); | ||
732 | this.coords.Add(center); | 597 | this.coords.Add(center); |
733 | if (this.calcVertexNormals) | ||
734 | this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); | ||
735 | this.us.Add(0.0f); | ||
736 | } | ||
737 | |||
738 | float z = 0.0f; | ||
739 | |||
740 | Angle angle; | ||
741 | Coord newVert = new Coord(); | ||
742 | if (hasHollow && hollowSides != sides) | ||
743 | { | ||
744 | int numHollowAngles = hollowAngles.angles.Count; | ||
745 | for (int i = 0; i < numHollowAngles; i++) | ||
746 | { | ||
747 | angle = hollowAngles.angles[i]; | ||
748 | newVert.X = hollow * xScale * angle.X; | ||
749 | newVert.Y = hollow * yScale * angle.Y; | ||
750 | newVert.Z = z; | ||
751 | |||
752 | hollowCoords.Add(newVert); | ||
753 | if (this.calcVertexNormals) | ||
754 | { | ||
755 | if (hollowSides < 5) | ||
756 | hollowNormals.Add(hollowAngles.normals[i].Invert()); | ||
757 | else | ||
758 | hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); | ||
759 | |||
760 | if (hollowSides == 4) | ||
761 | hollowUs.Add(angle.angle * hollow * 0.707107f); | ||
762 | else | ||
763 | hollowUs.Add(angle.angle * hollow); | ||
764 | } | ||
765 | } | ||
766 | } | 598 | } |
767 | 599 | ||
768 | int index = 0; | ||
769 | int numAngles = angles.angles.Count; | 600 | int numAngles = angles.angles.Count; |
601 | bool hollowsame = (hasHollow && hollowSides == sides); | ||
770 | 602 | ||
771 | for (int i = 0; i < numAngles; i++) | 603 | for (int i = 0; i < numAngles; i++) |
772 | { | 604 | { |
773 | angle = angles.angles[i]; | 605 | angle = angles.angles[i]; |
774 | newVert.X = angle.X * xScale; | 606 | newVert.X = angle.X * xScale; |
775 | newVert.Y = angle.Y * yScale; | 607 | newVert.Y = angle.Y * yScale; |
776 | newVert.Z = z; | 608 | newVert.Z = 0.0f; |
777 | this.coords.Add(newVert); | 609 | this.coords.Add(newVert); |
778 | if (this.calcVertexNormals) | 610 | if (hollowsame) |
779 | { | 611 | { |
780 | this.outerCoordIndices.Add(this.coords.Count - 1); | 612 | newVert.X *= hollow; |
781 | 613 | newVert.Y *= hollow; | |
782 | if (sides < 5) | 614 | hollowCoords.Add(newVert); |
783 | { | ||
784 | this.vertexNormals.Add(angles.normals[i]); | ||
785 | float u = angle.angle; | ||
786 | this.us.Add(u); | ||
787 | } | ||
788 | else | ||
789 | { | ||
790 | this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f)); | ||
791 | this.us.Add(angle.angle); | ||
792 | } | ||
793 | } | ||
794 | |||
795 | if (hasHollow) | ||
796 | { | ||
797 | if (hollowSides == sides) | ||
798 | { | ||
799 | newVert.X *= hollow; | ||
800 | newVert.Y *= hollow; | ||
801 | newVert.Z = z; | ||
802 | hollowCoords.Add(newVert); | ||
803 | if (this.calcVertexNormals) | ||
804 | { | ||
805 | if (sides < 5) | ||
806 | { | ||
807 | hollowNormals.Add(angles.normals[i].Invert()); | ||
808 | } | ||
809 | |||
810 | else | ||
811 | hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); | ||
812 | |||
813 | hollowUs.Add(angle.angle * hollow); | ||
814 | } | ||
815 | } | ||
816 | } | ||
817 | else if (!simpleFace && createFaces && angle.angle > 0.0001f) | ||
818 | { | ||
819 | Face newFace = new Face(); | ||
820 | newFace.v1 = 0; | ||
821 | newFace.v2 = index; | ||
822 | newFace.v3 = index + 1; | ||
823 | |||
824 | this.faces.Add(newFace); | ||
825 | } | 615 | } |
826 | index += 1; | ||
827 | } | 616 | } |
828 | 617 | ||
829 | if (hasHollow) | 618 | if (hasHollow) |
830 | { | 619 | { |
831 | hollowCoords.Reverse(); | 620 | hollowCoords.Reverse(); |
832 | if (this.calcVertexNormals) | 621 | this.coords.AddRange(hollowCoords); |
833 | { | ||
834 | hollowNormals.Reverse(); | ||
835 | hollowUs.Reverse(); | ||
836 | } | ||
837 | 622 | ||
838 | if (createFaces) | 623 | if (createFaces) |
839 | { | 624 | { |
@@ -855,187 +640,176 @@ namespace PrimMesher | |||
855 | newFace.v3 = numTotalVerts - coordIndex - 1; | 640 | newFace.v3 = numTotalVerts - coordIndex - 1; |
856 | this.faces.Add(newFace); | 641 | this.faces.Add(newFace); |
857 | } | 642 | } |
643 | if (!hasProfileCut) | ||
644 | { | ||
645 | newFace.v1 = this.numOuterVerts - 1; | ||
646 | newFace.v2 = 0; | ||
647 | newFace.v3 = this.numOuterVerts; | ||
648 | this.faces.Add(newFace); | ||
649 | |||
650 | newFace.v1 = 0; | ||
651 | newFace.v2 = numTotalVerts - 1; | ||
652 | newFace.v3 = this.numOuterVerts; | ||
653 | this.faces.Add(newFace); | ||
654 | } | ||
858 | } | 655 | } |
859 | else | 656 | else if (this.numOuterVerts < this.numHollowVerts) |
860 | { | 657 | { |
861 | if (this.numOuterVerts < this.numHollowVerts) | 658 | Face newFace = new Face(); |
659 | int j = 0; // j is the index for outer vertices | ||
660 | int i; | ||
661 | int maxJ = this.numOuterVerts - 1; | ||
662 | float curHollowAngle = 0; | ||
663 | for (i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices | ||
862 | { | 664 | { |
863 | Face newFace = new Face(); | 665 | curHollowAngle = hollowAngles.angles[i].angle; |
864 | int j = 0; // j is the index for outer vertices | 666 | if (j < maxJ) |
865 | int maxJ = this.numOuterVerts - 1; | ||
866 | for (int i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices | ||
867 | { | 667 | { |
868 | if (j < maxJ) | 668 | if (angles.angles[j + 1].angle - curHollowAngle < curHollowAngle - angles.angles[j].angle + 0.000001f) |
869 | if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f) | 669 | { |
870 | { | 670 | newFace.v1 = numTotalVerts - i - 1; |
871 | newFace.v1 = numTotalVerts - i - 1; | 671 | newFace.v2 = j; |
872 | newFace.v2 = j; | 672 | newFace.v3 = j + 1; |
873 | newFace.v3 = j + 1; | 673 | this.faces.Add(newFace); |
674 | j++; | ||
675 | } | ||
676 | } | ||
677 | else | ||
678 | { | ||
679 | if (1.0f - curHollowAngle < curHollowAngle - angles.angles[j].angle + 0.000001f) | ||
680 | break; | ||
681 | } | ||
682 | |||
683 | newFace.v1 = j; | ||
684 | newFace.v2 = numTotalVerts - i - 2; | ||
685 | newFace.v3 = numTotalVerts - i - 1; | ||
874 | 686 | ||
875 | this.faces.Add(newFace); | 687 | this.faces.Add(newFace); |
876 | j += 1; | 688 | } |
877 | } | ||
878 | 689 | ||
879 | newFace.v1 = j; | 690 | if (!hasProfileCut) |
880 | newFace.v2 = numTotalVerts - i - 2; | 691 | { |
881 | newFace.v3 = numTotalVerts - i - 1; | 692 | if (i == this.numHollowVerts) |
693 | { | ||
694 | newFace.v1 = numTotalVerts - this.numHollowVerts; | ||
695 | newFace.v2 = maxJ; | ||
696 | newFace.v3 = 0; | ||
882 | 697 | ||
883 | this.faces.Add(newFace); | 698 | this.faces.Add(newFace); |
884 | } | 699 | } |
885 | } | 700 | else |
886 | else // numHollowVerts < numOuterVerts | ||
887 | { | ||
888 | Face newFace = new Face(); | ||
889 | int j = 0; // j is the index for inner vertices | ||
890 | int maxJ = this.numHollowVerts - 1; | ||
891 | for (int i = 0; i < this.numOuterVerts; i++) | ||
892 | { | 701 | { |
893 | if (j < maxJ) | 702 | if (1.0f - curHollowAngle < curHollowAngle - angles.angles[maxJ].angle + 0.000001f) |
894 | if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) | 703 | { |
895 | { | 704 | newFace.v1 = numTotalVerts - i - 1; |
896 | newFace.v1 = i; | 705 | newFace.v2 = maxJ; |
897 | newFace.v2 = numTotalVerts - j - 2; | 706 | newFace.v3 = 0; |
898 | newFace.v3 = numTotalVerts - j - 1; | ||
899 | 707 | ||
900 | this.faces.Add(newFace); | 708 | this.faces.Add(newFace); |
901 | j += 1; | 709 | } |
902 | } | ||
903 | 710 | ||
904 | newFace.v1 = numTotalVerts - j - 1; | 711 | for (; i < this.numHollowVerts - 1; i++) |
905 | newFace.v2 = i; | 712 | { |
906 | newFace.v3 = i + 1; | 713 | newFace.v1 = 0; |
714 | newFace.v2 = numTotalVerts - i - 2; | ||
715 | newFace.v3 = numTotalVerts - i - 1; | ||
907 | 716 | ||
908 | this.faces.Add(newFace); | 717 | this.faces.Add(newFace); |
718 | } | ||
909 | } | 719 | } |
720 | |||
721 | newFace.v1 = 0; | ||
722 | newFace.v2 = numTotalVerts - this.numHollowVerts; | ||
723 | newFace.v3 = numTotalVerts - 1; | ||
724 | this.faces.Add(newFace); | ||
910 | } | 725 | } |
911 | } | 726 | } |
912 | } | 727 | else // numHollowVerts < numOuterVerts |
913 | |||
914 | if (calcVertexNormals) | ||
915 | { | ||
916 | foreach (Coord hc in hollowCoords) | ||
917 | { | 728 | { |
918 | this.coords.Add(hc); | 729 | Face newFace = new Face(); |
919 | hollowCoordIndices.Add(this.coords.Count - 1); | 730 | int j = 0; // j is the index for inner vertices |
920 | } | 731 | int maxJ = this.numHollowVerts - 1; |
921 | } | 732 | for (int i = 0; i < this.numOuterVerts; i++) |
922 | else | 733 | { |
923 | this.coords.AddRange(hollowCoords); | 734 | if (j < maxJ) |
735 | if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) | ||
736 | { | ||
737 | newFace.v1 = i; | ||
738 | newFace.v2 = numTotalVerts - j - 2; | ||
739 | newFace.v3 = numTotalVerts - j - 1; | ||
924 | 740 | ||
925 | if (this.calcVertexNormals) | 741 | this.faces.Add(newFace); |
926 | { | 742 | j += 1; |
927 | this.vertexNormals.AddRange(hollowNormals); | 743 | } |
928 | this.us.AddRange(hollowUs); | ||
929 | 744 | ||
930 | } | 745 | newFace.v1 = numTotalVerts - j - 1; |
931 | } | 746 | newFace.v2 = i; |
747 | newFace.v3 = i + 1; | ||
932 | 748 | ||
933 | if (simpleFace && createFaces) | 749 | this.faces.Add(newFace); |
934 | { | 750 | } |
935 | if (sides == 3) | ||
936 | this.faces.Add(new Face(0, 1, 2)); | ||
937 | else if (sides == 4) | ||
938 | { | ||
939 | this.faces.Add(new Face(0, 1, 2)); | ||
940 | this.faces.Add(new Face(0, 2, 3)); | ||
941 | } | ||
942 | } | ||
943 | 751 | ||
944 | if (calcVertexNormals && hasProfileCut) | 752 | if (!hasProfileCut) |
945 | { | 753 | { |
946 | int lastOuterVertIndex = this.numOuterVerts - 1; | 754 | int i = this.numOuterVerts - 1; |
947 | 755 | ||
948 | if (hasHollow) | 756 | if (hollowAngles.angles[0].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[maxJ].angle + 0.000001f) |
949 | { | 757 | { |
950 | this.cut1CoordIndices.Add(0); | 758 | newFace.v1 = 0; |
951 | this.cut1CoordIndices.Add(this.coords.Count - 1); | 759 | newFace.v2 = numTotalVerts - maxJ - 1; |
760 | newFace.v3 = numTotalVerts - 1; | ||
952 | 761 | ||
953 | this.cut2CoordIndices.Add(lastOuterVertIndex + 1); | 762 | this.faces.Add(newFace); |
954 | this.cut2CoordIndices.Add(lastOuterVertIndex); | 763 | } |
955 | 764 | ||
956 | this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y; | 765 | newFace.v1 = numTotalVerts - maxJ - 1; |
957 | this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X); | 766 | newFace.v2 = i; |
767 | newFace.v3 = 0; | ||
958 | 768 | ||
959 | this.cutNormal2.X = this.coords[lastOuterVertIndex + 1].Y - this.coords[lastOuterVertIndex].Y; | 769 | this.faces.Add(newFace); |
960 | this.cutNormal2.Y = -(this.coords[lastOuterVertIndex + 1].X - this.coords[lastOuterVertIndex].X); | 770 | } |
771 | } | ||
961 | } | 772 | } |
773 | |||
774 | } | ||
962 | 775 | ||
776 | else if (createFaces) | ||
777 | { | ||
778 | if (simpleFace) | ||
779 | { | ||
780 | if (sides == 3) | ||
781 | this.faces.Add(new Face(0, 1, 2)); | ||
782 | else if (sides == 4) | ||
783 | { | ||
784 | this.faces.Add(new Face(0, 1, 2)); | ||
785 | this.faces.Add(new Face(0, 2, 3)); | ||
786 | } | ||
787 | } | ||
963 | else | 788 | else |
964 | { | 789 | { |
965 | this.cut1CoordIndices.Add(0); | 790 | for (int i = 1; i < numAngles ; i++) |
966 | this.cut1CoordIndices.Add(1); | 791 | { |
967 | 792 | Face newFace = new Face(); | |
968 | this.cut2CoordIndices.Add(lastOuterVertIndex); | 793 | newFace.v1 = 0; |
969 | this.cut2CoordIndices.Add(0); | 794 | newFace.v2 = i; |
970 | 795 | newFace.v3 = i + 1; | |
971 | this.cutNormal1.X = this.vertexNormals[1].Y; | 796 | this.faces.Add(newFace); |
972 | this.cutNormal1.Y = -this.vertexNormals[1].X; | 797 | } |
973 | 798 | if (!hasProfileCut) | |
974 | this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 2].Y; | 799 | { |
975 | this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 2].X; | 800 | Face newFace = new Face(); |
976 | 801 | newFace.v1 = 0; | |
802 | newFace.v2 = numAngles; | ||
803 | newFace.v3 = 1; | ||
804 | this.faces.Add(newFace); | ||
805 | } | ||
977 | } | 806 | } |
978 | this.cutNormal1.Normalize(); | ||
979 | this.cutNormal2.Normalize(); | ||
980 | } | 807 | } |
981 | 808 | ||
982 | this.MakeFaceUVs(); | ||
983 | 809 | ||
984 | hollowCoords = null; | 810 | hollowCoords = null; |
985 | hollowNormals = null; | ||
986 | hollowUs = null; | ||
987 | |||
988 | if (calcVertexNormals) | ||
989 | { // calculate prim face numbers | ||
990 | |||
991 | // face number order is top, outer, hollow, bottom, start cut, end cut | ||
992 | // I know it's ugly but so is the whole concept of prim face numbers | ||
993 | |||
994 | int faceNum = 1; // start with outer faces | ||
995 | this.outerFaceNumber = faceNum; | ||
996 | |||
997 | int startVert = hasProfileCut && !hasHollow ? 1 : 0; | ||
998 | if (startVert > 0) | ||
999 | this.faceNumbers.Add(-1); | ||
1000 | for (int i = 0; i < this.numOuterVerts - 1; i++) | ||
1001 | this.faceNumbers.Add(sides < 5 && i <= sides ? faceNum++ : faceNum); | ||
1002 | |||
1003 | this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); | ||
1004 | |||
1005 | if (sides > 4 && (hasHollow || hasProfileCut)) | ||
1006 | faceNum++; | ||
1007 | |||
1008 | if (sides < 5 && (hasHollow || hasProfileCut) && this.numOuterVerts < sides) | ||
1009 | faceNum++; | ||
1010 | |||
1011 | if (hasHollow) | ||
1012 | { | ||
1013 | for (int i = 0; i < this.numHollowVerts; i++) | ||
1014 | this.faceNumbers.Add(faceNum); | ||
1015 | |||
1016 | this.hollowFaceNumber = faceNum++; | ||
1017 | } | ||
1018 | |||
1019 | this.bottomFaceNumber = faceNum++; | ||
1020 | |||
1021 | if (hasHollow && hasProfileCut) | ||
1022 | this.faceNumbers.Add(faceNum++); | ||
1023 | |||
1024 | for (int i = 0; i < this.faceNumbers.Count; i++) | ||
1025 | if (this.faceNumbers[i] == -1) | ||
1026 | this.faceNumbers[i] = faceNum++; | ||
1027 | |||
1028 | this.numPrimFaces = faceNum; | ||
1029 | } | ||
1030 | |||
1031 | } | 811 | } |
1032 | 812 | ||
1033 | public void MakeFaceUVs() | ||
1034 | { | ||
1035 | this.faceUVs = new List<UVCoord>(); | ||
1036 | foreach (Coord c in this.coords) | ||
1037 | this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); | ||
1038 | } | ||
1039 | 813 | ||
1040 | public Profile Copy() | 814 | public Profile Copy() |
1041 | { | 815 | { |
@@ -1047,24 +821,10 @@ namespace PrimMesher | |||
1047 | Profile copy = new Profile(); | 821 | Profile copy = new Profile(); |
1048 | 822 | ||
1049 | copy.coords.AddRange(this.coords); | 823 | copy.coords.AddRange(this.coords); |
1050 | copy.faceUVs.AddRange(this.faceUVs); | ||
1051 | 824 | ||
1052 | if (needFaces) | 825 | if (needFaces) |
1053 | copy.faces.AddRange(this.faces); | 826 | copy.faces.AddRange(this.faces); |
1054 | if ((copy.calcVertexNormals = this.calcVertexNormals) == true) | 827 | |
1055 | { | ||
1056 | copy.vertexNormals.AddRange(this.vertexNormals); | ||
1057 | copy.faceNormal = this.faceNormal; | ||
1058 | copy.cutNormal1 = this.cutNormal1; | ||
1059 | copy.cutNormal2 = this.cutNormal2; | ||
1060 | copy.us.AddRange(this.us); | ||
1061 | copy.faceNumbers.AddRange(this.faceNumbers); | ||
1062 | |||
1063 | copy.cut1CoordIndices = new List<int>(this.cut1CoordIndices); | ||
1064 | copy.cut2CoordIndices = new List<int>(this.cut2CoordIndices); | ||
1065 | copy.hollowCoordIndices = new List<int>(this.hollowCoordIndices); | ||
1066 | copy.outerCoordIndices = new List<int>(this.outerCoordIndices); | ||
1067 | } | ||
1068 | copy.numOuterVerts = this.numOuterVerts; | 828 | copy.numOuterVerts = this.numOuterVerts; |
1069 | copy.numHollowVerts = this.numHollowVerts; | 829 | copy.numHollowVerts = this.numHollowVerts; |
1070 | 830 | ||
@@ -1099,18 +859,6 @@ namespace PrimMesher | |||
1099 | 859 | ||
1100 | for (i = 0; i < numVerts; i++) | 860 | for (i = 0; i < numVerts; i++) |
1101 | this.coords[i] *= q; | 861 | this.coords[i] *= q; |
1102 | |||
1103 | if (this.calcVertexNormals) | ||
1104 | { | ||
1105 | int numNormals = this.vertexNormals.Count; | ||
1106 | for (i = 0; i < numNormals; i++) | ||
1107 | this.vertexNormals[i] *= q; | ||
1108 | |||
1109 | this.faceNormal *= q; | ||
1110 | this.cutNormal1 *= q; | ||
1111 | this.cutNormal2 *= q; | ||
1112 | |||
1113 | } | ||
1114 | } | 862 | } |
1115 | 863 | ||
1116 | public void Scale(float x, float y) | 864 | public void Scale(float x, float y) |
@@ -1146,29 +894,6 @@ namespace PrimMesher | |||
1146 | tmpFace.v1 = tmp; | 894 | tmpFace.v1 = tmp; |
1147 | this.faces[i] = tmpFace; | 895 | this.faces[i] = tmpFace; |
1148 | } | 896 | } |
1149 | |||
1150 | if (this.calcVertexNormals) | ||
1151 | { | ||
1152 | int normalCount = this.vertexNormals.Count; | ||
1153 | if (normalCount > 0) | ||
1154 | { | ||
1155 | Coord n = this.vertexNormals[normalCount - 1]; | ||
1156 | n.Z = -n.Z; | ||
1157 | this.vertexNormals[normalCount - 1] = n; | ||
1158 | } | ||
1159 | } | ||
1160 | |||
1161 | this.faceNormal.X = -this.faceNormal.X; | ||
1162 | this.faceNormal.Y = -this.faceNormal.Y; | ||
1163 | this.faceNormal.Z = -this.faceNormal.Z; | ||
1164 | |||
1165 | int numfaceUVs = this.faceUVs.Count; | ||
1166 | for (i = 0; i < numfaceUVs; i++) | ||
1167 | { | ||
1168 | UVCoord uv = this.faceUVs[i]; | ||
1169 | uv.V = 1.0f - uv.V; | ||
1170 | this.faceUVs[i] = uv; | ||
1171 | } | ||
1172 | } | 897 | } |
1173 | 898 | ||
1174 | public void AddValue2FaceVertexIndices(int num) | 899 | public void AddValue2FaceVertexIndices(int num) |
@@ -1186,25 +911,7 @@ namespace PrimMesher | |||
1186 | } | 911 | } |
1187 | } | 912 | } |
1188 | 913 | ||
1189 | public void AddValue2FaceNormalIndices(int num) | 914 | public void DumpRaw(String path, String name, String title) |
1190 | { | ||
1191 | if (this.calcVertexNormals) | ||
1192 | { | ||
1193 | int numFaces = this.faces.Count; | ||
1194 | Face tmpFace; | ||
1195 | for (int i = 0; i < numFaces; i++) | ||
1196 | { | ||
1197 | tmpFace = this.faces[i]; | ||
1198 | tmpFace.n1 += num; | ||
1199 | tmpFace.n2 += num; | ||
1200 | tmpFace.n3 += num; | ||
1201 | |||
1202 | this.faces[i] = tmpFace; | ||
1203 | } | ||
1204 | } | ||
1205 | } | ||
1206 | |||
1207 | public void DumpRaw(String path, String name, String title) | ||
1208 | { | 915 | { |
1209 | if (path == null) | 916 | if (path == null) |
1210 | return; | 917 | return; |
@@ -1451,11 +1158,9 @@ namespace PrimMesher | |||
1451 | private const float twoPi = 2.0f * (float)Math.PI; | 1158 | private const float twoPi = 2.0f * (float)Math.PI; |
1452 | 1159 | ||
1453 | public List<Coord> coords; | 1160 | public List<Coord> coords; |
1454 | public List<Coord> normals; | 1161 | // public List<Coord> normals; |
1455 | public List<Face> faces; | 1162 | public List<Face> faces; |
1456 | 1163 | ||
1457 | public List<ViewerFace> viewerFaces; | ||
1458 | |||
1459 | private int sides = 4; | 1164 | private int sides = 4; |
1460 | private int hollowSides = 4; | 1165 | private int hollowSides = 4; |
1461 | private float profileStart = 0.0f; | 1166 | private float profileStart = 0.0f; |
@@ -1478,15 +1183,8 @@ namespace PrimMesher | |||
1478 | public float revolutions = 1.0f; | 1183 | public float revolutions = 1.0f; |
1479 | public int stepsPerRevolution = 24; | 1184 | public int stepsPerRevolution = 24; |
1480 | 1185 | ||
1481 | private int profileOuterFaceNumber = -1; | ||
1482 | private int profileHollowFaceNumber = -1; | ||
1483 | |||
1484 | private bool hasProfileCut = false; | 1186 | private bool hasProfileCut = false; |
1485 | private bool hasHollow = false; | 1187 | private bool hasHollow = false; |
1486 | public bool calcVertexNormals = false; | ||
1487 | private bool normalsProcessed = false; | ||
1488 | public bool viewerMode = false; | ||
1489 | public bool sphereMode = false; | ||
1490 | 1188 | ||
1491 | public int numPrimFaces = 0; | 1189 | public int numPrimFaces = 0; |
1492 | 1190 | ||
@@ -1518,27 +1216,16 @@ namespace PrimMesher | |||
1518 | s += "\nradius...............: " + this.radius.ToString(); | 1216 | s += "\nradius...............: " + this.radius.ToString(); |
1519 | s += "\nrevolutions..........: " + this.revolutions.ToString(); | 1217 | s += "\nrevolutions..........: " + this.revolutions.ToString(); |
1520 | s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); | 1218 | s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); |
1521 | s += "\nsphereMode...........: " + this.sphereMode.ToString(); | ||
1522 | s += "\nhasProfileCut........: " + this.hasProfileCut.ToString(); | 1219 | s += "\nhasProfileCut........: " + this.hasProfileCut.ToString(); |
1523 | s += "\nhasHollow............: " + this.hasHollow.ToString(); | 1220 | s += "\nhasHollow............: " + this.hasHollow.ToString(); |
1524 | s += "\nviewerMode...........: " + this.viewerMode.ToString(); | ||
1525 | 1221 | ||
1526 | return s; | 1222 | return s; |
1527 | } | 1223 | } |
1528 | 1224 | ||
1529 | public int ProfileOuterFaceNumber | ||
1530 | { | ||
1531 | get { return profileOuterFaceNumber; } | ||
1532 | } | ||
1533 | |||
1534 | public int ProfileHollowFaceNumber | ||
1535 | { | ||
1536 | get { return profileHollowFaceNumber; } | ||
1537 | } | ||
1538 | |||
1539 | public bool HasProfileCut | 1225 | public bool HasProfileCut |
1540 | { | 1226 | { |
1541 | get { return hasProfileCut; } | 1227 | get { return hasProfileCut; } |
1228 | set { hasProfileCut = value; } | ||
1542 | } | 1229 | } |
1543 | 1230 | ||
1544 | public bool HasHollow | 1231 | public bool HasHollow |
@@ -1555,6 +1242,7 @@ namespace PrimMesher | |||
1555 | /// <param name="profileEnd"></param> | 1242 | /// <param name="profileEnd"></param> |
1556 | /// <param name="hollow"></param> | 1243 | /// <param name="hollow"></param> |
1557 | /// <param name="hollowSides"></param> | 1244 | /// <param name="hollowSides"></param> |
1245 | /// <param name="sphereMode"></param> | ||
1558 | public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides) | 1246 | public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides) |
1559 | { | 1247 | { |
1560 | this.coords = new List<Coord>(); | 1248 | this.coords = new List<Coord>(); |
@@ -1594,32 +1282,12 @@ namespace PrimMesher | |||
1594 | this.coords = new List<Coord>(); | 1282 | this.coords = new List<Coord>(); |
1595 | this.faces = new List<Face>(); | 1283 | this.faces = new List<Face>(); |
1596 | 1284 | ||
1597 | if (this.viewerMode) | ||
1598 | { | ||
1599 | this.viewerFaces = new List<ViewerFace>(); | ||
1600 | this.calcVertexNormals = true; | ||
1601 | } | ||
1602 | |||
1603 | if (this.calcVertexNormals) | ||
1604 | this.normals = new List<Coord>(); | ||
1605 | |||
1606 | int steps = 1; | 1285 | int steps = 1; |
1607 | 1286 | ||
1608 | float length = this.pathCutEnd - this.pathCutBegin; | 1287 | float length = this.pathCutEnd - this.pathCutBegin; |
1609 | normalsProcessed = false; | ||
1610 | 1288 | ||
1611 | if (this.viewerMode && this.sides == 3) | 1289 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; |
1612 | { | ||
1613 | // prisms don't taper well so add some vertical resolution | ||
1614 | // other prims may benefit from this but just do prisms for now | ||
1615 | if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01) | ||
1616 | steps = (int)(steps * 4.5 * length); | ||
1617 | } | ||
1618 | 1290 | ||
1619 | if (this.sphereMode) | ||
1620 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; | ||
1621 | else | ||
1622 | this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; | ||
1623 | this.hasHollow = (this.hollow > 0.001f); | 1291 | this.hasHollow = (this.hollow > 0.001f); |
1624 | 1292 | ||
1625 | float twistBegin = this.twistBegin / 360.0f * twoPi; | 1293 | float twistBegin = this.twistBegin / 360.0f * twoPi; |
@@ -1701,47 +1369,16 @@ namespace PrimMesher | |||
1701 | hollow *= 1.414f; | 1369 | hollow *= 1.414f; |
1702 | } | 1370 | } |
1703 | 1371 | ||
1704 | Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals); | 1372 | Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, this.hasProfileCut,true); |
1705 | this.errorMessage = profile.errorMessage; | 1373 | this.errorMessage = profile.errorMessage; |
1706 | 1374 | ||
1707 | this.numPrimFaces = profile.numPrimFaces; | 1375 | this.numPrimFaces = profile.numPrimFaces; |
1708 | 1376 | ||
1709 | int cut1FaceNumber = profile.bottomFaceNumber + 1; | ||
1710 | int cut2FaceNumber = cut1FaceNumber + 1; | ||
1711 | if (!needEndFaces) | ||
1712 | { | ||
1713 | cut1FaceNumber -= 2; | ||
1714 | cut2FaceNumber -= 2; | ||
1715 | } | ||
1716 | |||
1717 | profileOuterFaceNumber = profile.outerFaceNumber; | ||
1718 | if (!needEndFaces) | ||
1719 | profileOuterFaceNumber--; | ||
1720 | |||
1721 | if (hasHollow) | ||
1722 | { | ||
1723 | profileHollowFaceNumber = profile.hollowFaceNumber; | ||
1724 | if (!needEndFaces) | ||
1725 | profileHollowFaceNumber--; | ||
1726 | } | ||
1727 | |||
1728 | int cut1Vert = -1; | ||
1729 | int cut2Vert = -1; | ||
1730 | if (hasProfileCut) | ||
1731 | { | ||
1732 | cut1Vert = hasHollow ? profile.coords.Count - 1 : 0; | ||
1733 | cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; | ||
1734 | } | ||
1735 | |||
1736 | if (initialProfileRot != 0.0f) | 1377 | if (initialProfileRot != 0.0f) |
1737 | { | 1378 | { |
1738 | profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); | 1379 | profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); |
1739 | if (viewerMode) | ||
1740 | profile.MakeFaceUVs(); | ||
1741 | } | 1380 | } |
1742 | 1381 | ||
1743 | Coord lastCutNormal1 = new Coord(); | ||
1744 | Coord lastCutNormal2 = new Coord(); | ||
1745 | float thisV = 0.0f; | 1382 | float thisV = 0.0f; |
1746 | float lastV = 0.0f; | 1383 | float lastV = 0.0f; |
1747 | 1384 | ||
@@ -1764,57 +1401,21 @@ namespace PrimMesher | |||
1764 | path.stepsPerRevolution = stepsPerRevolution; | 1401 | path.stepsPerRevolution = stepsPerRevolution; |
1765 | 1402 | ||
1766 | path.Create(pathType, steps); | 1403 | path.Create(pathType, steps); |
1404 | |||
1405 | int lastNode = path.pathNodes.Count -1; | ||
1767 | 1406 | ||
1768 | for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) | 1407 | for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) |
1769 | { | 1408 | { |
1770 | PathNode node = path.pathNodes[nodeIndex]; | 1409 | PathNode node = path.pathNodes[nodeIndex]; |
1771 | Profile newLayer = profile.Copy(); | 1410 | Profile newLayer = profile.Copy(); |
1772 | newLayer.Scale(node.xScale, node.yScale); | ||
1773 | 1411 | ||
1412 | newLayer.Scale(node.xScale, node.yScale); | ||
1774 | newLayer.AddRot(node.rotation); | 1413 | newLayer.AddRot(node.rotation); |
1775 | newLayer.AddPos(node.position); | 1414 | newLayer.AddPos(node.position); |
1776 | 1415 | ||
1777 | if (needEndFaces && nodeIndex == 0) | 1416 | if (needEndFaces && nodeIndex == 0) |
1778 | { | 1417 | { |
1779 | newLayer.FlipNormals(); | 1418 | newLayer.FlipNormals(); |
1780 | |||
1781 | // add the bottom faces to the viewerFaces list | ||
1782 | if (this.viewerMode) | ||
1783 | { | ||
1784 | Coord faceNormal = newLayer.faceNormal; | ||
1785 | ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber); | ||
1786 | int numFaces = newLayer.faces.Count; | ||
1787 | List<Face> faces = newLayer.faces; | ||
1788 | |||
1789 | for (int i = 0; i < numFaces; i++) | ||
1790 | { | ||
1791 | Face face = faces[i]; | ||
1792 | newViewerFace.v1 = newLayer.coords[face.v1]; | ||
1793 | newViewerFace.v2 = newLayer.coords[face.v2]; | ||
1794 | newViewerFace.v3 = newLayer.coords[face.v3]; | ||
1795 | |||
1796 | newViewerFace.coordIndex1 = face.v1; | ||
1797 | newViewerFace.coordIndex2 = face.v2; | ||
1798 | newViewerFace.coordIndex3 = face.v3; | ||
1799 | |||
1800 | newViewerFace.n1 = faceNormal; | ||
1801 | newViewerFace.n2 = faceNormal; | ||
1802 | newViewerFace.n3 = faceNormal; | ||
1803 | |||
1804 | newViewerFace.uv1 = newLayer.faceUVs[face.v1]; | ||
1805 | newViewerFace.uv2 = newLayer.faceUVs[face.v2]; | ||
1806 | newViewerFace.uv3 = newLayer.faceUVs[face.v3]; | ||
1807 | |||
1808 | if (pathType == PathType.Linear) | ||
1809 | { | ||
1810 | newViewerFace.uv1.Flip(); | ||
1811 | newViewerFace.uv2.Flip(); | ||
1812 | newViewerFace.uv3.Flip(); | ||
1813 | } | ||
1814 | |||
1815 | this.viewerFaces.Add(newViewerFace); | ||
1816 | } | ||
1817 | } | ||
1818 | } // if (nodeIndex == 0) | 1419 | } // if (nodeIndex == 0) |
1819 | 1420 | ||
1820 | // append this layer | 1421 | // append this layer |
@@ -1824,15 +1425,17 @@ namespace PrimMesher | |||
1824 | 1425 | ||
1825 | this.coords.AddRange(newLayer.coords); | 1426 | this.coords.AddRange(newLayer.coords); |
1826 | 1427 | ||
1827 | if (this.calcVertexNormals) | 1428 | if (needEndFaces) |
1828 | { | 1429 | { |
1829 | newLayer.AddValue2FaceNormalIndices(this.normals.Count); | 1430 | if (nodeIndex == 0) |
1830 | this.normals.AddRange(newLayer.vertexNormals); | 1431 | this.faces.AddRange(newLayer.faces); |
1432 | else if (nodeIndex == lastNode) | ||
1433 | { | ||
1434 | if (node.xScale > 1e-6 && node.yScale > 1e-6) | ||
1435 | this.faces.AddRange(newLayer.faces); | ||
1436 | } | ||
1831 | } | 1437 | } |
1832 | 1438 | ||
1833 | if (node.percentOfPath < this.pathCutBegin + 0.01f || node.percentOfPath > this.pathCutEnd - 0.01f) | ||
1834 | this.faces.AddRange(newLayer.faces); | ||
1835 | |||
1836 | // fill faces between layers | 1439 | // fill faces between layers |
1837 | 1440 | ||
1838 | int numVerts = newLayer.coords.Count; | 1441 | int numVerts = newLayer.coords.Count; |
@@ -1843,219 +1446,88 @@ namespace PrimMesher | |||
1843 | 1446 | ||
1844 | if (nodeIndex > 0) | 1447 | if (nodeIndex > 0) |
1845 | { | 1448 | { |
1846 | int startVert = coordsLen + 1; | 1449 | int startVert = coordsLen; |
1847 | int endVert = this.coords.Count; | 1450 | int endVert = this.coords.Count; |
1848 | 1451 | if (!this.hasProfileCut) | |
1849 | if (sides < 5 || this.hasProfileCut || this.hasHollow) | ||
1850 | startVert--; | ||
1851 | |||
1852 | for (int i = startVert; i < endVert; i++) | ||
1853 | { | 1452 | { |
1854 | int iNext = i + 1; | 1453 | int i = startVert; |
1855 | if (i == endVert - 1) | 1454 | for (int l = 0; l < profile.numOuterVerts - 1; l++) |
1856 | iNext = startVert; | 1455 | { |
1857 | 1456 | newFace1.v1 = i; | |
1858 | int whichVert = i - startVert; | 1457 | newFace1.v2 = i - numVerts; |
1458 | newFace1.v3 = i + 1; | ||
1459 | this.faces.Add(newFace1); | ||
1460 | |||
1461 | newFace2.v1 = i + 1; | ||
1462 | newFace2.v2 = i - numVerts; | ||
1463 | newFace2.v3 = i + 1 - numVerts; | ||
1464 | this.faces.Add(newFace2); | ||
1465 | i++; | ||
1466 | } | ||
1859 | 1467 | ||
1860 | newFace1.v1 = i; | 1468 | newFace1.v1 = i; |
1861 | newFace1.v2 = i - numVerts; | 1469 | newFace1.v2 = i - numVerts; |
1862 | newFace1.v3 = iNext; | 1470 | newFace1.v3 = startVert; |
1863 | |||
1864 | newFace1.n1 = newFace1.v1; | ||
1865 | newFace1.n2 = newFace1.v2; | ||
1866 | newFace1.n3 = newFace1.v3; | ||
1867 | this.faces.Add(newFace1); | 1471 | this.faces.Add(newFace1); |
1868 | 1472 | ||
1869 | newFace2.v1 = iNext; | 1473 | newFace2.v1 = startVert; |
1870 | newFace2.v2 = i - numVerts; | 1474 | newFace2.v2 = i - numVerts; |
1871 | newFace2.v3 = iNext - numVerts; | 1475 | newFace2.v3 = startVert - numVerts; |
1872 | |||
1873 | newFace2.n1 = newFace2.v1; | ||
1874 | newFace2.n2 = newFace2.v2; | ||
1875 | newFace2.n3 = newFace2.v3; | ||
1876 | this.faces.Add(newFace2); | 1476 | this.faces.Add(newFace2); |
1877 | 1477 | ||
1878 | if (this.viewerMode) | 1478 | if (this.hasHollow) |
1879 | { | 1479 | { |
1880 | // add the side faces to the list of viewerFaces here | 1480 | startVert = ++i; |
1881 | 1481 | for (int l = 0; l < profile.numHollowVerts - 1; l++) | |
1882 | int primFaceNum = profile.faceNumbers[whichVert]; | ||
1883 | if (!needEndFaces) | ||
1884 | primFaceNum -= 1; | ||
1885 | |||
1886 | ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); | ||
1887 | ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); | ||
1888 | |||
1889 | int uIndex = whichVert; | ||
1890 | if (!hasHollow && sides > 4 && uIndex < newLayer.us.Count - 1) | ||
1891 | { | ||
1892 | uIndex++; | ||
1893 | } | ||
1894 | |||
1895 | float u1 = newLayer.us[uIndex]; | ||
1896 | float u2 = 1.0f; | ||
1897 | if (uIndex < (int)newLayer.us.Count - 1) | ||
1898 | u2 = newLayer.us[uIndex + 1]; | ||
1899 | |||
1900 | if (whichVert == cut1Vert || whichVert == cut2Vert) | ||
1901 | { | ||
1902 | u1 = 0.0f; | ||
1903 | u2 = 1.0f; | ||
1904 | } | ||
1905 | else if (sides < 5) | ||
1906 | { | ||
1907 | if (whichVert < profile.numOuterVerts) | ||
1908 | { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled | ||
1909 | // to reflect the entire texture width | ||
1910 | u1 *= sides; | ||
1911 | u2 *= sides; | ||
1912 | u2 -= (int)u1; | ||
1913 | u1 -= (int)u1; | ||
1914 | if (u2 < 0.1f) | ||
1915 | u2 = 1.0f; | ||
1916 | } | ||
1917 | } | ||
1918 | |||
1919 | if (this.sphereMode) | ||
1920 | { | 1482 | { |
1921 | if (whichVert != cut1Vert && whichVert != cut2Vert) | 1483 | newFace1.v1 = i; |
1922 | { | 1484 | newFace1.v2 = i - numVerts; |
1923 | u1 = u1 * 2.0f - 1.0f; | 1485 | newFace1.v3 = i + 1; |
1924 | u2 = u2 * 2.0f - 1.0f; | 1486 | this.faces.Add(newFace1); |
1925 | 1487 | ||
1926 | if (whichVert >= newLayer.numOuterVerts) | 1488 | newFace2.v1 = i + 1; |
1927 | { | 1489 | newFace2.v2 = i - numVerts; |
1928 | u1 -= hollow; | 1490 | newFace2.v3 = i + 1 - numVerts; |
1929 | u2 -= hollow; | 1491 | this.faces.Add(newFace2); |
1930 | } | 1492 | i++; |
1931 | |||
1932 | } | ||
1933 | } | ||
1934 | |||
1935 | newViewerFace1.uv1.U = u1; | ||
1936 | newViewerFace1.uv2.U = u1; | ||
1937 | newViewerFace1.uv3.U = u2; | ||
1938 | |||
1939 | newViewerFace1.uv1.V = thisV; | ||
1940 | newViewerFace1.uv2.V = lastV; | ||
1941 | newViewerFace1.uv3.V = thisV; | ||
1942 | |||
1943 | newViewerFace2.uv1.U = u2; | ||
1944 | newViewerFace2.uv2.U = u1; | ||
1945 | newViewerFace2.uv3.U = u2; | ||
1946 | |||
1947 | newViewerFace2.uv1.V = thisV; | ||
1948 | newViewerFace2.uv2.V = lastV; | ||
1949 | newViewerFace2.uv3.V = lastV; | ||
1950 | |||
1951 | newViewerFace1.v1 = this.coords[newFace1.v1]; | ||
1952 | newViewerFace1.v2 = this.coords[newFace1.v2]; | ||
1953 | newViewerFace1.v3 = this.coords[newFace1.v3]; | ||
1954 | |||
1955 | newViewerFace2.v1 = this.coords[newFace2.v1]; | ||
1956 | newViewerFace2.v2 = this.coords[newFace2.v2]; | ||
1957 | newViewerFace2.v3 = this.coords[newFace2.v3]; | ||
1958 | |||
1959 | newViewerFace1.coordIndex1 = newFace1.v1; | ||
1960 | newViewerFace1.coordIndex2 = newFace1.v2; | ||
1961 | newViewerFace1.coordIndex3 = newFace1.v3; | ||
1962 | |||
1963 | newViewerFace2.coordIndex1 = newFace2.v1; | ||
1964 | newViewerFace2.coordIndex2 = newFace2.v2; | ||
1965 | newViewerFace2.coordIndex3 = newFace2.v3; | ||
1966 | |||
1967 | // profile cut faces | ||
1968 | if (whichVert == cut1Vert) | ||
1969 | { | ||
1970 | newViewerFace1.primFaceNumber = cut1FaceNumber; | ||
1971 | newViewerFace2.primFaceNumber = cut1FaceNumber; | ||
1972 | newViewerFace1.n1 = newLayer.cutNormal1; | ||
1973 | newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; | ||
1974 | |||
1975 | newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1; | ||
1976 | newViewerFace2.n2 = lastCutNormal1; | ||
1977 | } | ||
1978 | else if (whichVert == cut2Vert) | ||
1979 | { | ||
1980 | newViewerFace1.primFaceNumber = cut2FaceNumber; | ||
1981 | newViewerFace2.primFaceNumber = cut2FaceNumber; | ||
1982 | newViewerFace1.n1 = newLayer.cutNormal2; | ||
1983 | newViewerFace1.n2 = lastCutNormal2; | ||
1984 | newViewerFace1.n3 = lastCutNormal2; | ||
1985 | |||
1986 | newViewerFace2.n1 = newLayer.cutNormal2; | ||
1987 | newViewerFace2.n3 = newLayer.cutNormal2; | ||
1988 | newViewerFace2.n2 = lastCutNormal2; | ||
1989 | } | ||
1990 | |||
1991 | else // outer and hollow faces | ||
1992 | { | ||
1993 | if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) | ||
1994 | { // looks terrible when path is twisted... need vertex normals here | ||
1995 | newViewerFace1.CalcSurfaceNormal(); | ||
1996 | newViewerFace2.CalcSurfaceNormal(); | ||
1997 | } | ||
1998 | else | ||
1999 | { | ||
2000 | newViewerFace1.n1 = this.normals[newFace1.n1]; | ||
2001 | newViewerFace1.n2 = this.normals[newFace1.n2]; | ||
2002 | newViewerFace1.n3 = this.normals[newFace1.n3]; | ||
2003 | |||
2004 | newViewerFace2.n1 = this.normals[newFace2.n1]; | ||
2005 | newViewerFace2.n2 = this.normals[newFace2.n2]; | ||
2006 | newViewerFace2.n3 = this.normals[newFace2.n3]; | ||
2007 | } | ||
2008 | } | 1493 | } |
2009 | 1494 | ||
2010 | this.viewerFaces.Add(newViewerFace1); | 1495 | newFace1.v1 = i; |
2011 | this.viewerFaces.Add(newViewerFace2); | 1496 | newFace1.v2 = i - numVerts; |
1497 | newFace1.v3 = startVert; | ||
1498 | this.faces.Add(newFace1); | ||
2012 | 1499 | ||
1500 | newFace2.v1 = startVert; | ||
1501 | newFace2.v2 = i - numVerts; | ||
1502 | newFace2.v3 = startVert - numVerts; | ||
1503 | this.faces.Add(newFace2); | ||
2013 | } | 1504 | } |
2014 | } | ||
2015 | } | ||
2016 | 1505 | ||
2017 | lastCutNormal1 = newLayer.cutNormal1; | ||
2018 | lastCutNormal2 = newLayer.cutNormal2; | ||
2019 | lastV = thisV; | ||
2020 | 1506 | ||
2021 | if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode) | 1507 | } |
2022 | { | 1508 | else |
2023 | // add the top faces to the viewerFaces list here | ||
2024 | Coord faceNormal = newLayer.faceNormal; | ||
2025 | ViewerFace newViewerFace = new ViewerFace(0); | ||
2026 | int numFaces = newLayer.faces.Count; | ||
2027 | List<Face> faces = newLayer.faces; | ||
2028 | |||
2029 | for (int i = 0; i < numFaces; i++) | ||
2030 | { | 1509 | { |
2031 | Face face = faces[i]; | 1510 | for (int i = startVert; i < endVert; i++) |
2032 | newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen]; | 1511 | { |
2033 | newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen]; | 1512 | int iNext = i + 1; |
2034 | newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen]; | 1513 | if (i == endVert - 1) |
2035 | 1514 | iNext = startVert; | |
2036 | newViewerFace.coordIndex1 = face.v1 - coordsLen; | ||
2037 | newViewerFace.coordIndex2 = face.v2 - coordsLen; | ||
2038 | newViewerFace.coordIndex3 = face.v3 - coordsLen; | ||
2039 | 1515 | ||
2040 | newViewerFace.n1 = faceNormal; | 1516 | newFace1.v1 = i; |
2041 | newViewerFace.n2 = faceNormal; | 1517 | newFace1.v2 = i - numVerts; |
2042 | newViewerFace.n3 = faceNormal; | 1518 | newFace1.v3 = iNext; |
1519 | this.faces.Add(newFace1); | ||
2043 | 1520 | ||
2044 | newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen]; | 1521 | newFace2.v1 = iNext; |
2045 | newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; | 1522 | newFace2.v2 = i - numVerts; |
2046 | newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; | 1523 | newFace2.v3 = iNext - numVerts; |
1524 | this.faces.Add(newFace2); | ||
2047 | 1525 | ||
2048 | if (pathType == PathType.Linear) | ||
2049 | { | ||
2050 | newViewerFace.uv1.Flip(); | ||
2051 | newViewerFace.uv2.Flip(); | ||
2052 | newViewerFace.uv3.Flip(); | ||
2053 | } | 1526 | } |
2054 | |||
2055 | this.viewerFaces.Add(newViewerFace); | ||
2056 | } | 1527 | } |
2057 | } | 1528 | } |
2058 | 1529 | ||
1530 | lastV = thisV; | ||
2059 | 1531 | ||
2060 | } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) | 1532 | } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) |
2061 | 1533 | ||
@@ -2138,51 +1610,17 @@ namespace PrimMesher | |||
2138 | copy.radius = this.radius; | 1610 | copy.radius = this.radius; |
2139 | copy.revolutions = this.revolutions; | 1611 | copy.revolutions = this.revolutions; |
2140 | copy.stepsPerRevolution = this.stepsPerRevolution; | 1612 | copy.stepsPerRevolution = this.stepsPerRevolution; |
2141 | copy.calcVertexNormals = this.calcVertexNormals; | 1613 | |
2142 | copy.normalsProcessed = this.normalsProcessed; | ||
2143 | copy.viewerMode = this.viewerMode; | ||
2144 | copy.numPrimFaces = this.numPrimFaces; | 1614 | copy.numPrimFaces = this.numPrimFaces; |
2145 | copy.errorMessage = this.errorMessage; | 1615 | copy.errorMessage = this.errorMessage; |
2146 | 1616 | ||
2147 | copy.coords = new List<Coord>(this.coords); | 1617 | copy.coords = new List<Coord>(this.coords); |
2148 | copy.faces = new List<Face>(this.faces); | 1618 | copy.faces = new List<Face>(this.faces); |
2149 | copy.viewerFaces = new List<ViewerFace>(this.viewerFaces); | ||
2150 | copy.normals = new List<Coord>(this.normals); | ||
2151 | 1619 | ||
2152 | return copy; | 1620 | return copy; |
2153 | } | 1621 | } |
2154 | 1622 | ||
2155 | /// <summary> | 1623 | /// <summary> |
2156 | /// Calculate surface normals for all of the faces in the list of faces in this mesh | ||
2157 | /// </summary> | ||
2158 | public void CalcNormals() | ||
2159 | { | ||
2160 | if (normalsProcessed) | ||
2161 | return; | ||
2162 | |||
2163 | normalsProcessed = true; | ||
2164 | |||
2165 | int numFaces = faces.Count; | ||
2166 | |||
2167 | if (!this.calcVertexNormals) | ||
2168 | this.normals = new List<Coord>(); | ||
2169 | |||
2170 | for (int i = 0; i < numFaces; i++) | ||
2171 | { | ||
2172 | Face face = faces[i]; | ||
2173 | |||
2174 | this.normals.Add(SurfaceNormal(i).Normalize()); | ||
2175 | |||
2176 | int normIndex = normals.Count - 1; | ||
2177 | face.n1 = normIndex; | ||
2178 | face.n2 = normIndex; | ||
2179 | face.n3 = normIndex; | ||
2180 | |||
2181 | this.faces[i] = face; | ||
2182 | } | ||
2183 | } | ||
2184 | |||
2185 | /// <summary> | ||
2186 | /// Adds a value to each XYZ vertex coordinate in the mesh | 1624 | /// Adds a value to each XYZ vertex coordinate in the mesh |
2187 | /// </summary> | 1625 | /// </summary> |
2188 | /// <param name="x"></param> | 1626 | /// <param name="x"></param> |
@@ -2202,18 +1640,6 @@ namespace PrimMesher | |||
2202 | vert.Z += z; | 1640 | vert.Z += z; |
2203 | this.coords[i] = vert; | 1641 | this.coords[i] = vert; |
2204 | } | 1642 | } |
2205 | |||
2206 | if (this.viewerFaces != null) | ||
2207 | { | ||
2208 | int numViewerFaces = this.viewerFaces.Count; | ||
2209 | |||
2210 | for (i = 0; i < numViewerFaces; i++) | ||
2211 | { | ||
2212 | ViewerFace v = this.viewerFaces[i]; | ||
2213 | v.AddPos(x, y, z); | ||
2214 | this.viewerFaces[i] = v; | ||
2215 | } | ||
2216 | } | ||
2217 | } | 1643 | } |
2218 | 1644 | ||
2219 | /// <summary> | 1645 | /// <summary> |
@@ -2227,38 +1653,11 @@ namespace PrimMesher | |||
2227 | 1653 | ||
2228 | for (i = 0; i < numVerts; i++) | 1654 | for (i = 0; i < numVerts; i++) |
2229 | this.coords[i] *= q; | 1655 | this.coords[i] *= q; |
2230 | |||
2231 | if (this.normals != null) | ||
2232 | { | ||
2233 | int numNormals = this.normals.Count; | ||
2234 | for (i = 0; i < numNormals; i++) | ||
2235 | this.normals[i] *= q; | ||
2236 | } | ||
2237 | |||
2238 | if (this.viewerFaces != null) | ||
2239 | { | ||
2240 | int numViewerFaces = this.viewerFaces.Count; | ||
2241 | |||
2242 | for (i = 0; i < numViewerFaces; i++) | ||
2243 | { | ||
2244 | ViewerFace v = this.viewerFaces[i]; | ||
2245 | v.v1 *= q; | ||
2246 | v.v2 *= q; | ||
2247 | v.v3 *= q; | ||
2248 | |||
2249 | v.n1 *= q; | ||
2250 | v.n2 *= q; | ||
2251 | v.n3 *= q; | ||
2252 | this.viewerFaces[i] = v; | ||
2253 | } | ||
2254 | } | ||
2255 | } | 1656 | } |
2256 | 1657 | ||
2257 | #if VERTEX_INDEXER | 1658 | #if VERTEX_INDEXER |
2258 | public VertexIndexer GetVertexIndexer() | 1659 | public VertexIndexer GetVertexIndexer() |
2259 | { | 1660 | { |
2260 | if (this.viewerMode && this.viewerFaces.Count > 0) | ||
2261 | return new VertexIndexer(this); | ||
2262 | return null; | 1661 | return null; |
2263 | } | 1662 | } |
2264 | #endif | 1663 | #endif |
@@ -2278,21 +1677,6 @@ namespace PrimMesher | |||
2278 | Coord m = new Coord(x, y, z); | 1677 | Coord m = new Coord(x, y, z); |
2279 | for (i = 0; i < numVerts; i++) | 1678 | for (i = 0; i < numVerts; i++) |
2280 | this.coords[i] *= m; | 1679 | this.coords[i] *= m; |
2281 | |||
2282 | if (this.viewerFaces != null) | ||
2283 | { | ||
2284 | int numViewerFaces = this.viewerFaces.Count; | ||
2285 | for (i = 0; i < numViewerFaces; i++) | ||
2286 | { | ||
2287 | ViewerFace v = this.viewerFaces[i]; | ||
2288 | v.v1 *= m; | ||
2289 | v.v2 *= m; | ||
2290 | v.v3 *= m; | ||
2291 | this.viewerFaces[i] = v; | ||
2292 | } | ||
2293 | |||
2294 | } | ||
2295 | |||
2296 | } | 1680 | } |
2297 | 1681 | ||
2298 | /// <summary> | 1682 | /// <summary> |