Initial Commit
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using Oculus.Interaction.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Oculus.Interaction.Grab.GrabSurfaces.Editor
|
||||
{
|
||||
[CustomEditor(typeof(BoxGrabSurface))]
|
||||
[CanEditMultipleObjects]
|
||||
public class BoxGrabSurfaceEditor : UnityEditor.Editor
|
||||
{
|
||||
private BoxBoundsHandle _boxHandle = new BoxBoundsHandle();
|
||||
private BoxGrabSurface _surface;
|
||||
private Transform _relativeTo;
|
||||
|
||||
private SerializedProperty _relativeToProperty;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_boxHandle.handleColor = EditorConstants.PRIMARY_COLOR;
|
||||
_boxHandle.wireframeColor = EditorConstants.PRIMARY_COLOR_DISABLED;
|
||||
_boxHandle.axes = PrimitiveBoundsHandle.Axes.X | PrimitiveBoundsHandle.Axes.Z;
|
||||
|
||||
_surface = (target as BoxGrabSurface);
|
||||
_relativeToProperty = serializedObject.FindProperty("_relativeTo");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
_relativeTo = _relativeToProperty.objectReferenceValue as Transform;
|
||||
}
|
||||
|
||||
public void OnSceneGUI()
|
||||
{
|
||||
if (_relativeTo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DrawRotator(_surface, _relativeTo);
|
||||
DrawBoxEditor(_surface, _relativeTo);
|
||||
DrawSlider(_surface, _relativeTo);
|
||||
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
DrawSnapLines(_surface, _relativeTo);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSnapLines(BoxGrabSurface surface, Transform relativeTo)
|
||||
{
|
||||
Handles.color = EditorConstants.PRIMARY_COLOR;
|
||||
Vector3 size = surface.GetSize(relativeTo);
|
||||
Quaternion rotation = surface.GetRotation(relativeTo);
|
||||
Vector3 surfacePosition = surface.GetReferencePose(relativeTo).position;
|
||||
float widthOffset = surface.GetWidthOffset(relativeTo);
|
||||
Vector4 snapOffset = surface.GetSnapOffset(relativeTo);
|
||||
Vector3 rightAxis = rotation * Vector3.right;
|
||||
Vector3 forwardAxis = rotation * Vector3.forward;
|
||||
Vector3 forwardOffset = forwardAxis * size.z;
|
||||
|
||||
Vector3 bottomLeft = surfacePosition - rightAxis * size.x * (1f - widthOffset);
|
||||
Vector3 bottomRight = surfacePosition + rightAxis * size.x * (widthOffset);
|
||||
Vector3 topLeft = bottomLeft + forwardOffset;
|
||||
Vector3 topRight = bottomRight + forwardOffset;
|
||||
|
||||
Handles.DrawLine(bottomLeft + rightAxis * snapOffset.y, bottomRight + rightAxis * snapOffset.x);
|
||||
Handles.DrawLine(topLeft - rightAxis * snapOffset.x, topRight - rightAxis * snapOffset.y);
|
||||
Handles.DrawLine(bottomLeft - forwardAxis * snapOffset.z, topLeft - forwardAxis * snapOffset.w);
|
||||
Handles.DrawLine(bottomRight + forwardAxis * snapOffset.w, topRight + forwardAxis * snapOffset.z);
|
||||
}
|
||||
|
||||
private void DrawSlider(BoxGrabSurface surface, Transform relativeTo)
|
||||
{
|
||||
Handles.color = EditorConstants.PRIMARY_COLOR;
|
||||
Vector3 size = surface.GetSize(relativeTo);
|
||||
Quaternion rotation = surface.GetRotation(relativeTo);
|
||||
Vector3 surfacePosition = surface.GetReferencePose(relativeTo).position;
|
||||
float widthOffset = surface.GetWidthOffset(relativeTo);
|
||||
Vector4 snapOffset = surface.GetSnapOffset(relativeTo);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Vector3 rightDir = rotation * Vector3.right;
|
||||
Vector3 forwardDir = rotation * Vector3.forward;
|
||||
Vector3 bottomRight = surfacePosition
|
||||
+ rightDir * size.x * (widthOffset);
|
||||
Vector3 bottomLeft = surfacePosition
|
||||
- rightDir * size.x * (1f - widthOffset);
|
||||
Vector3 topRight = bottomRight + forwardDir * size.z;
|
||||
|
||||
Vector3 rightHandle = DrawOffsetHandle(bottomRight + rightDir * snapOffset.x, rightDir);
|
||||
Vector3 leftHandle = DrawOffsetHandle(bottomLeft + rightDir * snapOffset.y, -rightDir);
|
||||
Vector3 topHandle = DrawOffsetHandle(topRight + forwardDir * snapOffset.z, forwardDir);
|
||||
Vector3 bottomHandle = DrawOffsetHandle(bottomRight + forwardDir * snapOffset.w, -forwardDir);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(surface, "Change Offset Box");
|
||||
Vector4 offset = snapOffset;
|
||||
offset.x = DistanceToHandle(bottomRight, rightHandle, rightDir);
|
||||
offset.y = DistanceToHandle(bottomLeft, leftHandle, rightDir);
|
||||
offset.z = DistanceToHandle(topRight, topHandle, forwardDir);
|
||||
offset.w = DistanceToHandle(bottomRight, bottomHandle, forwardDir);
|
||||
surface.SetSnapOffset(offset, relativeTo);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 DrawOffsetHandle(Vector3 point, Vector3 dir)
|
||||
{
|
||||
float size = HandleUtility.GetHandleSize(point) * 0.2f;
|
||||
return Handles.Slider(point, dir, size, Handles.ConeHandleCap, 0f);
|
||||
}
|
||||
|
||||
private float DistanceToHandle(Vector3 origin, Vector3 handlePoint, Vector3 dir)
|
||||
{
|
||||
float distance = Vector3.Distance(origin, handlePoint);
|
||||
if (Vector3.Dot(handlePoint - origin, dir) < 0f)
|
||||
{
|
||||
distance = -distance;
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
private void DrawRotator(BoxGrabSurface surface, Transform relativeTo)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Quaternion rotation = Handles.RotationHandle(
|
||||
surface.GetRotation(relativeTo),
|
||||
surface.GetReferencePose(relativeTo).position);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(surface, "Change Rotation Box");
|
||||
surface.SetRotation(rotation, relativeTo);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBoxEditor(BoxGrabSurface surface, Transform relativeTo)
|
||||
{
|
||||
Quaternion rot = surface.GetRotation(relativeTo);
|
||||
Vector3 size = surface.GetSize(relativeTo);
|
||||
float widthOffset = surface.GetWidthOffset(relativeTo);
|
||||
Vector3 snapP = surface.GetReferencePose(relativeTo).position;
|
||||
|
||||
_boxHandle.size = size;
|
||||
float widthPos = Mathf.Lerp(-size.x * 0.5f, size.x * 0.5f, widthOffset);
|
||||
_boxHandle.center = new Vector3(widthPos, 0f, size.z * 0.5f);
|
||||
|
||||
Matrix4x4 handleMatrix = Matrix4x4.TRS(
|
||||
snapP,
|
||||
rot,
|
||||
Vector3.one
|
||||
);
|
||||
|
||||
using (new Handles.DrawingScope(handleMatrix))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
_boxHandle.DrawHandle();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(surface, "Change Box Properties");
|
||||
|
||||
surface.SetSize(_boxHandle.size, relativeTo);
|
||||
float width = _boxHandle.size.x;
|
||||
if (width != 0f)
|
||||
{
|
||||
width = (_boxHandle.center.x + width * 0.5f) / width;
|
||||
}
|
||||
surface.SetWidthOffset(width, relativeTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user