/// <summary> /// Adds a new control point to the scene view and its drag point data /// to the game object. /// </summary> public void AddDragPointOnTraveller() { if (CurveTravellerControlPointIdx < 0 || CurveTravellerControlPointIdx >= ControlPoints.Count) { return; } var dragPoint = new DragPointData(DragPointEditable.GetDragPoints()[CurveTravellerControlPointIdx]) { IsLocked = false }; var newIdx = CurveTravellerControlPointIdx + 1; float ratio = (float)newIdx / (DragPointEditable.GetDragPoints().Length - 1); var dragPointPosition = Transform.worldToLocalMatrix.MultiplyPoint(CurveTravellerPosition); dragPointPosition -= DragPointEditable.GetEditableOffset(); dragPointPosition -= DragPointEditable.GetDragPointOffset(ratio); dragPoint.Vertex = dragPointPosition.ToVertex3D(); var dragPoints = DragPointEditable.GetDragPoints().ToList(); dragPoints.Insert(newIdx, dragPoint); DragPointEditable.SetDragPoints(dragPoints.ToArray()); ControlPoints.Insert(newIdx, new ControlPoint( DragPointEditable.GetDragPoints()[newIdx], GUIUtility.GetControlID(FocusType.Passive), newIdx, ratio )); RebuildControlPoints(); }
private void InitSceneGui() { SelectedControlPoints.Clear(); _flipAxis = Vector3.zero; //Setup Screen positions & controlID for control points (in case of modification of drag points coordinates outside) foreach (var controlPoint in ControlPoints) { controlPoint.WorldPos = controlPoint.DragPoint.Vertex.ToUnityVector3(); controlPoint.WorldPos += DragPointEditable.GetEditableOffset(); controlPoint.WorldPos += DragPointEditable.GetDragPointOffset(controlPoint.IndexRatio); controlPoint.WorldPos = Transform.localToWorldMatrix.MultiplyPoint(controlPoint.WorldPos); _flipAxis += controlPoint.WorldPos; controlPoint.ScrPos = Handles.matrix.MultiplyPoint(controlPoint.WorldPos); if (controlPoint.IsSelected) { if (!controlPoint.DragPoint.IsLocked) { SelectedControlPoints.Add(controlPoint); } } HandleUtility.AddControl(controlPoint.ControlId, HandleUtility.DistanceToCircle(controlPoint.ScrPos, HandleUtility.GetHandleSize(controlPoint.WorldPos) * ControlPoint.ScreenRadius * _sceneViewHandler.ControlPointsSizeRatio)); } if (ControlPoints.Count > 0) { _flipAxis /= ControlPoints.Count; } //Setup PositionHandle if some control points are selected if (SelectedControlPoints.Count > 0) { _positionHandlePosition = Vector3.zero; foreach (var sCp in SelectedControlPoints) { _positionHandlePosition += sCp.WorldPos; } _positionHandlePosition /= SelectedControlPoints.Count; } if (CurveTravellerVisible) { HandleUtility.AddControl(CurveTravellerControlId, HandleUtility.DistanceToCircle(Handles.matrix.MultiplyPoint(CurveTravellerPosition), HandleUtility.GetHandleSize(CurveTravellerPosition) * ControlPoint.ScreenRadius * _sceneViewHandler.CurveTravellerSizeRatio * 0.5f)); } }
/// <summary> /// References drag point data to control points. /// </summary> /// <returns>True if control points were re-built, false otherwise.</returns> public bool RemapControlPoints() { // if count differs, rebuild if (ControlPoints.Count != DragPointEditable.GetDragPoints().Length) { RebuildControlPoints(); return(true); } for (var i = 0; i < DragPointEditable.GetDragPoints().Length; ++i) { ControlPoints[i].DragPoint = DragPointEditable.GetDragPoints()[i]; } return(false); }
/// <summary> /// Re-creates the control points of the scene view and references their /// drag point data. /// </summary> private void RebuildControlPoints() { ControlPoints.Clear(); for (var i = 0; i < DragPointEditable.GetDragPoints().Length; ++i) { var cp = new ControlPoint( DragPointEditable.GetDragPoints()[i], GUIUtility.GetControlID(FocusType.Passive), i, DragPointEditable.GetDragPoints().Length >= 2 ? (float)i / (DragPointEditable.GetDragPoints().Length - 1) : 0.0f ); ControlPoints.Add(cp); } CurveTravellerControlId = GUIUtility.GetControlID(FocusType.Passive); }
/// <summary> /// Removes a control point and its data. /// </summary> /// <param name="controlId"></param> public void RemoveDragPoint(int controlId) { var idx = ControlPoints.FindIndex(controlPoint => controlPoint.ControlId == controlId); if (idx >= 0) { var removalOk = !ControlPoints[idx].DragPoint.IsLocked; if (!removalOk) { removalOk = EditorUtility.DisplayDialog("Locked DragPoint Removal", "This drag point is locked!\nAre you really sure you want to remove it?", "Yes", "No"); } if (removalOk) { var dragPoints = DragPointEditable.GetDragPoints().ToList(); dragPoints.RemoveAt(idx); DragPointEditable.SetDragPoints(dragPoints.ToArray()); ControlPoints.RemoveAt(idx); RebuildControlPoints(); } } }
/// <summary> /// Flips all drag points around the given axis. /// </summary> /// <param name="flipAxis">Axis to flip</param> public void FlipDragPoints(FlipAxis flipAxis) { var axis = flipAxis == FlipAxis.X ? _flipAxis.x : flipAxis == FlipAxis.Y ? _flipAxis.y : _flipAxis.z; var offset = DragPointEditable.GetEditableOffset(); var wlMat = Transform.worldToLocalMatrix; foreach (var controlPoint in ControlPoints) { var coord = flipAxis == FlipAxis.X ? controlPoint.WorldPos.x : flipAxis == FlipAxis.Y ? controlPoint.WorldPos.y : controlPoint.WorldPos.z; coord = axis + (axis - coord); switch (flipAxis) { case FlipAxis.X: controlPoint.WorldPos.x = coord; break; case FlipAxis.Y: controlPoint.WorldPos.y = coord; break; case FlipAxis.Z: controlPoint.WorldPos.z = coord; break; default: throw new ArgumentOutOfRangeException(nameof(flipAxis), flipAxis, null); } controlPoint.UpdateDragPoint(DragPointEditable, Transform); } }
/// <summary> /// Takes care of the rendering-related stuff. /// </summary> /// /// <remarks> /// This is called by the drag point inspector. /// </remarks> /// /// <param name="evt">Event from the inspector</param> /// <param name="onChange"></param> public void OnSceneGUI(Event evt, OnDragPointPositionChange onChange = null) { switch (evt.type) { case EventType.Layout: InitSceneGui(); break; case EventType.MouseDown: OnMouseDown(); break; case EventType.Repaint: CurveTravellerVisible = false; break; } // Handle the common position handler for all selected control points if (SelectedControlPoints.Count > 0) { var parentRot = Quaternion.identity; if (Transform.parent != null) { parentRot = Transform.parent.transform.rotation; } EditorGUI.BeginChangeCheck(); var newHandlePos = HandlesUtils.HandlePosition(_positionHandlePosition, DragPointEditable.GetHandleType(), parentRot); if (EditorGUI.EndChangeCheck()) { onChange?.Invoke(newHandlePos); var deltaPosition = newHandlePos - _positionHandlePosition; foreach (var controlPoint in SelectedControlPoints) { controlPoint.WorldPos += deltaPosition; controlPoint.UpdateDragPoint(DragPointEditable, Transform); } } } //Render the curve & drag points _sceneViewHandler.OnSceneGUI(); }