TelescopeSegment CreateStraightSegment(float length, float radius) { GameObject segObj = new GameObject(); TelescopeSegment seg = segObj.AddComponent <TelescopeSegment>(); List <TelescopeParameters> paramList = new List <TelescopeParameters>(); float thickness = Constants.WALL_THICKNESS; float startRadius = radius + 3 * thickness + 3 * length * Constants.TAPER_SLOPE; TelescopeParameters firstParam = new TelescopeParameters(length, startRadius, thickness, 0, 0, 0); paramList.Add(firstParam); paramList.Add(new TelescopeParameters(0, 0, 0, 0, 0, 0)); paramList.Add(new TelescopeParameters(0, 0, 0, 0, 0, 0)); seg.material = segment1.material; seg.MakeShellsFromDiffs(paramList); seg.transform.parent = transform; return(seg); }
public static TelescopeSegment telescopeOfCone(Vector3 startPos, float startRadius, Vector3 endPos, float endRadius, Vector3 curvatureCenter, float wallThickness = Constants.WALL_THICKNESS, bool useCurvature = false) { float curvature; Vector3 segmentDirection; if (useCurvature) { float radius = Vector3.Distance(curvatureCenter, startPos); curvature = 1f / radius; if (curvature < 1e-6) { curvature = 0; segmentDirection = endPos - startPos; segmentDirection.Normalize(); } else { segmentDirection = CurveDirectionFromParent(startPos, endPos, curvatureCenter); } } else { curvature = 0; segmentDirection = endPos - startPos; segmentDirection.Normalize(); } float distance = ArcLengthFromChord(startPos, endPos, curvature); int numShells = Mathf.CeilToInt((Mathf.Max(startRadius, endRadius) - Mathf.Min(startRadius, endRadius)) / wallThickness); if (numShells < 2) { numShells = 2; } // int numShells = Mathf.CeilToInt(distance / Mathf.Min(startRadius, endRadius)); // Length is just the distance we need to cover divided by the number of shells. float lengthPerShell = distance / numShells; // We attempt to choose the radii such that the telescope tapers from the start // radius to the end radius over the given number of shells. float radiusStep = (startRadius - endRadius) / numShells; float twist = 0; if (curvature >= 1e-6) { // Compute twist angles Quaternion rotationToOrigin = Quaternion.FromToRotation(Vector3.forward, segmentDirection); // The "up" direction we would like to have -- orthogonal direction from circle center. Vector3 startEnd = endPos - startPos; Vector3 desiredUp = startEnd - Vector3.Dot(segmentDirection, startEnd) * segmentDirection; desiredUp.Normalize(); Vector3 inverseDesired = Quaternion.Inverse(rotationToOrigin) * desiredUp; // The angle computation doesn't work right in 3rd and 4th quadrants, // so work around it by doing everything in 1st and 2nd. if (inverseDesired.x < 0) { inverseDesired *= -1; twist = 180; } float angleBetween = Mathf.Atan2(Vector3.Cross(Vector3.up, inverseDesired).magnitude, Vector3.Dot(Vector3.up, inverseDesired)); twist += -angleBetween * Mathf.Rad2Deg; } List <TelescopeParameters> diffList = new List <TelescopeParameters>(); // Create the initial shell parameters. TelescopeParameters initialParams = new TelescopeParameters(lengthPerShell, startRadius, wallThickness, curvature, 0, twist); diffList.Add(initialParams); // Create all the diffs. for (int i = 1; i < numShells; i++) { TelescopeParameters tp = new TelescopeParameters(0, -radiusStep, wallThickness, 0, 0, 0); diffList.Add(tp); } // Create a game object that will be the new segment. GameObject obj = new GameObject(); obj.name = "segment" + segmentCount; segmentCount++; obj.transform.position = startPos; TelescopeSegment seg = obj.AddComponent <TelescopeSegment>(); seg.material = DesignerController.instance.defaultTelescopeMaterial; seg.initialDirection = segmentDirection; seg.MakeShellsFromDiffs(diffList); seg.transform.position = startPos; return(seg); }