|
@@ -0,0 +1,179 @@
|
|
|
+using System;
|
|
|
+using System.Reflection;
|
|
|
+using UnityEngine;
|
|
|
+
|
|
|
+namespace COM3D2.MeidoPhotoStudio.Plugin
|
|
|
+{
|
|
|
+ public class CustomGizmo : GizmoRender
|
|
|
+ {
|
|
|
+ private Transform target;
|
|
|
+ private FieldInfo beSelectedType = Utility.GetFieldInfo<GizmoRender>("beSelectedType");
|
|
|
+ private int SelectedType => (int)beSelectedType.GetValue(this);
|
|
|
+ private static FieldInfo is_drag_ = Utility.GetFieldInfo<GizmoRender>("is_drag_");
|
|
|
+ private static bool IsDrag => (bool)is_drag_.GetValue(null);
|
|
|
+ private Vector3 positionOld = Vector3.zero;
|
|
|
+ private Vector3 deltaPosition = Vector3.zero;
|
|
|
+ private Vector3 localPositionOld = Vector3.zero;
|
|
|
+ private Vector3 deltaLocalPosition = Vector3.zero;
|
|
|
+ private Quaternion rotationOld = Quaternion.identity;
|
|
|
+ private Quaternion deltaRotation = Quaternion.identity;
|
|
|
+ private Quaternion deltaLocalRotation = Quaternion.identity;
|
|
|
+ private Vector3 deltaScale = Vector3.zero;
|
|
|
+ private Vector3 scaleOld = Vector3.one;
|
|
|
+ private GizmoType gizmoTypeOld;
|
|
|
+ private GizmoType gizmoType;
|
|
|
+ public GizmoType CurrentGizmoType
|
|
|
+ {
|
|
|
+ get => gizmoType;
|
|
|
+ set
|
|
|
+ {
|
|
|
+ gizmoType = value;
|
|
|
+ if (gizmoTypeOld != gizmoType) SetGizmoType(gizmoType);
|
|
|
+ gizmoTypeOld = gizmoType;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public bool IsGizmoDrag => IsDrag && SelectedType != 0;
|
|
|
+ public GizmoMode gizmoMode = GizmoMode.Local;
|
|
|
+ public event EventHandler GizmoDrag;
|
|
|
+ public enum GizmoType
|
|
|
+ {
|
|
|
+ Rotate, Move, Scale, None
|
|
|
+ }
|
|
|
+ public enum GizmoMode
|
|
|
+ {
|
|
|
+ Local, World, Global
|
|
|
+ }
|
|
|
+
|
|
|
+ public static GameObject MakeGizmo(Transform target, float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
|
|
|
+ {
|
|
|
+ GameObject gizmoGo = new GameObject();
|
|
|
+ gizmoGo.transform.SetParent(target);
|
|
|
+
|
|
|
+ CustomGizmo gizmo = gizmoGo.AddComponent<CustomGizmo>();
|
|
|
+ gizmo.target = target;
|
|
|
+ gizmo.lineRSelectedThick = 0.25f;
|
|
|
+ gizmo.offsetScale = scale;
|
|
|
+ gizmo.gizmoMode = mode;
|
|
|
+ gizmo.CurrentGizmoType = GizmoType.Rotate;
|
|
|
+
|
|
|
+ return gizmoGo;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void Update()
|
|
|
+ {
|
|
|
+ BeginUpdate();
|
|
|
+
|
|
|
+ base.Update();
|
|
|
+
|
|
|
+ if (IsGizmoDrag) SetTargetTransform();
|
|
|
+
|
|
|
+ SetTransform();
|
|
|
+
|
|
|
+ EndUpdate();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void BeginUpdate()
|
|
|
+ {
|
|
|
+ deltaPosition = transform.position - positionOld;
|
|
|
+ deltaRotation = transform.rotation * Quaternion.Inverse(rotationOld);
|
|
|
+ deltaLocalPosition = transform.InverseTransformVector(deltaPosition);
|
|
|
+ deltaLocalRotation = Quaternion.Inverse(rotationOld) * transform.rotation;
|
|
|
+ deltaScale = transform.localScale - scaleOld;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void EndUpdate()
|
|
|
+ {
|
|
|
+ positionOld = transform.position;
|
|
|
+ rotationOld = transform.rotation;
|
|
|
+ scaleOld = transform.localScale;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetTargetTransform()
|
|
|
+ {
|
|
|
+ switch (gizmoMode)
|
|
|
+ {
|
|
|
+ case GizmoMode.Local:
|
|
|
+ target.transform.position += target.transform.TransformVector(deltaLocalPosition).normalized
|
|
|
+ * deltaLocalPosition.magnitude;
|
|
|
+ target.transform.rotation = target.transform.rotation * deltaLocalRotation;
|
|
|
+ target.transform.localScale += deltaScale;
|
|
|
+ if (deltaLocalRotation != Quaternion.identity || deltaLocalPosition != Vector3.zero
|
|
|
+ || deltaScale != Vector3.zero
|
|
|
+ )
|
|
|
+ {
|
|
|
+ OnGizmoDrag();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case GizmoMode.World:
|
|
|
+ case GizmoMode.Global:
|
|
|
+ target.transform.position += deltaPosition;
|
|
|
+ target.transform.rotation = deltaRotation * target.transform.rotation;
|
|
|
+ if (deltaRotation != Quaternion.identity || deltaPosition != Vector3.zero) OnGizmoDrag();
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetTransform()
|
|
|
+ {
|
|
|
+ switch (gizmoMode)
|
|
|
+ {
|
|
|
+ case GizmoMode.Local:
|
|
|
+ transform.position = target.transform.position;
|
|
|
+ transform.rotation = target.transform.rotation;
|
|
|
+ break;
|
|
|
+ case GizmoMode.World:
|
|
|
+ transform.position = target.transform.position;
|
|
|
+ transform.rotation = Quaternion.identity;
|
|
|
+ break;
|
|
|
+ case GizmoMode.Global:
|
|
|
+ transform.position = target.transform.position;
|
|
|
+ transform.rotation = Quaternion.LookRotation(
|
|
|
+ transform.position - Camera.main.transform.position, transform.up
|
|
|
+ );
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ transform.localScale = Vector3.one;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetGizmoType(GizmoType gizmoType)
|
|
|
+ {
|
|
|
+ switch (gizmoType)
|
|
|
+ {
|
|
|
+ case GizmoType.Move:
|
|
|
+ this.eAxis = true;
|
|
|
+ this.eRotate = false;
|
|
|
+ this.eScal = false;
|
|
|
+ break;
|
|
|
+ case GizmoType.Rotate:
|
|
|
+ this.eAxis = false;
|
|
|
+ this.eRotate = true;
|
|
|
+ this.eScal = false;
|
|
|
+ break;
|
|
|
+ case GizmoType.Scale:
|
|
|
+ this.eAxis = false;
|
|
|
+ this.eRotate = false;
|
|
|
+ this.eScal = true;
|
|
|
+ break;
|
|
|
+ case GizmoType.None:
|
|
|
+ this.eAxis = false;
|
|
|
+ this.eRotate = false;
|
|
|
+ this.eScal = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnGizmoDrag()
|
|
|
+ {
|
|
|
+ GizmoDrag?.Invoke(this, EventArgs.Empty);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnEnable()
|
|
|
+ {
|
|
|
+ if (target != null)
|
|
|
+ {
|
|
|
+ SetTransform();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|