Ejemplo n.º 1
0
	/// <summary>
	/// Set editing state for given curve.
	/// </summary>
	/// <param name="newState">New state to set</param>
	/// <param name="serializedCurve">Curve to change state for</param>
	private void SetCurveState(HEU_Curve.CurveEditState newState, SerializedObject serializedCurve)
	{
	    SerializedProperty editStateProperty = serializedCurve.FindProperty("_editState");
	    editStateProperty.intValue = (int)newState;

	    // Once we're done editing, we sync points to parameters so cooking will get latest values
	    if (newState == HEU_Curve.CurveEditState.REQUIRES_GENERATION)
	    {
		SyncCurvePointsToParameters(serializedCurve);
	    }

	    // This allows to apply serialized changes
	    GUI.changed = true;
	}
Ejemplo n.º 2
0
	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;
		}
	    }
	}