/// <summary> /// Reverses this entire spline. /// </summary> public void Reverse() { DraggablePoint oldStart = StartBulb; DraggablePoint oldEnd = EndBulb; // Remove connections if (StartBulb) { StartBulb.RemoveSplineStart(this); } if (EndBulb) { EndBulb.RemoveSplineEnd(this); } // Reverse points and recreate everything points.Reverse(); makeSegments(); createSpheres(); updateRenderPoints(); // Reconnect to bulbs, reversed if (oldEnd) { spheres[1].AttachToBulb(oldEnd); } if (oldStart) { spheres[spheres.Count - 2].AttachToBulb(oldStart); } }
public void AttachToBulb(DraggablePoint bulb) { if (Type == PointType.Bulb) { return; } if (parentSpline.points.Count < 4) { return; } if (index == 1) { parentSpline.StartBulb = bulb; splinesStart.Add(parentSpline); } else if (index == parentSpline.points.Count - 2) { parentSpline.EndBulb = bulb; splinesEnd.Add(parentSpline); } else { return; } }
void createSpheres() { foreach (DraggablePoint p in spheres) { Destroy(p.gameObject); } spheres.Clear(); for (int i = 0; i < points.Count; i++) { GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere); obj.name = "splineMarker" + i; obj.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); obj.transform.position = points[i]; obj.transform.parent = transform; obj.AddComponent <SphereCollider>(); DraggablePoint draggable = obj.AddComponent <DraggablePoint>(); draggable.index = i; draggable.parentSpline = this; draggable.containingCanvas = containingCanvas; draggable.Type = PointType.Spline; spheres.Add(draggable); } if (spheres.Count >= 4) { spheres[0].gameObject.SetActive(false); spheres[spheres.Count - 1].gameObject.SetActive(false); } }
public void FollowBulb(DraggablePoint bulb, Vector3 tangent) { float radius = bulb.radius; Vector3 newPosition = bulb.transform.position + (radius * tangent); Move(newPosition); }
public void ReloadFromData(SplineCanvasData data) { // Clear everything Reset(); bulbs.Clear(); foreach (BulbData bData in data.bulbs) { // Make bulbs at all the saved positions with the saved radii DraggablePoint pt = AddBulb(bData.position.GetVector()); pt.SetSize(bData.radius); pt.containingCanvas = this; if (bData.type == PointType.Spline) { pt.SwitchBulbType(PointType.Bulb); } else { pt.SwitchBulbType(bData.type); } } foreach (SplineData sData in data.splines) { // Convert the serialized vectors to Unity vectors List <Vector3> posList = new List <Vector3>(); foreach (V3Serialize v3s in sData.points) { posList.Add(v3s.GetVector()); } // Make a spline with the same control points CatmullRomSpline spline = CatmullRomSpline.SplineOfPoints(posList); AddExistingSpline(spline); // Set the begin/end bulbs if (sData.startBulb >= 0) { spline.StartBulb = bulbs[sData.startBulb]; } if (sData.endBulb >= 0) { spline.EndBulb = bulbs[sData.endBulb]; } } }
/// <summary> /// Add a new bulb to this canvas at the given location. /// </summary> /// <param name="pos">The position of the bulb.</param> /// <returns></returns> public DraggablePoint AddBulb(Vector3 pos) { GameObject bulbObj = GameObject.CreatePrimitive(PrimitiveType.Sphere); bulbObj.transform.position = pos; bulbObj.transform.parent = transform; DraggablePoint point = bulbObj.AddComponent <DraggablePoint>(); point.Type = PointType.Bulb; point.containingCanvas = this; point.radius = 0.5f; bulbs.Add(point); bulbObj.name = "bulb" + bulbs.Count; return(point); }
// Update is called once per frame void Update() { if (Input.GetButtonDown("ToggleMode")) { if (currentMode == DesignerMode.Shell) { currentMode = DesignerMode.Curve; modeText.text = "Curve mode"; } else if (currentMode == DesignerMode.Curve) { currentMode = DesignerMode.Curvature; modeText.text = "Curvature mode"; } else if (currentMode == DesignerMode.Curvature) { currentMode = DesignerMode.Shell; modeText.text = "Shell mode"; } } RaycastHit hitInfo = new RaycastHit(); if (Input.GetMouseButtonDown(0) && RaycastShells(Input.mousePosition, out hitInfo)) { TelescopeShell selection = hitInfo.collider.GetComponent <TelescopeShell>(); DraggablePoint draggablePt = hitInfo.collider.GetComponent <DraggablePoint>(); if (selection) { SelectShell(selection); } else if (draggablePt) { draggable = draggablePt; selectedDepth = Camera.main.WorldToScreenPoint(draggablePt.transform.position).z; } } else if (Input.GetKeyDown("r") && RaycastShells(Input.mousePosition, out hitInfo)) { DraggablePoint draggablePt = hitInfo.collider.GetComponent <DraggablePoint>(); if (draggablePt && draggablePt.parentSpline) { Debug.Log("Reverse " + draggablePt.parentSpline.name); draggablePt.parentSpline.Reverse(); } } else if (Input.GetKeyDown("j") && RaycastShells(Input.mousePosition, out hitInfo)) { DraggablePoint draggablePt = hitInfo.collider.GetComponent <DraggablePoint>(); if (draggablePt) { if (draggablePt.Type == PointType.Bulb) { draggablePt.SwitchBulbType(PointType.EmptyJuncture); } else if (draggablePt.Type == PointType.EmptyJuncture) { draggablePt.SwitchBulbType(PointType.Bulb); } } } else if (Input.GetMouseButton(0) && draggable) { Vector3 clickPos = Input.mousePosition; clickPos.z = selectedDepth; Vector3 worldPos = Camera.main.ScreenToWorldPoint(clickPos); DraggablePoint intersectedBulb = splineCanvas.IntersectedBulb(worldPos); if (draggable.Type == PointType.Spline && draggable.IsEndPoint() && intersectedBulb) { draggable.AttachToBulb(intersectedBulb); } else { draggable.Move(worldPos); } } else if (Input.GetMouseButtonDown(1) && RaycastShells(Input.mousePosition, out hitInfo)) { Vector3 clickPos = Input.mousePosition; DraggablePoint clicked = hitInfo.collider.GetComponent <DraggablePoint>(); if (clicked) { if (Input.GetKey("left ctrl")) { clicked.Delete(); } else { clicked.Duplicate(); } } // Store the eye-space position of the click. // Use eye space because we always want moving up/down to correspond // to bigger or smaller, regardless of camera orientation. lastMousePos = clickPos; lastMousePos.z = selectedDepth; lastMousePos = Camera.main.ScreenToViewportPoint(lastMousePos); } else if (Input.GetMouseButtonDown(2) && RaycastShells(Input.mousePosition, out hitInfo)) { Vector3 clickPos = Input.mousePosition; // Store the eye-space position of the click. // Use eye space because we always want moving up/down to correspond // to bigger or smaller, regardless of camera orientation. lastMousePos = clickPos; lastMousePos.z = selectedDepth; lastMousePos = Camera.main.ScreenToViewportPoint(lastMousePos); } else if (Input.mouseScrollDelta.y != 0 && RaycastShells(Input.mousePosition, out hitInfo)) { DraggablePoint draggablePt = hitInfo.collider.GetComponent <DraggablePoint>(); if (draggablePt) { float change = Input.mouseScrollDelta.y * 0.05f; draggablePt.Resize(change); } } else if (Input.GetKeyDown("delete") && RaycastShells(Input.mousePosition, out hitInfo)) { DraggablePoint draggablePt = hitInfo.collider.GetComponent <DraggablePoint>(); if (draggablePt) { draggablePt.Delete(); } } else if (Input.GetKeyDown("b") && RaycastShells(Input.mousePosition, out hitInfo)) { DraggablePoint draggablePt = hitInfo.collider.GetComponent <DraggablePoint>(); if (draggablePt) { draggablePt.ReplaceWithBulb(); } } else if (Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(2)) { draggable = null; } else if (Input.GetButtonDown("Cancel")) { Deselect(); } else if (Input.GetButtonDown("Submit")) { Debug.Log("submit"); } shootTime += Time.deltaTime; if (shootTime > shootDelay && Input.GetKey("z")) { ShootSphere(); } }
public void InitFromPoint(DraggablePoint p) { transform.parent = p.transform.parent; InitFromValues(p.transform.position, p.radius); }
public void ReplaceWithBulb(int index) { // Do nothing if this is an endpoint -- we can only insert // a bulb at an interior point. if (index <= 1) { return; } if (index >= points.Count - 2) { return; } List <Vector3> beforePoints = new List <Vector3>(); List <Vector3> afterPoints = new List <Vector3>(); // We want to copy all of the points up to the split position, // and make a new spline out of that. for (int i = 0; i < index; i++) { beforePoints.Add(points[i]); } // Add the split position as the last point beforePoints.Add(points[index]); // Add the last tangent handle as a point farther down the spline Vector3 middleBefore = sample(index + 0.5f); beforePoints.Add(middleBefore); // We also want to make a new spline of all the points // starting after the split position. // Add first tangent handle as coming before the split Vector3 middleAfter = sample(index - 0.5f); afterPoints.Add(middleAfter); // Add the split position as the first point afterPoints.Add(points[index]); for (int i = index + 1; i < points.Count; i++) { afterPoints.Add(points[i]); } // Make the splines CatmullRomSpline before = SplineOfPoints(beforePoints); containingCanvas.AddExistingSpline(before); CatmullRomSpline after = SplineOfPoints(afterPoints); containingCanvas.AddExistingSpline(after); // Connect splines to the bulb we just added DraggablePoint bulb = containingCanvas.AddBulb(points[index]); before.StartBulb = StartBulb; before.EndBulb = bulb; after.StartBulb = bulb; after.EndBulb = EndBulb; bulb.SetSize(0.1f); // Delete the current spline that was split containingCanvas.DeleteSpline(this); Destroy(gameObject); }
public BulbData(DraggablePoint bulb) { position = new V3Serialize(bulb.transform.position); radius = bulb.radius; type = bulb.Type; }
/// <summary> /// Remove the given bulb from this canvas. /// </summary> /// <param name="bulb"></param> public void DeleteBulb(DraggablePoint bulb) { bulbs.Remove(bulb); }
void DepthFirstSearch(int initial) { GetCanvas(); bool[] visited = new bool[heMesh.Vertices.Length]; int numVisited = 0; foreach (bool b in visited) { if (b) { numVisited++; } } Debug.Log("Initial " + numVisited + " / " + visited.Length); Stack <IntPair> dfsStack = new Stack <IntPair>(); dfsStack.Push(new IntPair(initial, initial)); // Keep track of the current chain of points List <int> currentPoints = null; Dictionary <int, DraggablePoint> bulbDict = new Dictionary <int, DraggablePoint>(); DraggablePoint bulbAtStart = null; while (dfsStack.Count > 0) { IntPair nextPair = dfsStack.Pop(); int next = nextPair.num; if (visited[next]) { continue; } HashSet <int> equivClass = uf.Find(next).MergedPoints; // Mark this point and all points merged with it as visited foreach (int p in equivClass) { visited[p] = true; } // Add all neighbors of this point to the list // if they haven't been visited already HashSet <int> neighbors = adjacency[next]; foreach (int neighbor in neighbors) { if (!visited[neighbor]) { dfsStack.Push(new IntPair(neighbor, next)); } } // If this is the first point, start a new line segment. if (currentPoints == null) { Vector3 pos = transform.rotation * mesh.vertices[next] + transform.position; bulbAtStart = outputCanvas.AddBulb(pos); //bulbAtStart.SetSize(FitSphere(mesh.vertices[next])); bulbAtStart.SetSize(0.1f); bulbDict.Add(next, bulbAtStart); currentPoints = new List <int>(); currentPoints.Add(next); } // If this point has degree 2 (i.e. is a part of a straight line segment) // then just continue the current segment. else if (neighbors.Count == 2) { currentPoints.Add(next); } // If this point has degree 1, then we just end the current segment. else if (neighbors.Count == 1) { currentPoints.Add(next); // Can filter out single dead-ends to try to remove noise //if (currentPoints.Count > 2) CatmullRomSpline spline = AddLine(currentPoints); spline.StartBulb = bulbAtStart; // Start a new segment at the predecessor of the most recent branch point. currentPoints = new List <int>(); if (dfsStack.Count > 0) { currentPoints.Add(dfsStack.Peek().predecessor); DraggablePoint bulb; if (bulbDict.TryGetValue(dfsStack.Peek().predecessor, out bulb)) { bulbAtStart = bulb; } else { bulbAtStart = null; } } } // If the point has degree greater than 2, then it is a branch, and we // start a new segment at the current point. else { Vector3 pos = transform.rotation * mesh.vertices[next] + transform.position; DraggablePoint bulb = outputCanvas.AddBulb(pos); //bulb.SetSize(FitSphere(mesh.vertices[next])); bulb.SetSize(0.1f); bulbDict.Add(next, bulb); currentPoints.Add(next); CatmullRomSpline spline = AddLine(currentPoints); spline.EndBulb = bulb; spline.StartBulb = bulbAtStart; // New segments should start at the bulb we just inserted. bulbAtStart = bulb; currentPoints = new List <int>(); currentPoints.Add(next); } } numVisited = 0; foreach (bool b in visited) { if (b) { numVisited++; } } Debug.Log("Visited " + numVisited + " / " + visited.Length); }