Vector3 ApproximateNearestPointBezierMousePos(Vector3 startPos, Vector3 endPos, Vector3 startTangent, Vector3 endTangent) { float nearDistOnRay = 0; float farDistOnRay = 100; float nearDistToCurve = HandleUtility.DistancePointBezier(mouseRay.origin + mouseRay.direction * nearDistOnRay, startPos, endPos, startTangent, endTangent); float farDistToCurve = HandleUtility.DistancePointBezier(mouseRay.origin + mouseRay.direction * farDistOnRay, startPos, endPos, startTangent, endTangent); float mediumDistOnRay = 50; float timeElapsed = 0; while (farDistOnRay - nearDistOnRay > .05f) { Vector3 currentPointOnRay = mouseRay.origin + mouseRay.direction * mediumDistOnRay; float mediumDistToCurve = HandleUtility.DistancePointBezier(currentPointOnRay, startPos, endPos, startTangent, endTangent); if (farDistToCurve > nearDistToCurve) { farDistToCurve = mediumDistToCurve; farDistOnRay = mediumDistOnRay; } else if (nearDistToCurve > farDistToCurve) { nearDistToCurve = mediumDistToCurve; nearDistOnRay = mediumDistOnRay; } mediumDistOnRay = (farDistOnRay + nearDistOnRay) * .5f; } return(mouseRay.origin + mouseRay.direction * mediumDistOnRay); }
public NodeConnection HitsConnection(Vector2 p_position, float p_distance) { foreach (NodeConnection connection in _connections) { NodeBase inputNode = connection.inputNode; NodeBase outputNode = connection.outputNode; Rect inputOffsetRect = new Rect(inputNode.rect.x + viewOffset.x, inputNode.rect.y + viewOffset.y, inputNode.Size.x, inputNode.Size.y); Rect outputOffsetRect = new Rect(outputNode.rect.x + viewOffset.x, outputNode.rect.y + viewOffset.y, outputNode.Size.x, outputNode.Size.y); Vector3 startPos = new Vector3(outputOffsetRect.x + outputOffsetRect.width + 8, outputOffsetRect.y + DashEditorCore.EditorConfig.theme.TitleTabHeight + DashEditorCore.EditorConfig.theme.ConnectorHeight / 2 + connection.outputIndex * 32); Vector3 startTan = startPos + Vector3.right * 50; Vector3 endPos = new Vector3(inputOffsetRect.x - 8, inputOffsetRect.y + DashEditorCore.EditorConfig.theme.TitleTabHeight + DashEditorCore.EditorConfig.theme.ConnectorHeight / 2 + connection.inputIndex * 32); Vector3 endTan = endPos + Vector3.left * 50; if (HandleUtility.DistancePointBezier(new Vector3(p_position.x, p_position.y, 0), startPos, endPos, startTan, endTan) < p_distance) { return(connection); } } return(null); }
void Input() { UnityEngine.Event guiEvent = UnityEngine.Event.current; Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin; if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift) { if (selectedSegmentIndex != -1) { Undo.RecordObject(creator, "Split Segment"); Path.SplitSegment(mousePos, selectedSegmentIndex); } else if (!Path.IsClosed) { Undo.RecordObject(creator, "Add Segment"); Path.AddSegment(mousePos); } } if (guiEvent.type == EventType.MouseDown && guiEvent.button == 1) { float minDstToAnchor = creator.anchorDiamertre * 0.5f; int closestAnchorIndex = -1; for (int i = 0; i < Path.NumPoints; i += 3) { float dst = Vector2.Distance(mousePos, Path[i]); if (dst < minDstToAnchor) { minDstToAnchor = dst; closestAnchorIndex = i; } } if (closestAnchorIndex != -1) { Undo.RecordObject(creator, "Delete Segment"); Path.DeleteSegment(closestAnchorIndex); } } if (guiEvent.type == EventType.mouseMove) { float minDstToSegment = segmeantSelectDistanceThreshold; int newSelectedSegmentIndex = -1; for (int i = 0; i < Path.NumSegments; i++) { Vector2[] points = Path.GetPointsInSegment(i); float dst = HandleUtility.DistancePointBezier(mousePos, points[0], points[3], points[1], points[2]); if (dst < minDstToSegment) { minDstToSegment = dst; newSelectedSegmentIndex = i; } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; SceneView.RepaintAll(); } } }
public static float DistancePointCurve(Vector2 point, Vector2 curveStart, Vector2 curveEnd) { var l = Mathf.Min(Mathf.Abs(curveStart.y - curveEnd.y), 150); var tangentStart = curveStart + new Vector2(l, 0); var tangentEnd = curveEnd - new Vector2(l, 0); return(HandleUtility.DistancePointBezier(point, curveStart, curveEnd, tangentStart, tangentEnd)); }
void DrawLinks() { Vector3 a; Vector3 b; Vector3 at; Vector3 bt; float d; Vector3 off; float yDiff; Rect r = new Rect(); foreach (var mod in Modules) { //Debug.Log(mod.name + ":" + mod.Properties.Dimensions.yMin+" to "+mod.Properties.Dimensions.yMax); if (mod.OutputByName != null) { foreach (var slotOut in mod.OutputByName.Values) { a = slotOut.Origin; foreach (var slotIn in slotOut.LinkedSlots) { b = slotIn.Origin; r.Set(a.x, a.y, b.x - a.x, b.y - a.y); // draw only visible lines if (Canvas.ViewPort.Overlaps(r, true)) { d = Mathf.Abs(b.x - a.x); off = new Vector3(Mathf.Min(d / 2, Mathf.Max(d, 80)), 0, 0); yDiff = Mathf.Max(slotIn.Module.Properties.Dimensions.yMin - mod.Properties.Dimensions.yMax, mod.Properties.Dimensions.yMin - b.y); if (yDiff > 0) { off.x = Mathf.Min(yDiff, 80); } at = a + off; bt = b - off; if (EV.type == EventType.Repaint) { float w = (Sel.SelectedLink != null && Sel.SelectedLink.IsBetween(slotOut, slotIn)) ? 7 : 2; Color slotColor = getTypeColor(slotOut.Info.DataTypes); Handles.DrawBezier(a, b, at, bt, slotColor, CurvyStyles.LineTexture, w); if (((CGModuleInputSlot)slotIn).InputInfo.RequestDataOnly || slotIn.OnRequestModule != null) { Vector3 yOff = new Vector3(0, 4, 0); Handles.DrawBezier(a + yOff, b + yOff, at + yOff, bt + yOff, slotColor, CurvyStyles.LineTexture, w); } } if (LMB && HandleUtility.DistancePointBezier(EV.mousePosition, a, b, at, bt) < 4) { Sel.Select(slotOut.Module.GetOutputLink((CGModuleOutputSlot)slotOut, (CGModuleInputSlot)slotIn)); } } } } } } }
private void Input() { Event guiEvent = Event.current; Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin; // Shift + 左键 = 添加节点 if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift) { // 计算是否点击线段(插入节点) float minDist = minDistSegment; int segIndex = -1; for (int i = 0; i < path.NumSegments; i++) { Vector2[] p = path.GetPointsInSegment(i); float dst = HandleUtility.DistancePointBezier(mousePos, p[0], p[3], p[1], p[2]); if (dst < minDist) { minDist = dst; segIndex = i; } } // 插入或者添加节点 if (segIndex != -1) { Undo.RecordObject(creator, "插入节点"); path.SplitSegment(mousePos, segIndex); } else if (!path.IsClosed) { Undo.RecordObject(creator, "添加节点"); path.AddSegment(mousePos); } } // 右键删除节点 if (guiEvent.type == EventType.MouseDown && guiEvent.button == 1) { float minDist = 0.05f; int index = -1; for (int i = 0; i < path.NumPoints; i += 3) { float dst = Vector2.Distance(path[i], mousePos); if (dst < minDist) { minDist = dst; index = i; } } if (index != -1) { Undo.RecordObject(creator, "删除节点"); path.DeleteSegment(index); } } HandleUtility.AddDefaultControl(0); // 点击空白地方时仍选中 PathCreator }
private float GetDistanceToBezier(Vector2 mousePosition, Vector2 startPos, Vector2 endPos) { return(HandleUtility.DistancePointBezier ( mousePosition, GetBezierStartPosition(startPos), GetBezierEndPosition(endPos), GetBezierStartPosition(startPos) + Vector2.right * 50f, GetBezierEndPosition(endPos) + Vector2.left * 50f )); }
public bool IsPointCloseTo(Vector2 point) { switch (Type) { case NodeEditorEdgeType.Line: return(HandleUtility.DistancePointLine(point, RenderStart, RenderEnd) < ClickEpsilon); case NodeEditorEdgeType.Bezier: return(HandleUtility.DistancePointBezier(point, RenderStart, RenderEnd, StartBezierTangent, EndBezierTangent) < ClickEpsilon); } return(false); }
bool HitCheckConnection(Vector2 pos, Vector2 start, Vector2 end) { var startV3 = new Vector3(start.x, start.y, 0f); var endV3 = new Vector3(end.x, end.y + 1f, 0f); var centerPoint = startV3 + ((endV3 - startV3) / 2); var pointDistance = (endV3.x - startV3.x) / 3f; var startTan = new Vector3(startV3.x + pointDistance, startV3.y, 0f); var endTan = new Vector3(endV3.x - pointDistance, endV3.y, 0f); return(HandleUtility.DistancePointBezier(pos, start, end, startTan, endTan) < 5.0f); }
public int IntersectsPathSegment(Vector2 windowPosition) { for (int i = 0; i <= _path.Count; i++) { float distance = HandleUtility.DistancePointBezier(windowPosition, GetSegmentStartPosition(i), GetSegmentEndPosition(i), GetSegmentTangent01(i), GetSegmentTangent02(i)); if (distance <= Config.PathPointSize) { return(i); } } return(-1); }
public bool MouseOverLink(CGModuleLink link) { if (link == null) { return(false); } var outSlot = Parent.Generator.ModulesByID[link.ModuleID].GetOutputSlot(link.SlotName); var inSlot = Parent.Generator.ModulesByID[link.TargetModuleID].GetInputSlot(link.TargetSlotName); Vector3 a = outSlot.Origin; Vector3 at = a + new Vector3(40, 0, 0); Vector3 b = inSlot.Origin; Vector3 bt = b + new Vector3(-40, 0, 0); return(HandleUtility.DistancePointBezier(EV.mousePosition, a, b, at, bt) < 3); }
void Input() { RaycastHit hit; bool mouseHit = MouseUtility.GetMouseWorldPosition(out hit); if (Event.current.type == EventType.MouseDown && mouseHit) { if (Event.current.button == 0 && Event.current.shift) { if (closestSegmentIndex != -1) { Undo.RecordObject(creator, "Split segment"); path.SplitSegment(hit.point, closestSegmentIndex); } else if (!path.IsLoop) { Undo.RecordObject(creator, "Add segment"); path.AddSegment(hit.point); } } if (Event.current.button == 1 && Event.current.shift) { if (closestAnchorIndex != -1) { Undo.RecordObject(creator, "Delete segment"); path.DeleteSegment(closestAnchorIndex); } } } if (Event.current.type == EventType.MouseMove) { List <float> distToSegment = new List <float>(); List <float> distToAnchor = new List <float>(); for (int i = 0; i < path.NumSegments + (path.IsLoop ? 0 : 1); i++) { List <Vector3> handles = path.GetSegmentHandles(i % path.NumSegments); distToSegment.Add(HandleUtility.DistancePointBezier(hit.point, handles[0], handles[3], handles[1], handles[2])); distToAnchor.Add(Vector3.Distance(hit.point, path[i * 3])); } int newClosestSegmentIndex = distToSegment.IndexOf(distToSegment.Min()); int newClosestAnchorIndex = distToAnchor.IndexOf(distToAnchor.Min()) * 3; closestSegmentIndex = distToSegment.Min() < minDistFromElement ? (closestSegmentIndex != newClosestSegmentIndex ? newClosestSegmentIndex : closestSegmentIndex) : -1; closestAnchorIndex = distToAnchor.Min() < minDistFromElement ? (closestAnchorIndex != newClosestAnchorIndex ? newClosestAnchorIndex : closestAnchorIndex) : -1; } }
private bool CheckDistanceFromPointToLoop(Vector2 p, INodeDrawInfo nodeDrawInfo) { var drawInfo = nodeDrawInfo as NodeDrawInfo; Vector3 fromDirection = Vector3.down; Vector3 toDirection = Vector3.right;; var from = (Vector3)nodeDrawInfo.Position + fromDirection * drawInfo.Radius; var to = (Vector3)nodeDrawInfo.Position + toDirection * drawInfo.Radius; var tangentDistance = drawInfo.Radius * 4; var startTangent = from + fromDirection * tangentDistance; var endTangent = from + toDirection * tangentDistance; return(HandleUtility.DistancePointBezier(p, from, to, startTangent, endTangent) < SelectionArcDistanceThreshold * DrawingContext.Current.Zoom); }
// ---------------------------------------------------------------------- public static Vector3 ClosestPointBezier(Vector3 point, Vector3 start, Vector3 end, Vector3 startTangent, Vector3 endTangent, int iteration = 1) { // Have we finished iterating ? if (iteration == 0) { return(point); } // Get distance from bezier curve. float distance = HandleUtility.DistancePointBezier(point, start, end, startTangent, endTangent); // Point is on Bezier so just return it. if (Math3D.IsZero(distance)) { return(point); } Vector3 px = point; px.x += distance; Vector3 py = point; py.y += distance; float dx = HandleUtility.DistancePointBezier(px, start, end, startTangent, endTangent); float dy = HandleUtility.DistancePointBezier(py, start, end, startTangent, endTangent); float xSign = 1f; float ySign = 1f; if (dx > distance) { dx = 2f * distance - dx; xSign = -1f; } if (dy > distance) { dy = 2f * distance - dy; ySign = -1f; } float fx = 1f - dx / distance; float fy = 1f - dy / distance; point.x += xSign * fx * distance; point.y += ySign * fy * distance; return(ClosestPointBezier(point, start, end, startTangent, endTangent, iteration - 1)); }
private bool IsPointInBezierRange(Vector2 point, Connection connection) { var startGridPosition = GridToGuiPositionNoClip(connection.OutputKnob.Rect.center); var endGridPosition = GridToGuiPositionNoClip(connection.InputKnob.Rect.center); var distance = endGridPosition - startGridPosition; var angle = Mathf.Atan2(distance.y, distance.x) / 4; var outputVector = new Vector2(1, Mathf.Sin(angle)); var inputVector = Mathf.Abs(Mathf.Atan2(distance.y, distance.x)) * Mathf.Rad2Deg > 150 ? new Vector2(-1, Mathf.Sin(angle)) : new Vector2(-1, -Mathf.Sin(angle)); return(HandleUtility.DistancePointBezier( GridToGuiPositionNoClip(point), startGridPosition, endGridPosition, startGridPosition + outputVector * distance.magnitude, endGridPosition + inputVector * distance.magnitude) < ConnectionLineWidth); }
Types.BezierSegmentInfo FindClosestSegment(Vector3 mousePos, Vector3 mouseDir) { Vector3 recordBezierCurveDot = Vector3.zero; for (int i = 0; i < creator.snakePath.NumSegments; i++) { Vector3[] points = creator.snakePath.GetPointsInSegment(i); points = ConvertArrayToWorldPos(points); float dist = 1000; float record_t = 0; for (float t = 0.1f; t < 1; t += 0.1f) { Vector3 bezierCurveDot = HUtil.SnakeUtility.BezierCurve(points[0], points[1], points[2], points[3], t); float distToCamera = (bezierCurveDot - mousePos).magnitude; Vector3 simulateMousePoint = mousePos + (distToCamera * mouseDir); float tempDist = HandleUtility.DistancePointBezier(simulateMousePoint, points[0], points[3], points[1], points[2]); if (tempDist < dist) { dist = tempDist; record_t = t; recordBezierCurveDot = bezierCurveDot; } } if (dist > minBezierDistThreshold) { continue; } lastBezierSegmentInfo.SegmentIndex = i; lastBezierSegmentInfo.Position = recordBezierCurveDot; return(lastBezierSegmentInfo); } lastBezierSegmentInfo.SegmentIndex = -1; return(lastBezierSegmentInfo); }
public override void SceneMouseMove(Vector2 mousePos) { float minDstToSegment = segmentSelectDistanceThreshold; int newSelectedSegmentIndex = -1; for (int i = 0; i < this.NumSegments; i++) { Vector2[] segPoints = GetPointsInSegment(i); float dst = HandleUtility.DistancePointBezier(mousePos, segPoints[0], segPoints[3], segPoints[1], segPoints[2]); if (dst < minDstToSegment) { minDstToSegment = dst; newSelectedSegmentIndex = i; } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; HandleUtility.Repaint(); } }
private void HandleConnectionSegmentDeletion(int branchIndex) { Event e = Event.current; if (e.type != EventType.MouseMove) { return; } float selectionThreshHold = 5f; int newSelectedIndex = -1; for (int i = 0; i < _SplineCreator.ConnectionSegmentCount; i++) { ConnectionSegment segment = _SplineCreator.GetConnectionSegment(i); float distance = HandleUtility.DistancePointBezier( e.mousePosition, HandleUtility.WorldToGUIPoint(segment[0]), HandleUtility.WorldToGUIPoint(segment[3]), HandleUtility.WorldToGUIPoint(segment[1]), HandleUtility.WorldToGUIPoint(segment[2])); if (distance < selectionThreshHold) { selectionThreshHold = distance; newSelectedIndex = i; } if (newSelectedIndex == _HoveredConnectionSegmentIndex) { continue; } _HoveredConnectionSegmentIndex = newSelectedIndex; HandleUtility.Repaint(); } }
void Input() { Event guiEvent = Event.current; Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin; if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift) //if shift + left click is pressed { if (selectedSegmentIndex != -1) { Undo.RecordObject(creator, "Split segment"); //signifies to record the next change in the undo stack so you can ctrl+z it Path.SplitSegment(mousePos, selectedSegmentIndex); //adds new point } else if (!Path.IsClosed) { Undo.RecordObject(creator, "add segment"); //signifies to record the next change in the undo stack so you can ctrl+z it Path.AddSegment(mousePos); //adds new point } } if (guiEvent.type == EventType.MouseDown && guiEvent.button == 1) { float minDstToAnchor = creator.anchorDiameter * .5f; int closestAnchorIndex = -1; for (int i = 0; i < Path.NumPoints; i += 3) { float dst = Vector2.Distance(mousePos, Path[i]); if (dst < minDstToAnchor) { minDstToAnchor = dst; closestAnchorIndex = i; } } if (closestAnchorIndex != -1) { Undo.RecordObject(creator, "Delete segment"); Path.DeleteSegment(closestAnchorIndex); } } if (guiEvent.type == EventType.MouseMove) { float minDstToSegment = segmentSelectDistanceThreshold; int newSelectedSegmentIndex = -1; for (int i = 0; i < Path.NumSegments; i++) { Vector2[] points = Path.GetPointsInSegment(i); float dst = HandleUtility.DistancePointBezier(mousePos, points[0], points[3], points[1], points[2]); if (dst < minDstToSegment) { minDstToSegment = dst; newSelectedSegmentIndex = i; } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; HandleUtility.Repaint(); } } }
void Input() { if (guiEvent.type == EventType.MouseDown && guiEvent.isMouse) { if (guiEvent.button == 0 && guiEvent.shift && !guiEvent.control) { //DONT DO ANYTHING IF NOT CURRENT HOVERED PATH if (selectedSegmentIndex != -1) { if (hoveredPathIndex != currentPathIndex) { } else { Undo.RecordObject(creator, "Split segment"); Vector3[] points = Path[currentPathIndex].GetPointsInSegment(selectedSegmentIndex); Vector3 nearestPointToCurve = ApproximateNearestPointBezierMousePos(points[0], points[3], points[1], points[2]); Path[currentPathIndex].SplitSegment(nearestPointToCurve, selectedSegmentIndex); creator.SetVertPath(Path[currentPathIndex].CalculateEvenlySpacedPointsAndNormals(VertOptions.VertSpacing, VertOptions.Resolution), currentPathIndex); } } else if (!Path[currentPathIndex].IsClosed) { Undo.RecordObject(creator, "Add segment"); Ray mouseRay = Camera.current.ScreenPointToRay(screenSpaceMousePos); RaycastHit hit; Vector3 segmentPos = mouseRay.origin + mouseRay.direction * 5f; if (Physics.Raycast(mouseRay.origin, mouseRay.direction, out hit, 30f)) { segmentPos = hit.point; } Path[currentPathIndex].AddSegment(segmentPos); creator.SetVertPath(Path[currentPathIndex].CalculateEvenlySpacedPointsAndNormals(VertOptions.VertSpacing, VertOptions.Resolution), currentPathIndex); //Path.CalculateEvenlySpacedPoints(creator.VertSpacing); } } else if (guiEvent.button == 0 && guiEvent.control && guiEvent.shift) { if (hoveredPathIndex != currentPathIndex) { } else if (selectedSegmentIndex != -1) { Undo.RecordObject(creator, "Add New PathSplit On Currently Selected"); Vector3[] points = Path[currentPathIndex].GetPointsInSegment(selectedSegmentIndex); Vector3 nearestPointToCurve = ApproximateNearestPointBezierMousePos(points[0], points[3], points[1], points[2]); creator.AddNewPathSplit(currentPathIndex, nearestPointToCurve); currentPathIndex = Path.Count - 1; creator.SetVertPath(Path[currentPathIndex].CalculateEvenlySpacedPointsAndNormals(VertOptions.VertSpacing, VertOptions.Resolution), currentPathIndex); } } else if (guiEvent.button == 0) { Undo.RecordObject(creator, "Select Path"); currentPathIndex = (hoveredPathIndex == -1) ? currentPathIndex : hoveredPathIndex; } } else if (guiEvent.isKey && guiEvent.type == EventType.KeyDown) { if (guiEvent.character == 'p' || guiEvent.character == 'P') { handleMode = AnchorModes.POSITION; } if (guiEvent.character == 'r' || guiEvent.character == 'R') { handleMode = AnchorModes.ROTATION; } } else if (guiEvent.type == EventType.MouseMove) { float minDstToSegment = segmentSelectDistanceThreshold; int newSelectedSegmentIndex = -1; int newHoveredPathIndex = -1; for (int i = 0; i < Path.Count; i++) { for (int j = 0; j < Path[i].NumSegments; j++) { Vector3[] points = Path[i].GetPointsInSegment(j); Vector2[] screenSpacePoints = new Vector2[points.Length]; float minX = 0, maxX = 0, minY = 0, maxY = 0; for (int k = 0; k < points.Length; k++) { screenSpacePoints[k] = Camera.current.WorldToScreenPoint(points[k]); if (k == 0) { minX = screenSpacePoints[k].x; maxX = screenSpacePoints[k].x; minY = screenSpacePoints[k].y; maxY = screenSpacePoints[k].y; } else { if (screenSpacePoints[k].x < minX) { minX = screenSpacePoints[k].x; } else if (screenSpacePoints[k].x > maxX) { maxX = screenSpacePoints[k].x; } if (screenSpacePoints[k].y < minY) { minY = screenSpacePoints[k].y; } else if (screenSpacePoints[k].y > maxY) { maxY = screenSpacePoints[k].y; } } } if (screenSpaceMousePos.x > minX && screenSpaceMousePos.x < maxX && screenSpaceMousePos.y > minY && screenSpaceMousePos.y < maxY) { Vector3 nearestPointToCurve = ApproximateNearestPointBezierMousePos(points[0], points[3], points[1], points[2]); float dst = HandleUtility.DistancePointBezier(nearestPointToCurve, points[0], points[3], points[1], points[2]); if (dst < minDstToSegment) { minDstToSegment = dst; newSelectedSegmentIndex = j; newHoveredPathIndex = i; } } } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; hoveredPathIndex = newHoveredPathIndex; HandleUtility.Repaint(); } } }
internal static bool DrawEdge(Vector3 start, Vector3 startDirection, Vector3 end, Vector3 endDirection, Color startColor, Color endColor, Color startColorHighlighted, Color endColorHighlighted, float thickness = 3, Action onContextClick = null, bool highlightAndContextClick = true, float minDistanceFromStartEnd = 0) { int segments = 40; float dirFactor = Mathf.Clamp((end - start).magnitude, 10f, 120); float correctionAngle = 22.5F; if (start.x > end.x) { if (start.y < end.y) { if (Mathf.Approximately(startDirection.y, 0)) { startDirection = (Quaternion.AngleAxis(-correctionAngle, new Vector3(0, 0, 1)) * startDirection) * 3; } if (Mathf.Approximately(endDirection.y, 0)) { endDirection = (Quaternion.AngleAxis(-correctionAngle, new Vector3(0, 0, 1)) * endDirection) * 3; } } else { if (Mathf.Approximately(startDirection.y, 0)) { startDirection = (Quaternion.AngleAxis(correctionAngle, new Vector3(0, 0, 1)) * startDirection) * 3; } if (Mathf.Approximately(endDirection.y, 0)) { endDirection = (Quaternion.AngleAxis(correctionAngle, new Vector3(0, 0, 1)) * endDirection) * 3; } } } Vector2 startTan = start + new Vector3(startDirection.x, -startDirection.y) * dirFactor; Vector2 endTan = end + new Vector3(endDirection.x, -endDirection.y) * dirFactor; Vector3[] points = Handles.MakeBezierPoints(start, end, startTan, endTan, segments); bool selectLine = HandleUtility.DistancePointBezier(Event.current.mousePosition, start, end, startTan, endTan) < thickness * 2 && highlightAndContextClick; Color oldColor = Handles.color; Handles.BeginGUI(); for (int i = 1; i < points.Length; i++) { float t = (i * 1F) / points.Length; float t1 = Math.Clamp01(t, 0, 0.3F); float t2 = Math.Clamp01(t, 0.7F, 1F); Color colorStart = selectLine ? startColorHighlighted : Color.Lerp(startColorHighlighted, startColor, t1); Color colorEnd = selectLine ? endColorHighlighted : Color.Lerp(endColor, endColorHighlighted, t2); Color color = Color.Lerp(colorStart, colorEnd, t); Handles.color = color; Handles.DrawAAPolyLine(thickness, points[i - 1], points[i]); } Handles.EndGUI(); Handles.color = oldColor; if (selectLine && Event.current.type == EventType.MouseDown && Event.current.button == 1) { // use sqr distance for better performance. float sqrDistanceFromStart = (Event.current.mousePosition - (Vector2)start).sqrMagnitude; float sqrDistanceFromEnd = (Event.current.mousePosition - (Vector2)end).sqrMagnitude; if (sqrDistanceFromStart > minDistanceFromStartEnd * minDistanceFromStartEnd && sqrDistanceFromEnd > minDistanceFromStartEnd * minDistanceFromStartEnd) { if (onContextClick != null) { onContextClick(); Event.current.Use(); return(true); } } } return(selectLine); }
public bool IsPositionCloseToLine(Vector2 positionInWindow) { return(HandleUtility.DistancePointBezier(positionInWindow, startPos, endPos, startTangent, endTangent) < 10f); }
private void Input() { Event guiEvent = Event.current; // Get the mouse pos in World space using guiEvent.mousePosition; Vector3 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin; if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift) { if (selectedSegmentIndex != -1) { Undo.RecordObject(creator, "Split Segment"); path.SplitSegment(mousePos, selectedSegmentIndex); } else if (!path.Closed) { Undo.RecordObject(creator, "Add segment"); path.AddSegment(mousePos); } } if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.control) { Debug.Log("Deleting Segment"); float minDstToAnchor = 1f; int closestAnchor = -1; for (int i = 0; i < path.NumPoints; i += 3) { Vector3 screenPoint = Handles.matrix.MultiplyPoint(path[i]); float dst = Vector3.Distance(screenPoint, mousePos); Debug.Log(dst); Debug.Log("\n"); if (dst < minDstToAnchor) { minDstToAnchor = dst; closestAnchor = i; } } if (closestAnchor != -1) { Undo.RecordObject(creator, "Deleted segment"); path.RemoveSegment(closestAnchor); } } if (guiEvent.type == EventType.MouseMove) { float minDstToSegment = segmentSelectDistanceTreshold; int newSelectedSegment = -1; for (int i = 0; i < path.Segments; i++) { Vector3[] points = path.GetPointsSegment(i); float dst = HandleUtility.DistancePointBezier(mousePos, points[0], points[3], points[1], points[2]); if (dst < minDstToSegment) { minDstToSegment = dst; newSelectedSegment = i; } } if (newSelectedSegment != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegment; HandleUtility.Repaint(); } } }
void Input() { guiEvent = Event.current; Vector3 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin; screenSpaceMousePos = guiEvent.mousePosition; screenSpaceMousePos.y = Camera.current.pixelRect.height - screenSpaceMousePos.y; //if(guiEvent.type == EventType.Layout) //{ if (guiEvent.button == 0 && guiEvent.type == EventType.MouseDown) { selectedAnchor = HandleUtility.nearestControl; Vector2 anchorScreenSpace = Camera.current.WorldToScreenPoint(Path[selectedAnchor]); if ((anchorScreenSpace - screenSpaceMousePos).sqrMagnitude > 20) { //selectedAnchor = -1; } } //} if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift) { if (selectedSegmentIndex != -1) { Undo.RecordObject(creator, "Split segment"); Path.SplitSegment(mousePos, selectedSegmentIndex); } else if (!Path.IsClosed) { Undo.RecordObject(creator, "Add segment"); Ray mouseRay = Camera.current.ScreenPointToRay(screenSpaceMousePos); RaycastHit hit; Vector3 segmentPos = mouseRay.origin + mouseRay.direction * 5f; if (Physics.Raycast(mouseRay.origin, mouseRay.direction, out hit, 15f)) { segmentPos = hit.point; } Path.AddSegment(segmentPos); //Path.CalculateEvenlySpacedPoints(creator.VertSpacing); } } if (guiEvent.type == EventType.MouseDown && guiEvent.button == 1) { float minDstToAnchor = creator.anchorDiameter * .5f; int closestAnchorIndex = -1; for (int i = 0; i < Path.NumPoints; i += 3) { float dst = Vector2.Distance(mousePos, Path[i]); if (dst < minDstToAnchor) { minDstToAnchor = dst; closestAnchorIndex = i; } } if (closestAnchorIndex != -1) { Undo.RecordObject(creator, "Delete Segment"); Path.DeleteSegment(closestAnchorIndex); creator.navPath = Path.CalculateEvenlySpacedPointsAndNormals(creator.VertSpacing, creator.Resolution); } } if (guiEvent.type == EventType.MouseMove) { float minDstToSegment = segmentSelectDistanceThreshold; int newSelectedSegmentIndex = -1; for (int i = 0; i < Path.NumSegments; i++) { Vector3[] points = Path.GetPointsInSegment(i); float dst = HandleUtility.DistancePointBezier(mousePos, points[0], points[3], points[1], points[2]); if (dst < minDstToSegment) { minDstToSegment = dst; newSelectedSegmentIndex = i; } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; HandleUtility.Repaint(); } } HandleUtility.AddDefaultControl(0); }
void Input() { Event guiEvent = Event.current; Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin; if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift) { if (selectedSegmentIndex != -1) { Undo.RecordObject(creator, "Split segment"); Path.SplitSegment(mousePos, selectedSegmentIndex); } else if (!Path.IsClosed) { Undo.RecordObject(creator, "Add segment"); Path.AddSegment(mousePos); } } if (guiEvent.type == EventType.MouseDown && guiEvent.button == 1) { float minDistanceToAnchor = creator.anchorDiameter * .5f; int closestAnchorIndex = -1; for (int i = 0; i < Path.NumPoints; i += 3) { float distance = Vector2.Distance(mousePos, Path[i]); if (distance < minDistanceToAnchor) { minDistanceToAnchor = distance; closestAnchorIndex = i; } } if (closestAnchorIndex != -1) { Undo.RecordObject(creator, "Delete segment"); Path.DeleteSegment(closestAnchorIndex); } } if (guiEvent.type == EventType.MouseMove) { float minDistanceToSegment = segmentSelectDistanceThreshold; int newSelectedSegmentIndex = -1; for (int i = 0; i < Path.NumSegments; ++i) { Vector2[] points = Path.GetPointsInSegment(i); float distance = HandleUtility.DistancePointBezier(mousePos, points[0], points[3], points[1], points[2]); if (distance < minDistanceToSegment) { minDistanceToSegment = distance; newSelectedSegmentIndex = i; } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; HandleUtility.Repaint(); } } HandleUtility.AddDefaultControl(0); }
protected override float GetDistanceOfPointToSegment(int segmentIndex, Vector2 point) { pathBehaviour.GetSegment(segmentIndex, out Vector2 anchP1, out Vector2 contP1, out Vector2 contP2, out Vector2 anchP2); return(HandleUtility.DistancePointBezier(point, anchP1, anchP2, contP1, contP2)); }
void Input() { Event guiEvent = Event.current; Vector2 mousePos = guiEvent.mousePosition; if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift) { if (selectedSegmentIndex != -1) { Undo.RecordObject(creator, "Split Segment"); Vector3 pos = GetCloserPointInSegment(mousePos, selectedSegmentIndex); Path.SplitSegment(WorldToLocal(pos), selectedSegmentIndex); } /* else if(!Path.IsClosed){ * Undo.RecordObject(creator, "Add Segment"); * Path.AddSegment(mousePos); * }*/ } if (guiEvent.type == EventType.MouseDown && guiEvent.button == 1) { float minDst = float.MaxValue; int closestAnchorIndex = -1; for (int i = 0; i < Path.NumPoints; i += 3) { float dstToAnchor = (creator.anchorDiameter * .5f) / HandleUtility.GetHandleSize(LocalToWorld(Path[i])) * 100; float dst = Vector2.Distance(mousePos, HandleUtility.WorldToGUIPoint(LocalToWorld(Path[i]))); if (dst < dstToAnchor && dst < minDst) { closestAnchorIndex = i; minDst = dst; } } if (closestAnchorIndex != -1) { Undo.RecordObject(creator, "Delete Segment"); Path.DeleteSegment(closestAnchorIndex); } } if (guiEvent.type == EventType.MouseMove) { float minDstToSegment = segmentSelectDistanceThreshold; int newSelectedSegmentIndex = -1; for (int i = 0; i < Path.NumSegments; i++) { Vector3[] points = LocalToWorld(Path.GetPointsInSegment(i)); float dst = HandleUtility.DistancePointBezier(mousePos, HandleUtility.WorldToGUIPoint(points[0]), HandleUtility.WorldToGUIPoint(points[3]), HandleUtility.WorldToGUIPoint(points[1]), HandleUtility.WorldToGUIPoint(points[2])); if (dst < minDstToSegment) { minDstToSegment = dst; newSelectedSegmentIndex = i; } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; HandleUtility.Repaint(); } } HandleUtility.AddDefaultControl(0); }
void DrawNodeCurve(PWNodeLink link) { if (link == null) { Debug.LogError("[PWGraphEditor] attempt to draw null link !"); return; } if (link.fromAnchor == null || link.toAnchor == null) { Debug.LogError("[PWGraphEditor] null anchors in a the link: " + link); return; } Event e = Event.current; link.controlId = GUIUtility.GetControlID(FocusType.Passive); Rect start = link.fromAnchor.rectInGraph; Rect end = link.toAnchor.rectInGraph; Vector3 startPos = new Vector3(start.x + start.width, start.y + start.height / 2, 0); Vector3 endPos = new Vector3(end.x, end.y + end.height / 2, 0); Vector3 startDir = Vector3.right; Vector3 endDir = Vector3.left; float tanPower = (startPos - endPos).magnitude / 2; tanPower = Mathf.Clamp(tanPower, 0, 100); Vector3 startTan = startPos + startDir * tanPower; Vector3 endTan = endPos + endDir * tanPower; if (e.type == EventType.MouseDown && !editorEvents.isMouseOverAnchor) { if (HandleUtility.nearestControl == link.controlId && e.button == 0) { GUIUtility.hotControl = link.controlId; //unselect all others links: UnselectAllLinks(); UnselectAllNodes(); link.selected = true; link.highlight = PWLinkHighlight.Selected; e.Use(); } } //mouse over bezier curve: if (HandleUtility.nearestControl == link.controlId) { editorEvents.mouseOverLink = link; editorEvents.isMouseOverLinkFrame = true; } if (e.type == EventType.Repaint) { DrawSelectedBezier(startPos, endPos, startTan, endTan, link.colorSchemeName, 4, link.highlight); if (link != null && link.highlight == PWLinkHighlight.DeleteAndReset) { link.highlight = PWLinkHighlight.None; } if (link != null && !link.selected && link.highlight == PWLinkHighlight.Selected) { link.highlight = PWLinkHighlight.None; } } else if (e.type == EventType.Layout) { float bezierDistance = HandleUtility.DistancePointBezier(e.mousePosition, startPos, endPos, startTan, endTan); HandleUtility.AddControl(link.controlId, bezierDistance); } }
private void Input() { Event current = Event.current; Ray screenRay = HandleUtility.GUIPointToWorldRay(current.mousePosition); Vector3 mouse = screenRay.direction * ((creater.transform.position.y - screenRay.origin.y) / screenRay.direction.y) + screenRay.origin; if (current.type == EventType.MouseDown && current.button == 0 && current.shift) { if (selectedSegmentIndex != -1) { Undo.RecordObject(creater, $"Split Segment {selectedSegmentIndex}"); Path.SplitSegment(mouse, selectedSegmentIndex); } else if (!Path.IsClosed) { Undo.RecordObject(creater, "Add segment"); Debug.DrawRay(screenRay.origin, mouse - screenRay.origin, Color.black, 5f); Path.AddSegment(mouse); } } if (current.type == EventType.MouseDown && current.button == 1 && current.shift) { float minDistToAnchor = creater.anchorDiameter * 0.5f; int closestAnchorIndex = -1; for (int i = 0; i < Path.NumberOfPoints; i += 3) { float distance = Vector3.Distance(mouse, Path[i]); if (distance < minDistToAnchor) { minDistToAnchor = distance; closestAnchorIndex = i; } } if (closestAnchorIndex != -1) { Debug.Log("Deletion"); Undo.RecordObject(creater, "Delete Segment"); Path.RemoveSegment(closestAnchorIndex); } } if (current.type == EventType.MouseMove) { float minDistanceToSegment = segmentSelectDistanceTreshold; int newSelectedSegmentIndex = -1; float distance; for (int i = 0; i < Path.NumberOfSegments; i++) { Vector3[] points = Path.GetPointsInSegment(i, false); distance = HandleUtility.DistancePointBezier(mouse, points[0], points[3], points[1], points[2]); if (distance < minDistanceToSegment) { minDistanceToSegment = distance; newSelectedSegmentIndex = i; } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; HandleUtility.Repaint(); } } HandleUtility.AddDefaultControl(0); // prevent miss selection }
void Input() { Event guiEvent = Event.current; Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin; if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift) { if (selectedSegmentIndex != -1) { Undo.RecordObject(creator, "Split Segment"); CurvePath.SplitSegment(mousePos, selectedSegmentIndex); } else if (!CurvePath.IsClosed) { Undo.RecordObject(creator, "Add Segment"); CurvePath.AddSegment(mousePos); } } if (guiEvent.type == EventType.MouseDown && guiEvent.button == 1) { //Debug.Log("Right Click!"); float minDstToAnchor = creator.anchorDiameter * 0.5f; int closestAnchorIndex = -1; for (int i = 0; i < CurvePath.NumPoints; i += 3) { float dst = Vector2.Distance(mousePos, CurvePath[i]); if (dst < minDstToAnchor) { minDstToAnchor = dst; closestAnchorIndex = i; } } //Debug.Log("Closest Anchor Index is " + closestAnchorIndex.ToString()); if (closestAnchorIndex != -1) { Undo.RecordObject(creator, "Delete Segment"); CurvePath.DeleteSegment(closestAnchorIndex); } } if (guiEvent.type == EventType.MouseMove) { float minDistToSegment = segmentSelectionDistanceThreshold; int newSelectedSegmentIndex = -1; for (int i = 0; i < CurvePath.NumSegments; i++) { Vector2[] points = CurvePath.GetPointsInSegment(i); float dst = HandleUtility.DistancePointBezier(mousePos, points[0], points[3], points[1], points[2]); if (dst < minDistToSegment) { minDistToSegment = dst; newSelectedSegmentIndex = i; } } if (newSelectedSegmentIndex != selectedSegmentIndex) { selectedSegmentIndex = newSelectedSegmentIndex; HandleUtility.Repaint(); } } HandleUtility.AddDefaultControl(0); }