您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
413 行
17 KiB
413 行
17 KiB
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using System.Reflection;
|
|
|
|
namespace UnityEngine.Experimental.Rendering
|
|
{
|
|
public class Gizmo6FacesBox
|
|
{
|
|
const float k_HandleSizeCoef = 0.05f;
|
|
|
|
protected enum NamedFace { Right, Top, Front, Left, Bottom, Back, None }
|
|
protected enum Element { Face, SelectedFace, Handle }
|
|
|
|
Mesh m_face = null;
|
|
|
|
Mesh face
|
|
{
|
|
get
|
|
{
|
|
if (m_face == null)
|
|
{
|
|
m_face = new Mesh();
|
|
m_face.vertices = new Vector3[] {
|
|
new Vector3(-.5f,-.5f,0f),
|
|
new Vector3(+.5f,-.5f,0f),
|
|
new Vector3(+.5f,+.5f,0f),
|
|
new Vector3(-.5f,+.5f,0f)
|
|
};
|
|
m_face.triangles = new int[] {
|
|
0, 1, 2,
|
|
2, 3, 0
|
|
};
|
|
m_face.RecalculateNormals();
|
|
}
|
|
return m_face;
|
|
}
|
|
}
|
|
|
|
Color[] m_faceColorsSelected;
|
|
|
|
public Color[] faceColorsSelected
|
|
{
|
|
get
|
|
{
|
|
return m_faceColorsSelected ?? (m_faceColorsSelected = monochromeSelectedFace
|
|
? new Color[]
|
|
{
|
|
new Color(1f, 1f, 1f, .15f)
|
|
}
|
|
: new Color[]
|
|
{
|
|
new Color(1f, 0f, 0f, .15f),
|
|
new Color(0f, 1f, 0f, .15f),
|
|
new Color(0f, 0f, 1f, .15f),
|
|
new Color(1f, 0f, 0f, .15f),
|
|
new Color(0f, 1f, 0f, .15f),
|
|
new Color(0f, 0f, 1f, .15f)
|
|
});
|
|
}
|
|
set
|
|
{
|
|
if (value == null)
|
|
{
|
|
throw new ArgumentNullException("FaceColor cannot be set to null.");
|
|
}
|
|
if (value.Length != (monochromeSelectedFace ? 1 : 6))
|
|
{
|
|
throw new ArgumentException("FaceColor must have 6 entries: X Y Z -X -Y -Z or only one in monochrome mode");
|
|
}
|
|
m_faceColorsSelected = value;
|
|
}
|
|
}
|
|
|
|
Color[] m_faceColors;
|
|
|
|
public Color[] faceColors
|
|
{
|
|
get
|
|
{
|
|
return m_faceColors ?? (m_faceColors = monochromeFace
|
|
? new Color[]
|
|
{
|
|
new Color(.5f, .5f, .5f, .15f)
|
|
}
|
|
: new Color[]
|
|
{
|
|
new Color(.5f, 0f, 0f, .15f),
|
|
new Color(0f, .5f, 0f, .15f),
|
|
new Color(0f, 0f, .5f, .15f),
|
|
new Color(.5f, 0f, 0f, .15f),
|
|
new Color(0f, .5f, 0f, .15f),
|
|
new Color(0f, 0f, .5f, .15f)
|
|
});
|
|
}
|
|
set
|
|
{
|
|
if (value == null)
|
|
{
|
|
throw new ArgumentNullException("FaceColor cannot be set to null.");
|
|
}
|
|
if (value.Length != (monochromeFace ? 1 : 6))
|
|
{
|
|
throw new ArgumentException("FaceColor must have 6 entries: X Y Z -X -Y -Z or only one in monochrome mode");
|
|
}
|
|
m_faceColors = value;
|
|
}
|
|
}
|
|
|
|
Color[] m_handleColors;
|
|
|
|
public Color[] handleColors
|
|
{
|
|
get
|
|
{
|
|
return m_handleColors ?? (m_handleColors = monochromeHandle
|
|
? new Color[]
|
|
{
|
|
new Color(1f, 0f, 0f, 1f)
|
|
}
|
|
: new Color[]
|
|
{
|
|
new Color(1f, 0f, 0f, 1f),
|
|
new Color(0f, 1f, 0f, 1f),
|
|
new Color(0f, 0f, 1f, 1f),
|
|
new Color(1f, 0f, 0f, 1f),
|
|
new Color(0f, 1f, 0f, 1f),
|
|
new Color(0f, 0f, 1f, 1f)
|
|
});
|
|
}
|
|
set
|
|
{
|
|
if (value == null)
|
|
{
|
|
throw new ArgumentNullException("HandleColor cannot be set to null.");
|
|
}
|
|
if (value.Length != (monochromeHandle ? 1 : 6))
|
|
{
|
|
throw new ArgumentException("HandleColor must have 6 entries: X Y Z -X -Y -Z or only one in monochrome mode");
|
|
}
|
|
m_handleColors = value;
|
|
}
|
|
}
|
|
|
|
public readonly bool monochromeHandle;
|
|
public readonly bool monochromeFace;
|
|
public readonly bool monochromeSelectedFace;
|
|
|
|
public bool allHandleControledByOne = false;
|
|
|
|
private int[] m_ControlIDs = new int[6] { 0, 0, 0, 0, 0, 0 };
|
|
|
|
public Vector3 center { get; set; }
|
|
|
|
public Vector3 size { get; set; }
|
|
|
|
public Gizmo6FacesBox(bool monochromeHandle = false, bool monochromeFace = false, bool monochromeSelectedFace = false)
|
|
{
|
|
this.monochromeHandle = monochromeHandle;
|
|
this.monochromeFace = monochromeFace;
|
|
this.monochromeSelectedFace = monochromeSelectedFace;
|
|
}
|
|
|
|
protected Color GetColor(NamedFace name, Element element)
|
|
{
|
|
switch(element)
|
|
{
|
|
default:
|
|
case Element.Face: return faceColors[monochromeFace ? 0 : (int)name];
|
|
case Element.SelectedFace: return faceColorsSelected[monochromeSelectedFace ? 0 : (int)name];
|
|
case Element.Handle: return handleColors[monochromeHandle ? 0 : (int)name];
|
|
}
|
|
}
|
|
|
|
public virtual void DrawHull(bool selected)
|
|
{
|
|
Color colorGizmo = Gizmos.color;
|
|
|
|
Element element = selected ? Element.SelectedFace : Element.Face;
|
|
|
|
if (selected)
|
|
{
|
|
Vector3 xSize = new Vector3(size.z, size.y, 1f);
|
|
Gizmos.color = GetColor(NamedFace.Left, element);
|
|
Gizmos.DrawMesh(face, center + size.x * .5f * Vector3.left, Quaternion.FromToRotation(Vector3.forward, Vector3.left), xSize);
|
|
Gizmos.color = GetColor(NamedFace.Right, element);
|
|
Gizmos.DrawMesh(face, center + size.x * .5f * Vector3.right, Quaternion.FromToRotation(Vector3.forward, Vector3.right), xSize);
|
|
|
|
Vector3 ySize = new Vector3(size.x, size.z, 1f);
|
|
Gizmos.color = GetColor(NamedFace.Top, element);
|
|
Gizmos.DrawMesh(face, center + size.y * .5f * Vector3.up, Quaternion.FromToRotation(Vector3.forward, Vector3.up), ySize);
|
|
Gizmos.color = GetColor(NamedFace.Bottom, element);
|
|
Gizmos.DrawMesh(face, center + size.y * .5f * Vector3.down, Quaternion.FromToRotation(Vector3.forward, Vector3.down), ySize);
|
|
|
|
Vector3 zSize = new Vector3(size.x, size.y, 1f);
|
|
Gizmos.color = GetColor(NamedFace.Front, element);
|
|
Gizmos.DrawMesh(face, center + size.z * .5f * Vector3.forward, Quaternion.identity, zSize);
|
|
Gizmos.color = GetColor(NamedFace.Back, element);
|
|
Gizmos.DrawMesh(face, center + size.z * .5f * Vector3.back, Quaternion.FromToRotation(Vector3.forward, Vector3.back), zSize);
|
|
}
|
|
|
|
Gizmos.color = colorGizmo;
|
|
Gizmos.DrawWireCube(center, size);
|
|
}
|
|
|
|
//Note: Handles.Slider not allow to use a specific ControlID.
|
|
//Thus Slider1D is used (with reflection)
|
|
static PropertyInfo k_scale = Type.GetType("UnityEditor.SnapSettings, UnityEditor").GetProperty("scale");
|
|
static Type k_Slider1D = Type.GetType("UnityEditorInternal.Slider1D, UnityEditor");
|
|
static MethodInfo k_Slider1D_Do = k_Slider1D
|
|
.GetMethod(
|
|
"Do",
|
|
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public,
|
|
null,
|
|
CallingConventions.Any,
|
|
new[] { typeof(int), typeof(Vector3), typeof(Vector3), typeof(float), typeof(Handles.CapFunction), typeof(float) },
|
|
null);
|
|
|
|
static void Slider1D(int controlID, ref Vector3 handlePosition, Vector3 handleOrientation, float snapScale, Color color)
|
|
{
|
|
using (new Handles.DrawingScope(color))
|
|
{
|
|
handlePosition = (Vector3)k_Slider1D_Do.Invoke(null, new object[]
|
|
{
|
|
controlID,
|
|
handlePosition,
|
|
handleOrientation,
|
|
HandleUtility.GetHandleSize(handlePosition) * k_HandleSizeCoef,
|
|
new Handles.CapFunction(Handles.DotHandleCap),
|
|
snapScale
|
|
});
|
|
}
|
|
}
|
|
|
|
public void DrawHandle()
|
|
{
|
|
for (int i = 0, count = m_ControlIDs.Length; i < count; ++i)
|
|
m_ControlIDs[i] = GUIUtility.GetControlID(GetHashCode(), FocusType.Passive);
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
Vector3 leftPosition = center + size.x * .5f * Vector3.left;
|
|
Vector3 rightPosition = center + size.x * .5f * Vector3.right;
|
|
Vector3 topPosition = center + size.y * .5f * Vector3.up;
|
|
Vector3 bottomPosition = center + size.y * .5f * Vector3.down;
|
|
Vector3 frontPosition = center + size.z * .5f * Vector3.forward;
|
|
Vector3 backPosition = center + size.z * .5f * Vector3.back;
|
|
|
|
float snapScale = (float)k_scale.GetValue(null, null);
|
|
NamedFace theChangedFace = NamedFace.None;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
Slider1D(m_ControlIDs[(int)NamedFace.Left], ref leftPosition, Vector3.left, snapScale, GetColor(NamedFace.Left, Element.Handle));
|
|
if (EditorGUI.EndChangeCheck() && allHandleControledByOne)
|
|
theChangedFace = NamedFace.Left;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
using (new Handles.DrawingScope(GetColor(NamedFace.Right, Element.Handle)))
|
|
Slider1D(m_ControlIDs[(int)NamedFace.Right], ref rightPosition, Vector3.right, snapScale, GetColor(NamedFace.Right, Element.Handle));
|
|
if (EditorGUI.EndChangeCheck() && allHandleControledByOne)
|
|
theChangedFace = NamedFace.Right;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
Slider1D(m_ControlIDs[(int)NamedFace.Top], ref topPosition, Vector3.up, snapScale, GetColor(NamedFace.Top, Element.Handle));
|
|
if (EditorGUI.EndChangeCheck() && allHandleControledByOne)
|
|
theChangedFace = NamedFace.Top;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
Slider1D(m_ControlIDs[(int)NamedFace.Bottom], ref bottomPosition, Vector3.down, snapScale, GetColor(NamedFace.Bottom, Element.Handle));
|
|
if (EditorGUI.EndChangeCheck() && allHandleControledByOne)
|
|
theChangedFace = NamedFace.Bottom;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
Slider1D(m_ControlIDs[(int)NamedFace.Front], ref frontPosition, Vector3.forward, snapScale, GetColor(NamedFace.Front, Element.Handle));
|
|
if (EditorGUI.EndChangeCheck() && allHandleControledByOne)
|
|
theChangedFace = NamedFace.Front;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
Slider1D(m_ControlIDs[(int)NamedFace.Back], ref backPosition, Vector3.back, snapScale, GetColor(NamedFace.Back, Element.Handle));
|
|
if (EditorGUI.EndChangeCheck() && allHandleControledByOne)
|
|
theChangedFace = NamedFace.Back;
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
if(allHandleControledByOne)
|
|
{
|
|
float decal = 0f;
|
|
switch(theChangedFace)
|
|
{
|
|
case NamedFace.Left:
|
|
decal = (leftPosition - center - size.x * .5f * Vector3.left).x;
|
|
break;
|
|
case NamedFace.Right:
|
|
decal = -(rightPosition - center - size.x * .5f * Vector3.right).x;
|
|
break;
|
|
case NamedFace.Top:
|
|
decal = -(topPosition - center - size.y * .5f * Vector3.up).y;
|
|
break;
|
|
case NamedFace.Bottom:
|
|
decal = (bottomPosition - center - size.y * .5f * Vector3.down).y;
|
|
break;
|
|
case NamedFace.Front:
|
|
decal = -(frontPosition - center - size.z * .5f * Vector3.forward).z;
|
|
break;
|
|
case NamedFace.Back:
|
|
decal = (backPosition - center - size.z * .5f * Vector3.back).z;
|
|
break;
|
|
}
|
|
|
|
Vector3 tempSize = size - Vector3.one * decal;
|
|
for (int axis = 0; axis < 3; ++axis)
|
|
{
|
|
if (tempSize[axis] < 0)
|
|
{
|
|
decal += tempSize[axis];
|
|
tempSize = size - Vector3.one * decal;
|
|
}
|
|
}
|
|
|
|
size = tempSize;
|
|
}
|
|
else
|
|
{
|
|
Vector3 max = new Vector3(rightPosition.x, topPosition.y, frontPosition.z);
|
|
Vector3 min = new Vector3(leftPosition.x, bottomPosition.y, backPosition.z);
|
|
|
|
//ensure that the box face are still facing outside
|
|
for (int axis = 0; axis < 3; ++axis)
|
|
{
|
|
if (min[axis] > max[axis])
|
|
{
|
|
if (GUIUtility.hotControl == m_ControlIDs[axis])
|
|
{
|
|
max[axis] = min[axis];
|
|
}
|
|
else
|
|
{
|
|
min[axis] = max[axis];
|
|
}
|
|
}
|
|
}
|
|
|
|
center = (max + min) * .5f;
|
|
size = max - min;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class Gizmo6FacesBoxContained : Gizmo6FacesBox
|
|
{
|
|
private Gizmo6FacesBox m_container;
|
|
|
|
public Gizmo6FacesBox container
|
|
{
|
|
get
|
|
{
|
|
return m_container;
|
|
}
|
|
set
|
|
{
|
|
if (value == null)
|
|
throw new System.ArgumentNullException("Container cannot be null. Use Gizmo6FacesBox instead.");
|
|
m_container = value;
|
|
}
|
|
}
|
|
|
|
public Gizmo6FacesBoxContained(Gizmo6FacesBox container, bool monochromeHandle = false, bool monochromeFace = false, bool monochromeSelectedFace = false) : base(monochromeHandle, monochromeFace, monochromeSelectedFace)
|
|
{
|
|
m_container = container;
|
|
}
|
|
|
|
public override void DrawHull(bool selected)
|
|
{
|
|
Color colorGizmo = Gizmos.color;
|
|
base.DrawHull(selected);
|
|
|
|
//if selected, also draw handle distance to container here
|
|
if (selected)
|
|
{
|
|
Vector3 centerDiff = center - m_container.center;
|
|
Vector3 xRecal = centerDiff;
|
|
Vector3 yRecal = centerDiff;
|
|
Vector3 zRecal = centerDiff;
|
|
xRecal.x = 0;
|
|
yRecal.y = 0;
|
|
zRecal.z = 0;
|
|
|
|
Gizmos.color = GetColor(NamedFace.Left, Element.Handle);
|
|
Gizmos.DrawLine(m_container.center + xRecal + m_container.size.x * .5f * Vector3.left, center + size.x * .5f * Vector3.left);
|
|
|
|
Gizmos.color = GetColor(NamedFace.Right, Element.Handle);
|
|
Gizmos.DrawLine(m_container.center + xRecal + m_container.size.x * .5f * Vector3.right, center + size.x * .5f * Vector3.right);
|
|
|
|
Gizmos.color = GetColor(NamedFace.Top, Element.Handle);
|
|
Gizmos.DrawLine(m_container.center + yRecal + m_container.size.y * .5f * Vector3.up, center + size.y * .5f * Vector3.up);
|
|
|
|
Gizmos.color = GetColor(NamedFace.Bottom, Element.Handle);
|
|
Gizmos.DrawLine(m_container.center + yRecal + m_container.size.y * .5f * Vector3.down, center + size.y * .5f * Vector3.down);
|
|
|
|
Gizmos.color = GetColor(NamedFace.Front, Element.Handle);
|
|
Gizmos.DrawLine(m_container.center + zRecal + m_container.size.z * .5f * Vector3.forward, center + size.z * .5f * Vector3.forward);
|
|
|
|
Gizmos.color = GetColor(NamedFace.Back, Element.Handle);
|
|
Gizmos.DrawLine(m_container.center + zRecal + m_container.size.z * .5f * Vector3.back, center + size.z * .5f * Vector3.back);
|
|
}
|
|
|
|
Gizmos.color = colorGizmo;
|
|
}
|
|
}
|
|
}
|