/// <summary> /// Clear out cache, and reset any Editor states. /// </summary> private void DisableUI() { // Make sure all curves being edited will be ready to be cooked, since we're done editing. foreach (Object targetObject in targets) { HEU_Curve curve = targetObject as HEU_Curve; if (curve != null && curve.EditState == HEU_Curve.CurveEditState.EDITING) { SetCurveState(HEU_Curve.CurveEditState.REQUIRES_GENERATION, GetOrCreateSerializedCurve(curve.CurveName)); } } DeselectAllPoints(); ShowTools(); _curves.Clear(); _serializedCurvesCache.Clear(); _latestPointAddedCurve = null; _latestPointsAdded.Clear(); _closestCurveName = null; _closestPointIndex = -1; _dragMouseDown = false; _cleanMouseDown = false; }
private void ProcessGeoCurve(HEU_SessionBase session) { HEU_HoudiniAsset parentAsset = ParentAsset; string curveName = GenerateGeoCurveName(); curveName = HEU_EditorUtility.GetUniqueNameForSibling(ParentAsset.RootGameObject.transform, curveName); if (_geoCurve == null) { // New geo curve _geoCurve = HEU_Curve.CreateSetupCurve(parentAsset, Editable, curveName, GeoID, true); } else { _geoCurve.UploadParameterPreset(session, GeoID, parentAsset); } SetupGeoCurveGameObjectAndTransform(_geoCurve); _geoCurve.SetCurveName(curveName); _geoCurve.SyncFromParameters(session, parentAsset); // If geo node has part, generate the mesh using position attribute. // Note that without any parts we can't generate a mesh so we pass in an invalid part ID // to at least set default values. HAPI_PartId partID = _geoInfo.partCount > 0 ? 0 : HEU_Defines.HEU_INVALID_NODE_ID; _geoCurve.UpdateCurve(session, partID); _geoCurve.GenerateMesh(_geoCurve._targetGameObject); bool bIsVisible = IsVisible() && HEU_PluginSettings.Curves_ShowInSceneView; _geoCurve.SetCurveGeometryVisibility(bIsVisible); }
private void AddPoint(string curveName, int pointIndex, Vector3 newPointPosition, List<SerializedObject> updatedCurves) { SerializedObject serializedCurve = GetOrCreateSerializedCurve(curveName); SerializedProperty curvePointsProperty = serializedCurve.FindProperty("_points"); if (pointIndex >= 0 && pointIndex <= curvePointsProperty.arraySize) { HEU_Curve curve = GetCurve(curveName); newPointPosition = curve.GetInvertedTransformedPosition(newPointPosition); curvePointsProperty.InsertArrayElementAtIndex(pointIndex); curvePointsProperty.GetArrayElementAtIndex(pointIndex).vector3Value = newPointPosition; SerializedProperty editStateProperty = serializedCurve.FindProperty("_editState"); if (editStateProperty.intValue != (int)HEU_Curve.CurveEditState.EDITING) { SetCurveState(HEU_Curve.CurveEditState.REQUIRES_GENERATION, serializedCurve); } _latestPointAddedCurve = curveName; _latestPointsAdded.Push(pointIndex); AddChangedSerializedObject(serializedCurve, updatedCurves); GUI.changed = true; } }
/// <summary> /// Update given curve's parameters with values from its points array. /// During editing, the points should have been updated, which now need to be transferred to coords parameters. /// </summary> /// <param name="serializedCurve"></param> private void SyncCurvePointsToParameters(SerializedObject serializedCurve) { // Get the parameters, find the coords parameter data, then set the points array as string SerializedProperty parametersProperty = serializedCurve.FindProperty("_parameters"); // Since Unity doesn't automatically serialize referenced objects, so we need to create serialized object, and apply changes SerializedObject parameterObject = new SerializedObject(parametersProperty.objectReferenceValue); SerializedProperty parameterList = parameterObject.FindProperty("_parameterList"); for (int i = 0; i < parameterList.arraySize; ++i) { SerializedProperty parameterDataProperty = parameterList.GetArrayElementAtIndex(i); SerializedProperty nameProperty = parameterDataProperty.FindPropertyRelative("_name"); if (nameProperty.stringValue.Equals(HEU_Defines.CURVE_COORDS_PARAM)) { SerializedProperty stringsProperty = parameterDataProperty.FindPropertyRelative("_stringValues"); List<Vector3> points = new List<Vector3>(); SerializedProperty curvePointsProperty = serializedCurve.FindProperty("_points"); for (int j = 0; j < curvePointsProperty.arraySize; ++j) { points.Add(curvePointsProperty.GetArrayElementAtIndex(j).vector3Value); } stringsProperty.GetArrayElementAtIndex(0).stringValue = HEU_Curve.GetPointsString(points); break; } } parameterObject.ApplyModifiedProperties(); }
/// <summary> /// Destroy all generated data. /// </summary> public void DestroyAllData() { HEU_PartData.DestroyParts(_parts); if (_inputNode != null) { HEU_SessionBase session = null; if (ParentAsset != null) { ParentAsset.RemoveInputNode(_inputNode); session = ParentAsset.GetAssetSession(false); } _inputNode.DestroyAllData(session); HEU_GeneralUtility.DestroyImmediate(_inputNode); _inputNode = null; } if (_geoCurve != null) { if (ParentAsset != null) { ParentAsset.RemoveCurve(_geoCurve); } _geoCurve.DestroyAllData(); HEU_GeneralUtility.DestroyImmediate(_geoCurve); _geoCurve = null; } DestroyVolumeCache(); }
private void SelectAddPoint(HEU_Curve curve, int pointIndex) { if (!_selectedCurvePoints.ContainsKey(curve.CurveName)) { _selectedCurvePoints[curve.CurveName] = new List<int>(); } _selectedCurvePoints[curve.CurveName].Add(pointIndex); }
// LOGIC ------------------------------------------------------------------------------------------------------ public static HEU_Curve CreateSetupCurve(HEU_HoudiniAsset parentAsset, bool isEditable, string curveName, HAPI_NodeId geoID, bool bGeoCurve) { HEU_Curve newCurve = ScriptableObject.CreateInstance<HEU_Curve>(); newCurve._isEditable = isEditable; newCurve._curveName = curveName; newCurve._geoID = geoID; newCurve.SetEditState(CurveEditState.INVALID); newCurve._isGeoCurve = bGeoCurve; parentAsset.AddCurve(newCurve); return newCurve; }
private void DrawCurveUsingVertices(HEU_Curve curve, Color lineColor) { Vector3[] vertices = curve.GetVertices(); Color defaultColor = Handles.color; Handles.color = lineColor; Matrix4x4 defaultMatrix = Handles.matrix; Handles.matrix = curve._targetGameObject.transform.localToWorldMatrix; Handles.DrawAAPolyLine(_lineTexture, 10f, vertices); Handles.matrix = defaultMatrix; Handles.color = defaultColor; }
private void DrawCurveUsingPoints(HEU_Curve curve, Color lineColor) { List<Vector3> points = curve.GetAllPoints(); Color defaultColor = Handles.color; Handles.color = lineColor; Matrix4x4 defaultMatrix = Handles.matrix; Handles.matrix = curve._targetGameObject.transform.localToWorldMatrix; Handles.DrawAAPolyLine(_lineTexture, 10f, points.ToArray()); Handles.matrix = defaultMatrix; Handles.color = defaultColor; }
private void DrawPointCaps(HEU_Curve curve, Color capColor) { List<Vector3> points = curve.GetAllPoints(); Color defaultColor = Handles.color; Handles.color = capColor; for (int i = 0; i < points.Count; ++i) { Vector3 pointPos = curve.GetTransformedPosition(points[i]); HEU_EditorUI.DrawSphereCap(GUIUtility.GetControlID(FocusType.Passive), pointPos, Quaternion.identity, HEU_EditorUI.GetHandleSize(pointPos)); } Handles.color = defaultColor; }
/// <summary> /// Finds and returns existing serialized object of specified curve. /// Creates serialized object if not found. /// </summary> /// <param name="curveName">Name of curve to look for</param> /// <returns>Serialized curve object</returns> private SerializedObject GetOrCreateSerializedCurve(string curveName) { SerializedObject serializedCurve = null; if (!_serializedCurvesCache.TryGetValue(curveName, out serializedCurve)) { HEU_Curve curve = GetCurve(curveName); if (curve != null) { serializedCurve = new SerializedObject(curve); _serializedCurvesCache.Add(curveName, serializedCurve); } } return serializedCurve; }
public void FillData(HEU_InputCurveInfo curveInfo) { if (curveInfo == null) { return; } closed = curveInfo.closed; curveType = curveInfo.curveType; order = HEU_Curve.GetOrderForCurveType(curveInfo.order, curveInfo.curveType); reverse = curveInfo.reverse; inputMethod = curveInfo.inputMethod; breakpointParameterization = curveInfo.breakpointParameterization; }
public void GetCurves(List <HEU_Curve> curves, bool bEditableOnly) { if (_geoCurve != null && (!bEditableOnly || _geoCurve.IsEditable())) { curves.Add(_geoCurve); } foreach (HEU_PartData part in _parts) { HEU_Curve partCurve = part.GetCurve(bEditableOnly); if (partCurve != null) { curves.Add(partCurve); } } }
private void SetupGeoCurveGameObjectAndTransform(HEU_Curve curve) { if (curve._targetGameObject == null) { curve._targetGameObject = new GameObject(); } // For geo curve, the parent is the HDA_Data Transform curveTransform = curve._targetGameObject.transform; curveTransform.parent = ParentAsset.OwnerGameObject.transform; curve._targetGameObject.isStatic = curveTransform.parent.gameObject.isStatic; // Reset to origin curveTransform.localPosition = Vector3.zero; curveTransform.localRotation = Quaternion.identity; curveTransform.localScale = Vector3.one; }
private void SetupGeoCurveGameObjectAndTransform(HEU_Curve curve) { if (ParentAsset == null) { return; } if (curve.TargetGameObject == null) { curve.TargetGameObject = HEU_GeneralUtility.CreateNewGameObject(); } // For geo curve, the parent is the HDA_Data Transform curveTransform = curve.TargetGameObject.transform; curveTransform.parent = ParentAsset.OwnerGameObject.transform; HEU_GeneralUtility.CopyFlags(curveTransform.parent.gameObject, curve.TargetGameObject, true); // Reset to origin curveTransform.localPosition = Vector3.zero; curveTransform.localRotation = Quaternion.identity; curveTransform.localScale = Vector3.one; }
private void UpdateEditMode(HEU_HoudiniAsset asset, int controlID, EventType eventType, Vector3 mousePosition, List<SerializedObject> updatedCurves) { // In edit, we draw points as interactable buttons, allowing for selection/deselection. // We also draw drag handle for selected buttons. Event currentEvent = Event.current; // For multi-point selection, calculates bounds and centre point Bounds bounds = new Bounds(); int numSelectedPoints = 0; bool bInteractionOcurred = false; bool isDraggingPoints = false; bool wasDraggingPoints = false; // Draw the curve points EditModeDrawCurvePoints(currentEvent, eventType, ref numSelectedPoints, ref bounds, ref bInteractionOcurred); // Two types of dragging: dragging selected points, dragging selection box to select points if (numSelectedPoints > 0) { // Drag selected points Vector3 dragHandlePosition = bounds.center; // Let Unity do the transform handle magic Vector3 newPosition = Handles.PositionHandle(dragHandlePosition, Quaternion.identity); isDraggingPoints = (EditorGUIUtility.hotControl != 0); Vector3 deltaMove = newPosition - dragHandlePosition; if (deltaMove.magnitude > 0) { // User dragged point(s) // We update point value here, but defer parameter coords update until after we finished editing foreach (KeyValuePair<string, List<int>> curvePoints in _selectedCurvePoints) { List<int> selectedPoints = curvePoints.Value; if (selectedPoints.Count > 0) { SerializedObject serializedCurve = GetOrCreateSerializedCurve(curvePoints.Key); SerializedProperty curvePointsProperty = serializedCurve.FindProperty("_points"); foreach (int pointIndex in selectedPoints) { SerializedProperty pointProperty = curvePointsProperty.GetArrayElementAtIndex(pointIndex); Vector3 updatedPosition = pointProperty.vector3Value + deltaMove; HEU_Curve curve = serializedCurve.targetObject as HEU_Curve; if (curve != null) { // Localize the movement vector to the curve point's transform, // since deltaMove is based on the transformed curve point, // and we're adding to the local curve point. Vector3 localDeltaMove = curve.GetInvertedTransformedDirection(deltaMove); updatedPosition = pointProperty.vector3Value + localDeltaMove; } pointProperty.vector3Value = updatedPosition; } // Setting to editing mode to flag that cooking needs to be deferred SetCurveState(HEU_Curve.CurveEditState.EDITING, serializedCurve); AddChangedSerializedObject(serializedCurve, updatedCurves); } } bInteractionOcurred = true; } // After drag, process/cook each curve to update its state foreach (HEU_Curve curve in _curves) { SerializedObject serializedCurve = GetOrCreateSerializedCurve(curve.CurveName); SerializedProperty stateProperty = serializedCurve.FindProperty("_editState"); HEU_Curve.CurveEditState editState = (HEU_Curve.CurveEditState)stateProperty.intValue; // On mouse release, transition editing curve to generation state if (!isDraggingPoints) { if (editState == HEU_Curve.CurveEditState.EDITING) { // Flag to cook once user has stopped dragging SetCurveState(HEU_Curve.CurveEditState.REQUIRES_GENERATION, serializedCurve); AddChangedSerializedObject(serializedCurve, updatedCurves); wasDraggingPoints = true; } } // Draw uncooked curve to show user the intermediate curve if (editState == HEU_Curve.CurveEditState.EDITING || editState == HEU_Curve.CurveEditState.REQUIRES_GENERATION) { if (eventType == EventType.Repaint) { DrawCurveUsingPoints(curve, Color.red); } } } } // Drag to select points switch (eventType) { case EventType.MouseDown: { if (currentEvent.button == 0 && !_dragMouseDown && !isDraggingPoints && !wasDraggingPoints) { // This is to reduce the possibility of getting into drag selection mode right after // dragging a point. _cleanMouseDown = true; } break; } case EventType.MouseUp: { if (currentEvent.button == 0 && !bInteractionOcurred && !_dragMouseDown && !isDraggingPoints && !wasDraggingPoints) { if (_selectedCurvePoints.Count > 0 && !currentEvent.alt && !currentEvent.control) { DeselectAllPoints(); currentEvent.Use(); } } if (currentEvent.button == 0) { if (_dragMouseDown) { // Note that as user was dragging, the points were auto-selected, so we shouldn't // need to do anything here other than stop dragging. _dragMouseDown = false; currentEvent.Use(); } _cleanMouseDown = false; } break; } case EventType.MouseDrag: { if (!_dragMouseDown && !currentEvent.alt && !currentEvent.control && currentEvent.button == 0 && !isDraggingPoints && !wasDraggingPoints && _cleanMouseDown) { _dragMouseStart = mousePosition; _dragMouseDown = true; } if (_dragMouseDown) { currentEvent.Use(); } break; } case EventType.MouseMove: { // Use the mouse move event will force a repaint allowing for much more responsive UI currentEvent.Use(); break; } case EventType.KeyUp: { if (currentEvent.keyCode == KeyCode.Escape || currentEvent.keyCode == KeyCode.Return || currentEvent.keyCode == KeyCode.KeypadEnter) { SwitchToMode(HEU_Curve.Interaction.VIEW); currentEvent.Use(); } else if (!currentEvent.alt && currentEvent.keyCode == KeyCode.Space) { // Toggle modes SwitchToMode(HEU_Curve.Interaction.ADD); currentEvent.Use(); } break; } case EventType.KeyDown: { if (currentEvent.keyCode == KeyCode.Backspace || currentEvent.keyCode == KeyCode.Delete) { DeleteSelectedPoints(updatedCurves); currentEvent.Use(); } else if (currentEvent.keyCode == KeyCode.F1) { _showInfo = !_showInfo; } break; } case EventType.Layout: { // This disables deselection on asset while in Add mode HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); break; } case EventType.Repaint: { if (_dragMouseDown) { DrawSelectionBox(mousePosition, true); } break; } } }
private void UpdateAddMode(HEU_HoudiniAsset asset, int controlID, EventType eventType, Vector3 mousePosition, List<SerializedObject> updatedCurves) { Event currentEvent = Event.current; Color defaultHandleColor = Handles.color; switch (eventType) { case EventType.MouseDown: { if (!currentEvent.alt && currentEvent.button == 0 && _closestCurveName != null && _closestPointIndex >= 0) { AddPoint(_closestCurveName, _closestPointIndex, _newPointPosition, updatedCurves); _closestCurveName = null; currentEvent.Use(); } break; } case EventType.MouseUp: { break; } case EventType.MouseMove: { // Use the mouse move event will force a repaint allowing for much more responsive UI currentEvent.Use(); break; } case EventType.KeyUp: { if (currentEvent.keyCode == KeyCode.Space && !currentEvent.alt) { // Toggle modes SwitchToMode(HEU_Curve.Interaction.EDIT); } else if (currentEvent.keyCode == KeyCode.Escape || currentEvent.keyCode == KeyCode.Return || currentEvent.keyCode == KeyCode.KeypadEnter) { SwitchToMode(HEU_Curve.Interaction.VIEW); currentEvent.Use(); } break; } case EventType.KeyDown: { if (currentEvent.keyCode == KeyCode.Backspace || currentEvent.keyCode == KeyCode.Delete) { // Delete last added point if (_latestPointAddedCurve != null) { HEU_Curve latestAddCurve = GetCurve(_latestPointAddedCurve); if (latestAddCurve != null && _latestPointsAdded.Count > 0) { SelectSinglePoint(latestAddCurve, _latestPointsAdded.Pop()); DeleteSelectedPoints(updatedCurves); } } currentEvent.Use(); } else if (currentEvent.keyCode == KeyCode.A) { int mode = (int)_newPointMode + 1; if (mode > (int)CurveNewPointMode.END) { mode = (int)CurveNewPointMode.START; } _newPointMode = (CurveNewPointMode)mode; } else if (currentEvent.keyCode == KeyCode.F1) { _showInfo = !_showInfo; } break; } case EventType.Layout: { // This disables deselection on asset while in Add mode HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); break; } case EventType.Repaint: { bool bMouseInDrawArea = HEU_GeneralUtility.IsMouseWithinSceneView(_currentCamera, mousePosition) && !HEU_GeneralUtility.IsMouseOverRect(_currentCamera, mousePosition, ref _curveEditorUIRect) && (!_showInfoRepaint || !HEU_GeneralUtility.IsMouseOverRect(_currentCamera, mousePosition, ref _infoRect)); // Plane for default collider Plane collisionPlane = new Plane(Vector3.up, Vector3.zero); //Ray mouseRay = _currentCamera.ScreenPointToRay(mousePosition); //Vector3 planePosition = mouseRay.origin + mouseRay.direction * 100f; //Plane collisionPlane = new Plane(-_currentCamera.transform.forward, planePosition); HEU_Curve.CurveDrawCollision drawCollision = asset.CurveDrawCollision; List<Collider> drawColliders = null; LayerMask drawLayerMask = Physics.DefaultRaycastLayers; if (drawCollision == HEU_Curve.CurveDrawCollision.LAYERMASK) { drawLayerMask = asset.GetCurveDrawLayerMask(); } else if (drawCollision == HEU_Curve.CurveDrawCollision.COLLIDERS) { drawColliders = asset.GetCurveDrawColliders(); } // Adding new point between line segments _closestPointIndex = -1; _closestCurveName = null; _newPointPosition = Vector3.zero; float closestDistance = float.MaxValue; foreach (HEU_Curve curve in _curves) { // Draw the cooked curve using its vertices DrawCurveUsingVertices(curve, _selectedCurveColor); DrawPointCaps(curve, _addModeDefaultPointColor); List<Vector3> points = curve.GetAllPoints(); int numPoints = points.Count; if (_currentCamera != null && bMouseInDrawArea) { Ray ray = _currentCamera.ScreenPointToRay(mousePosition); RaycastHit[] results = null; if (numPoints > 0 && (_newPointMode == CurveNewPointMode.INSIDE)) { // Control -> add point between closest line segment for (int i = 0; i < numPoints - 1; ++i) { Vector3 pointPos0 = curve.GetTransformedPosition(points[i]); Vector3 pointPos1 = curve.GetTransformedPosition(points[i + 1]); Vector3 screenPos0 = HEU_EditorUI.GetHandleWorldToScreenPosition(pointPos0, _currentCamera); Vector3 screenPos1 = HEU_EditorUI.GetHandleWorldToScreenPosition(pointPos1, _currentCamera); float distance = HandleUtility.DistancePointToLineSegment(mousePosition, screenPos0, screenPos1); if (distance < closestDistance) { closestDistance = distance; _closestPointIndex = i + 1; _closestCurveName = curve.CurveName; } } } else { // Show new point from either end of curve, whichever is closest. // Use collision to find new point. Vector3 hitPoint = Vector3.zero; bool bHit = false; if (drawCollision == HEU_Curve.CurveDrawCollision.LAYERMASK) { // Using layermask RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo, _rayCastMaxDistance, drawLayerMask)) { hitPoint = hitInfo.point; bHit = true; } } else if (drawColliders != null && drawColliders.Count > 0) { // Using colliders results = Physics.RaycastAll(ray, _rayCastMaxDistance, drawLayerMask); foreach (RaycastHit hit in results) { foreach (Collider drawCollider in drawColliders) { if (hit.collider == drawCollider) { hitPoint = hit.point; bHit = true; break; } } } } else { // Using identity plane float collisionEnter = 0f; if (collisionPlane.Raycast(ray, out collisionEnter)) { collisionEnter = Mathf.Clamp(collisionEnter, _currentCamera.nearClipPlane, _currentCamera.farClipPlane); hitPoint = ray.origin + ray.direction * collisionEnter; bHit = true; } } if (bHit) { Vector3 hitPointScreenPosition = HEU_EditorUI.GetHandleWorldToScreenPosition(hitPoint, _currentCamera); // Find the closest point to add from (either first or last point) // Empty curve: // If its just a single curve, we can use the hit point as closest point. // For multiple curves, it gets trickier since we don't have an existing point // to check for closest point. So we'll just use the parent's transform position // as our anchor point. Vector3 checkPoint = Vector3.zero; int curveClosestPointIndex = 0; if (numPoints == 0) { if (_curves.Count > 1) { // Multiple curves -> use position of asset checkPoint = curve._targetGameObject.transform.position; } else { // Single curve -> use hit point as closest checkPoint = hitPoint; } } else if (_newPointMode == CurveNewPointMode.START) { // Curve with at least 1 point + shift held -> use first point checkPoint = HEU_EditorUI.GetHandleWorldToScreenPosition(curve.GetTransformedPoint(0), _currentCamera); curveClosestPointIndex = 0; } else { // Curve with at least 1 point -> use last point checkPoint = HEU_EditorUI.GetHandleWorldToScreenPosition(curve.GetTransformedPoint(numPoints - 1), _currentCamera); curveClosestPointIndex = numPoints; } float curveClosestPointDistance = Vector3.Distance(checkPoint, hitPointScreenPosition); if (curveClosestPointDistance < closestDistance) { closestDistance = curveClosestPointDistance; _closestPointIndex = curveClosestPointIndex; _closestCurveName = curve.CurveName; _newPointPosition = hitPoint; } // Snap to grid _newPointPosition = HEU_EditorUI.GetSnapPosition(_newPointPosition); } } } } // Note that curve name can be empty for valid empty curves if (_closestCurveName != null && _closestPointIndex >= 0) { HEU_Curve closestCurve = GetCurve(_closestCurveName); if (closestCurve != null) { int numPoints = closestCurve.GetNumPoints(); if ((_newPointMode == CurveNewPointMode.INSIDE) && !currentEvent.alt && numPoints >= 2) { // Handle adding new point at projected mouse cursor between points // First draw the curve line segments DrawCurveUsingPoints(closestCurve, Color.yellow); // Draw the caps again to hid the ends of line segments above (visually pleasing) DrawPointCaps(closestCurve, _addModeDefaultPointColor); Vector3 pointPos0 = closestCurve.GetTransformedPoint(_closestPointIndex - 1); Vector3 pointPos1 = closestCurve.GetTransformedPoint(_closestPointIndex); Vector3 screenPos0 = HEU_EditorUI.GetHandleWorldToScreenPosition(pointPos0, _currentCamera); Vector3 screenPos1 = HEU_EditorUI.GetHandleWorldToScreenPosition(pointPos1, _currentCamera); Vector3 curveNewPointPosition = HandleUtility.ProjectPointLine(mousePosition, screenPos0, screenPos1); Vector2 deltaNew = curveNewPointPosition - screenPos0; Vector2 deltaLine = screenPos1 - screenPos0; float ratio = Mathf.Clamp01(deltaNew.magnitude / deltaLine.magnitude); Vector3 newDir = (pointPos1 - pointPos0); curveNewPointPosition = pointPos0 + (newDir.normalized * newDir.magnitude * ratio); Handles.color = _selectedPointColor; HEU_EditorUI.DrawSphereCap(GUIUtility.GetControlID(FocusType.Passive), curveNewPointPosition, Quaternion.identity, HEU_EditorUI.GetHandleSize(curveNewPointPosition)); Handles.color = Color.yellow; HEU_EditorUI.DrawCircleCap(0, pointPos0, Quaternion.LookRotation(_currentCamera.transform.forward), HEU_EditorUI.GetHandleSize(pointPos0)); HEU_EditorUI.DrawCircleCap(0, pointPos1, Quaternion.LookRotation(_currentCamera.transform.forward), HEU_EditorUI.GetHandleSize(pointPos1)); Handles.color = defaultHandleColor; _newPointPosition = curveNewPointPosition; SceneView.RepaintAll(); } else if (!currentEvent.alt) { // Handle adding new point at closest curve's end points if (closestCurve.GetNumPoints() > 0) { // Draw dotted line from last point to newPointPosition int connectionPoint = (_closestPointIndex > 0) ? _closestPointIndex - 1 : 0; Vector3 pointPos0 = closestCurve.GetTransformedPoint(connectionPoint); Vector3[] dottedLineSegments = new Vector3[] { pointPos0, _newPointPosition }; Handles.color = _dottedLineColor; Handles.DrawDottedLines(dottedLineSegments, 4f); } Handles.color = _selectedPointColor; HEU_EditorUI.DrawSphereCap(GUIUtility.GetControlID(FocusType.Passive), _newPointPosition, Quaternion.identity, HEU_EditorUI.GetHandleSize(_newPointPosition)); Handles.color = defaultHandleColor; SceneView.RepaintAll(); } } } break; } } }
/// <summary> /// Update and draw the curves for the specified asset. /// Manages the interaction modes. /// </summary> /// <param name="asset"></param> public void UpdateSceneCurves(HEU_HoudiniAsset asset) { _serializedCurvesCache.Clear(); // Filter out non-editable curves _curves.Clear(); foreach (Object targetObject in targets) { HEU_Curve curve = targetObject as HEU_Curve; if (curve != null && curve.IsEditable()) { _curves.Add(curve); } } if (_curves.Count == 0) { return; } _currentCamera = Camera.current; Color defaultHandleColor = Handles.color; Event currentEvent = Event.current; Vector3 mousePosition = HEU_EditorUI.GetMousePosition(ref currentEvent, _currentCamera); int controlID = GUIUtility.GetControlID(FocusType.Keyboard); EventType eventType = currentEvent.GetTypeForControl(controlID); EditorGUI.BeginChangeCheck(); // Keep track of curves that were updated so we can apply changes via serialization List<SerializedObject> updatedCurves = new List<SerializedObject>(); if (_interactionMode == HEU_Curve.Interaction.VIEW) { UpdateViewMode(asset, controlID, eventType, mousePosition, updatedCurves); } else if (_interactionMode == HEU_Curve.Interaction.ADD) { UpdateAddMode(asset, controlID, eventType, mousePosition, updatedCurves); } else if (_interactionMode == HEU_Curve.Interaction.EDIT) { UpdateEditMode(asset, controlID, eventType, mousePosition, updatedCurves); } if (EditorGUI.EndChangeCheck()) { foreach (SerializedObject serializedCurve in updatedCurves) { serializedCurve.ApplyModifiedProperties(); } } Handles.color = defaultHandleColor; if (eventType == EventType.Layout) { // Delay update the show info so that the error doesn't popup trying to draw elements during drawing. _showInfoRepaint = _showInfo; } DrawSceneInfo(); }
private void SelectSinglePoint(HEU_Curve curve, int pointIndex) { _selectedCurvePoints.Clear(); _selectedCurvePoints[curve.CurveName] = new List<int>(); _selectedCurvePoints[curve.CurveName].Add(pointIndex); }