示例#1
0
	/// <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;
	}
示例#2
0
        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);
        }
示例#3
0
	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;
	    }
	}
示例#4
0
	/// <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();
        }
示例#6
0
	private void SelectAddPoint(HEU_Curve curve, int pointIndex)
	{
	    if (!_selectedCurvePoints.ContainsKey(curve.CurveName))
	    {
		_selectedCurvePoints[curve.CurveName] = new List<int>();
	    }
	    _selectedCurvePoints[curve.CurveName].Add(pointIndex);
	}
示例#7
0
	// 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;
	}
示例#8
0
	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;
	}
示例#9
0
	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;
	}
示例#10
0
	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;
	}
示例#11
0
	/// <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;
	}
示例#12
0
        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;
        }
示例#16
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;
		}
	    }
	}
示例#17
0
	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;
		}
	    }
	}
示例#18
0
	/// <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();
	}
示例#19
0
	private void SelectSinglePoint(HEU_Curve curve, int pointIndex)
	{
	    _selectedCurvePoints.Clear();
	    _selectedCurvePoints[curve.CurveName] = new List<int>();
	    _selectedCurvePoints[curve.CurveName].Add(pointIndex);
	}