|
| 1 | +using System; |
| 2 | +using Unity.Mathematics; |
| 3 | +using UnityEditor; |
| 4 | +using UnityEditor.IMGUI.Controls; |
| 5 | +using UnityEngine; |
| 6 | + |
| 7 | +namespace Unity.Physics.Editor |
| 8 | +{ |
| 9 | + class BeveledBoxBoundsHandle : BoxBoundsHandle |
| 10 | + { |
| 11 | + public float bevelRadius |
| 12 | + { |
| 13 | + get => math.min(m_BevelRadius, math.cmin(GetSize()) * 0.5f); |
| 14 | + set |
| 15 | + { |
| 16 | + if (!m_IsDragging) |
| 17 | + m_BevelRadius = math.max(0f, value); |
| 18 | + } |
| 19 | + } |
| 20 | + float m_BevelRadius = ConvexHullGenerationParameters.Default.BevelRadius; |
| 21 | + bool m_IsDragging = false; |
| 22 | + |
| 23 | + static PhysicsBoundsHandleUtility.Corner[] s_Corners = new PhysicsBoundsHandleUtility.Corner[8]; |
| 24 | + |
| 25 | + public new void DrawHandle() |
| 26 | + { |
| 27 | + int prevHotControl = GUIUtility.hotControl; |
| 28 | + if (prevHotControl == 0) |
| 29 | + m_IsDragging = false; |
| 30 | + base.DrawHandle(); |
| 31 | + int currHotcontrol = GUIUtility.hotControl; |
| 32 | + if (currHotcontrol != prevHotControl) |
| 33 | + m_IsDragging = currHotcontrol != 0; |
| 34 | + } |
| 35 | + |
| 36 | + protected override void DrawWireframe() |
| 37 | + { |
| 38 | + if (this.bevelRadius <= 0f) |
| 39 | + { |
| 40 | + base.DrawWireframe(); |
| 41 | + return; |
| 42 | + } |
| 43 | + |
| 44 | + var cameraPosition = float3.zero; |
| 45 | + var cameraForward = new float3 { z = 1f }; |
| 46 | + if (Camera.current != null) |
| 47 | + { |
| 48 | + cameraPosition = Camera.current.transform.position; |
| 49 | + cameraForward = Camera.current.transform.forward; |
| 50 | + } |
| 51 | + |
| 52 | + var bounds = new Bounds(this.center, this.size); |
| 53 | + bool isCameraInsideBox = Camera.current != null && bounds.Contains(Handles.inverseMatrix.MultiplyPoint(cameraPosition)); |
| 54 | + var bevelRadius = this.bevelRadius; |
| 55 | + var origin = (float3)this.center; |
| 56 | + var size = (float3)this.size; |
| 57 | + |
| 58 | + PhysicsBoundsHandleUtility.DrawFace(origin, size * new float3(1f, 1f, 1f), bevelRadius, 0, axes, isCameraInsideBox); |
| 59 | + PhysicsBoundsHandleUtility.DrawFace(origin, size * new float3(-1f, 1f, 1f), bevelRadius, 0, axes, isCameraInsideBox); |
| 60 | + PhysicsBoundsHandleUtility.DrawFace(origin, size * new float3(1f, 1f, 1f), bevelRadius, 1, axes, isCameraInsideBox); |
| 61 | + PhysicsBoundsHandleUtility.DrawFace(origin, size * new float3(1f, -1f, 1f), bevelRadius, 1, axes, isCameraInsideBox); |
| 62 | + PhysicsBoundsHandleUtility.DrawFace(origin, size * new float3(1f, 1f, 1f), bevelRadius, 2, axes, isCameraInsideBox); |
| 63 | + PhysicsBoundsHandleUtility.DrawFace(origin, size * new float3(1f, 1f, -1f), bevelRadius, 2, axes, isCameraInsideBox); |
| 64 | + |
| 65 | + var corner = 0.5f * size - new float3(1f) * bevelRadius; |
| 66 | + var axisx = new float3(1f, 0f, 0f); |
| 67 | + var axisy = new float3(0f, 1f, 0f); |
| 68 | + var axisz = new float3(0f, 0f, 1f); |
| 69 | + |
| 70 | + // Since the geometry is transformed by Handles.matrix during rendering, we transform the camera position |
| 71 | + // by the inverse matrix so that the two-shaded wireframe will have the proper orientation. |
| 72 | + var invMatrix = Handles.inverseMatrix; |
| 73 | + cameraPosition = invMatrix.MultiplyPoint(cameraPosition); |
| 74 | + cameraForward = invMatrix.MultiplyVector(cameraForward); |
| 75 | + var cameraOrtho = Camera.current == null || Camera.current.orthographic; |
| 76 | + |
| 77 | + PhysicsBoundsHandleUtility.CalculateCornerHorizon(origin + corner * new float3(-1f, 1f, -1f), quaternion.LookRotation(-axisz, axisy), cameraPosition, cameraForward, cameraOrtho, bevelRadius, out s_Corners[0]); |
| 78 | + PhysicsBoundsHandleUtility.CalculateCornerHorizon(origin + corner * new float3(-1f, 1f, 1f), quaternion.LookRotation(-axisx, axisy), cameraPosition, cameraForward, cameraOrtho, bevelRadius, out s_Corners[1]); |
| 79 | + PhysicsBoundsHandleUtility.CalculateCornerHorizon(origin + corner * new float3(1f, 1f, 1f), quaternion.LookRotation(axisz, axisy), cameraPosition, cameraForward, cameraOrtho, bevelRadius, out s_Corners[2]); |
| 80 | + PhysicsBoundsHandleUtility.CalculateCornerHorizon(origin + corner * new float3(1f, 1f, -1f), quaternion.LookRotation(axisx, axisy), cameraPosition, cameraForward, cameraOrtho, bevelRadius, out s_Corners[3]); |
| 81 | + |
| 82 | + PhysicsBoundsHandleUtility.CalculateCornerHorizon(origin + corner * new float3(-1f, -1f, -1f), quaternion.LookRotation(-axisx, -axisy), cameraPosition, cameraForward, cameraOrtho, bevelRadius, out s_Corners[4]); |
| 83 | + PhysicsBoundsHandleUtility.CalculateCornerHorizon(origin + corner * new float3(-1f, -1f, 1f), quaternion.LookRotation(axisz, -axisy), cameraPosition, cameraForward, cameraOrtho, bevelRadius, out s_Corners[5]); |
| 84 | + PhysicsBoundsHandleUtility.CalculateCornerHorizon(origin + corner * new float3(1f, -1f, 1f), quaternion.LookRotation(axisx, -axisy), cameraPosition, cameraForward, cameraOrtho, bevelRadius, out s_Corners[6]); |
| 85 | + PhysicsBoundsHandleUtility.CalculateCornerHorizon(origin + corner * new float3(1f, -1f, -1f), quaternion.LookRotation(-axisz, -axisy), cameraPosition, cameraForward, cameraOrtho, bevelRadius, out s_Corners[7]); |
| 86 | + |
| 87 | + for (int i = 0; i < s_Corners.Length; i++) |
| 88 | + PhysicsBoundsHandleUtility.DrawCorner(s_Corners[i], true); |
| 89 | + |
| 90 | + // Draw the horizon edges between the corners |
| 91 | + for (int upA = 3, upB = 0; upB < 4; upA = upB, upB++) |
| 92 | + { |
| 93 | + int dnA = upA + 4; |
| 94 | + int dnB = upB + 4; |
| 95 | + |
| 96 | + if (s_Corners[upA].splitAxis[0].z && s_Corners[upB].splitAxis[1].x) Handles.DrawLine(s_Corners[upA].points[0], s_Corners[upB].points[1]); |
| 97 | + if (s_Corners[upA].splitAxis[1].z && s_Corners[upB].splitAxis[0].x) Handles.DrawLine(s_Corners[upA].points[1], s_Corners[upB].points[0]); |
| 98 | + |
| 99 | + if (s_Corners[dnA].splitAxis[0].x && s_Corners[dnB].splitAxis[1].z) Handles.DrawLine(s_Corners[dnA].points[0], s_Corners[dnB].points[1]); |
| 100 | + if (s_Corners[dnA].splitAxis[1].x && s_Corners[dnB].splitAxis[0].z) Handles.DrawLine(s_Corners[dnA].points[1], s_Corners[dnB].points[0]); |
| 101 | + |
| 102 | + if (s_Corners[dnA].splitAxis[0].y && s_Corners[upA].splitAxis[1].y) Handles.DrawLine(s_Corners[dnA].points[0], s_Corners[upA].points[1]); |
| 103 | + if (s_Corners[dnA].splitAxis[1].y && s_Corners[upA].splitAxis[0].y) Handles.DrawLine(s_Corners[dnA].points[1], s_Corners[upA].points[0]); |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | +} |
0 commit comments