public static MeshDraft Torus_Multi(float rotations, float radius, int segments, float outerRadius, int torusSegments, float orbitalRadius) { var draft = new MeshDraft(); float torusAngle = Mathf.PI * 24 / torusSegments; float segmentAngle = Mathf.PI * 2 / segments; Vector3 vPointingR; Vector3 vOrbitalR; float orbitAngle = Mathf.PI * 2 / torusSegments; float currentTorusAngle = 0f; float currentOrbitalAngle = 0f; //First ring vPointingR = PTUtils.PointOnCircle3_XY(outerRadius, 0); vOrbitalR = PTUtils.PointOnCircle3(orbitalRadius, 0); var lowerRing = new List<Vector3>(segments); var endCap = new List<Vector3>(segments); //var upperRing = new List<Vector3>(segments); var nR = vPointingR.normalized; var nX = Vector3.Cross(Vector3.up, nR).normalized; float cA = 0f; for (var i = 0; i < segments; i++) { var point = PTUtils.PointOnCircle3(radius, cA); var vLoc = vOrbitalR + vPointingR + point.z * nR + point.x * nX; lowerRing.Add(vLoc); cA -= segmentAngle; } endCap = lowerRing; currentTorusAngle += torusAngle; currentOrbitalAngle += orbitAngle; float eulerAng = 0; float deltaEuler = (rotations*720) / torusSegments; Quaternion q; for (int j = 0; j < torusSegments; j++) { eulerAng += deltaEuler; vPointingR = PTUtils.PointOnCircle3_XY(outerRadius, currentTorusAngle); vOrbitalR = PTUtils.PointOnCircle3(orbitalRadius, currentOrbitalAngle); nR = vPointingR.normalized; nX = Vector3.forward; q = Quaternion.Euler(0, eulerAng, 0); nR = q * nR; nX = q * nX; vPointingR = q * vPointingR; float currentAngle = 0f; var upperRing = new List<Vector3>(segments); for (var i = 0; i < segments; i++) { var point = PTUtils.PointOnCircle3(radius, currentAngle); var vLoc = vOrbitalR + vPointingR + point.z * nR + point.x * nX; upperRing.Add(vLoc); currentAngle -= segmentAngle; } if (j == torusSegments - 1) { draft.Add(Band(lowerRing, endCap)); } else { draft.Add(Band(lowerRing, upperRing)); } lowerRing = upperRing; currentTorusAngle += torusAngle; currentOrbitalAngle += orbitAngle; //upperRing.Clear(); } draft.name = "Torus_Multi"; return draft; }