mirror of
https://github.com/originalnicodr/CinematicUnityExplorer.git
synced 2025-07-18 09:27:57 +08:00
Added gizmos (Mono compatibility only for now).
This commit is contained in:
@ -62,7 +62,10 @@ namespace UnityExplorer.UI.Panels
|
||||
}
|
||||
|
||||
public void ResetAnimation(){
|
||||
if (bonesManager != null) bonesManager.turnOffAnimatorToggle.isOn = true;
|
||||
if (bonesManager != null){
|
||||
bonesManager.turnOffAnimatorToggle.isOn = true;
|
||||
bonesManager.DisableGizmos();
|
||||
}
|
||||
// Let the game change animations again
|
||||
animator.StopPlayback();
|
||||
if (originalAnimatorController != null && animator.wrappedObject != null){
|
||||
|
@ -17,6 +17,7 @@ namespace UnityExplorer.UI.Panels
|
||||
public AxisComponentControl CurrentSlidingAxisControl { get; set; }
|
||||
public BonesManager Owner;
|
||||
private ButtonRef inspectButton;
|
||||
private Dropdown gizmoDropdown;
|
||||
|
||||
// ICell
|
||||
public float DefaultHeight => 25f;
|
||||
@ -52,6 +53,20 @@ namespace UnityExplorer.UI.Panels
|
||||
UIFactory.SetLayoutElement(inspectButton.GameObject, minWidth: 150, minHeight: 25);
|
||||
inspectButton.OnClick += () => InspectorManager.Inspect(bone.gameObject);
|
||||
|
||||
GameObject gizmoObj = UIFactory.CreateDropdown(header, "Gizmo_Dropdown", out gizmoDropdown, null, 14, (idx) => {
|
||||
if (Owner.turnOffAnimatorToggle.isOn) Owner.turnOffAnimatorToggle.isOn = false;
|
||||
ExplorerBehaviour.GizmoTools.targetTransform = bone;
|
||||
ExplorerBehaviour.GizmoTools.ChangeGizmo((GizmoType)idx);
|
||||
}
|
||||
);
|
||||
UIFactory.SetLayoutElement(gizmoObj, minHeight: 25, minWidth: 150);
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("No Gizmo"));
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("Local Position"));
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("Local Rotation"));
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("Global Position"));
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("Global Rotation"));
|
||||
gizmoDropdown.captionText.text = "No Gizmo";
|
||||
|
||||
GameObject headerButtons = UIFactory.CreateUIObject("BoneHeader", header);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(headerButtons, false, false, true, true, 4, childAlignment: TextAnchor.MiddleRight);
|
||||
UIFactory.SetLayoutElement(headerButtons, minHeight: 25, flexibleWidth: 9999, flexibleHeight: 800);
|
||||
@ -75,6 +90,12 @@ namespace UnityExplorer.UI.Panels
|
||||
bone.gameObject.SetActive(value);
|
||||
}
|
||||
|
||||
public void DisableGizmo(){
|
||||
if (gizmoDropdown.value != 0){
|
||||
gizmoDropdown.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TransformControls-like functions
|
||||
public void UpdateTransformControlValues(bool force){
|
||||
positionControl.Update(force);
|
||||
|
@ -18,6 +18,7 @@ namespace UnityExplorer
|
||||
public class ExplorerBehaviour : MonoBehaviour
|
||||
{
|
||||
internal static ExplorerBehaviour Instance { get; private set; }
|
||||
static public ExtendedTransformTools GizmoTools { get; private set; }
|
||||
|
||||
#if CPP
|
||||
public ExplorerBehaviour(System.IntPtr ptr) : base(ptr) { }
|
||||
@ -33,6 +34,7 @@ namespace UnityExplorer
|
||||
DontDestroyOnLoad(obj);
|
||||
obj.hideFlags = HideFlags.HideAndDontSave;
|
||||
Instance = obj.AddComponent<ExplorerBehaviour>();
|
||||
GizmoTools = obj.AddComponent<ExtendedTransformTools>();
|
||||
}
|
||||
|
||||
internal void Update()
|
||||
|
126
src/GizmosLibraryPlugin/ExtendedTransformTools.cs
Normal file
126
src/GizmosLibraryPlugin/ExtendedTransformTools.cs
Normal file
@ -0,0 +1,126 @@
|
||||
// Credits to https://github.com/Vesper-Works/Unity-Explorer-For-Outer-Wilds/
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
using GizmosLibraryPlugin;
|
||||
using UnityExplorer.Inspectors;
|
||||
using UnityExplorer.TransformGizmos;
|
||||
|
||||
using UniverseLib.Input;
|
||||
|
||||
#if INTEROP
|
||||
using Il2CppInterop.Runtime.Injection;
|
||||
#endif
|
||||
|
||||
namespace UnityExplorer
|
||||
{
|
||||
public enum GizmoType
|
||||
{
|
||||
None,
|
||||
LocalPosition,
|
||||
LocalRotation,
|
||||
GlobalPosition,
|
||||
GlobalRotation
|
||||
}
|
||||
|
||||
public class ExtendedTransformTools : MonoBehaviour
|
||||
{
|
||||
#if CPP
|
||||
static ExtendedTransformTools()
|
||||
{
|
||||
ClassInjector.RegisterTypeInIl2Cpp<ExtendedTransformTools>();
|
||||
}
|
||||
|
||||
public ExtendedTransformTools(IntPtr ptr) : base(ptr) { }
|
||||
#endif
|
||||
public Transform targetTransform;
|
||||
|
||||
float maxDistanceToSelect = 0.05f;
|
||||
|
||||
private List<BaseTransformGizmo> EnabledGizmos = new();
|
||||
|
||||
private List<BaseTransformGizmo> NewGizmo(GizmoType type){
|
||||
List<BaseTransformGizmo> returnList = new List<BaseTransformGizmo>();
|
||||
switch(type){
|
||||
case GizmoType.LocalPosition:
|
||||
returnList.Add(new LocalPositionGizmo());
|
||||
break;
|
||||
case GizmoType.LocalRotation:
|
||||
returnList.Add(new LocalEulerAngleGizmo());
|
||||
break;
|
||||
case GizmoType.GlobalPosition:
|
||||
returnList.Add(new TransformOrientationGizmo());
|
||||
break;
|
||||
case GizmoType.GlobalRotation:
|
||||
returnList.Add(new LocalEulerAngleGizmo());
|
||||
returnList.Add(new FromCameraViewRotationGizmo());
|
||||
break;
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public void ChangeGizmo(GizmoType type) {
|
||||
EnabledGizmos.Clear();
|
||||
if (type != GizmoType.None){
|
||||
EnabledGizmos.AddRange(NewGizmo(type));
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (targetTransform == null){
|
||||
EnabledGizmos.ForEach((gizmo) => gizmo.Reset());
|
||||
return;
|
||||
}
|
||||
|
||||
float scale = Vector3.Distance(Camera.current.transform.position, targetTransform.position) / 5f;
|
||||
|
||||
EnabledGizmos.ForEach((gizmo) =>
|
||||
{
|
||||
gizmo.SetScale(scale);
|
||||
gizmo.Set(targetTransform);
|
||||
});
|
||||
|
||||
Ray ray = Camera.current.ScreenPointToRay(IInputManager.MousePosition);
|
||||
|
||||
if (IInputManager.GetMouseButtonDown(0))
|
||||
{
|
||||
bool noneIsSelected = EnabledGizmos.TrueForAll((gizmo) => !gizmo.IsSelected());
|
||||
|
||||
if (noneIsSelected)
|
||||
{
|
||||
EnabledGizmos.ForEach((gizmo) => gizmo.CheckSelected(ray, maxDistanceToSelect * scale));
|
||||
}
|
||||
}
|
||||
else if (IInputManager.GetMouseButton(0))
|
||||
{
|
||||
EnabledGizmos.ForEach((gizmo) =>
|
||||
{
|
||||
if (gizmo.IsSelected())
|
||||
{
|
||||
gizmo.OnSelected(ray);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
EnabledGizmos.ForEach((gizmo) => gizmo.Reset());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void OnRenderObject()
|
||||
{
|
||||
if (targetTransform == null)
|
||||
return;
|
||||
|
||||
GL.wireframe = true;
|
||||
|
||||
GLHelper.SetDefaultMaterialPass(0, true);
|
||||
|
||||
EnabledGizmos.ForEach((gizmo) => gizmo.OnRender());
|
||||
|
||||
GL.wireframe = false;
|
||||
}
|
||||
}
|
||||
}
|
289
src/GizmosLibraryPlugin/GLDraw.cs
Normal file
289
src/GizmosLibraryPlugin/GLDraw.cs
Normal file
@ -0,0 +1,289 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityExplorer;
|
||||
|
||||
namespace GizmosLibraryPlugin
|
||||
{
|
||||
public static class GLDraw
|
||||
{
|
||||
|
||||
//GL.LINES = 1
|
||||
|
||||
/// <summary>
|
||||
/// Draws a cube that follows the Vector.foward, Vector.up and Vector.right axis with center in offset.
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="color"></param>
|
||||
public static void SimpleWireframeCube(Vector3 offset, Color color)
|
||||
{
|
||||
WireframeCube(Vector3.forward, Vector3.up, Vector3.right, offset, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a cube that follows the specified axis with center in offset.
|
||||
/// </summary>
|
||||
/// <param name="foward"></param>
|
||||
/// <param name="up"></param>
|
||||
/// <param name="right"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="color"></param>
|
||||
public static void WireframeCube(Vector3 foward, Vector3 up, Vector3 right, Vector3 offset, Color color)
|
||||
{
|
||||
Vector3[] vertex = new Vector3[4];
|
||||
vertex[0] = (foward + right) / 2f;
|
||||
vertex[1] = (-foward + right) / 2f;
|
||||
vertex[2] = (-foward - right) / 2f;
|
||||
vertex[3] = (foward - right) / 2f;
|
||||
|
||||
//GL.Begin(GL.LINE_STRIP);
|
||||
GL.Begin(GL.LINES);
|
||||
GL.Color(color);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
GL.Vertex(vertex[i] + offset - up / 2f);
|
||||
}
|
||||
GL.Vertex(vertex[0] + offset - up / 2f); ;
|
||||
GL.End();
|
||||
|
||||
//GL.Begin(GL.LINE_STRIP);
|
||||
GL.Begin(GL.LINES);
|
||||
GL.Color(color);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
GL.Vertex(vertex[i] + offset + up / 2f);
|
||||
}
|
||||
GL.Vertex(vertex[0] + offset + up / 2f);
|
||||
GL.End();
|
||||
|
||||
GL.Begin(GL.LINES);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
GL.Color(color);
|
||||
GL.Vertex(vertex[i] + offset - up / 2f);
|
||||
GL.Vertex(vertex[i] + offset + up / 2f);
|
||||
}
|
||||
GL.End();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a circle on a plane facing the specified normal, centered in offset with the angle 0 meaning the same direction as up.
|
||||
/// </summary>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="normal"></param>
|
||||
/// <param name="up"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="resolution"></param>
|
||||
/// <param name="startAngle"></param>
|
||||
/// <param name="endAngle"></param>
|
||||
/// <param name="isWholeCircle">If it is a 2 PI circle you then need to set this to true</param>
|
||||
public static void WireframeCircle(float radius, Vector3 normal, Vector3 up, Vector3 offset, Color color, int resolution = 3, float startAngle = 0f, float endAngle = 2f * Mathf.PI, bool isWholeCircle = true)
|
||||
{
|
||||
if (resolution < 3 || radius <= 0f)
|
||||
return;
|
||||
normal = normal.normalized;
|
||||
up = up.normalized;
|
||||
|
||||
//GL.Begin(GL.LINE_STRIP);
|
||||
GL.Begin(GL.LINES);
|
||||
|
||||
float angleStep = (endAngle - startAngle) / resolution;
|
||||
int aditionalSteps = isWholeCircle ? 1 : 0;
|
||||
|
||||
GL.Color(color);
|
||||
Vector3 rotationVector = Vector3MathUtils.GetRotationVector(normal, up);
|
||||
for (int i = 0; i <= resolution + aditionalSteps; i++)
|
||||
{
|
||||
Vector3 radiusVector = Vector3MathUtils.GetRotatedVectorComponent(rotationVector, up, angleStep * i + startAngle);
|
||||
GL.Vertex(radiusVector * radius + offset);
|
||||
}
|
||||
GL.End();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a sphere centered on offset following the Vector.foward, Vector.up and Vector.right axis.
|
||||
/// </summary>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="resolution"></param>
|
||||
public static void SimpleWireframeSphere(float radius, Vector3 offset, Color color, int resolution)
|
||||
{
|
||||
WireframeCircle(radius, Vector3.up, Vector3.forward, offset, color, resolution);
|
||||
WireframeCircle(radius, Vector3.forward, Vector3.right, offset, color, resolution);
|
||||
WireframeCircle(radius, Vector3.right, Vector3.up, offset, color, resolution);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a sphere centered on offset following the specified axis.
|
||||
/// </summary>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="foward"></param>
|
||||
/// <param name="up"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="resolution"></param>
|
||||
public static void WireframeSphere(float radius, Vector3 offset, Vector3 foward, Vector3 up, Color color, int resolution = 3)
|
||||
{
|
||||
Vector3 right = Vector3.Cross(foward, up);
|
||||
WireframeCircle(radius, up, foward, offset, color, resolution);
|
||||
WireframeCircle(radius, foward, right, offset, color, resolution);
|
||||
WireframeCircle(radius, right, up, offset, color, resolution);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws half a sphere centered on offset facing the up direction.
|
||||
/// </summary>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="foward"></param>
|
||||
/// <param name="up"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="resolution"></param>
|
||||
public static void WireframeHemisphere(float radius, Vector3 offset, Vector3 foward, Vector3 up, Color color, int resolution = 3)
|
||||
{
|
||||
Vector3 right = Vector3.Cross(foward, up);
|
||||
WireframeCircle(radius, up, foward, offset, color, resolution, -Mathf.PI / 2f, Mathf.PI / 2f, false);
|
||||
WireframeCircle(radius, foward, right, offset, color, resolution);
|
||||
WireframeCircle(radius, right, foward, offset, color, resolution, -Mathf.PI / 2f, Mathf.PI / 2f, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a capsule with the startPoint and endPoint being the center of the spheres on its extreme.
|
||||
/// </summary>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="startPoint"></param>
|
||||
/// <param name="endPoint"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="resolution"></param>
|
||||
public static void WireframeCapsule(float radius, Vector3 startPoint, Vector3 endPoint, Color color, int resolution = 3)
|
||||
{
|
||||
Vector3 direction = startPoint - endPoint;
|
||||
Vector3 randomUpVector = Vector3MathUtils.GetArbitraryPerpendicularVector(direction);
|
||||
|
||||
//Top and bottom Spheres
|
||||
WireframeHemisphere(radius, startPoint, direction, randomUpVector, color, resolution);
|
||||
WireframeHemisphere(radius, endPoint, -direction, -randomUpVector, color, resolution);
|
||||
|
||||
GL.Begin(GL.LINES);
|
||||
float angleStep = 2f * Mathf.PI / resolution;
|
||||
Vector3 rotationVector = Vector3MathUtils.GetRotationVector(direction.normalized, randomUpVector);
|
||||
for (int i = 0; i <= resolution; i++)
|
||||
{
|
||||
Vector3 radiusVector = Vector3MathUtils.GetRotatedVectorComponent(rotationVector, randomUpVector, angleStep * i);
|
||||
Vector3 vertex1 = radiusVector * radius + startPoint;
|
||||
Vector3 vertex2 = radiusVector * radius + endPoint;
|
||||
|
||||
GL.Color(color);
|
||||
GL.Vertex(vertex1);
|
||||
GL.Vertex(vertex2);
|
||||
}
|
||||
GL.End();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a capsule oriented with the Vector.up direction.
|
||||
/// </summary>
|
||||
/// <param name="radius"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <param name="up"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="resolution"></param>
|
||||
public static void SimpleWireframeCapsule(float radius, float height, Vector3 up, Vector3 offset, Color color, int resolution = 3)
|
||||
{
|
||||
Vector3 randomFowardVector = Vector3MathUtils.GetArbitraryPerpendicularVector(up);
|
||||
//Top and bottom Spheres
|
||||
WireframeSphere(radius, offset - up * height / 2f, randomFowardVector, up, color, resolution);
|
||||
WireframeSphere(radius, offset + up * height / 2f, randomFowardVector, up, color, resolution);
|
||||
|
||||
GL.Begin(GL.LINES);
|
||||
float angleStep = 2f * Mathf.PI / resolution;
|
||||
Vector3 rotationVector = Vector3MathUtils.GetRotationVector(up.normalized, randomFowardVector);
|
||||
for (int i = 0; i <= resolution; i++)
|
||||
{
|
||||
Vector3 radiusVector = Vector3MathUtils.GetRotatedVectorComponent(rotationVector, randomFowardVector, angleStep * i);
|
||||
Vector3 vertex1 = radiusVector * radius + offset - up * height / 2f;
|
||||
Vector3 vertex2 = radiusVector * radius + offset + up * height / 2f;
|
||||
|
||||
GL.Color(color);
|
||||
GL.Vertex(vertex1);
|
||||
GL.Vertex(vertex2);
|
||||
}
|
||||
GL.End();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws a cone with specifiend star and end positions as well as start and end radius (for cone trunks). It can be used to draw cylinder too.
|
||||
/// </summary>
|
||||
/// <param name="coneRadiusStart"></param>
|
||||
/// <param name="coneRadiusEnd"></param>
|
||||
/// <param name="coneStart"></param>
|
||||
/// <param name="coneEnd"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="resolution"></param>
|
||||
public static void WireframeCone(float coneRadiusStart, float coneRadiusEnd, Vector3 coneStart, Vector3 coneEnd, Color color, int resolution = 3)
|
||||
{
|
||||
Vector3 direction = coneEnd - coneStart;
|
||||
Vector3 randomFowardVector = Vector3MathUtils.GetArbitraryPerpendicularVector(direction);
|
||||
//Start Circle
|
||||
WireframeCircle(coneRadiusStart, direction, randomFowardVector, coneStart, color, resolution);
|
||||
//End Circle
|
||||
WireframeCircle(coneRadiusEnd, direction, randomFowardVector, coneEnd, color, resolution);
|
||||
//Connecting Lines
|
||||
GL.Begin(GL.LINES);
|
||||
float angleStep = 2f * Mathf.PI / resolution;
|
||||
Vector3 rotationVector = Vector3MathUtils.GetRotationVector(direction.normalized, randomFowardVector);
|
||||
for (int i = 0; i <= resolution; i++)
|
||||
{
|
||||
Vector3 radiusVector = Vector3MathUtils.GetRotatedVectorComponent(rotationVector, randomFowardVector, angleStep * i);
|
||||
Vector3 vertex1 = radiusVector * coneRadiusStart + coneStart;
|
||||
Vector3 vertex2 = radiusVector * coneRadiusEnd + coneEnd;
|
||||
|
||||
GL.Color(color);
|
||||
GL.Vertex(vertex1);
|
||||
GL.Vertex(vertex2);
|
||||
}
|
||||
GL.End();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the direction of a vector as a 3d arrow starting on the offset.
|
||||
/// </summary>
|
||||
/// <param name="vector"></param>
|
||||
/// <param name="headSize"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="color"></param>
|
||||
public static void Vector(Vector3 vector, float headSize, Vector3 offset, Color color)
|
||||
{
|
||||
if (vector.magnitude <= 0f)
|
||||
return;
|
||||
|
||||
GL.Begin(GL.LINES);
|
||||
GL.Color(color);
|
||||
//Main arrow body
|
||||
GL.Vertex(offset);
|
||||
Vector3 endPoint = vector + offset;
|
||||
GL.Vertex(endPoint);
|
||||
//Head of the arrow
|
||||
Vector3 direction = vector.normalized;
|
||||
Vector3 firstHeadDirection = Vector3MathUtils.GetArbitraryPerpendicularVector(vector);
|
||||
Vector3 secondHeadDirection = Vector3.Cross(direction, firstHeadDirection);
|
||||
|
||||
GL.Vertex(endPoint);
|
||||
GL.Vertex((firstHeadDirection - direction).normalized * headSize + endPoint);
|
||||
|
||||
GL.Vertex(endPoint);
|
||||
GL.Vertex(-(firstHeadDirection + direction).normalized * headSize + endPoint);
|
||||
|
||||
GL.Vertex(endPoint);
|
||||
GL.Vertex((secondHeadDirection - direction).normalized * headSize + endPoint);
|
||||
|
||||
GL.Vertex(endPoint);
|
||||
GL.Vertex(-(secondHeadDirection + direction).normalized * headSize + endPoint);
|
||||
|
||||
GL.End();
|
||||
}
|
||||
}
|
||||
}
|
128
src/GizmosLibraryPlugin/GLHelper.cs
Normal file
128
src/GizmosLibraryPlugin/GLHelper.cs
Normal file
@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GizmosLibraryPlugin
|
||||
{
|
||||
public static class GLHelper
|
||||
{
|
||||
static Material defaultGizmosMaterial;
|
||||
static Material alwaysDrawOnTopDefaultGizmosMaterial;
|
||||
public static Material GetDefaultMaterial()
|
||||
{
|
||||
if (!defaultGizmosMaterial)
|
||||
{
|
||||
Shader shader = Shader.Find("Hidden/Internal-Colored");
|
||||
defaultGizmosMaterial = new Material(shader)
|
||||
{
|
||||
hideFlags = HideFlags.HideAndDontSave
|
||||
};
|
||||
// Turn on alpha blending
|
||||
defaultGizmosMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||||
defaultGizmosMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||||
// Turn backface culling off
|
||||
defaultGizmosMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
|
||||
// Turn off depth writes
|
||||
defaultGizmosMaterial.SetInt("_ZWrite", 0);
|
||||
}
|
||||
return defaultGizmosMaterial;
|
||||
}
|
||||
public static void SetDefaultMaterialPass(int pass = 0, bool alwaysDrawOnTop = false)
|
||||
{
|
||||
if(!alwaysDrawOnTop)
|
||||
GetDefaultMaterial().SetPass(pass);
|
||||
else
|
||||
GetAlwaysDrawOnTopDefaultMaterial().SetPass(pass);
|
||||
}
|
||||
public static Material GetAlwaysDrawOnTopDefaultMaterial()
|
||||
{
|
||||
if (!alwaysDrawOnTopDefaultGizmosMaterial)
|
||||
{
|
||||
Shader shader = Shader.Find("Hidden/Internal-Colored");
|
||||
alwaysDrawOnTopDefaultGizmosMaterial = new Material(shader)
|
||||
{
|
||||
hideFlags = HideFlags.HideAndDontSave
|
||||
};
|
||||
// Turn on alpha blending
|
||||
alwaysDrawOnTopDefaultGizmosMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||||
alwaysDrawOnTopDefaultGizmosMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||||
// Turn backface culling off
|
||||
alwaysDrawOnTopDefaultGizmosMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
|
||||
// Turn off depth writes
|
||||
//From https://answers.unity.com/questions/1674373/rendering-gl-lines-z-order-manipulation.html
|
||||
alwaysDrawOnTopDefaultGizmosMaterial.SetInt("_ZWrite", -10);
|
||||
alwaysDrawOnTopDefaultGizmosMaterial.SetInt("_ZTest", (int)UnityEngine.Rendering.CompareFunction.Disabled);
|
||||
}
|
||||
return alwaysDrawOnTopDefaultGizmosMaterial;
|
||||
}
|
||||
public static void DrawWithReference(Transform reference, Action drawMethod)
|
||||
{
|
||||
GL.PushMatrix();
|
||||
GL.MultMatrix(reference.localToWorldMatrix);
|
||||
drawMethod?.Invoke();
|
||||
GL.PopMatrix();
|
||||
}
|
||||
public static void DrawOnGlobalReference(Action drawMethod)
|
||||
{
|
||||
GL.PushMatrix();
|
||||
GL.MultMatrix(Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one));
|
||||
drawMethod?.Invoke();
|
||||
GL.PopMatrix();
|
||||
}
|
||||
public static void DrawWithOrthoProjection(Action drawMethod)
|
||||
{
|
||||
GL.PushMatrix();
|
||||
GL.LoadOrtho();
|
||||
drawMethod?.Invoke();
|
||||
GL.PopMatrix();
|
||||
}
|
||||
|
||||
public static void DrawAxis(float headSize, Color color, Vector3 offset)
|
||||
{
|
||||
GLDraw.Vector(Vector3.up, headSize, offset, color);
|
||||
GLDraw.Vector(Vector3.forward, headSize, offset, color);
|
||||
GLDraw.Vector(Vector3.right, headSize, offset, color);
|
||||
}
|
||||
public static void DrawAxis(float headSize, Color upColor, Color fowardColor, Color rightColor, Vector3 offset)
|
||||
{
|
||||
GLDraw.Vector(Vector3.up, headSize, offset, upColor);
|
||||
GLDraw.Vector(Vector3.forward, headSize, offset, fowardColor);
|
||||
GLDraw.Vector(Vector3.right, headSize, offset, rightColor);
|
||||
}
|
||||
public static void DrawTransform(Transform transform, float headSize, Color color)
|
||||
{
|
||||
GLDraw.Vector(transform.up * transform.lossyScale.x, headSize, transform.position, color);
|
||||
GLDraw.Vector(transform.forward * transform.lossyScale.z, headSize, transform.position, color);
|
||||
GLDraw.Vector(transform.right * transform.lossyScale.y, headSize, transform.position, color);
|
||||
}
|
||||
public static void DrawTransform(Transform transform, float headSize, Color upColor, Color fowardColor, Color rightColor)
|
||||
{
|
||||
GLDraw.Vector(transform.up * transform.lossyScale.x, headSize, transform.position, upColor);
|
||||
GLDraw.Vector(transform.forward * transform.lossyScale.z, headSize, transform.position, fowardColor);
|
||||
GLDraw.Vector(transform.right * transform.lossyScale.y, headSize, transform.position, rightColor);
|
||||
}
|
||||
public static void DrawColliderBoundingBox(Collider collider, Color color)
|
||||
{
|
||||
Bounds box = collider.bounds;
|
||||
GLDraw.WireframeCube(Vector3.forward * box.size.z, Vector3.up * box.size.y, Vector3.right * box.size.z, box.center, color);
|
||||
}
|
||||
public static void DrawCollider(Collider collider, Color color)
|
||||
{
|
||||
const int resolution = 12;
|
||||
if (collider is BoxCollider)
|
||||
{
|
||||
BoxCollider box = collider as BoxCollider;
|
||||
GLDraw.WireframeCube(Vector3.forward * box.size.z, Vector3.up * box.size.y, Vector3.right * box.size.z, box.center, color);
|
||||
}
|
||||
else if (collider is SphereCollider)
|
||||
{
|
||||
SphereCollider sphere = collider as SphereCollider;
|
||||
GLDraw.WireframeSphere(sphere.radius, sphere.center, Vector3.forward, Vector3.up, color, resolution);
|
||||
}
|
||||
else if (collider is CapsuleCollider)
|
||||
{
|
||||
CapsuleCollider capsule = collider as CapsuleCollider;
|
||||
GLDraw.WireframeCapsule(capsule.radius, capsule.center + capsule.height * Vector3.up / 2f, capsule.center - capsule.height * Vector3.up / 2f, color, resolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
56
src/GizmosLibraryPlugin/GizmoControls/ArrowControl.cs
Normal file
56
src/GizmosLibraryPlugin/GizmoControls/ArrowControl.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using GizmosLibraryPlugin;
|
||||
namespace UnityExplorer.GizmoControls
|
||||
{
|
||||
internal class ArrowControl : BaseControl<Vector3>
|
||||
{
|
||||
private Vector3 selectedPosition;
|
||||
|
||||
public Transform Transform;
|
||||
|
||||
public Func<Transform, Vector3> Direction = (t) => Vector3.up;
|
||||
|
||||
public float Lenght;
|
||||
public float HeadLenght;
|
||||
|
||||
public float MaxDistanceToSelect;
|
||||
|
||||
public Color Color;
|
||||
public Color SelectedColor;
|
||||
|
||||
|
||||
public override Vector3 GetValue(Ray ray)
|
||||
{
|
||||
Vector3 direction = Direction(Transform);
|
||||
Vector3MathUtils.GetClosestPointFromLines(ray.direction, ray.origin, direction, Transform.position, out _, out Vector3 currentSelectedPosition);
|
||||
currentSelectedPosition = Vector3MathUtils.GetPositionWithReferencial(Transform, currentSelectedPosition);
|
||||
float distanceWihReference = Vector3.Dot(currentSelectedPosition - selectedPosition, Vector3MathUtils.GetDirectionWithReferencial(Transform, direction));
|
||||
|
||||
return distanceWihReference * Vector3MathUtils.GetDirectionWithReferencial(Transform, direction);
|
||||
}
|
||||
|
||||
public override bool IsSelected(Ray ray)
|
||||
{
|
||||
Vector3 direction = Direction(Transform);
|
||||
|
||||
if (Vector3MathUtils.GetDistanceFromLineToLineSegment(ray.direction, ray.origin, Transform.position, Transform.position + direction * Lenght * Scale) <= MaxDistanceToSelect)
|
||||
{
|
||||
Selected = true;
|
||||
Vector3MathUtils.GetClosestPointFromLines(ray.direction, ray.origin, direction, Transform.position, out _, out selectedPosition);
|
||||
selectedPosition = Vector3MathUtils.GetPositionWithReferencial(Transform, selectedPosition);
|
||||
}
|
||||
return Selected;
|
||||
}
|
||||
public override void Draw()
|
||||
{
|
||||
Vector3 direction = Direction(Transform);
|
||||
|
||||
GLHelper.DrawOnGlobalReference(() =>
|
||||
{
|
||||
Color color = Selected ? SelectedColor : Color;
|
||||
GLDraw.Vector(direction * Lenght * Scale, HeadLenght * Scale, Transform.position, color);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
17
src/GizmosLibraryPlugin/GizmoControls/BaseControl.cs
Normal file
17
src/GizmosLibraryPlugin/GizmoControls/BaseControl.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer.GizmoControls
|
||||
{
|
||||
public abstract class BaseControl<T>
|
||||
{
|
||||
public float Scale = 1f;
|
||||
public bool Selected { get; protected set; } = false;
|
||||
public abstract bool IsSelected(Ray ray);
|
||||
public abstract void Draw();
|
||||
public abstract T GetValue(Ray ray);
|
||||
public virtual void Reset()
|
||||
{
|
||||
Selected = false;
|
||||
}
|
||||
}
|
||||
}
|
64
src/GizmosLibraryPlugin/GizmoControls/CircleControl.cs
Normal file
64
src/GizmosLibraryPlugin/GizmoControls/CircleControl.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using GizmosLibraryPlugin;
|
||||
|
||||
namespace UnityExplorer.GizmoControls
|
||||
{
|
||||
public class CircleControl : BaseControl<float>
|
||||
{
|
||||
private Vector3 selectedPosition;
|
||||
|
||||
private Vector3 selectedFowardDirection;
|
||||
|
||||
public Transform Transform;
|
||||
|
||||
public float DistanceForFullRevolution = 4f;
|
||||
|
||||
public Func<Transform, Vector3> Normal = (t) => Vector3.up;
|
||||
|
||||
public float Radius;
|
||||
|
||||
public float MaxDistanceToSelect;
|
||||
|
||||
public Color Color;
|
||||
public Color SelectedColor;
|
||||
|
||||
|
||||
public override float GetValue(Ray ray)
|
||||
{
|
||||
Vector3 foward = Vector3MathUtils.ReturnDirectionWithReferencial(Transform, selectedFowardDirection);
|
||||
|
||||
Vector3MathUtils.GetClosestPointFromLines(ray.direction, ray.origin, foward, Transform.position, out _, out Vector3 currentXSelectedPosition);
|
||||
currentXSelectedPosition = Vector3MathUtils.GetPositionWithReferencial(Transform, currentXSelectedPosition);
|
||||
float distanceWihReference = Vector3.Dot(currentXSelectedPosition - selectedPosition, selectedFowardDirection);
|
||||
return distanceWihReference * 360f / DistanceForFullRevolution;
|
||||
}
|
||||
|
||||
public override bool IsSelected(Ray ray)
|
||||
{
|
||||
Vector3 normal = Normal(Transform);
|
||||
if (Vector3MathUtils.GetClosestPointFromLineToCircle(ray.direction, ray.origin, Transform.position, normal, Radius * Scale, out bool lineParalelToCircle, out bool isEquidistant, out Vector3 selectedPoint) <= MaxDistanceToSelect)
|
||||
{
|
||||
if (!lineParalelToCircle && !isEquidistant)
|
||||
{
|
||||
selectedPosition = selectedPoint;
|
||||
selectedPosition = Vector3MathUtils.GetPositionWithReferencial(Transform, selectedPosition);
|
||||
selectedFowardDirection = Vector3.Cross(normal, (selectedPoint - Transform.position).normalized);
|
||||
selectedFowardDirection = Vector3MathUtils.GetDirectionWithReferencial(Transform, selectedFowardDirection);
|
||||
Selected = true;
|
||||
}
|
||||
}
|
||||
return Selected;
|
||||
}
|
||||
public override void Draw()
|
||||
{
|
||||
Vector3 normal = Normal(Transform);
|
||||
GLHelper.DrawOnGlobalReference(() =>
|
||||
{
|
||||
Vector3 randomUp = Vector3MathUtils.GetArbitraryPerpendicularVector(normal);
|
||||
Color color = Selected ? SelectedColor : Color;
|
||||
GLDraw.WireframeCircle(Radius * Scale, normal, randomUp, Transform.position, color, 16);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
40
src/GizmosLibraryPlugin/GizmosAPI.cs
Normal file
40
src/GizmosLibraryPlugin/GizmosAPI.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GizmosLibraryPlugin
|
||||
{
|
||||
|
||||
public static class GizmosAPI
|
||||
{
|
||||
//GLHelper
|
||||
public static Material GetDefaultMaterial() => GLHelper.GetDefaultMaterial();
|
||||
public static void SetDefaultMaterialPass(int pass = 0) => GLHelper.SetDefaultMaterialPass(pass);
|
||||
public static void DrawWithReference(Transform reference, Action drawMethod) => GLHelper.DrawWithReference(reference, drawMethod);
|
||||
public static void DrawOnGlobalReference(Action drawMethod) => GLHelper.DrawOnGlobalReference(drawMethod);
|
||||
public static void DrawWithOrthoProjection(Action drawMethod) => GLHelper.DrawWithOrthoProjection(drawMethod);
|
||||
public static void DrawAxis(float headSize, Color color, Vector3 offset) => GLHelper.DrawAxis(headSize, color, offset);
|
||||
public static void DrawAxis(float headSize, Color upColor, Color fowardColor, Color rightColor, Vector3 offset) => GLHelper.DrawAxis(headSize, upColor, fowardColor, rightColor, offset);
|
||||
public static void DrawTransform(Transform transform, float headSize, Color color) => GLHelper.DrawTransform(transform, headSize, color);
|
||||
public static void DrawTransform(Transform transform, float headSize, Color upColor, Color fowardColor, Color rightColor) => GLHelper.DrawTransform(transform, headSize, upColor, fowardColor, rightColor);
|
||||
public static void DrawCollider(Collider collider, Color color) => GLHelper.DrawCollider(collider, color);
|
||||
public static void DrawColliderBoundingBox(Collider collider, Color color) => GLHelper.DrawColliderBoundingBox(collider, color);
|
||||
//GLDraw
|
||||
public static void DrawSimpleWireframeCube(Vector3 offset, Color color) => GLDraw.SimpleWireframeCube(offset, color);
|
||||
public static void DrawWireframeCube(Vector3 foward, Vector3 up, Vector3 right, Vector3 offset, Color color) => GLDraw.WireframeCube(foward, up, right, offset, color);
|
||||
public static void DrawWireframeCircle(float radius, Vector3 normal, Vector3 up, Vector3 offset, Color color, int resolution = 3, float startAngle = 0f, float endAngle = 2f * Mathf.PI, bool isWholeCircle = true)
|
||||
=> GLDraw.WireframeCircle(radius, normal, up, offset, color, resolution, startAngle, endAngle, isWholeCircle);
|
||||
public static void DrawSimpleWireframeSphere(float radius, Vector3 offset, Color color, int resolution)
|
||||
=> GLDraw.SimpleWireframeSphere(radius, offset, color, resolution);
|
||||
public static void DrawWireframeSphere(float radius, Vector3 offset, Vector3 foward, Vector3 up, Color color, int resolution = 3)
|
||||
=> GLDraw.WireframeSphere(radius, offset, foward, up, color, resolution);
|
||||
public static void DrawWireframeHemisphere(float radius, Vector3 offset, Vector3 foward, Vector3 up, Color color, int resolution = 3)
|
||||
=> GLDraw.WireframeHemisphere(radius, offset, foward, up, color, resolution);
|
||||
public static void DrawWireframeCapsule(float radius, Vector3 startPoint, Vector3 endPoint, Color color, int resolution = 3)
|
||||
=> GLDraw.WireframeCapsule(radius, startPoint, endPoint, color, resolution);
|
||||
public static void DrawSimpleWireframeCapsule(float radius, float height, Vector3 up, Vector3 offset, Color color, int resolution = 3)
|
||||
=> GLDraw.SimpleWireframeCapsule(radius, height, up, offset, color, resolution);
|
||||
public static void DrawWireframeCone(float coneRadiusStart, float coneRadiusEnd, Vector3 coneStart, Vector3 coneEnd, Color color, int resolution = 3)
|
||||
=> GLDraw.WireframeCone(coneRadiusStart, coneRadiusEnd, coneStart, coneEnd, color, resolution);
|
||||
public static void DrawVector(Vector3 vector, float headSize, Vector3 offset, Color color) => GLDraw.Vector(vector, headSize, offset, color);
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
using UnityEngine;
|
||||
using UnityExplorer.GizmoControls;
|
||||
|
||||
namespace UnityExplorer.TransformGizmos
|
||||
{
|
||||
public abstract class BaseInteractablePositionGizmo : BaseTransformGizmo
|
||||
{
|
||||
ArrowControl x = new();
|
||||
ArrowControl y = new();
|
||||
ArrowControl z = new();
|
||||
|
||||
Vector3 initialPosition;
|
||||
|
||||
protected float LineLenght;
|
||||
protected float HeadLenght;
|
||||
|
||||
public override void SetScale(float scale)
|
||||
{
|
||||
base.SetScale(scale);
|
||||
x.Scale = scale;
|
||||
y.Scale = scale;
|
||||
z.Scale = scale;
|
||||
}
|
||||
|
||||
public void SetLineLenght(float lenght, float headLenght)
|
||||
{
|
||||
LineLenght = lenght;
|
||||
HeadLenght = headLenght;
|
||||
|
||||
x.Lenght = lenght;
|
||||
x.HeadLenght = headLenght;
|
||||
y.Lenght = lenght;
|
||||
y.HeadLenght = headLenght;
|
||||
z.Lenght = lenght;
|
||||
z.HeadLenght = headLenght;
|
||||
}
|
||||
public abstract Vector3 GetXDirection();
|
||||
public abstract Vector3 GetYDirection();
|
||||
public abstract Vector3 GetZDirection();
|
||||
|
||||
public override void Set(Transform transform)
|
||||
{
|
||||
base.Set(transform);
|
||||
|
||||
x.Lenght = LineLenght;
|
||||
x.HeadLenght = HeadLenght;
|
||||
x.Transform = transform;
|
||||
x.Color = Color.red;
|
||||
x.SelectedColor = Color.Lerp(Color.red, Color.white, 0.8f);
|
||||
x.Direction = (t) => GetXDirection();
|
||||
|
||||
y.Lenght = LineLenght;
|
||||
y.HeadLenght = HeadLenght;
|
||||
y.Transform = transform;
|
||||
y.Color = Color.yellow;
|
||||
y.SelectedColor = Color.Lerp(Color.yellow, Color.white, 0.8f);
|
||||
y.Direction = (t) => GetYDirection();
|
||||
|
||||
z.Lenght = LineLenght;
|
||||
z.HeadLenght = HeadLenght;
|
||||
z.Transform = transform;
|
||||
z.Color = Color.cyan;
|
||||
z.SelectedColor = Color.Lerp(Color.cyan, Color.white, 0.8f);
|
||||
z.Direction = (t) => GetZDirection();
|
||||
}
|
||||
|
||||
public override bool CheckSelected(Ray ray, float maxDistanceToSelect)
|
||||
{
|
||||
x.MaxDistanceToSelect = maxDistanceToSelect;
|
||||
y.MaxDistanceToSelect = maxDistanceToSelect;
|
||||
z.MaxDistanceToSelect = maxDistanceToSelect;
|
||||
|
||||
x.IsSelected(ray);
|
||||
y.IsSelected(ray);
|
||||
z.IsSelected(ray);
|
||||
|
||||
initialPosition = Vector3MathUtils.GetPositionWithReferencial(transform, transform.position);
|
||||
|
||||
return IsSelected();
|
||||
}
|
||||
|
||||
public override void OnRender()
|
||||
{
|
||||
x.Draw();
|
||||
y.Draw();
|
||||
z.Draw();
|
||||
}
|
||||
public override void OnSelected(Ray ray)
|
||||
{
|
||||
Vector3 aditionToPosition = Vector3.zero;
|
||||
|
||||
if (x.Selected)
|
||||
aditionToPosition += x.GetValue(ray);
|
||||
if (y.Selected)
|
||||
aditionToPosition += y.GetValue(ray);
|
||||
if (z.Selected)
|
||||
aditionToPosition += z.GetValue(ray);
|
||||
|
||||
transform.position = Vector3MathUtils.ReturnPositionFromReferencial(transform, initialPosition + aditionToPosition);
|
||||
}
|
||||
public override bool IsSelected()
|
||||
{
|
||||
return x.Selected || y.Selected || z.Selected;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
x.Reset();
|
||||
y.Reset();
|
||||
z.Reset();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer.TransformGizmos
|
||||
{
|
||||
public abstract class BaseTransformGizmo
|
||||
{
|
||||
protected Transform transform;
|
||||
|
||||
protected float Scale;
|
||||
public virtual void SetScale(float scale)
|
||||
{
|
||||
Scale = scale;
|
||||
}
|
||||
|
||||
public virtual void Set(Transform transform)
|
||||
{
|
||||
this.transform = transform;
|
||||
}
|
||||
public abstract void Reset();
|
||||
|
||||
public abstract bool CheckSelected(Ray ray,float maxDistanceToSelect);
|
||||
|
||||
public abstract void OnSelected(Ray ray);
|
||||
public abstract bool IsSelected();
|
||||
public abstract void OnRender();
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
using UnityEngine;
|
||||
using UnityExplorer.GizmoControls;
|
||||
|
||||
namespace UnityExplorer.TransformGizmos
|
||||
{
|
||||
public class FromCameraViewRotationGizmo : BaseTransformGizmo
|
||||
{
|
||||
CircleControl control = new();
|
||||
|
||||
float distanceForFullRevolution = 4f;
|
||||
|
||||
Vector3 rotationAxis;
|
||||
|
||||
Quaternion initialLocalRotation;
|
||||
|
||||
public override void SetScale(float scale)
|
||||
{
|
||||
base.SetScale(scale);
|
||||
control.Scale = scale;
|
||||
}
|
||||
|
||||
public override void Set(Transform transform)
|
||||
{
|
||||
base.Set(transform);
|
||||
|
||||
control.DistanceForFullRevolution = distanceForFullRevolution;
|
||||
control.Color = Color.blue;
|
||||
control.SelectedColor = Color.Lerp(Color.blue, Color.white, 0.8f);
|
||||
control.Radius = 1.5f;
|
||||
control.Transform = transform;
|
||||
control.Normal = (t) => rotationAxis;
|
||||
}
|
||||
|
||||
public override bool CheckSelected(Ray ray, float maxDistanceToSelect)
|
||||
{
|
||||
control.MaxDistanceToSelect = maxDistanceToSelect;
|
||||
control.IsSelected(ray);
|
||||
|
||||
rotationAxis = (Camera.current.transform.position - transform.position).normalized;
|
||||
initialLocalRotation = transform.localRotation;
|
||||
|
||||
return IsSelected();
|
||||
}
|
||||
|
||||
public override bool IsSelected()
|
||||
{
|
||||
return control.Selected;
|
||||
}
|
||||
|
||||
public override void OnRender()
|
||||
{
|
||||
if (!control.Selected)
|
||||
{
|
||||
rotationAxis = (Camera.current.transform.position - transform.position).normalized;
|
||||
}
|
||||
|
||||
control.Draw();
|
||||
}
|
||||
|
||||
public override void OnSelected(Ray ray)
|
||||
{
|
||||
float angle = control.GetValue(ray);
|
||||
|
||||
transform.localRotation = initialLocalRotation * Quaternion.AngleAxis(angle, Vector3MathUtils.GetDirectionWithReferencial(transform, rotationAxis));
|
||||
}
|
||||
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
control.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
using UnityEngine;
|
||||
using GizmosLibraryPlugin;
|
||||
|
||||
namespace UnityExplorer.TransformGizmos
|
||||
{
|
||||
public class GlobalEulerAnglesGizmo : BaseTransformGizmo
|
||||
{
|
||||
public override bool CheckSelected(Ray ray, float maxDistanceToSelect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsSelected()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnRender()
|
||||
{
|
||||
GLHelper.DrawOnGlobalReference(() =>
|
||||
{
|
||||
//Global position axis
|
||||
Vector3 localFowardAxis = transform.forward;
|
||||
Vector3 localRightAxis = transform.right;
|
||||
|
||||
//Local Euler Rotation
|
||||
Vector3 yRotationAxis = Vector3.Cross(Vector3.up, localFowardAxis);
|
||||
//if (yRotationAxis.ApproxEquals(Vector3.zero))
|
||||
if (Math.Abs(yRotationAxis.x) < 0.0001 && Math.Abs(yRotationAxis.y) < 0.0001 && Math.Abs(yRotationAxis.z) < 0.0001)
|
||||
{
|
||||
yRotationAxis = localRightAxis;
|
||||
}
|
||||
|
||||
GLDraw.WireframeCircle(1f, yRotationAxis, localFowardAxis, transform.position, Color.red, 16);
|
||||
GLDraw.WireframeCircle(1f, Vector3.up, Vector3.forward, transform.position, Color.yellow, 16);
|
||||
GLDraw.WireframeCircle(1f, localFowardAxis, transform.up, transform.position, Color.cyan, 16);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnSelected(Ray ray)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
using UnityEngine;
|
||||
using GizmosLibraryPlugin;
|
||||
|
||||
namespace UnityExplorer.TransformGizmos
|
||||
{
|
||||
public class GlobalPositionGizmo : BaseTransformGizmo
|
||||
{
|
||||
public override bool CheckSelected(Ray ray, float maxDistanceToSelect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsSelected()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnRender()
|
||||
{
|
||||
GLHelper.DrawOnGlobalReference(() =>
|
||||
{
|
||||
GLDraw.Vector(Vector3.right, 0.25f, transform.position, Color.red);
|
||||
GLDraw.Vector(Vector3.up, 0.25f, transform.position, Color.yellow);
|
||||
GLDraw.Vector(Vector3.forward, 0.25f, transform.position, Color.cyan);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnSelected(Ray ray)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
115
src/GizmosLibraryPlugin/TransformGizmos/LocalEulerAngleGizmo.cs
Normal file
115
src/GizmosLibraryPlugin/TransformGizmos/LocalEulerAngleGizmo.cs
Normal file
@ -0,0 +1,115 @@
|
||||
using UnityEngine;
|
||||
using UnityExplorer.GizmoControls;
|
||||
|
||||
namespace UnityExplorer.TransformGizmos
|
||||
{
|
||||
internal class LocalEulerAngleGizmo : BaseTransformGizmo
|
||||
{
|
||||
CircleControl x = new();
|
||||
CircleControl y = new();
|
||||
CircleControl z = new();
|
||||
|
||||
float distanceForFullRevolution = 4f;
|
||||
|
||||
Vector3 initialLocalEulerRotation;
|
||||
|
||||
public override void SetScale(float scale)
|
||||
{
|
||||
base.SetScale(scale);
|
||||
x.Scale = scale;
|
||||
y.Scale = scale;
|
||||
z.Scale = scale;
|
||||
}
|
||||
public override void Set(Transform transform)
|
||||
{
|
||||
base.Set(transform);
|
||||
|
||||
x.DistanceForFullRevolution = distanceForFullRevolution;
|
||||
x.Color = Color.red;
|
||||
x.SelectedColor = Color.Lerp(Color.red, Color.white, 0.8f);
|
||||
x.Radius = 1f;
|
||||
x.Transform = transform;
|
||||
x.Normal = (t) =>
|
||||
{
|
||||
Vector3 localFowardAxis = t.forward;
|
||||
Vector3 localUp = Vector3MathUtils.ReturnDirectionWithReferencial(t, Vector3.up);
|
||||
Vector3 yRotationAxis = Vector3.Cross(localUp, localFowardAxis);
|
||||
//if (yRotationAxis.ApproxEquals(Vector3.zero))
|
||||
if (Math.Abs(yRotationAxis.x) < 0.0001 && Math.Abs(yRotationAxis.y) < 0.0001 && Math.Abs(yRotationAxis.z) < 0.0001)
|
||||
{
|
||||
yRotationAxis = t.right;
|
||||
}
|
||||
return yRotationAxis;
|
||||
};
|
||||
|
||||
y.DistanceForFullRevolution = distanceForFullRevolution;
|
||||
y.Color = Color.yellow;
|
||||
y.SelectedColor = Color.Lerp(Color.yellow, Color.white, 0.8f);
|
||||
y.Radius = 1f;
|
||||
y.Transform = transform;
|
||||
y.Normal = (t) =>
|
||||
{
|
||||
Vector3 localUp = Vector3MathUtils.ReturnDirectionWithReferencial(t, Vector3.up);
|
||||
return localUp;
|
||||
};
|
||||
|
||||
z.DistanceForFullRevolution = distanceForFullRevolution;
|
||||
z.Color = Color.cyan;
|
||||
z.SelectedColor = Color.Lerp(Color.cyan, Color.white, 0.8f);
|
||||
z.Radius = 1f;
|
||||
z.Transform = transform;
|
||||
z.Normal = (t) =>
|
||||
{
|
||||
return t.forward;
|
||||
};
|
||||
}
|
||||
|
||||
public override bool CheckSelected(Ray ray, float maxDistanceToSelect)
|
||||
{
|
||||
x.MaxDistanceToSelect = maxDistanceToSelect;
|
||||
y.MaxDistanceToSelect = maxDistanceToSelect;
|
||||
z.MaxDistanceToSelect = maxDistanceToSelect;
|
||||
|
||||
x.IsSelected(ray);
|
||||
y.IsSelected(ray);
|
||||
z.IsSelected(ray);
|
||||
|
||||
initialLocalEulerRotation = transform.localEulerAngles;
|
||||
|
||||
return IsSelected();
|
||||
}
|
||||
|
||||
public override bool IsSelected()
|
||||
{
|
||||
return x.Selected || y.Selected || z.Selected;
|
||||
}
|
||||
|
||||
public override void OnRender()
|
||||
{
|
||||
x.Draw();
|
||||
y.Draw();
|
||||
z.Draw();
|
||||
}
|
||||
|
||||
public override void OnSelected(Ray ray)
|
||||
{
|
||||
Vector3 aditionToAngle = Vector3.zero;
|
||||
|
||||
if (x.Selected)
|
||||
aditionToAngle.x = x.GetValue(ray);
|
||||
if (y.Selected)
|
||||
aditionToAngle.y = y.GetValue(ray);
|
||||
if (z.Selected)
|
||||
aditionToAngle.z = z.GetValue(ray);
|
||||
|
||||
transform.localEulerAngles = initialLocalEulerRotation + aditionToAngle;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
x.Reset();
|
||||
y.Reset();
|
||||
z.Reset();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer.TransformGizmos
|
||||
{
|
||||
public class LocalPositionGizmo : BaseInteractablePositionGizmo
|
||||
{
|
||||
public override void Set(Transform transform)
|
||||
{
|
||||
LineLenght = 1.1f;
|
||||
HeadLenght = 0.25f;
|
||||
base.Set(transform);
|
||||
}
|
||||
public override Vector3 GetXDirection()
|
||||
{
|
||||
if (transform.parent == null)
|
||||
return Vector3.right;
|
||||
|
||||
return transform.parent.right;
|
||||
}
|
||||
|
||||
public override Vector3 GetYDirection()
|
||||
{
|
||||
if (transform.parent == null)
|
||||
return Vector3.up;
|
||||
|
||||
return transform.parent.up;
|
||||
}
|
||||
|
||||
public override Vector3 GetZDirection()
|
||||
{
|
||||
if (transform.parent == null)
|
||||
return Vector3.forward;
|
||||
|
||||
return transform.parent.forward;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,191 @@
|
||||
using UnityEngine;
|
||||
using GizmosLibraryPlugin;
|
||||
|
||||
namespace UnityExplorer.TransformGizmos
|
||||
{
|
||||
//TODO recreate this with GizmoControls and fix bug when radius = 0 -> position = NaN
|
||||
public class LocalPositionCylindricalCoordinates : BaseTransformGizmo
|
||||
{
|
||||
// x = radius
|
||||
// y = y
|
||||
// z = theta
|
||||
|
||||
bool selectedRadius = false;
|
||||
bool selectedTheta = false;
|
||||
bool selectedY = false;
|
||||
|
||||
float lineSegmentDistance = 0.25f;
|
||||
|
||||
Vector3 selectedRadiusPosition;
|
||||
float aditionalThetaRotation;
|
||||
Vector3 selectedYPosition;
|
||||
|
||||
Vector3 initialLocalPositionCylindrical;
|
||||
|
||||
protected Vector3 GetPositionWithReferencial(Transform transform, Vector3 position)
|
||||
{
|
||||
if (transform.parent == null)
|
||||
return position;
|
||||
|
||||
return transform.parent.InverseTransformPoint(position);
|
||||
}
|
||||
protected Vector3 ReturnPositionFromReferencial(Transform transform, Vector3 position)
|
||||
{
|
||||
if (transform.parent == null)
|
||||
return position;
|
||||
|
||||
return transform.parent.TransformPoint(position);
|
||||
}
|
||||
protected Vector3 GetDirectionWithReferencial(Transform transform, Vector3 direction)
|
||||
{
|
||||
if (transform.parent == null)
|
||||
return direction;
|
||||
|
||||
return transform.parent.InverseTransformDirection(direction);
|
||||
}
|
||||
protected Vector3 ReturnDirectionFromReferencial(Transform transform, Vector3 direction)
|
||||
{
|
||||
if (transform.parent == null)
|
||||
return direction;
|
||||
|
||||
return transform.parent.TransformDirection(direction);
|
||||
}
|
||||
|
||||
public Vector3 GetRadiusDirection(Transform transform)
|
||||
{
|
||||
if (transform.parent == null)
|
||||
return new Vector3(transform.position.x, 0f, transform.position.y).normalized;
|
||||
|
||||
return transform.parent.TransformDirection(new Vector3(transform.localPosition.x, 0f, transform.localPosition.z).normalized);
|
||||
}
|
||||
public Vector3 GetUpDirection(Transform transform)
|
||||
{
|
||||
Vector3 up = Vector3.up;
|
||||
if (transform.parent != null)
|
||||
{
|
||||
up = transform.parent.up;
|
||||
}
|
||||
return up;
|
||||
}
|
||||
public Vector3 GetThetaDirection(Vector3 radiusDirection, Vector3 upDirection)
|
||||
{
|
||||
return Vector3.Cross(upDirection, radiusDirection);
|
||||
}
|
||||
|
||||
|
||||
public static Vector3 FromCylindricalToCartesian(Vector3 cylindrical)
|
||||
{
|
||||
if(cylindrical.x < 0f)
|
||||
{
|
||||
cylindrical.x = 0f;
|
||||
//cylindrical.z += Mathf.PI;
|
||||
}
|
||||
return new Vector3(cylindrical.x * Mathf.Cos(cylindrical.z), cylindrical.y, cylindrical.x * Mathf.Sin(cylindrical.z));
|
||||
}
|
||||
public static Vector3 FromCartesianToCylindrical(Vector3 cartesian)
|
||||
{
|
||||
float y = cartesian.y;
|
||||
Vector2 polar = new(cartesian.z, cartesian.x);
|
||||
float radius = polar.magnitude;
|
||||
float theta = 0f;
|
||||
if (!( Mathf.Abs(polar.x) < 1e-2f || Mathf.Abs(polar.y) < 1e-2f))
|
||||
{
|
||||
theta = Mathf.Atan2(polar.x, polar.y);
|
||||
}
|
||||
return new Vector3(radius, y, theta);
|
||||
}
|
||||
|
||||
public override bool CheckSelected(Ray ray, float maxDistanceToSelect)
|
||||
{
|
||||
Vector3 radius = GetRadiusDirection(transform);
|
||||
Vector3 up = GetUpDirection(transform);
|
||||
Vector3 centerAxis = ReturnPositionFromReferencial(transform, new Vector3(0f, transform.localPosition.y, 0f));
|
||||
float radiusValue = ReturnDirectionFromReferencial(transform, new Vector3(transform.localPosition.x, 0f, transform.localPosition.z)).magnitude;
|
||||
|
||||
if (Vector3MathUtils.GetDistanceFromLineToLineSegment(ray.direction, ray.origin, transform.position, transform.position + radius * lineSegmentDistance) <= maxDistanceToSelect)
|
||||
{
|
||||
selectedRadius = true;
|
||||
Vector3MathUtils.GetClosestPointFromLines(ray.direction, ray.origin, radius, transform.position, out _, out selectedRadiusPosition);
|
||||
selectedRadiusPosition = GetPositionWithReferencial(transform, selectedRadiusPosition);
|
||||
}
|
||||
if (Vector3MathUtils.GetClosestPointFromLineToCircle(ray.direction, ray.origin, centerAxis, up, radiusValue, out bool lineParalelToCircle, out _, out _) <= maxDistanceToSelect)
|
||||
{
|
||||
if (!lineParalelToCircle)
|
||||
{
|
||||
selectedTheta = true;
|
||||
aditionalThetaRotation = 0f;
|
||||
}
|
||||
}
|
||||
if (Vector3MathUtils.GetDistanceFromLineToLineSegment(ray.direction, ray.origin, transform.position, transform.position + up * lineSegmentDistance) <= maxDistanceToSelect)
|
||||
{
|
||||
selectedY = true;
|
||||
Vector3MathUtils.GetClosestPointFromLines(ray.direction, ray.origin, up, transform.position, out _, out selectedYPosition);
|
||||
selectedYPosition = GetPositionWithReferencial(transform, selectedYPosition);
|
||||
}
|
||||
|
||||
initialLocalPositionCylindrical = FromCartesianToCylindrical(GetPositionWithReferencial(transform, transform.position));
|
||||
|
||||
return IsSelected();
|
||||
}
|
||||
|
||||
public override void OnRender()
|
||||
{
|
||||
Vector3 radius = GetRadiusDirection(transform);
|
||||
Vector3 up = GetUpDirection(transform);
|
||||
Vector3 centerAxis = ReturnPositionFromReferencial(transform, new Vector3(0f, transform.localPosition.y, 0f));
|
||||
|
||||
float radiusValue = ReturnDirectionFromReferencial(transform, new Vector3(transform.localPosition.x, 0f, transform.localPosition.z)).magnitude;
|
||||
|
||||
GLHelper.DrawOnGlobalReference(() =>
|
||||
{
|
||||
GLDraw.Vector(radius, lineSegmentDistance, transform.position, selectedRadius ? Color.Lerp(Color.red, Color.white, 0.8f) : Color.red);
|
||||
GLDraw.Vector(up, lineSegmentDistance, transform.position, selectedY ? Color.Lerp(Color.yellow, Color.white, 0.8f) : Color.yellow);
|
||||
GLDraw.WireframeCircle(radiusValue, up, radius, centerAxis, selectedTheta ? Color.Lerp(Color.cyan, Color.white, 0.8f) : Color.cyan, 16);
|
||||
});
|
||||
}
|
||||
public override void OnSelected(Ray ray)
|
||||
{
|
||||
Vector3 radius = GetRadiusDirection(transform);
|
||||
Vector3 up = GetUpDirection(transform);
|
||||
|
||||
float mouseScrollDelta = UniverseLib.Input.InputManager.MouseScrollDelta.y * 0.1f;
|
||||
|
||||
Vector3 cylindricalAditionToPosition = Vector3.zero;
|
||||
if (selectedRadius)
|
||||
{
|
||||
Vector3MathUtils.GetClosestPointFromLines(ray.direction, ray.origin, radius, transform.position, out _, out Vector3 currentRadiusSelectedPosition);
|
||||
currentRadiusSelectedPosition = GetPositionWithReferencial(transform, currentRadiusSelectedPosition);
|
||||
|
||||
float distanceWihReference = Vector3.Dot(currentRadiusSelectedPosition - selectedRadiusPosition, GetDirectionWithReferencial(transform, radius));
|
||||
|
||||
cylindricalAditionToPosition.x = distanceWihReference;
|
||||
}
|
||||
if (selectedTheta)
|
||||
{
|
||||
aditionalThetaRotation += mouseScrollDelta * Mathf.Deg2Rad;
|
||||
cylindricalAditionToPosition.z = aditionalThetaRotation;
|
||||
}
|
||||
if (selectedY)
|
||||
{
|
||||
Vector3MathUtils.GetClosestPointFromLines(ray.direction, ray.origin, up, transform.position, out _, out Vector3 currentYSelectedPosition);
|
||||
currentYSelectedPosition = GetPositionWithReferencial(transform, currentYSelectedPosition);
|
||||
float distanceWihReference = Vector3.Dot(currentYSelectedPosition - selectedYPosition, GetDirectionWithReferencial(transform, up));
|
||||
cylindricalAditionToPosition.y = distanceWihReference;
|
||||
}
|
||||
transform.position = ReturnPositionFromReferencial(transform, FromCylindricalToCartesian(initialLocalPositionCylindrical + cylindricalAditionToPosition));
|
||||
}
|
||||
public override bool IsSelected()
|
||||
{
|
||||
return selectedRadius || selectedTheta || selectedY;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
aditionalThetaRotation = 0f;
|
||||
|
||||
selectedRadius = false;
|
||||
selectedTheta = false;
|
||||
selectedY = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer.TransformGizmos
|
||||
{
|
||||
public class TransformOrientationGizmo : BaseInteractablePositionGizmo
|
||||
{
|
||||
public override void Set(Transform transform)
|
||||
{
|
||||
LineLenght = 1.1f;
|
||||
HeadLenght = 0.25f;
|
||||
base.Set(transform);
|
||||
}
|
||||
public override Vector3 GetXDirection()
|
||||
{
|
||||
return transform.right;
|
||||
}
|
||||
|
||||
public override Vector3 GetYDirection()
|
||||
{
|
||||
return transform.up;
|
||||
}
|
||||
|
||||
public override Vector3 GetZDirection()
|
||||
{
|
||||
return transform.forward;
|
||||
}
|
||||
}
|
||||
}
|
144
src/GizmosLibraryPlugin/Vector3MathUtils.cs
Normal file
144
src/GizmosLibraryPlugin/Vector3MathUtils.cs
Normal file
@ -0,0 +1,144 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer
|
||||
{
|
||||
public static class Vector3MathUtils
|
||||
{
|
||||
public static Vector3 GetPositionWithReferencial(Transform t, Vector3 position)
|
||||
{
|
||||
if (t.parent == null)
|
||||
return position;
|
||||
|
||||
return t.parent.InverseTransformPoint(position);
|
||||
}
|
||||
public static Vector3 ReturnPositionFromReferencial(Transform t, Vector3 position)
|
||||
{
|
||||
if (t.parent == null)
|
||||
return position;
|
||||
|
||||
return t.parent.TransformPoint(position);
|
||||
}
|
||||
public static Vector3 GetDirectionWithReferencial(Transform t, Vector3 direction)
|
||||
{
|
||||
if (t.parent == null)
|
||||
return direction;
|
||||
|
||||
return t.parent.InverseTransformDirection(direction);
|
||||
}
|
||||
public static Vector3 ReturnDirectionWithReferencial(Transform t, Vector3 direction)
|
||||
{
|
||||
if (t.parent == null)
|
||||
return direction;
|
||||
|
||||
return t.parent.TransformDirection(direction);
|
||||
}
|
||||
|
||||
//From https://math.stackexchange.com/questions/511370/how-to-rotate-one-vector-about-another
|
||||
public static void GetParalelAndPerpendicularComponent(Vector3 axis, Vector3 v, out Vector3 paralel, out Vector3 perpendicular)
|
||||
{
|
||||
paralel = Vector3.Dot(v, axis) * axis / axis.magnitude;
|
||||
perpendicular = v - paralel;
|
||||
}
|
||||
public static Vector3 GetRotationVector(Vector3 axis, Vector3 perpendicularComponent)
|
||||
{
|
||||
return Vector3.Cross(axis, perpendicularComponent);
|
||||
}
|
||||
public static Vector3 GetRotatedVectorComponent(Vector3 rotationVector, Vector3 perpendicularComponent, float angle)
|
||||
{
|
||||
float x1 = Mathf.Cos(angle) / perpendicularComponent.sqrMagnitude;
|
||||
float x2 = Mathf.Sin(angle);
|
||||
|
||||
return perpendicularComponent.sqrMagnitude * (x1 * perpendicularComponent + x2 * rotationVector);
|
||||
}
|
||||
|
||||
//From https://codereview.stackexchange.com/questions/43928/algorithm-to-get-an-arbitrary-perpendicular-vector
|
||||
public static Vector3 GetArbitraryPerpendicularVector(Vector3 v)
|
||||
{
|
||||
if (v.magnitude == 0f)
|
||||
{
|
||||
return Vector3.forward;
|
||||
}
|
||||
Vector3 firstAttempt = Vector3.Cross(v, Vector3.forward);
|
||||
if (firstAttempt.magnitude != 0f)
|
||||
{
|
||||
return firstAttempt.normalized;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Vector3.Cross(v, Vector3.up).normalized;
|
||||
}
|
||||
}
|
||||
//From https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
|
||||
public static float GetDistanceFromLine(Vector3 point, Vector3 direction, Vector3 lineStartingPoint)
|
||||
{
|
||||
return Vector3.Cross(point - lineStartingPoint, direction).magnitude / direction.magnitude;
|
||||
}
|
||||
//From https://en.wikipedia.org/wiki/Skew_lines#Distance
|
||||
public static float GetDistanceFromLineToLineSegment(Vector3 direction, Vector3 lineStartingPoint, Vector3 segmentStartingPoint, Vector3 segmentEndPoint)
|
||||
{
|
||||
Vector3 directionOfSegment = segmentEndPoint - segmentStartingPoint;
|
||||
Vector3 n = Vector3.Cross(direction, directionOfSegment);
|
||||
Vector3 n2 = Vector3.Cross(directionOfSegment, n);
|
||||
Vector3 closestPointFromLineToSegment = lineStartingPoint + Vector3.Dot(segmentStartingPoint - lineStartingPoint, n2) / (Vector3.Dot(direction, n2)) * direction;
|
||||
|
||||
return GetDistanceFromLineSegment(closestPointFromLineToSegment, segmentStartingPoint, segmentEndPoint);
|
||||
}
|
||||
public static void GetClosestPointFromLines(Vector3 directionOne, Vector3 lineStartingPointOne, Vector3 directionTwo, Vector3 lineStartingPointTwo, out Vector3 closesPointOnLineOne, out Vector3 closesPointOnLineTwo)
|
||||
{
|
||||
Vector3 n = Vector3.Cross(directionOne, directionTwo);
|
||||
Vector3 n2 = Vector3.Cross(directionTwo, n);
|
||||
closesPointOnLineOne = lineStartingPointOne + Vector3.Dot(lineStartingPointTwo - lineStartingPointOne, n2) / (Vector3.Dot(directionOne, n2)) * directionOne;
|
||||
|
||||
Vector3 n1 = Vector3.Cross(directionOne, n);
|
||||
closesPointOnLineTwo = lineStartingPointTwo + Vector3.Dot(lineStartingPointOne - lineStartingPointTwo, n1) / (Vector3.Dot(directionTwo, n1)) * directionTwo;
|
||||
|
||||
}
|
||||
public static float GetDistanceFromLineSegment(Vector3 point, Vector3 startingPoint, Vector3 endPoint)
|
||||
{
|
||||
float distanceFromStartingPoint = Vector3.Distance(point, startingPoint);
|
||||
float distanceFromEndPoint = Vector3.Distance(point, endPoint);
|
||||
float distanceFromLine = GetDistanceFromLine(point, endPoint - startingPoint, startingPoint);
|
||||
|
||||
return Mathf.Min(distanceFromStartingPoint, distanceFromEndPoint, distanceFromLine);
|
||||
}
|
||||
//From https://www.geometrictools.com/Documentation/DistanceToCircle3.pdf
|
||||
public static float GetClosestPointToCircle(Vector3 point, Vector3 center, Vector3 normal, float radius,out bool isEquidistant, out Vector3 closestPoint)
|
||||
{
|
||||
Vector3 delta = point - center;
|
||||
float dotND = Vector3.Dot(normal, delta);
|
||||
Vector3 QmC = delta - dotND * normal;
|
||||
float lenghtQmC = QmC.magnitude;
|
||||
if (lenghtQmC > 0f)
|
||||
{
|
||||
closestPoint = center + radius * (QmC / lenghtQmC);
|
||||
isEquidistant = false;
|
||||
return (point - closestPoint).magnitude;
|
||||
}
|
||||
else
|
||||
{
|
||||
closestPoint = Vector3.zero;
|
||||
isEquidistant = true;
|
||||
return delta.sqrMagnitude + radius * radius;
|
||||
}
|
||||
}
|
||||
//From https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection
|
||||
public static float GetClosestPointFromLineToCircle(Vector3 direction, Vector3 point, Vector3 center, Vector3 normal, float radius, out bool lineParalelToCircle, out bool isEquidistant, out Vector3 closestPoint)
|
||||
{
|
||||
float ln = Vector3.Dot(direction, normal);
|
||||
if(ln == 0f) //Yes, I know we are ignoring when the line and the circle are on the same plane, I just don't want to write a proper GetClosestPointFromLineToCircle
|
||||
{
|
||||
lineParalelToCircle = true;
|
||||
isEquidistant = false;
|
||||
closestPoint = Vector3.zero;
|
||||
return 0f;
|
||||
}
|
||||
|
||||
float d = Vector3.Dot((center - point), normal) / ln;
|
||||
Vector3 intersectionPoint = point + direction * d;
|
||||
|
||||
lineParalelToCircle = false;
|
||||
|
||||
return GetClosestPointToCircle(intersectionPoint, center, normal, radius, out isEquidistant, out closestPoint);
|
||||
}
|
||||
}
|
||||
}
|
@ -64,6 +64,7 @@ namespace UnityExplorer.Inspectors
|
||||
|
||||
public override void CloseInspector()
|
||||
{
|
||||
Controls.TransformControl.DisableGizmo();
|
||||
InspectorManager.ReleaseInspector(this);
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,10 @@ namespace UnityExplorer.UI.Panels
|
||||
boneScrollPool.Initialize(this);
|
||||
DoneScrollPoolInit = true;
|
||||
}
|
||||
|
||||
if (!active){
|
||||
DisableGizmos();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ConstructPanelContent()
|
||||
@ -79,6 +83,13 @@ namespace UnityExplorer.UI.Panels
|
||||
animator.enabled = value;
|
||||
}
|
||||
|
||||
public void DisableGizmos(){
|
||||
// TODO: Create a structure for each cell data instead
|
||||
foreach (BonesCell cell in boneScrollPool.CellPool){
|
||||
cell.DisableGizmo();
|
||||
}
|
||||
}
|
||||
|
||||
public void RestoreBoneState(string boneName)
|
||||
{
|
||||
foreach (Transform bone in bones){
|
||||
|
@ -12,6 +12,8 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
public AxisControl CurrentSlidingAxisControl { get; set; }
|
||||
|
||||
Dropdown gizmoDropdown;
|
||||
|
||||
Vector3Control PositionControl;
|
||||
Vector3Control LocalPositionControl;
|
||||
Vector3Control RotationControl;
|
||||
@ -98,6 +100,25 @@ namespace UnityExplorer.UI.Widgets
|
||||
LocalPositionControl = Vector3Control.Create(this, transformGroup, "Local Position:", TransformType.LocalPosition);
|
||||
RotationControl = Vector3Control.Create(this, transformGroup, "Rotation:", TransformType.Rotation);
|
||||
ScaleControl = Vector3Control.Create(this, transformGroup, "Scale:", TransformType.Scale);
|
||||
|
||||
GameObject gizmoObj = UIFactory.CreateDropdown(transformGroup, "Gizmo_Dropdown", out gizmoDropdown, null, 14, (idx) => {
|
||||
ExplorerBehaviour.GizmoTools.targetTransform = Target.transform;
|
||||
ExplorerBehaviour.GizmoTools.ChangeGizmo((GizmoType)idx);
|
||||
}
|
||||
);
|
||||
UIFactory.SetLayoutElement(gizmoObj, minHeight: 25, minWidth: 150);
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("No Gizmo"));
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("Local Position"));
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("Local Rotation"));
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("Global Position"));
|
||||
gizmoDropdown.options.Add(new Dropdown.OptionData("Global Rotation"));
|
||||
gizmoDropdown.captionText.text = "No Gizmo";
|
||||
}
|
||||
|
||||
public void DisableGizmo(){
|
||||
if (gizmoDropdown.value != 0){
|
||||
gizmoDropdown.value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user