您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

173 行
8.7 KiB

using System;
using UnityEngine;
namespace UnityEditor.IMGUI.Controls
{
public class DecalProjectorComponentHandle : PrimitiveBoundsHandle
{
public DecalProjectorComponentHandle() : base()
{
midpointHandleDrawFunction = DrawHandleMidpoint;
}
public UnityEngine.Vector3 size { get { return GetSize(); } set { SetSize(value); } }
protected override void DrawWireframe()
{
Handles.DrawWireCube(center, size);
DrawArrowDownProjectionDirection();
}
protected void DrawArrowDownProjectionDirection()
{
int controlID = GUIUtility.GetControlID(GetHashCode(), FocusType.Passive);
Quaternion arrowRotation = Quaternion.LookRotation(Vector3.down, Vector3.right);
float arrowSize = size.y * 0.25f;
Handles.ArrowHandleCap(controlID, center, arrowRotation, arrowSize, EventType.Repaint);
}
// Could use a static readonly LUT, but this would require syncing with order with enum HandleDirection.
protected static Color ColorFromHandleDirection(HandleDirection handleDirection)
{
switch (handleDirection)
{
case HandleDirection.PositiveX:
case HandleDirection.NegativeX:
return Handles.xAxisColor;
case HandleDirection.PositiveY:
case HandleDirection.NegativeY:
return Handles.yAxisColor;
case HandleDirection.PositiveZ:
case HandleDirection.NegativeZ:
return Handles.zAxisColor;
default:
throw new ArgumentOutOfRangeException("handleDirection", "Must be PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, or NegativeZ");
}
}
protected static void PlaneVerticesFromHandleDirection(ref Vector3[] outVertices, HandleDirection handleDirection, Vector3 boundsSize, Vector3 boundsCenter)
{
Vector3 boundsMin = boundsSize * -0.5f + boundsCenter;
Vector3 boundsMax = boundsSize * 0.5f + boundsCenter;
switch (handleDirection)
{
case HandleDirection.PositiveX:
outVertices[0] = new Vector3(boundsMax.x, boundsMin.y, boundsMin.z);
outVertices[1] = new Vector3(boundsMax.x, boundsMax.y, boundsMin.z);
outVertices[2] = new Vector3(boundsMax.x, boundsMax.y, boundsMax.z);
outVertices[3] = new Vector3(boundsMax.x, boundsMin.y, boundsMax.z);
break;
case HandleDirection.NegativeX:
outVertices[0] = new Vector3(boundsMin.x, boundsMin.y, boundsMin.z);
outVertices[1] = new Vector3(boundsMin.x, boundsMax.y, boundsMin.z);
outVertices[2] = new Vector3(boundsMin.x, boundsMax.y, boundsMax.z);
outVertices[3] = new Vector3(boundsMin.x, boundsMin.y, boundsMax.z);
break;
case HandleDirection.PositiveY:
outVertices[0] = new Vector3(boundsMin.x, boundsMax.y, boundsMin.z);
outVertices[1] = new Vector3(boundsMax.x, boundsMax.y, boundsMin.z);
outVertices[2] = new Vector3(boundsMax.x, boundsMax.y, boundsMax.z);
outVertices[3] = new Vector3(boundsMin.x, boundsMax.y, boundsMax.z);
break;
case HandleDirection.NegativeY:
outVertices[0] = new Vector3(boundsMin.x, boundsMin.y, boundsMin.z);
outVertices[1] = new Vector3(boundsMax.x, boundsMin.y, boundsMin.z);
outVertices[2] = new Vector3(boundsMax.x, boundsMin.y, boundsMax.z);
outVertices[3] = new Vector3(boundsMin.x, boundsMin.y, boundsMax.z);
break;
case HandleDirection.PositiveZ:
outVertices[0] = new Vector3(boundsMin.x, boundsMin.y, boundsMax.z);
outVertices[1] = new Vector3(boundsMax.x, boundsMin.y, boundsMax.z);
outVertices[2] = new Vector3(boundsMax.x, boundsMax.y, boundsMax.z);
outVertices[3] = new Vector3(boundsMin.x, boundsMax.y, boundsMax.z);
break;
case HandleDirection.NegativeZ:
outVertices[0] = new Vector3(boundsMin.x, boundsMin.y, boundsMin.z);
outVertices[1] = new Vector3(boundsMax.x, boundsMin.y, boundsMin.z);
outVertices[2] = new Vector3(boundsMax.x, boundsMax.y, boundsMin.z);
outVertices[3] = new Vector3(boundsMin.x, boundsMax.y, boundsMin.z);
break;
default:
throw new ArgumentOutOfRangeException("handleDirection", "Must be PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, or NegativeZ");
}
}
// As DrawHandleDirectionPlane() is called every frame during gizmo rendering, we pre-allocate a scratch array for passing along to DrawSolidRectangleWithOutline()
// rather than putting pressure on the garbage collector every frame. Since DrawHandleDirectionPlane() is responsible for drawing handles, we will only ever call
// it from the main thread, so there is no realistic risk of a race condition occuring due to this static allocation.
private static Vector3[] s_PlaneVertices = new Vector3[4];
protected static void DrawHandleDirectionPlane(HandleDirection handleDirection, Vector3 size, Vector3 center)
{
// Set global Handles.color to white to avoid global state from interfering with the desired colors set at DrawSolidRectangleWithOutline().
Color handlesColorPrevious = Handles.color;
Handles.color = Color.white;
Color planeColorOutline = ColorFromHandleDirection(handleDirection);
const float planeColorFillAlpha = 0.25f;
Color planeColorFill = planeColorOutline * planeColorFillAlpha;
PlaneVerticesFromHandleDirection(ref s_PlaneVertices, handleDirection, size, center);
Handles.DrawSolidRectangleWithOutline(s_PlaneVertices, planeColorFill, planeColorOutline);
Handles.color = handlesColorPrevious;
}
// Utility function for determining the handle direction (which face) we are currently rendering within DrawHandleMidpoint().
// Ideally, the base class PrimitiveBoundsHandle would expose the reverse lookup: HandleDirectionFromControlID().
// In lieu of an explicit way to handle this look up, we derive the handle direction from the handle rotation.
protected static HandleDirection HandleDirectionFromRotation(Quaternion rotation)
{
if (rotation.x == 0.0f && rotation.y == 0.7071068f && rotation.z == 0.0f && rotation.w == 0.7071068f)
{
return HandleDirection.PositiveX;
}
else if (rotation.x == 0.0f && rotation.y == -0.7071068f && rotation.z == 0.0f && rotation.w == 0.7071068f)
{
return HandleDirection.NegativeX;
}
else if (rotation.x == -0.7071068f && rotation.y == 0.0f && rotation.z == 0.0f && rotation.w == 0.7071068f)
{
return HandleDirection.PositiveY;
}
else if (rotation.x == 0.7071068f && rotation.y == 0.0f && rotation.z == 0.0f && rotation.w == 0.7071068f)
{
return HandleDirection.NegativeY;
}
else if (rotation.x == 0.0f && rotation.y == 0.0f && rotation.z == 0.0f && rotation.w == 1.0f)
{
return HandleDirection.PositiveZ;
}
else if (rotation.x == 0.0f && rotation.y == 1.0f && rotation.z == 0.0f && rotation.w == 0.0f)
{
return HandleDirection.NegativeZ;
}
else
{
throw new ArgumentOutOfRangeException("rotation", "Must point down PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, or NegativeZ");
}
}
protected void DrawHandleMidpoint(int handleControlID, Vector3 handlePosition, Quaternion handleRotation, float handleSize, EventType eventType)
{
// Highlight the plane we are currently interacting with.
if (handleControlID == GUIUtility.hotControl)
{
HandleDirection handleDirection = HandleDirectionFromRotation(handleRotation);
DrawHandleDirectionPlane(handleDirection, size, center);
}
// Draw standard PrimitiveBoundsHandle mindpoint handle.
Handles.DotHandleCap(handleControlID, handlePosition, handleRotation, handleSize, eventType);
}
}
}