/// <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);
        }
Example #5
0
        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];
                }
            }
        }
Example #6
0
        /// <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);
        }
Example #10
0
 public BulbData(DraggablePoint bulb)
 {
     position = new V3Serialize(bulb.transform.position);
     radius   = bulb.radius;
     type     = bulb.Type;
 }
Example #11
0
 /// <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);
        }