private void OnSceneGUI() { curve = target as CubicBezierCurve; t = curve.transform; q = Tools.pivotRotation == PivotRotation.Local ? t.rotation : Quaternion.identity; Vector3 world0 = ShowPoint(0); Vector3 world1 = ShowPoint(1); Vector3 world2 = ShowPoint(2); Vector3 world3 = ShowPoint(3); Handles.color = Color.gray; Handles.DrawLine(world0, world1); Handles.DrawLine(world1, world2); Handles.DrawLine(world2, world3); Vector3 lineStart = curve.GetPoint(0f); Handles.color = Color.green; Handles.DrawLine(lineStart, lineStart + curve.GetDirection(0f) * directionVectorsScale); for (int i = 1; i <= steps; i++) { float normalizedStep = i / (float)steps; Vector3 lineEnd = curve.GetPoint(normalizedStep); Handles.color = Color.white; Handles.DrawLine(lineStart, lineEnd); Handles.color = Color.green; Handles.DrawLine(lineEnd, lineEnd + curve.GetDirection(normalizedStep) * directionVectorsScale); lineStart = lineEnd; } }
// This function returns a single closest point. There may be more than one point on the path at the same distance. // Use ComputeApproxParamPerUnitLength to determine a good paramThreshold. eg. Say you want a 15cm threshold, // use: paramThreshold = ComputeApproxParamPerUnitLength() * 0.15f. public float ComputeClosestParam(Vector3 pos, float paramThreshold) { float minDistSq = float.MaxValue; float closestParam = 0.0f; for (int startIndex = 0; startIndex < controlVerts.Length - 1; startIndex += 3) { Vector3[] curveCVs = new Vector3[4]; for (int i = 0; i < 4; i++) { curveCVs[i] = controlVerts[startIndex + i]; } CubicBezierCurve curve = new CubicBezierCurve(curveCVs); float curveClosestParam = curve.GetClosestParam(pos, paramThreshold); Vector3 curvePos = curve.GetPoint(curveClosestParam); float distSq = (curvePos - pos).sqrMagnitude; if (distSq < minDistSq) { minDistSq = distSq; float startParam = ((float)startIndex) / 3.0f; closestParam = startParam + curveClosestParam; } } return(closestParam); }
// t E [0, numSegments]. If the type is closed, the number of segments is one more than the equivalent open path. public Vector3 GetPoint(float t) { // Only closed paths accept t values out of range. if (type == Type.Closed) { while (t < 0.0f) { t += (float)numCurveSegments; } while (t > (float)numCurveSegments) { t -= (float)numCurveSegments; } } else { t = Mathf.Clamp(t, 0.0f, (float)numCurveSegments); } Assert.IsTrue((t >= 0) && (t <= (float)numCurveSegments)); // Segment 0 is for t E [0, 1). The last segment is for t E [NumCurveSegments-1, NumCurveSegments]. // The following 'if' statement deals with the final inclusive bracket on the last segment. The cast must truncate. var segment = (int)t; if (segment >= numCurveSegments) { segment = numCurveSegments - 1; } var bc = new CubicBezierCurve(controlVerts[3 * segment + 0], controlVerts[3 * segment + 1], controlVerts[3 * segment + 2], controlVerts[3 * segment + 3]); return(bc.GetPoint(t - (float)segment)); }
public void Update() { if (pathActive) { float canvasScale = Screen.width / RecipeTreeMaster.myCanvas.GetComponent <CanvasScaler>().referenceResolution.x; //canvasScale = 1; //canvasScale = 1f / canvasScale; float localScale = 1 / myRend.transform.lossyScale.x; //print(canvasScale); Vector3 startWorldPoint = /*RecipeTreeMaster.mainCam.ScreenToWorldPoint*/ (lineConnectionPoint.position - myRend.transform.position) * localScale /*+ Vector3.forward*5*/; Vector3 endWorldPoint = /*RecipeTreeMaster.mainCam.ScreenToWorldPoint*/ (myConnection.lineConnectionPoint.position - myRend.transform.position) * localScale /*+ Vector3.forward*5*/; float pushDistance = Mathf.Abs(startWorldPoint.x - endWorldPoint.x) / 2f; Vector3[] knots = new[] { startWorldPoint, startWorldPoint + (isInput ? Vector3.left : Vector3.right) * pushDistance, endWorldPoint + (!isInput ? Vector3.left : Vector3.right) * pushDistance, endWorldPoint }; /*Debug.DrawLine(lineConnectionPoint.position, lineConnectionPoint.position+Vector3.up); * Debug.DrawLine(lineConnectionPoint.position + (isInput? Vector3.left : Vector3.right), lineConnectionPoint.position + (isInput? Vector3.left : Vector3.right)+Vector3.up); * Debug.DrawLine(myConnection.lineConnectionPoint.position + (isInput? Vector3.left : Vector3.right), myConnection.lineConnectionPoint.position + (isInput? Vector3.left : Vector3.right)+Vector3.up); * Debug.DrawLine(myConnection.lineConnectionPoint.position, myConnection.lineConnectionPoint.position+Vector3.up);*/ path.SetControlVerts(knots); for (int i = 0; i <= resolution; i++) { Vector3 pos = path.GetPoint(((float)i) / (float)resolution); myRend.m_points[i] = new Vector2(pos.x, pos.y); } myRend.SetAllDirty(); } }
public Vector3 GetPoint(float t, int curveSection) { int offset = curveSection * 3; return(transform.TransformPoint(CubicBezierCurve.GetPoint( controlPoints[0 + offset], controlPoints[1 + offset], controlPoints[2 + offset], controlPoints[3 + offset], t))); }
public void OnPositionUpdated() { if (pathActive) { float canvasScale = Screen.width / myMaster.myViewer.myCanvas.GetComponent <CanvasScaler>().referenceResolution.x; //canvasScale = 1; //canvasScale = 1f / canvasScale; float localScale = 1 / myRend.transform.lossyScale.x; //print(canvasScale); Vector3 startWorldPoint = /*RecipeTreeMaster.mainCam.ScreenToWorldPoint*/ (lineConnectionPoint.position - myRend.transform.position) * localScale /*+ Vector3.forward*5*/; Vector3 endWorldPoint = /*RecipeTreeMaster.mainCam.ScreenToWorldPoint*/ (connectedPortGfx.lineConnectionPoint.position - myRend.transform.position) * localScale /*+ Vector3.forward*5*/; float pushDistance = Mathf.Abs(Vector3.Distance(startWorldPoint, endWorldPoint)) / 2f; //pushDistance = Mathf.Max(pushDistance, 50f*localScale); Vector3[] knots = new[] { startWorldPoint, startWorldPoint + (myAdapterGroup.isLeftAdapter ? Vector3.left : Vector3.right) * pushDistance, endWorldPoint + (!myAdapterGroup.isLeftAdapter ? Vector3.left : Vector3.right) * pushDistance, endWorldPoint }; resolution = Mathf.CeilToInt(pushDistance / 7f); /*Debug.DrawLine(lineConnectionPoint.position, lineConnectionPoint.position+Vector3.up); * Debug.DrawLine(lineConnectionPoint.position + (isInput? Vector3.left : Vector3.right), lineConnectionPoint.position + (isInput? Vector3.left : Vector3.right)+Vector3.up); * Debug.DrawLine(connectedPortGfx.lineConnectionPoint.position + (isInput? Vector3.left : Vector3.right), connectedPortGfx.lineConnectionPoint.position + (isInput? Vector3.left : Vector3.right)+Vector3.up); * Debug.DrawLine(connectedPortGfx.lineConnectionPoint.position, connectedPortGfx.lineConnectionPoint.position+Vector3.up);*/ path.SetControlVerts(knots); var points = new Vector2[resolution + 1]; for (int i = 0; i <= resolution; i++) { Vector3 pos = path.GetPoint(((float)i) / (float)resolution); points[i] = new Vector2(pos.x, pos.y); } myRend.Points = points; myRend.SetAllDirty(); } }
// This function returns a single closest point. There may be more than one point on the path at the same distance. // Use ComputeApproxParamPerUnitLength to determine a good paramThreshold. eg. Say you want a 15cm threshold, // use: paramThreshold = ComputeApproxParamPerUnitLength() * 0.15f. public float ComputeClosestParam(Vector3 pos, float paramThreshold) { var minDistSq = float.MaxValue; var closestParam = 0.0f; for (var startIndex = 0; startIndex < controlVerts.Length - 1; startIndex += 3) { var curve = new CubicBezierCurve(controlVerts[startIndex + 0], controlVerts[startIndex + 1], controlVerts[startIndex + 2], controlVerts[startIndex + 3]); var curveClosestParam = curve.GetClosestParam(pos, paramThreshold); var curvePos = curve.GetPoint(curveClosestParam); var distSq = (curvePos - pos).sqrMagnitude; if (distSq < minDistSq) { minDistSq = distSq; var startParam = ((float)startIndex) / 3.0f; closestParam = startParam + curveClosestParam; } } return(closestParam); }
public Vector3 GetPoint(float t) { return(transform.TransformPoint(CubicBezierCurve.GetPoint(controlPoints[0], controlPoints[1], controlPoints[2], controlPoints[3], t))); }
/// <summary> /// Get local point from center curve of pipe at time. /// </summary> /// <param name="time">Time of pipe center curve.</param> /// <returns>Local point on pipe curve at time.</returns> protected override Vector3 GetLocalPoint(float time) { return(CubicBezierCurve.GetPoint(anchor, time)); }
/// <summary> /// Get point on path curve at time. /// </summary> /// <param name="time">Time of curve.</param> /// <returns>The point on path curve at time.</returns> public override Vector3 GetPoint(float time) { return(transform.TransformPoint(CubicBezierCurve.GetPoint(anchor, time))); }