|
1 | 1 | using System; |
2 | 2 | using System.Collections.Generic; |
3 | | -using System.Linq; |
4 | 3 | using UnityEngine; |
5 | 4 |
|
6 | 5 | namespace ProceduralToolkit |
@@ -661,131 +660,131 @@ public static MeshDraft PartialBox(Vector3 width, Vector3 depth, Vector3 height, |
661 | 660 | return draft; |
662 | 661 | } |
663 | 662 |
|
664 | | - /// <summary> |
665 | | - /// Constructs a capsule draft |
666 | | - /// </summary> |
667 | | - /// <param name="height">The height of the capsule, not including the end caps</param> |
668 | | - /// <param name="radius">The radius of the capsule</param> |
669 | | - /// <param name="segments">The number of radial segments. Defaults to 12</param> |
670 | | - /// <param name="rings">The number of end-cap rings. Defaults to 8</param> |
671 | | - /// <returns></returns> |
672 | | - public static MeshDraft Capsule(double height, double radius, int segments = 12, int rings = 8) |
673 | | - { |
674 | | - var numVerts = 2 * rings * segments + 2; |
675 | | - var numFaces = 4 * rings * segments; |
676 | | - var theta = 2 * Math.PI / segments; |
677 | | - var phi = Math.PI / (2 * rings); |
678 | | - |
679 | | - var verts = new Vector3[numVerts]; |
680 | | - var norms = new Vector3[numVerts]; |
681 | | - var faces = new int[3 * numFaces]; |
682 | | - int vi = 0, fi = 0, topCap = 0, botCap = 1; |
683 | | - |
684 | | - verts[vi].Set(0, (float)(height / 2 + radius), 0); |
685 | | - norms[vi++].Set(0, 1, 0); |
686 | | - verts[vi].Set(0, (float)(-height / 2 - radius), 0); |
687 | | - norms[vi++].Set(0, -1, 0); |
688 | | - |
689 | | - for (var s = 0; s < segments; s++) |
690 | | - { |
691 | | - for (var r = 1; r <= rings; r++) |
692 | | - { |
693 | | - var radial = radius * Math.Sin(r * phi); |
694 | | - |
695 | | - // create verts (top cap) |
696 | | - verts[vi].Set( |
697 | | - (float)(radial * Math.Cos(s * theta)), |
698 | | - (float)(height / 2 + radius * Math.Cos(r * phi)), |
699 | | - (float)(radial * Math.Sin(s * theta)) |
700 | | - ); |
701 | | - norms[vi].Set( |
702 | | - (float)Math.Cos(s * theta), |
703 | | - (float)Math.Cos(r * phi), |
704 | | - (float)Math.Sin(s * theta) |
705 | | - ); |
706 | | - norms[vi++].Normalize(); |
707 | | - |
708 | | - // mirror top-cap verts for bottom cap |
709 | | - verts[vi].Set(verts[vi - 1].x, -verts[vi - 1].y, verts[vi - 1].z); |
710 | | - norms[vi].Set(norms[vi - 1].x, -norms[vi - 1].y, norms[vi - 1].z); |
711 | | - vi++; |
712 | | - |
713 | | - int top_s1r1 = vi - 2, top_s1r0 = vi - 4; |
714 | | - int bot_s1r1 = vi - 1, bot_s1r0 = vi - 3; |
715 | | - int top_s0r1 = top_s1r1 - 2 * rings, top_s0r0 = top_s1r0 - 2 * rings; |
716 | | - int bot_s0r1 = bot_s1r1 - 2 * rings, bot_s0r0 = bot_s1r0 - 2 * rings; |
717 | | - if (s == 0) |
718 | | - { |
719 | | - top_s0r1 += numVerts - 2; |
720 | | - top_s0r0 += numVerts - 2; |
721 | | - bot_s0r1 += numVerts - 2; |
722 | | - bot_s0r0 += numVerts - 2; |
723 | | - } |
724 | | - |
725 | | - // create cap faces |
726 | | - if (r == 1) |
727 | | - { |
728 | | - faces[3 * fi + 0] = topCap; |
729 | | - faces[3 * fi + 1] = top_s1r1; |
730 | | - faces[3 * fi + 2] = top_s0r1; |
731 | | - fi++; |
732 | | - |
733 | | - faces[3 * fi + 0] = botCap; |
734 | | - faces[3 * fi + 1] = bot_s0r1; |
735 | | - faces[3 * fi + 2] = bot_s1r1; |
736 | | - fi++; |
737 | | - } |
738 | | - else |
739 | | - { |
740 | | - faces[3 * fi + 0] = top_s1r0; |
741 | | - faces[3 * fi + 1] = top_s1r1; |
742 | | - faces[3 * fi + 2] = top_s0r0; |
743 | | - fi++; |
744 | | - |
745 | | - faces[3 * fi + 0] = top_s0r0; |
746 | | - faces[3 * fi + 1] = top_s1r1; |
747 | | - faces[3 * fi + 2] = top_s0r1; |
748 | | - fi++; |
749 | | - |
750 | | - faces[3 * fi + 0] = bot_s0r1; |
751 | | - faces[3 * fi + 1] = bot_s1r1; |
752 | | - faces[3 * fi + 2] = bot_s0r0; |
753 | | - fi++; |
754 | | - |
755 | | - faces[3 * fi + 0] = bot_s0r0; |
756 | | - faces[3 * fi + 1] = bot_s1r1; |
757 | | - faces[3 * fi + 2] = bot_s1r0; |
758 | | - fi++; |
759 | | - } |
760 | | - } |
761 | | - |
762 | | - // create long sides |
763 | | - int top_s1 = vi - 2, top_s0 = top_s1 - 2 * rings; |
764 | | - int bot_s1 = vi - 1, bot_s0 = bot_s1 - 2 * rings; |
765 | | - if (s == 0) |
766 | | - { |
767 | | - top_s0 += numVerts - 2; |
768 | | - bot_s0 += numVerts - 2; |
769 | | - } |
770 | | - |
771 | | - faces[3 * fi + 0] = top_s0; |
772 | | - faces[3 * fi + 1] = top_s1; |
773 | | - faces[3 * fi + 2] = bot_s1; |
774 | | - fi++; |
775 | | - |
776 | | - faces[3 * fi + 0] = bot_s0; |
777 | | - faces[3 * fi + 1] = top_s0; |
778 | | - faces[3 * fi + 2] = bot_s1; |
779 | | - fi++; |
780 | | - } |
781 | | - |
782 | | - return new MeshDraft() |
783 | | - { |
784 | | - name = "Capsule", |
785 | | - vertices = new List<Vector3>(verts), |
786 | | - triangles = new List<int>(faces), |
787 | | - normals = new List<Vector3>(norms) |
788 | | - }; |
789 | | - } |
| 663 | + /// <summary> |
| 664 | + /// Constructs a capsule draft |
| 665 | + /// </summary> |
| 666 | + /// <param name="height">The height of the capsule, not including the end caps</param> |
| 667 | + /// <param name="radius">The radius of the capsule</param> |
| 668 | + /// <param name="segments">The number of radial segments. Defaults to 12</param> |
| 669 | + /// <param name="rings">The number of end-cap rings. Defaults to 8</param> |
| 670 | + /// <returns></returns> |
| 671 | + public static MeshDraft Capsule(float height, float radius, int segments = 12, int rings = 8) |
| 672 | + { |
| 673 | + int numVerts = 2 * rings * segments + 2; |
| 674 | + int numFaces = 4 * rings * segments; |
| 675 | + double theta = 2 * Math.PI / segments; |
| 676 | + double phi = Math.PI / (2 * rings); |
| 677 | + |
| 678 | + Vector3[] verts = new Vector3[numVerts]; |
| 679 | + Vector3[] norms = new Vector3[numVerts]; |
| 680 | + int[] faces = new int[3 * numFaces]; |
| 681 | + int vi = 0, fi = 0, topCap = 0, botCap = 1; |
| 682 | + |
| 683 | + verts[vi].Set(0, height / 2 + radius, 0); |
| 684 | + norms[vi++].Set(0, 1, 0); |
| 685 | + verts[vi].Set(0, -height / 2 - radius, 0); |
| 686 | + norms[vi++].Set(0, -1, 0); |
| 687 | + |
| 688 | + for (var s = 0; s < segments; s++) |
| 689 | + { |
| 690 | + for (var r = 1; r <= rings; r++) |
| 691 | + { |
| 692 | + double radial = radius * Math.Sin(r * phi); |
| 693 | + |
| 694 | + // create verts (top cap) |
| 695 | + verts[vi].Set( |
| 696 | + (float)(radial * Math.Cos(s * theta)), |
| 697 | + (float)(height / 2 + radius * Math.Cos(r * phi)), |
| 698 | + (float)(radial * Math.Sin(s * theta)) |
| 699 | + ); |
| 700 | + norms[vi].Set( |
| 701 | + (float)Math.Cos(s * theta), |
| 702 | + (float)Math.Cos(r * phi), |
| 703 | + (float)Math.Sin(s * theta) |
| 704 | + ); |
| 705 | + norms[vi++].Normalize(); |
| 706 | + |
| 707 | + // mirror top-cap verts for bottom cap |
| 708 | + verts[vi].Set(verts[vi - 1].x, -verts[vi - 1].y, verts[vi - 1].z); |
| 709 | + norms[vi].Set(norms[vi - 1].x, -norms[vi - 1].y, norms[vi - 1].z); |
| 710 | + vi++; |
| 711 | + |
| 712 | + int top_s1r1 = vi - 2, top_s1r0 = vi - 4; |
| 713 | + int bot_s1r1 = vi - 1, bot_s1r0 = vi - 3; |
| 714 | + int top_s0r1 = top_s1r1 - 2 * rings, top_s0r0 = top_s1r0 - 2 * rings; |
| 715 | + int bot_s0r1 = bot_s1r1 - 2 * rings, bot_s0r0 = bot_s1r0 - 2 * rings; |
| 716 | + if (s == 0) |
| 717 | + { |
| 718 | + top_s0r1 += numVerts - 2; |
| 719 | + top_s0r0 += numVerts - 2; |
| 720 | + bot_s0r1 += numVerts - 2; |
| 721 | + bot_s0r0 += numVerts - 2; |
| 722 | + } |
| 723 | + |
| 724 | + // create cap faces |
| 725 | + if (r == 1) |
| 726 | + { |
| 727 | + faces[3 * fi + 0] = topCap; |
| 728 | + faces[3 * fi + 1] = top_s1r1; |
| 729 | + faces[3 * fi + 2] = top_s0r1; |
| 730 | + fi++; |
| 731 | + |
| 732 | + faces[3 * fi + 0] = botCap; |
| 733 | + faces[3 * fi + 1] = bot_s0r1; |
| 734 | + faces[3 * fi + 2] = bot_s1r1; |
| 735 | + fi++; |
| 736 | + } |
| 737 | + else |
| 738 | + { |
| 739 | + faces[3 * fi + 0] = top_s1r0; |
| 740 | + faces[3 * fi + 1] = top_s1r1; |
| 741 | + faces[3 * fi + 2] = top_s0r0; |
| 742 | + fi++; |
| 743 | + |
| 744 | + faces[3 * fi + 0] = top_s0r0; |
| 745 | + faces[3 * fi + 1] = top_s1r1; |
| 746 | + faces[3 * fi + 2] = top_s0r1; |
| 747 | + fi++; |
| 748 | + |
| 749 | + faces[3 * fi + 0] = bot_s0r1; |
| 750 | + faces[3 * fi + 1] = bot_s1r1; |
| 751 | + faces[3 * fi + 2] = bot_s0r0; |
| 752 | + fi++; |
| 753 | + |
| 754 | + faces[3 * fi + 0] = bot_s0r0; |
| 755 | + faces[3 * fi + 1] = bot_s1r1; |
| 756 | + faces[3 * fi + 2] = bot_s1r0; |
| 757 | + fi++; |
| 758 | + } |
| 759 | + } |
| 760 | + |
| 761 | + // create long sides |
| 762 | + int top_s1 = vi - 2, top_s0 = top_s1 - 2 * rings; |
| 763 | + int bot_s1 = vi - 1, bot_s0 = bot_s1 - 2 * rings; |
| 764 | + if (s == 0) |
| 765 | + { |
| 766 | + top_s0 += numVerts - 2; |
| 767 | + bot_s0 += numVerts - 2; |
| 768 | + } |
| 769 | + |
| 770 | + faces[3 * fi + 0] = top_s0; |
| 771 | + faces[3 * fi + 1] = top_s1; |
| 772 | + faces[3 * fi + 2] = bot_s1; |
| 773 | + fi++; |
| 774 | + |
| 775 | + faces[3 * fi + 0] = bot_s0; |
| 776 | + faces[3 * fi + 1] = top_s0; |
| 777 | + faces[3 * fi + 2] = bot_s1; |
| 778 | + fi++; |
| 779 | + } |
| 780 | + |
| 781 | + return new MeshDraft() |
| 782 | + { |
| 783 | + name = "Capsule", |
| 784 | + vertices = new List<Vector3>(verts), |
| 785 | + triangles = new List<int>(faces), |
| 786 | + normals = new List<Vector3>(norms) |
| 787 | + }; |
| 788 | + } |
790 | 789 | } |
791 | 790 | } |
0 commit comments