/// <summary> /// Called to refresh the shape. Please call base.Refresh() or RefreshSpline() after your custom code! /// </summary> /// <remarks>Warning: Only work with ControlPoints, not with segments</remarks> public void Refresh() { if (Spline && Spline.IsInitialized && Dirty) { ApplyShape(); applyPlane(); Spline.Refresh(); } Dirty = false; }
// setup everything IEnumerator setup() { mInitState = 1; mGenerators = new CurvyGenerator[Sections]; // Add some start CP's to the spline TrackSpline.Add().position = Vector3.zero; TrackSpline.Add().position = new Vector3(0, 0, CPStepSize); mDir = Vector3.forward; int num = TailCP + HeadCP + Sections * SectionCPCount - 1; for (int i = 0; i < num; i++) { addTrackCP(); } TrackSpline.Refresh(); // setting anchors so new CP's won't change orientation of existing ones for (int i = TailCP; i < TrackSpline.ControlPointCount - HeadCP; i += SectionCPCount) { TrackSpline.ControlPoints[i].OrientationAnchor = true; } // build Curvy Generators for (int i = 0; i < Sections; i++) { mGenerators[i] = buildGenerator(); mGenerators[i].name = "Generator " + i; } // and wait until they're initialized for (int i = 0; i < Sections; i++) { while (!mGenerators[i].IsInitialized) { yield return(0); } } // let all generators do their extrusion for (int i = 0; i < Sections; i++) { updateSectionGenerator(mGenerators[i], i * SectionCPCount + TailCP, (i + 1) * SectionCPCount + TailCP); } mInitState = 2; mUpdateIn = SectionCPCount; // finally place the controller Controller.AbsolutePosition = TrackSpline.ControlPoints[TailCP + 2].Distance; Controller.InitialPosition = TrackSpline.ControlPoints[TailCP + 2].Distance; // just to be sure }
// Use this for initialization IEnumerator Start() { while (!mSpline.IsInitialized) { yield return(0); } for (int i = 0; i < CPCount; i++) { addCP(); } mSpline.Refresh(); mLastUpdateTime = Time.timeSinceLevelLoad + 0.1f; }
void addRandomCP(ref CurvySpline spline, int count, int totalLength) { Vector3[] pos = new Vector3[count]; float segLength = totalLength / (float)(count - 1); pos[0] = Vector3.zero; for (int i = 1; i < count; i++) { int dir = Random.Range(0, 2); int sign = Random.Range(0f, 1f) > 0.5f ? 1 : -1; switch (dir) { case 0: pos[i] = pos[i - 1] + new Vector3(segLength * sign, 0, 0); break; case 1: pos[i] = pos[i - 1] + new Vector3(0, segLength * sign, 0); break; case 2: pos[i] = pos[i - 1] + new Vector3(0, 0, segLength * sign); break; } } spline.Add(pos); spline.Refresh(); }
public void DeleteCP() { if (Spline && Spline.ControlPointCount > 0) { int idx = Random.Range(0, Spline.ControlPointCount - 1); Spline.ControlPoints[idx].Delete(); Spline.Refresh(); } }
/// <summary> /// Centers Control Points around Spline transform /// </summary> /// <param name="spline">The spline to address</param> public static void centerPivot(CurvySpline spline) { Bounds b = spline.GetBounds(false); Vector3 off = spline.Transform.position - b.center; foreach (CurvySplineSegment cp in spline.ControlPoints) { cp.Transform.position += off; } spline.transform.position -= off; spline.Refresh(); }
// Code that runs on entering the state. public override void OnEnter() { GameObject go = Fsm.GetOwnerDefaultTarget(GameObject); if (go) { CurvySpline spl = go.GetComponent <CurvySpline>(); if (spl) { spl.Clear(); spl.Refresh(); } } Finish(); }
/// <summary> /// Equalize one axis of a spline to match the first control points's value /// </summary> /// <param name="spline">a CurvySpline</param> /// <param name="axis">the axis to equalize (0=x,1=y,2=z)</param> public static void makePlanar(CurvySpline spline, int axis) { UnityEngine.Vector3 p = spline.ControlPoints[0].Position; for (int i = 1; i < spline.ControlPointCount; i++) { UnityEngine.Vector3 pi = spline.ControlPoints[i].Position; switch (axis) { case 0: pi.x = p.x; break; case 1: pi.y = p.y; break; case 2: pi.z = p.z; break; } spline.ControlPoints[i].Position = pi; } spline.Refresh(); }
public static void OnUndoRedoPerformed() { var item = Selection.activeGameObject; if (item != null) { CurvySpline spline = item.GetComponent <CurvySpline>(); CurvySplineSegment cp = item.GetComponent <CurvySplineSegment>(); if (!spline && cp) { spline = cp.Spline; } if (spline) { spline._RenameControlPointsByIndex(); spline.Refresh(); } } }
// Code that runs on entering the state. public override void OnEnter() { GameObject go = Fsm.GetOwnerDefaultTarget(GameObject); if (go) { CurvySpline spl = go.GetComponent <CurvySpline>(); if (spl) { if (!Index.IsNone) { CurvySplineSegment seg = (Index.Value >= 0 && Index.Value < spl.ControlPointCount) ? spl.ControlPoints[Index.Value] : null; for (int i = 0; i < Points.Length; i++) { if (!Points[i].IsNone) { CurvySplineSegment newCP; if (Mode == InsertMode.After) { newCP = spl.InsertAfter(seg); } else { newCP = spl.InsertBefore(seg); } if (Space == Space.Self) { newCP.localPosition = Points[i].Value; } else { newCP.position = Points[i].Value; } } } spl.Refresh(); } } } Finish(); }
// Code that runs on entering the state. public override void OnEnter() { GameObject go = Fsm.GetOwnerDefaultTarget(GameObject); if (go) { CurvySpline spl = go.GetComponent <CurvySpline>(); if (spl) { if (!StartIndex.IsNone && !Count.IsNone && Count.Value > 0) { for (int i = 0; i < Count.Value; i++) { spl.Delete(spl.ControlPointsList[StartIndex.Value]); } spl.Refresh(); } } } Finish(); }
/// <summary> /// Rearrange the spline to have a new first Control Point. /// </summary> /// <param name="newStartCP">the Control Point to become the first Control Point</param> public static void setFirstCP(CurvySplineSegment newStartCP) { CurvySpline spl = newStartCP.Spline; if (newStartCP.ControlPointIndex == 0) { return; } CurvySplineSegment[] toMove = new CurvySplineSegment[newStartCP.ControlPointIndex]; for (int i = 0; i < newStartCP.ControlPointIndex; i++) { toMove[i] = spl.ControlPoints[i]; } foreach (CurvySplineSegment seg in toMove) { spl.ControlPoints.Remove(seg); spl.ControlPoints.Add(seg); } spl._nameControlPoints(); spl.Refresh(); }
/// <summary> /// Centers Control Points around Spline transform /// </summary> /// <param name="spline">The spline to address</param> public static void centerPivot(CurvySpline spline) { Bounds b = spline.GetBounds(false); Vector3 off = spline.Transform.position - b.center; foreach (CurvySplineSegment cp in spline.ControlPoints) cp.Transform.position += off; spline.transform.position -= off; spline.Refresh(); }
/// <summary> /// Equalize one axis of a spline to match the first control points's value /// </summary> /// <param name="spline">a CurvySpline</param> /// <param name="axis">the axis to equalize (0=x,1=y,2=z)</param> public static void makePlanar(CurvySpline spline, int axis) { Vector3 p = spline.ControlPoints[0].Position; for (int i = 1; i < spline.ControlPointCount; i++) { Vector3 pi = spline.ControlPoints[i].Position; switch (axis) { case 0: pi.x = p.x; break; case 1: pi.y = p.y; break; case 2: pi.z = p.z; break; } spline.ControlPoints[i].Position = pi; } spline.Refresh(); }
void addCP(Vector2 cursor, bool castRay, bool connectNew) { if (selSpline) { if (!selCP && selSpline.ControlPointCount > 0) selCP = selSpline.ControlPoints[selSpline.ControlPointCount - 1]; } else { selSpline = CurvySpline.Create(); var parent = DTSelection.GetAs<Transform>(); selSpline.transform.SetParent(parent); if (parent == null) selSpline.transform.position = HandleUtility.GUIPointToWorldRay(cursor).GetPoint(10); Undo.RegisterCreatedObjectUndo(selSpline.gameObject, "Add ControlPoint"); } // Pick a point to add the CP at Vector3 pos; if (!pickScenePoint(cursor, castRay, selSpline, selCP, out pos)) return; CurvySplineSegment newCP=null; // Connect by creating a new spline with 2 CP, the first "over" selCP, the second at the desired new position // OR connect to existing C if (connectNew && selCP) { CurvySplineSegment conCP=null; // if mouse is over an existing CP, connect to this (if possible) var existingGO=HandleUtility.PickGameObject(cursor,false); if (existingGO) { conCP = existingGO.GetComponent<CurvySplineSegment>(); // if we picked a target cp, it may be a pick on it's segment, so check distance to CP if (conCP) { var P = new Plane(SceneView.currentDrawingSceneView.camera.transform.forward, conCP.transform.position); var R = HandleUtility.GUIPointToWorldRay(cursor); float dist; if (P.Raycast(R, out dist)) { Vector3 hit=R.GetPoint(dist); if ((hit - conCP.transform.position).magnitude <= HandleUtility.GetHandleSize(hit) * CurvyGlobalManager.GizmoControlPointSize) { newCP = insertCP(selSpline, selCP, conCP.transform.position); selCP = newCP; } else { hit=conCP.Interpolate(conCP.GetNearestPointF(hit)); conCP=conCP.Spline.InsertAfter(conCP); conCP.transform.position = hit; newCP = insertCP(selSpline, selCP, hit); selCP = newCP; } selSpline.Refresh(); } } } if (!conCP) { selSpline = CurvySpline.Create(selSpline); selSpline.Closed = false; conCP = insertCP(selSpline, null, selCP.transform.position); newCP = insertCP(selSpline, conCP, pos); selSpline.Refresh(); } selCP.ConnectTo(conCP); } else { newCP = insertCP(selSpline, selCP, pos); } DTSelection.SetGameObjects(newCP); }
void addRandomCP(ref CurvySpline spline, int count, int totalLength) { Vector3[] pos=new Vector3[count]; float segLength = totalLength / (float)(count - 1); pos[0] = Vector3.zero; for (int i = 1; i < count; i++) { int dir = Random.Range(0, 2); int sign=Random.Range(0f,1f)>0.5f ? 1 : -1; switch (dir) { case 0: pos[i] = pos[i - 1] + new Vector3(segLength * sign, 0, 0); break; case 1: pos[i] = pos[i - 1] + new Vector3(0,segLength * sign,0); break; case 2: pos[i] = pos[i - 1] + new Vector3(0,0,segLength * sign); break; } } spline.Add(pos); spline.Refresh(); }
/// <summary> /// Moves the Control Point along it's Up-Vector to match a desired Spline length /// </summary> /// <remarks>When the desired length can't be achieved, the Control Point will stop moving at the nearest possible point</remarks> /// <param name="newSplineLength">the desired length of the spline</param> /// <param name="stepSize">stepSize used when moving</param> /// <returns>false if the length can't be achieved by moving this Control Point.</returns> public bool SnapToFitSplineLength(float newSplineLength, float stepSize) { if (stepSize == 0 || Mathf.Approximately(newSplineLength, Spline.Length)) { return(true); } float curLength = Spline.Length; Vector3 oldPos = Transform.position; Vector3 upstep = Transform.up * stepSize; // Check if increasing by Up-Vector will increase the length Transform.position += upstep; Spline.Refresh(true, false, false); bool UpGrows = (Spline.Length > curLength); int loops = 30000; Transform.position = oldPos; // Need to grow? if (newSplineLength > curLength) { if (!UpGrows) { upstep *= -1; } while (Spline.Length < newSplineLength) { loops--; curLength = Spline.Length; Transform.position += upstep; Spline.Refresh(true, false, false); if (curLength > Spline.Length) { return(false); } if (loops == 0) { Debug.LogError( "CurvySplineSegment.SnapToFitSplineLength exceeds 30000 loops, considering this a dead loop! This shouldn't happen, please report this as an error!"); return(false); } } } else { // otherwise shrink if (UpGrows) { upstep *= -1; } while (Spline.Length > newSplineLength) { loops--; curLength = Spline.Length; Transform.position += upstep; Spline.Refresh(true, false, false); if (curLength < Spline.Length) { return(false); } if (loops == 0) { Debug.LogError( "CurvySplineSegment.SnapToFitSplineLength exceeds 30000 loops, considering this a dead loop! This shouldn't happen, please report this as an error!"); return(false); } } } return(true); }