173 lines
6.6 KiB
C#
173 lines
6.6 KiB
C#
/*
|
|
* 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(CylinderGrabSurface))]
|
|
[CanEditMultipleObjects]
|
|
public class CylinderGrabSurfaceEditor : UnityEditor.Editor
|
|
{
|
|
private const float DRAW_SURFACE_ANGULAR_RESOLUTION = 5f;
|
|
|
|
private ArcHandle _arcEndHandle = new ArcHandle();
|
|
private ArcHandle _arcStartHandle = new ArcHandle();
|
|
|
|
private Vector3[] _surfaceEdges;
|
|
|
|
private CylinderGrabSurface _surface;
|
|
private SerializedProperty _relativeToProperty;
|
|
private Transform _relativeTo;
|
|
|
|
private void OnEnable()
|
|
{
|
|
_arcStartHandle.SetColorWithRadiusHandle(EditorConstants.PRIMARY_COLOR_DISABLED, 0f);
|
|
_arcEndHandle.SetColorWithRadiusHandle(EditorConstants.PRIMARY_COLOR, 0f);
|
|
_surface = target as CylinderGrabSurface;
|
|
_relativeToProperty = serializedObject.FindProperty("_relativeTo");
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
base.OnInspectorGUI();
|
|
_relativeTo = _relativeToProperty.objectReferenceValue as Transform;
|
|
}
|
|
|
|
public void OnSceneGUI()
|
|
{
|
|
if (_relativeTo == null)
|
|
{
|
|
return;
|
|
}
|
|
DrawEndsCaps(_surface, _relativeTo);
|
|
|
|
float oldArcStart = _surface.ArcOffset;
|
|
Quaternion look = Quaternion.LookRotation(_surface.GetPerpendicularDir(_relativeTo), _surface.GetDirection(_relativeTo));
|
|
float newArcStart = DrawArcEditor(_surface, _arcStartHandle, _relativeTo,
|
|
oldArcStart,_surface.GetStartPoint(_relativeTo),
|
|
look);
|
|
|
|
_surface.ArcOffset = newArcStart;
|
|
_surface.ArcLength -= newArcStart - oldArcStart;
|
|
_surface.ArcLength = DrawArcEditor(_surface, _arcEndHandle, _relativeTo,
|
|
_surface.ArcLength,
|
|
_surface.GetStartPoint(_relativeTo),
|
|
Quaternion.LookRotation(_surface.GetStartArcDir(_relativeTo), _surface.GetDirection(_relativeTo)));
|
|
|
|
if (Event.current.type == EventType.Repaint)
|
|
{
|
|
DrawSurfaceVolume(_surface, _relativeTo);
|
|
}
|
|
}
|
|
|
|
private void DrawEndsCaps(CylinderGrabSurface surface, Transform relativeTo)
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
Quaternion handleRotation = relativeTo.rotation;
|
|
|
|
Vector3 startPosition = Handles.PositionHandle(surface.GetStartPoint(relativeTo), handleRotation);
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
Undo.RecordObject(surface, "Change Start Cylinder Position");
|
|
surface.SetStartPoint(startPosition, relativeTo);
|
|
}
|
|
EditorGUI.BeginChangeCheck();
|
|
Vector3 endPosition = Handles.PositionHandle(surface.GetEndPoint(relativeTo), handleRotation);
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
Undo.RecordObject(surface, "Change Start Cylinder Position");
|
|
surface.SetEndPoint(endPosition, relativeTo);
|
|
}
|
|
}
|
|
|
|
private void DrawSurfaceVolume(CylinderGrabSurface surface, Transform relativeTo)
|
|
{
|
|
Vector3 start = surface.GetStartPoint(relativeTo);
|
|
Vector3 end = surface.GetEndPoint(relativeTo);
|
|
Vector3 startArc = surface.GetStartArcDir(relativeTo);
|
|
Vector3 endArc = surface.GetEndArcDir(relativeTo);
|
|
Vector3 direction = surface.GetDirection(relativeTo);
|
|
|
|
float radius = surface.GetRadius(relativeTo);
|
|
|
|
Handles.color = EditorConstants.PRIMARY_COLOR;
|
|
Handles.DrawWireArc(end,
|
|
direction,
|
|
startArc,
|
|
surface.ArcLength,
|
|
radius);
|
|
|
|
Handles.DrawLine(start, end);
|
|
Handles.DrawLine(start, start + startArc * radius);
|
|
Handles.DrawLine(start, start + endArc * radius);
|
|
Handles.DrawLine(end, end + startArc * radius);
|
|
Handles.DrawLine(end, end + endArc * radius);
|
|
|
|
int edgePoints = Mathf.CeilToInt((2 * surface.ArcLength) / DRAW_SURFACE_ANGULAR_RESOLUTION) + 3;
|
|
if (_surfaceEdges == null
|
|
|| _surfaceEdges.Length != edgePoints)
|
|
{
|
|
_surfaceEdges = new Vector3[edgePoints];
|
|
}
|
|
|
|
Handles.color = EditorConstants.PRIMARY_COLOR_DISABLED;
|
|
int i = 0;
|
|
for (float angle = 0f; angle < surface.ArcLength; angle += DRAW_SURFACE_ANGULAR_RESOLUTION)
|
|
{
|
|
Vector3 dir = Quaternion.AngleAxis(angle, direction) * startArc;
|
|
_surfaceEdges[i++] = start + dir * radius;
|
|
_surfaceEdges[i++] = end + dir * radius;
|
|
}
|
|
_surfaceEdges[i++] = start + endArc * radius;
|
|
_surfaceEdges[i++] = end + endArc * radius;
|
|
Handles.DrawPolyLine(_surfaceEdges);
|
|
}
|
|
|
|
private float DrawArcEditor(CylinderGrabSurface surface, ArcHandle handle, Transform relativeTo,
|
|
float inputAngle, Vector3 position, Quaternion rotation)
|
|
{
|
|
handle.radius = surface.GetRadius(relativeTo);
|
|
handle.angle = inputAngle;
|
|
|
|
Matrix4x4 handleMatrix = Matrix4x4.TRS(
|
|
position,
|
|
rotation,
|
|
Vector3.one
|
|
);
|
|
|
|
using (new Handles.DrawingScope(handleMatrix))
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
handle.DrawHandle();
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
Undo.RecordObject(surface, "Change Cylinder Properties");
|
|
return handle.angle;
|
|
}
|
|
}
|
|
return inputAngle;
|
|
}
|
|
}
|
|
}
|