public List <Vector3> GetAdjacentRings() { List <Vector3> adjacentPoints = new List <Vector3>(); Quaternion invRot = Quaternion.Inverse(transform.rotation); if (parent && parent is TelescopeSegment) { TelescopeSegment ts = parent as TelescopeSegment; List <Vector3> lastRing = ts.LastVertRing; foreach (Vector3 v in lastRing) { adjacentPoints.Add(invRot * (v - transform.position)); } } foreach (var child in childSegments) { List <Vector3> firstRing = child.FirstVertRing; foreach (Vector3 v in firstRing) { adjacentPoints.Add(invRot * (v - transform.position)); } } return(adjacentPoints); }
public static List <string> WriteSTLOfShells(TelescopeSegment segment, Vector3 minOffset) { List <string> stlNames = new List <string>(); foreach (TelescopeShell shell in segment.shells) { string stl = "stls/" + shell.name + ".stl"; using (StreamWriter file = new StreamWriter("scad/" + stl)) { VectorTransform ShellTransform = (v => shell.transform.rotation * v + shell.transform.position - minOffset); List <string> shellLines = FacetsOfMesh(shell.mesh, ShellTransform); file.WriteLine("solid " + shell.name); foreach (string line in shellLines) { file.WriteLine(line); } file.WriteLine("endsolid"); } stlNames.Add(stl); } return(stlNames); }
public void SetParentToSegmentEnd(TelescopeSegment segment) { parent = segment; parentElementNum = segment.shells.Count - 1; parentSegment = segment; //SetParent(segment, segment.shells.Count - 1, 1); }
void MakeEnclosingTelescope() { Vector3 center = (segment1.transform.position + segment2.transform.position + segment3.transform.position) / 3; float minZ = 0; float maxZ = 0; float maxRadius = 0; foreach (Vector3 v in segment1.FirstShell.mesh.vertices) { minZ = Mathf.Min(v.z, minZ); maxZ = Mathf.Max(v.z, maxZ); Vector3 transformed = segment1.FirstShell.transform.position + segment1.FirstShell.transform.rotation * v; float distance = DistanceToAxis(transformed, center, Vector3.forward); maxRadius = Mathf.Max(maxRadius, distance); } foreach (Vector3 v in segment2.FirstShell.mesh.vertices) { minZ = Mathf.Min(v.z, minZ); maxZ = Mathf.Max(v.z, maxZ); Vector3 transformed = segment2.FirstShell.transform.position + segment2.FirstShell.transform.rotation * v; float distance = DistanceToAxis(transformed, center, Vector3.forward); maxRadius = Mathf.Max(maxRadius, distance); } foreach (Vector3 v in segment3.FirstShell.mesh.vertices) { minZ = Mathf.Min(v.z, minZ); maxZ = Mathf.Max(v.z, maxZ); Vector3 transformed = segment3.FirstShell.transform.position + segment3.FirstShell.transform.rotation * v; float distance = DistanceToAxis(transformed, center, Vector3.forward); maxRadius = Mathf.Max(maxRadius, distance); } Debug.Log("Max depth = " + maxZ + ", min depth = " + minZ); Debug.Log("Center position = " + center); Debug.Log("Max radius = " + maxRadius); TelescopeSegment seg = CreateStraightSegment(maxZ, maxRadius); seg.transform.position = center - 2.25f * maxZ * Vector3.forward; seg.ExtendImmediate(1); segment1.transform.parent = seg.LastShell.transform; segment2.transform.parent = seg.LastShell.transform; segment3.transform.parent = seg.LastShell.transform; }
void RotateChildSegment(TelescopeSegment seg, Quaternion localRotation) { Vector3 localPos = localRotation * seg.transform.localPosition; seg.transform.localPosition = localPos; Quaternion localRot = localRotation * seg.shells[0].transform.localRotation; seg.shells[0].transform.localRotation = localRot; }
public void ShrinkToFit() { if (selected) { TelescopeSegment segment = selected.containingSegment; List <TelescopeParameters> allParams = segment.getParamList(); TelescopeUtils.growChainToFit(allParams, shrinkFit: true); segment.MakeAllShells(allParams); segment.SetShellExtensions(1); selected = null; } }
public static void WriteSTLOfSegment(TelescopeSegment segment, Vector3 minOffset, string filename) { Debug.Log("Write STL to " + filename); List <string> allLines = new List <string>(); allLines.Add("solid " + segment.name); foreach (TelescopeShell shell in segment.shells) { VectorTransform ShellTransform = (v => shell.transform.rotation * v + shell.transform.position - minOffset); List <string> shellLines = FacetsOfMesh(shell.mesh, ShellTransform); allLines.AddRange(shellLines); } allLines.Add("endsolid"); File.WriteAllLines(filename, allLines.ToArray()); }
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); }
public TelescopeSegment MakeTelescope(float startRadius, bool reverse = false) { List <TelescopeParameters> tParams = new List <TelescopeParameters>(); CurveSegment initialSeg = (reverse) ? segments[segments.Count - 1] : segments[0]; float wallThickness = Constants.WALL_THICKNESS; float currRadius = startRadius * BulbShrinkRatio; TelescopeParameters initial = new TelescopeParameters(initialSeg.arcLength, currRadius, Constants.WALL_THICKNESS, initialSeg.curvature, initialSeg.torsion, 0); tParams.Add(initial); for (int i = 1; i < segments.Count; i++) { int index = (reverse) ? segments.Count - 1 - i : i; /* * if (i == 2 && StartJuncture && StartJuncture.childCurves.Count == 5) * { * Debug.Log("Hack to create lizard toenails, please delete once done"); * currRadius -= 1.5f * wallThickness; * }*/ // Subtract the wall thickness of the previous piece currRadius -= wallThickness; float curvature = (reverse) ? segments[index].curvature : segments[index].curvature; float torsion = (reverse) ? segments[index].torsion : segments[index].torsion; float impulse = (reverse) ? -segments[index + 1].impulse : -segments[index].impulse; impulse *= Mathf.Rad2Deg; TelescopeParameters p = new TelescopeParameters(segments[index].arcLength, currRadius, wallThickness, curvature, torsion, impulse); tParams.Add(p); } GameObject obj = new GameObject(); obj.name = "telescope" + (numScopes++); TelescopeSegment segment = obj.AddComponent <TelescopeSegment>(); segment.paramMode = SegmentParametersMode.Concrete; segment.material = DesignerController.instance.defaultTelescopeMaterial; if (reverse) { CurveSegment lastSeg = segments[segments.Count - 1]; obj.transform.position = TransformedHelixPoint(lastSeg, lastSeg.arcLength); OrthonormalFrame initFrame = TransformedHelixFrame(lastSeg, lastSeg.arcLength); segment.initialDirection = -initFrame.T; segment.initialUp = initFrame.N; } else { obj.transform.position = segments[0].startPosition; segment.initialDirection = segments[0].frame.T; segment.initialUp = segments[0].frame.N; } segment.MakeShellsFromConcrete(tParams); if (reverse) { segment.ReverseTelescope(); } return(segment); }
// Use this for initialization void Start() { added = false; segment = GetComponent <TelescopeSegment>(); }