public static float RadiusHandle(Quaternion rotation, Vector3 position, float radius, bool renderDisc = true) { var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevDisabled = SceneHandles.disabled; var prevColor = SceneHandles.color; var forward = rotation * Vector3.forward; var up = rotation * Vector3.up; var right = rotation * Vector3.right; // Radius handle in zenith bool temp = GUI.changed; // Radius handles at disc temp = GUI.changed; GUI.changed = false; var isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[1]; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); radius = SizeSlider(position, up, forward, up, right, radius); radius = SizeSlider(position, -up, forward, up, right, radius); isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[0]; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); radius = SizeSlider(position, right, forward, up, right, radius); radius = SizeSlider(position, -right, forward, up, right, radius); if (GUI.changed) { radius = Mathf.Max(0.0f, radius); } GUI.changed |= temp; isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); // Draw gizmo if (radius > 0 && renderDisc) { SceneHandles.DrawWireDisc(position, forward, radius); } SceneHandles.disabled = prevDisabled; SceneHandles.color = prevColor; return(radius); }
public static float Radius2DHandle(Quaternion rotation, Vector3 position, float radius, float minRadius = 0, float maxRadius = float.PositiveInfinity, bool renderDisc = true) { minRadius = Mathf.Abs(minRadius); maxRadius = Mathf.Abs(maxRadius); if (maxRadius < minRadius) { maxRadius = minRadius; } var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevDisabled = SceneHandles.disabled; var prevColor = SceneHandles.color; var forward = rotation * Vector3.forward; var up = rotation * Vector3.up; var right = rotation * Vector3.right; bool temp = GUI.changed; GUI.changed = false; var isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[1]; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); radius = Size2DSlider(position, up, forward, up, right, radius); radius = Size2DSlider(position, -up, forward, up, right, radius); isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[0]; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); radius = Size2DSlider(position, right, forward, up, right, radius); radius = Size2DSlider(position, -right, forward, up, right, radius); radius = Mathf.Max(minRadius, Mathf.Min(Mathf.Abs(radius), maxRadius)); GUI.changed |= temp; if (radius > 0 && renderDisc) { isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); SceneHandles.DrawWireDisc(position, forward, radius); SceneHandles.disabled = prevDisabled; SceneHandles.color = prevColor; } return(radius); }
public static Vector3 RadiusHandle(Vector3 center, Vector3 up, Vector3 radius) { var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevDisabled = SceneHandles.disabled; var prevColor = SceneHandles.color; var prevChanged = GUI.changed; var delta1 = radius - center; var delta2 = Quaternion.AngleAxis(90, up) * delta1; var position0 = center + delta1; var position1 = center - delta1; var position2 = center + delta2; var position3 = center - delta2; float size; Vector3 forward; Vector3 right; GeometryUtility.CalculateTangents(up, out right, out forward); var isDisabled = isStatic || prevDisabled; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position0); position0 = Slider2DHandle(position0, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { radius = position0; prevChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position1); position1 = Slider2DHandle(position1, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { radius = center - (position1 - center); prevChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position2); position2 = Slider2DHandle(position2, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { radius = center + (Quaternion.AngleAxis(-90, up) * (position2 - center)); prevChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position3); position3 = Slider2DHandle(position3, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { radius = center - (Quaternion.AngleAxis(-90, up) * (position3 - center)); prevChanged = true; } GUI.changed |= prevChanged; isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); float radiusMagnitude = delta1.magnitude; if (radiusMagnitude > 0) { SceneHandles.DrawWireDisc(center, up, radiusMagnitude); } SceneHandles.disabled = prevDisabled; SceneHandles.color = prevColor; return(radius); }
public static void RadiusHandle(Vector3 center, Vector3 up, ref Vector3 radius1, ref Vector3 radius2) { var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevColor = SceneHandles.color; var prevMatrix = SceneHandles.matrix; var prevDisabled = SceneHandles.disabled; var prevChanged = GUI.changed; var delta1 = radius1 - center; var delta2 = radius2 - center; var position0 = center + delta1; var position1 = center - delta1; var position2 = center + delta2; var position3 = center - delta2; float size; Vector3 forward; Vector3 right; GeometryUtility.CalculateTangents(up, out right, out forward); var isDisabled = isStatic || prevDisabled; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position0); position0 = Slider2DHandle(position0, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { radius1 = position0; radius2 = center + (Quaternion.AngleAxis(-90, up) * ((radius1 - center).normalized * (radius2 - center).magnitude)); prevChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position1); position1 = Slider2DHandle(position1, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { radius1 = center - (position1 - center); radius2 = center + (Quaternion.AngleAxis(-90, up) * ((radius1 - center).normalized * (radius2 - center).magnitude)); prevChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position2); position2 = Slider2DHandle(position2, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { radius2 = center + (position2 - center); radius1 = center + (Quaternion.AngleAxis(-90, up) * ((radius2 - center).normalized * (radius1 - center).magnitude)); prevChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position3); position3 = Slider2DHandle(position3, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { radius2 = center - (position3 - center); radius1 = center + (Quaternion.AngleAxis(-90, up) * ((radius2 - center).normalized * (radius1 - center).magnitude)); prevChanged = true; } GUI.changed |= prevChanged; isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); float radiusMagnitude1 = delta1.magnitude; float radiusMagnitude2 = delta2.magnitude; if (radiusMagnitude1 > 0 && radiusMagnitude2 > 0) { var ellipsis = Matrix4x4.TRS(center, Quaternion.identity, Vector3.one); ellipsis.m00 = delta1.x; ellipsis.m10 = delta1.y; ellipsis.m20 = delta1.z; ellipsis.m01 = delta2.x; ellipsis.m11 = delta2.y; ellipsis.m21 = delta2.z; ellipsis.m02 = up.x; ellipsis.m12 = up.y; ellipsis.m22 = up.z; ellipsis *= Matrix4x4.TRS(-center, Quaternion.identity, Vector3.one); var newMatrix = prevMatrix * ellipsis; SceneHandles.matrix = newMatrix; SceneHandles.DrawWireDisc(center, up, 1.0f); } SceneHandles.disabled = prevDisabled; SceneHandles.matrix = prevMatrix; SceneHandles.color = prevColor; }
public static Vector3 Radius2DHandle(Vector3 center, Vector3 up, Vector3 radius, float minRadius = 0, float maxRadius = float.PositiveInfinity, bool renderDisc = true) { minRadius = Mathf.Abs(minRadius); maxRadius = Mathf.Abs(maxRadius); if (maxRadius < minRadius) { maxRadius = minRadius; } var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevDisabled = SceneHandles.disabled; var prevColor = SceneHandles.color; var prevChanged = GUI.changed; var hasChanged = false; var plane = new Plane(up, Vector3.zero); var delta1 = GeometryUtility.ProjectPointPlane(radius - center, plane); var delta2 = Quaternion.AngleAxis(90, up) * delta1; var position0 = center + delta1; var position1 = center - delta1; var position2 = center + delta2; var position3 = center - delta2; float size; Vector3 forward; Vector3 right; GeometryUtility.CalculateTangents(up, out right, out forward); bool noRotation = Event.current.shift; var isDisabled = isStatic || prevDisabled; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); Vector3 moveDelta = Vector3.zero; GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position0); position0 = Slider2DHandle(position0, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { moveDelta = position0 - center; hasChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position1); position1 = Slider2DHandle(position1, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { moveDelta = -(position1 - center); hasChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position2); position2 = Slider2DHandle(position2, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { moveDelta = (Quaternion.AngleAxis(-90, up) * (position2 - center)); hasChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position3); position3 = Slider2DHandle(position3, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { moveDelta = -(Quaternion.AngleAxis(-90, up) * (position3 - center)); hasChanged = true; } if (hasChanged) { Vector3 prevRadius = radius; var newRadius = center + moveDelta; var newDelta = GeometryUtility.ProjectPointPlane((newRadius - center), plane); var length = newDelta.magnitude; if (length < minRadius || length > maxRadius) { var direction = (length > Vector3.kEpsilon) ? newDelta.normalized : ((delta1.magnitude > Vector3.kEpsilon) ? delta1.normalized : Vector3.up); length = Mathf.Max(minRadius, Mathf.Min(length, maxRadius)); radius = center + (length * direction); } else { radius = newRadius; } if (noRotation) { var magnitude = newRadius.magnitude; radius = prevRadius.normalized * magnitude; } } GUI.changed |= prevChanged | hasChanged; isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); float radiusMagnitude = delta1.magnitude; if (radiusMagnitude > 0 && renderDisc) { SceneHandles.DrawWireDisc(center, up, radiusMagnitude); } SceneHandles.disabled = prevDisabled; SceneHandles.color = prevColor; return(radius); }
public static bool Radius2DHandle(Vector3 center, Vector3 up, ref Vector3 radius1, ref Vector3 radius2, float minRadius1 = 0, float minRadius2 = 0, float maxRadius1 = float.PositiveInfinity, float maxRadius2 = float.PositiveInfinity, bool renderDisc = true) { var positionId0 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard); var positionId1 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard); var positionId2 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard); var positionId3 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard); minRadius1 = Mathf.Abs(minRadius1); minRadius2 = Mathf.Abs(minRadius2); maxRadius1 = Mathf.Abs(maxRadius1); if (maxRadius1 < minRadius1) { maxRadius1 = minRadius1; } maxRadius2 = Mathf.Abs(maxRadius2); if (maxRadius2 < minRadius2) { maxRadius2 = minRadius2; } var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevColor = SceneHandles.color; var prevMatrix = SceneHandles.matrix; var prevDisabled = SceneHandles.disabled; var prevChanged = GUI.changed; float size; Vector3 forward; Vector3 right; GeometryUtility.CalculateTangents(up, out right, out forward); var plane = new Plane(up, Vector3.zero); var delta1 = GeometryUtility.ProjectPointPlane(radius1 - center, plane); var delta2 = GeometryUtility.ProjectPointPlane(radius2 - center, plane); var delta1Magnitude = delta1.magnitude; var delta2Magnitude = delta2.magnitude; var delta1Normalized = (delta1Magnitude < Vector3.kEpsilon) ? Vector3.zero : (delta1 / delta1Magnitude); var delta2Normalized = (delta2Magnitude < Vector3.kEpsilon) ? Vector3.zero : (delta2 / delta2Magnitude); // useful to have when modifying the 'other' one var rotatedDelta1 = Quaternion.AngleAxis(-90, up) * delta1Normalized; var rotatedDelta2 = Quaternion.AngleAxis(90, up) * delta2Normalized; var position0 = center + delta1; var position1 = center - delta1; var position2 = center + delta2; var position3 = center - delta2; var isDisabled = isStatic || prevDisabled; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); bool noRotation = Event.current.shift; GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position0); position0 = Slider2DHandle(positionId0, position0, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { var moveDelta = (position0 - center); Vector3 newRadius; if (noRotation) { newRadius = GeometryUtility.ProjectPointRay(center + moveDelta, center, rotatedDelta2); } else { newRadius = center + moveDelta; } var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane); delta1Magnitude = newDelta.magnitude; if (!noRotation && delta1Magnitude > Vector3.kEpsilon) { radius2 = center + ((Quaternion.AngleAxis(-90, up) * (newDelta / delta1Magnitude)) * delta2Magnitude); } // set this after setting radius2 since both may lead to same variable delta1 = newDelta; radius1 = newRadius; prevChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position1); position1 = Slider2DHandle(positionId1, position1, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { var moveDelta = (position1 - center); Vector3 newRadius; if (noRotation) { newRadius = GeometryUtility.ProjectPointRay(center - moveDelta, center, rotatedDelta2); } else { newRadius = center - moveDelta; } var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane); delta1Magnitude = newDelta.magnitude; if (!noRotation && delta1Magnitude > Vector3.kEpsilon) { radius2 = center + ((Quaternion.AngleAxis(-90, up) * (newDelta / delta1Magnitude)) * delta2Magnitude); } // set this after setting radius2 since both may lead to same variable delta1 = newDelta; radius1 = newRadius; prevChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position2); position2 = Slider2DHandle(positionId2, position2, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { var moveDelta = (position2 - center); Vector3 newRadius; if (noRotation) { newRadius = GeometryUtility.ProjectPointRay(center + moveDelta, center, rotatedDelta1); } else { newRadius = center + moveDelta; } var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane); delta2Magnitude = newDelta.magnitude; if (!noRotation && delta2Magnitude > Vector3.kEpsilon) { radius1 = center + ((Quaternion.AngleAxis(90, up) * (newDelta / delta2Magnitude)) * delta1Magnitude); } // set this after setting radius1 since both may lead to same variable delta2 = newDelta; radius2 = newRadius; prevChanged = true; } GUI.changed = false; size = UnityEditor.HandleUtility.GetHandleSize(position3); position3 = Slider2DHandle(positionId3, position3, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap); if (GUI.changed) { var moveDelta = (position3 - center); Vector3 newRadius; if (noRotation) { newRadius = GeometryUtility.ProjectPointRay(center - moveDelta, center, rotatedDelta1); } else { newRadius = center - moveDelta; } var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane); delta2Magnitude = newDelta.magnitude; if (!noRotation && delta2Magnitude > Vector3.kEpsilon) { radius1 = center + ((Quaternion.AngleAxis(90, up) * (newDelta / delta2Magnitude)) * delta1Magnitude); } // set this after setting radius1 since both may lead to same variable delta2 = newDelta; radius2 = newRadius; prevChanged = true; } GUI.changed |= prevChanged; if (delta1Magnitude < minRadius1 || delta1Magnitude > maxRadius1) { if (delta2Magnitude < minRadius2 || delta2Magnitude > maxRadius2) { delta1Magnitude = Mathf.Max(minRadius1, Mathf.Min(delta1Magnitude, maxRadius1)); delta2Magnitude = Mathf.Max(minRadius2, Mathf.Min(delta2Magnitude, maxRadius2)); delta1Normalized = right; delta2Normalized = up; delta1 = GeometryUtility.ProjectPointPlane(delta1Normalized * delta1Magnitude, plane); delta2 = GeometryUtility.ProjectPointPlane(delta2Normalized * delta2Magnitude, plane); rotatedDelta2 = delta2Normalized; rotatedDelta1 = delta1Normalized; radius1 = center + delta1; radius2 = center + delta2; GUI.changed = true; } else { delta1Magnitude = Mathf.Max(minRadius1, Mathf.Min(delta1Magnitude, maxRadius1)); delta1Normalized = rotatedDelta2; delta1 = GeometryUtility.ProjectPointPlane(delta1Normalized * delta1Magnitude, plane); radius1 = center + delta1; GUI.changed = true; } } else if (delta2Magnitude < minRadius2 || delta2Magnitude > maxRadius2) { delta2Magnitude = Mathf.Max(minRadius2, Mathf.Min(delta2Magnitude, maxRadius2)); delta2Normalized = rotatedDelta1; delta2 = delta2Normalized * delta2Magnitude; radius2 = center + delta2; GUI.changed = true; } if (Event.current.type == EventType.Repaint) { isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); if (delta1Magnitude > Vector3.kEpsilon && delta2Magnitude > Vector3.kEpsilon) { var ellipsis = Matrix4x4.TRS(center, Quaternion.identity, Vector3.one); ellipsis.m00 = delta1.x; ellipsis.m10 = delta1.y; ellipsis.m20 = delta1.z; ellipsis.m01 = delta2.x; ellipsis.m11 = delta2.y; ellipsis.m21 = delta2.z; ellipsis.m02 = up.x; ellipsis.m12 = up.y; ellipsis.m22 = up.z; ellipsis *= Matrix4x4.TRS(-center, Quaternion.identity, Vector3.one); var newMatrix = prevMatrix * ellipsis; SceneHandles.matrix = newMatrix; if (renderDisc) { SceneHandles.DrawWireDisc(center, Vector3.forward, 1.0f); } } else if (delta1Magnitude > Vector3.kEpsilon) { SceneHandles.DrawLine(position0, position1); } else if (delta2Magnitude > Vector3.kEpsilon) { SceneHandles.DrawLine(position2, position3); } } SceneHandles.disabled = prevDisabled; SceneHandles.matrix = prevMatrix; SceneHandles.color = prevColor; var focus = SceneHandleUtility.focusControl; return((focus == positionId0) || (focus == positionId1) || (focus == positionId2) || (focus == positionId3)); }
public static void DrawAngle(UnityEngine.Vector3 center, UnityEngine.Vector3 direction, UnityEngine.Vector3 axis, float angle) { var rotation = UnityEngine.Quaternion.AngleAxis(angle, axis); var centerSize = UnityEditor.HandleUtility.GetHandleSize(center); var maxSize = direction.magnitude; var xdir = direction / maxSize; //var ydir = UnityEngine.Vector3.Cross(xdir, axis); var handleSize = Mathf.Min(centerSize, maxSize); var drawAngle = UnityEngine.Mathf.Clamp(angle, -360, 360); var realLength = Mathf.Max(1, Mathf.CeilToInt((anglePoints.Length / 360.0f) * Mathf.Abs(drawAngle))); var pointSize = centerSize * 0.04f; SceneHandles.color = SceneHandles.StateColor(SceneHandles.measureColor); SceneHandles.DrawAAPolyLine(center + (xdir * pointSize), center + direction); SceneHandles.DrawAAPolyLine(center + (rotation * (xdir * pointSize)), center + (rotation * direction)); SceneHandles.DrawWireDisc(center, Vector3.forward, pointSize); direction = xdir * handleSize; if (UnityEngine.Mathf.Abs(angle) > 0.0f) { var angleStep = drawAngle / realLength; var curAngle = 0.0f; for (int i = 0; i < realLength; i++) { anglePoints[i] = center + (UnityEngine.Quaternion.AngleAxis(curAngle, axis) * direction); curAngle += angleStep; } SceneHandles.DrawDottedLines(anglePoints.Take(realLength).ToArray(), 4.0f); rotation = UnityEngine.Quaternion.AngleAxis(angle, axis); var right = rotation * Vector3.right; var endPoint = center + (rotation * direction); var arrowSize = handleSize * 0.2f; // UnityEditor.HandleUtility.GetHandleSize(endPoint) * 0.2f; if (angle < 0.0f) { DrawFlatArrow(endPoint, -right, arrowSize); } else { DrawFlatArrow(endPoint, right, arrowSize); } } Vector3 facing; Vector3 position; if (handleSize == maxSize) { facing = rotation * xdir; position = center + (facing * handleSize); } else { var halfRotation = UnityEngine.Quaternion.AngleAxis(drawAngle / 2.0f, axis); facing = halfRotation * xdir; position = center; } DrawLabel(position, facing, 5, angle + "°"); }
public static float Radius3DHandle(Quaternion rotation, Vector3 position, float radius, float minRadius = 0, float maxRadius = float.PositiveInfinity) { minRadius = Mathf.Abs(minRadius); maxRadius = Mathf.Abs(maxRadius); if (maxRadius < minRadius) { maxRadius = minRadius; } const float kEpsilon = 0.000001F; var camera = Camera.current; var cameraLocalPos = SceneHandles.inverseMatrix.MultiplyPoint(camera.transform.position); var cameraLocalForward = SceneHandles.inverseMatrix.MultiplyVector(camera.transform.forward); var isCameraInsideSphere = (cameraLocalPos - position).magnitude < radius; var isCameraOrthographic = camera.orthographic; var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevDisabled = SceneHandles.disabled; var prevColor = SceneHandles.color; var forward = rotation * Vector3.forward; var up = rotation * Vector3.up; var right = rotation * Vector3.right; bool guiHasChanged = GUI.changed; GUI.changed = false; Vector3 positiveXDir = right; Vector3 negativeXDir = -right; Vector3 positiveYDir = up; Vector3 negativeYDir = -up; Vector3 positiveZDir = forward; Vector3 negativeZDir = -forward; Vector3 positiveXHandle = position + positiveXDir * radius; Vector3 negativeXHandle = position + negativeXDir * radius; Vector3 positiveYHandle = position + positiveYDir * radius; Vector3 negativeYHandle = position + negativeYDir * radius; Vector3 positiveZHandle = position + positiveZDir * radius; Vector3 negativeZHandle = position + negativeZDir * radius; bool positiveXBackfaced = false; bool negativeXBackfaced = false; bool positiveYBackfaced = false; bool negativeYBackfaced = false; bool positiveZBackfaced = false; bool negativeZBackfaced = false; if (!isCameraInsideSphere) { float cosV; cosV = isCameraOrthographic ? Vector3.Dot(positiveXDir, -cameraLocalForward) : Vector3.Dot(positiveXDir, (cameraLocalPos - positiveXHandle)); positiveXBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(negativeXDir, -cameraLocalForward) : Vector3.Dot(negativeXDir, (cameraLocalPos - negativeXHandle)); negativeXBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(positiveYDir, -cameraLocalForward) : Vector3.Dot(positiveYDir, (cameraLocalPos - positiveYHandle)); positiveYBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(negativeYDir, -cameraLocalForward) : Vector3.Dot(negativeYDir, (cameraLocalPos - negativeYHandle)); negativeYBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(positiveZDir, -cameraLocalForward) : Vector3.Dot(positiveZDir, (cameraLocalPos - positiveZHandle)); positiveZBackfaced = (cosV < -0.0001f); cosV = isCameraOrthographic ? Vector3.Dot(negativeZDir, -cameraLocalForward) : Vector3.Dot(negativeZDir, (cameraLocalPos - negativeZHandle)); negativeZBackfaced = (cosV < -0.0001f); } float positiveXSize = UnityEditor.HandleUtility.GetHandleSize(positiveXHandle) * 0.05f * (positiveXBackfaced ? backfaceSizeMultiplier : 1); float negativeXSize = UnityEditor.HandleUtility.GetHandleSize(negativeXHandle) * 0.05f * (negativeXBackfaced ? backfaceSizeMultiplier : 1); float positiveYSize = UnityEditor.HandleUtility.GetHandleSize(positiveYHandle) * 0.05f * (positiveYBackfaced ? backfaceSizeMultiplier : 1); float negativeYSize = UnityEditor.HandleUtility.GetHandleSize(negativeYHandle) * 0.05f * (negativeYBackfaced ? backfaceSizeMultiplier : 1); float positiveZSize = UnityEditor.HandleUtility.GetHandleSize(positiveZHandle) * 0.05f * (positiveZBackfaced ? backfaceSizeMultiplier : 1); float negativeZSize = UnityEditor.HandleUtility.GetHandleSize(negativeZHandle) * 0.05f * (negativeZBackfaced ? backfaceSizeMultiplier : 1); var isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[0]; var color = SceneHandles.StateColor(prevColor, isDisabled, false); var backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier); GUI.changed = false; SceneHandles.color = positiveXBackfaced ? backfacedColor : color; positiveXHandle = Slider2DHandle(positiveXHandle, Vector3.zero, forward, up, right, positiveXSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(positiveXHandle - position, positiveXDir); guiHasChanged = true; } GUI.changed = false; SceneHandles.color = negativeXBackfaced ? backfacedColor : color; negativeXHandle = Slider2DHandle(negativeXHandle, Vector3.zero, forward, up, right, negativeXSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(negativeXHandle - position, negativeXDir); guiHasChanged = true; } isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[1]; color = SceneHandles.StateColor(prevColor, isDisabled, false); backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier); GUI.changed = false; SceneHandles.color = positiveYBackfaced ? backfacedColor : color; positiveYHandle = Slider2DHandle(positiveYHandle, Vector3.zero, forward, up, right, positiveYSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(positiveYHandle - position, positiveYDir); guiHasChanged = true; } GUI.changed = false; SceneHandles.color = negativeYBackfaced ? backfacedColor : color; negativeYHandle = Slider2DHandle(negativeYHandle, Vector3.zero, forward, up, right, negativeYSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(negativeYHandle - position, negativeYDir); guiHasChanged = true; } isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[2]; color = SceneHandles.StateColor(prevColor, isDisabled, false); backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier); GUI.changed = false; SceneHandles.color = positiveZBackfaced ? backfacedColor : color; positiveZHandle = Slider2DHandle(positiveZHandle, Vector3.zero, up, forward, right, positiveZSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(positiveZHandle - position, positiveZDir); guiHasChanged = true; } GUI.changed = false; SceneHandles.color = negativeZBackfaced ? backfacedColor : color; negativeZHandle = Slider2DHandle(negativeZHandle, Vector3.zero, up, forward, right, negativeZSize, OutlinedDotHandleCap); if (GUI.changed) { radius = Vector3.Dot(negativeZHandle - position, negativeZDir); guiHasChanged = true; } radius = Mathf.Max(minRadius, Mathf.Min(Mathf.Abs(radius), maxRadius)); GUI.changed |= guiHasChanged; if (radius > 0) { isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); color = SceneHandles.StateColor(prevColor, isDisabled, false); backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier); var discOrientations = new Vector3[] { rotation *Vector3.right, rotation *Vector3.up, rotation *Vector3.forward }; var currentCamera = Camera.current; var cameraTransform = currentCamera.transform; if (currentCamera.orthographic) { var planeNormal = cameraTransform.forward; SceneHandles.DrawWireDisc(position, planeNormal, radius); planeNormal.Normalize(); for (int i = 0; i < 3; i++) { var discOrientation = discOrientations[i]; var discTangent = Vector3.Cross(discOrientation, planeNormal); // we may have view dir locked to one axis if (discTangent.sqrMagnitude > kEpsilon) { SceneHandles.color = color; SceneHandles.DrawWireArc(position, discOrientation, discTangent, 180, radius); SceneHandles.color = backfacedColor; SceneHandles.DrawWireArc(position, discOrientation, discTangent, -180, radius); } } } else { // Since the geometry is transformed by Handles.matrix during rendering, we transform the camera position // by the inverse matrix so that the two-shaded wireframe will have the proper orientation. var invMatrix = SceneHandles.inverseMatrix; var cameraCenter = cameraTransform.position; var cameraToCenter = position - invMatrix.MultiplyPoint(cameraCenter); // vector from camera to center var sqrDistCameraToCenter = cameraToCenter.sqrMagnitude; var sqrRadius = radius * radius; // squared radius var sqrOffset = sqrRadius * sqrRadius / sqrDistCameraToCenter; // squared distance from actual center to drawn disc center var insideAmount = sqrOffset / sqrRadius; if (insideAmount < 1) { if (Mathf.Abs(sqrDistCameraToCenter) < kEpsilon) { return(radius); } var horizonRadius = Mathf.Sqrt(sqrRadius - sqrOffset); var horizonCenter = position - sqrRadius * cameraToCenter / sqrDistCameraToCenter; SceneHandles.color = color; SceneHandles.DrawWireDisc(horizonCenter, cameraToCenter, horizonRadius); var planeNormal = cameraToCenter.normalized; for (int i = 0; i < 3; i++) { var discOrientation = discOrientations[i]; var angleBetweenDiscAndNormal = Mathf.Acos(Vector3.Dot(discOrientation, planeNormal)); angleBetweenDiscAndNormal = (Mathf.PI * 0.5f) - Mathf.Min(angleBetweenDiscAndNormal, Mathf.PI - angleBetweenDiscAndNormal); float f = Mathf.Tan(angleBetweenDiscAndNormal); float g = Mathf.Sqrt(sqrOffset + f * f * sqrOffset) / radius; if (g < 1) { var angleToHorizon = Mathf.Asin(g) * Mathf.Rad2Deg; var discTangent = Vector3.Cross(discOrientation, planeNormal); var vectorToPointOnHorizon = Quaternion.AngleAxis(angleToHorizon, discOrientation) * discTangent; var horizonArcLength = (90 - angleToHorizon) * 2.0f; SceneHandles.color = color; SceneHandles.DrawWireArc(position, discOrientation, vectorToPointOnHorizon, horizonArcLength, radius); SceneHandles.color = backfacedColor; SceneHandles.DrawWireArc(position, discOrientation, vectorToPointOnHorizon, horizonArcLength - 360, radius); } else { SceneHandles.color = backfacedColor; SceneHandles.DrawWireDisc(position, discOrientation, radius); } } } else { SceneHandles.color = backfacedColor; for (int i = 0; i < 3; i++) { var discOrientation = discOrientations[i]; SceneHandles.DrawWireDisc(position, discOrientation, radius); } } } } SceneHandles.disabled = prevDisabled; SceneHandles.color = prevColor; return(radius); }