Example #1
0
	private void EditModeDrawCurvePoints(Event currentEvent, EventType eventType, ref int numSelectedPoints, ref Bounds bounds, ref bool bInteractionOcurred)
	{
	    Color defaultHandleColor = Handles.color;

	    // First we draw all the curves, while drawing each point as button
	    // and collecting the selected points.
	    foreach (HEU_Curve curve in _curves)
	    {
		if (eventType == EventType.Repaint)
		{
		    // Draw the cooked curve using its vertices
		    DrawCurveUsingVertices(curve, _selectedCurveColor);
		}

		// During dragging, we draw the points in the drag logic later
		if (_dragMouseDown)
		{
		    continue;
		}

		// Now draw all the points, but tailor their visual style according to interaction
		List<Vector3> points = curve.GetAllPoints();

		List<int> selectedPoints = new List<int>();
		_selectedCurvePoints.TryGetValue(curve.CurveName, out selectedPoints);

		for (int i = 0; i < points.Count; ++i)
		{
		    Vector3 pointPos = curve.GetTransformedPosition(points[i]);
		    float pointSize = HEU_EditorUI.GetHandleSize(pointPos);
		    float pickSize = pointSize * 2f;

		    if (selectedPoints != null && selectedPoints.Contains(i))
		    {
			// Selected point
			numSelectedPoints++;

			if (numSelectedPoints == 1)
			{
			    bounds = new Bounds(pointPos, Vector3.zero);
			}
			else
			{
			    bounds.Encapsulate(pointPos);
			}

			if (selectedPoints.Count > 1 || _selectedCurvePoints.Keys.Count > 1)
			{
			    Handles.color = _selectedPointColor;
			    if (HEU_EditorUI.DrawSphereCapButton(pointPos, Quaternion.identity, pointSize, pickSize))
			    {
				if (currentEvent.control)
				{
				    DeselectPoint(curve.CurveName, i);
				}
				else
				{
				    SelectSinglePoint(curve, i);
				}
				bInteractionOcurred = true;
			    }
			    Handles.color = defaultHandleColor;
			}
		    }
		    else
		    {
			// Unselected point

			Handles.color = _unselectedPointColor;
			if (HEU_EditorUI.DrawSphereCapButton(pointPos, Quaternion.identity, pointSize, pickSize))
			{
			    if (currentEvent.control)
			    {
				SelectAddPoint(curve, i);
			    }
			    else
			    {
				SelectSinglePoint(curve, i);
			    }

			    bInteractionOcurred = true;
			}
		    }
		}
	    }
	}
Example #2
0
	private void DrawSelectionBox(Vector3 mousePosition, bool bAutoSelectPoints)
	{
	    // First draw the selection box from drag start to current mouse position.

	    // Calculating the bounding box in screenspace then converting to world seems to
	    // produce the best lines in the Scene view regardless of camera orientation.
	    Vector3 xVec = new Vector3((mousePosition.x - _dragMouseStart.x), 0, 0);
	    Vector3 yVec = new Vector3(0, (mousePosition.y - _dragMouseStart.y), 0);

	    Vector3 s00 = _dragMouseStart;
	    Vector3 s01 = _dragMouseStart + xVec;
	    Vector3 s10 = _dragMouseStart + yVec;
	    Vector3 s11 = _dragMouseStart + xVec + yVec;

	    Vector3 camFwd = _currentCamera.transform.forward;
	    float depth = Mathf.Abs((_currentCamera.transform.position + camFwd * 2f).z);
	    Vector3 w00 = _currentCamera.ScreenToWorldPoint(new Vector3(s00.x, s00.y, depth));
	    Vector3 w01 = _currentCamera.ScreenToWorldPoint(new Vector3(s01.x, s01.y, depth));
	    Vector3 w10 = _currentCamera.ScreenToWorldPoint(new Vector3(s10.x, s10.y, depth));
	    Vector3 w11 = _currentCamera.ScreenToWorldPoint(new Vector3(s11.x, s11.y, depth));

	    Color defaultColor = Handles.color;
	    Handles.color = Color.white;
	    Vector3[] lines = new Vector3[]
	    {
				w00, w01, w11, w10, w00
	    };
	    Handles.DrawSolidRectangleWithOutline(lines, _selectionBoxFillColor, _selectionBoxOutlineColor);
	    Handles.color = defaultColor;

	    if (bAutoSelectPoints)
	    {
		// Now we select points withing the selection box

		DeselectAllPoints();

		// We'll use a rect to test against each curve point
		Rect selectionRect = new Rect(_dragMouseStart.x, _dragMouseStart.y, (mousePosition.x - _dragMouseStart.x), (mousePosition.y - _dragMouseStart.y));

		foreach (HEU_Curve curve in _curves)
		{
		    int numPoints = curve.GetNumPoints();

		    for (int i = 0; i < numPoints; ++i)
		    {
			Vector3 pointPosition = curve.GetTransformedPoint(i);

			Vector3 pointScreenPosition = HEU_EditorUI.GetHandleWorldToScreenPosition(pointPosition, _currentCamera);

			if (selectionRect.Contains(pointScreenPosition, true))
			{
			    SelectAddPoint(curve, i);

			    Handles.color = _selectedPointColor;
			}
			else
			{
			    Handles.color = _unselectedPointColor;
			}

			HEU_EditorUI.DrawSphereCap(i, pointPosition, Quaternion.identity, HEU_EditorUI.GetHandleSize(pointPosition));
			Handles.color = defaultColor;
		    }
		}
	    }
	}
Example #3
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;
		}
	    }
	}
Example #4
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;
	}