public void RemoveSplineEnd(CatmullRomSpline spline) { if (spline.EndBulb == this) { splinesEnd.Remove(spline); spline.EndBulb = null; } }
public void RemoveSplineStart(CatmullRomSpline spline) { if (spline.StartBulb == this) { splinesStart.Remove(spline); spline.StartBulb = null; } }
CatmullRomSpline AddLine(List <int> pointIndices) { Vector3[] points = new Vector3[pointIndices.Count]; for (int i = 0; i < points.Length; i++) { Vector3 pos = mesh.vertices[pointIndices[i]]; points[i] = pos; } GameObject lineObj = new GameObject(); lineObj.transform.parent = outputCanvas.transform; lineObj.transform.localPosition = Vector3.zero; lineObj.transform.localRotation = Quaternion.identity; lineObj.name = "skeleton-spline"; // Create spline from points // Transform to world space for (int i = 0; i < points.Length; i++) { points[i] = transform.rotation * points[i] + transform.position; } CatmullRomSpline crs = lineObj.AddComponent <CatmullRomSpline>(); crs.points = new List <Vector3>(); Vector3 firstDiff = points[1] - points[0]; Vector3 first = points[0]; points[0] += firstDiff.normalized * 0.1f; Vector3 lastDiff = points[points.Length - 2] - points[points.Length - 1]; Vector3 last = points[points.Length - 1]; points[points.Length - 1] += lastDiff.normalized * 0.1f; crs.points.Add(first); crs.points.AddRange(points); crs.points.Add(last); outputCanvas.AddExistingSpline(crs); /* * LineRenderer line = lineObj.AddComponent<LineRenderer>(); * line.useWorldSpace = false; * * line.SetVertexCount(points.Length); * line.SetPositions(points); * line.SetWidth(0.1f, 0.1f); * line.material = DesignerController.instance.defaultLineMaterial; * Color c = Color.HSVToRGB(hue, 1, 1); * line.SetColors(c, c); * hue = Mathf.Repeat(hue + 0.3f, 1); */ return(crs); }
public SplineData(CatmullRomSpline spline) { points = new List <V3Serialize>(); foreach (Vector3 v in spline.points) { points.Add(new V3Serialize(v)); } startBulb = (spline.StartBulb) ? spline.StartBulb.index : -1; endBulb = (spline.EndBulb) ? spline.EndBulb.index : -1; }
/// <summary> /// Add a spline object that already exists to this canvas, without /// adding any new control points. /// </summary> /// <param name="spline">The existing spline object.</param> public void AddExistingSpline(CatmullRomSpline spline) { if (splines == null) { splines = new List <CatmullRomSpline>(); } spline.transform.parent = transform; spline.containingCanvas = this; splines.Add(spline); }
public static CatmullRomSpline SplineOfPoints(List <Vector3> pts) { GameObject splineObj = new GameObject(); CatmullRomSpline spline = splineObj.AddComponent <CatmullRomSpline>(); spline.points = new List <Vector3>(); spline.points.AddRange(pts); spline.SetMaterial(DesignerController.instance.defaultLineMaterial); spline.name = "spline" + numSplinesCreated; numSplinesCreated++; return(spline); }
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 spline object to this canvas, and add an initial control /// point for it. /// </summary> /// <param name="firstPos">The position of the first control point.</param> /// <returns></returns> CatmullRomSpline AddSpline(Vector3 firstPos) { GameObject splineObj = new GameObject(); splineObj.transform.parent = transform; mostRecentPoint = firstPos; CatmullRomSpline spline = splineObj.AddComponent <CatmullRomSpline>(); spline.points = new List <Vector3>(); spline.points.Add(firstPos - 0.1f * Vector3.up); spline.points.Add(firstPos); spline.points.Add(firstPos + 0.1f * Vector3.up); spline.points.Add(firstPos + 0.2f * Vector3.up); spline.containingCanvas = this; splines.Add(spline); spline.SetMaterial(DesignerController.instance.defaultLineMaterial); splineObj.name = "spline" + splines.Count; return(spline); }
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); }
/// <summary> /// Remove the given spline from this canvas. /// </summary> /// <param name="crs"></param> public void DeleteSpline(CatmullRomSpline crs) { splines.Remove(crs); }
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); }