123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- using System;
- using System.Collections.Generic;
- using Rokid.UXR.Native;
- using Rokid.UXR.Utility;
- using UnityEngine;
- using UnityEngine.EventSystems;
- namespace Rokid.UXR.Interaction
- {
- /// <summary>
- /// Base Ray Pose
- /// </summary>
- public abstract class BaseRayPose : MonoBehaviour
- {
- [Serializable]
- public class EditorParams
- {
- [Tooltip("是否使用鼠标模拟射线Rotate")]
- public bool useMouseRotate = true;
- [Tooltip("射线是否跟随相机,只在编辑器生效")]
- public bool followCameraInEditor = true;
- [Tooltip("相机空间下的局部坐标,只有在followCamera为真的情况下生效")]
- public Vector3 localPositionInCameraSpace = new Vector3(0, -0.1f, 0);
- public float maxDistanceInEditor = 10.0f;
- [HideInInspector]
- public float raycastDistance = -1.0f;
- public BaseRayCaster rayCaster;
- public static readonly RaycastHit[] hits = new RaycastHit[4];
- public readonly List<RaycastResult> sortedRaycastResults = new List<RaycastResult>();
- public Transform rayOrigin;
- }
- [SerializeField, Tooltip("编辑器模拟参数")]
- private EditorParams editorParams;
- private Transform hostTransform;
- protected virtual void Start()
- {
- if (editorParams.rayCaster == null)
- editorParams.rayCaster = GetComponent<BaseRayCaster>();
- hostTransform = editorParams.rayOrigin == null ? transform : editorParams.rayOrigin;
- }
- protected virtual void Update()
- {
- #if UNITY_EDITOR
- if (editorParams.useMouseRotate)
- {
- UpdateInEditor();
- }
- #endif
- }
- #if UNITY_EDITOR
- protected virtual void UpdateInEditor()
- {
- if (editorParams.followCameraInEditor)
- {
- hostTransform.position = MainCameraCache.mainCamera.transform.TransformPoint(editorParams.localPositionInCameraSpace);
- }
- if (editorParams.rayCaster != null)
- {
- Ray ray = MainCameraCache.mainCamera.ScreenPointToRay(Input.mousePosition);
- editorParams.rayCaster.Raycast(ray, Mathf.Infinity, editorParams.sortedRaycastResults);
- RaycastResult raycastResult = editorParams.rayCaster.FirstRaycastResult(editorParams.sortedRaycastResults);
- if (raycastResult.gameObject != null)
- {
- Vector3 targetPos = raycastResult.worldPosition;
- Vector3 toDirection = targetPos - hostTransform.position;
- hostTransform.localRotation = Quaternion.FromToRotation(Vector3.forward, toDirection);
- editorParams.raycastDistance = Mathf.Min(editorParams.maxDistanceInEditor, raycastResult.distance);
- }
- else if (editorParams.raycastDistance > 0.0f)
- {
- Vector3 targetPos = ray.origin + Mathf.Min(editorParams.maxDistanceInEditor, editorParams.raycastDistance) * ray.direction;
- Vector3 toDirection = targetPos - hostTransform.position;
- hostTransform.localRotation = Quaternion.FromToRotation(Vector3.forward, toDirection);
- }
- else
- {
- hostTransform.localRotation = Quaternion.identity;
- }
- }
- }
- #endif
- #region LimitInViewField
- protected Camera renderCamera;
- public Vector4 cursorSize;
- private Vector4 _halfFovTan = Vector4.zero;
- private Vector4 halfFovTan
- {
- get
- {
- if (_halfFovTan != Vector4.zero)
- {
- return _halfFovTan;
- }
- #if UNITY_EDITOR
- _halfFovTan.x = _halfFovTan.y = _halfFovTan.z = _halfFovTan.w = Mathf.Tan(renderCamera.fieldOfView / 2 * Mathf.Deg2Rad);
- return _halfFovTan;
- #endif
- float[] fov = new float[4];
- NativeInterface.NativeAPI.GetUnityEyeFrustumHalf(false, ref fov);
- if (fov[0] > 0 && fov[1] > 0 && fov[2] > 0 && fov[3] > 0)
- {
- _halfFovTan.x = Mathf.Tan(fov[0] * Mathf.Deg2Rad); // Left
- _halfFovTan.y = Mathf.Tan(fov[1] * Mathf.Deg2Rad); // Right
- _halfFovTan.z = Mathf.Tan(fov[2] * Mathf.Deg2Rad); // Top
- _halfFovTan.w = Mathf.Tan(fov[3] * Mathf.Deg2Rad); // Bottom
- return _halfFovTan;
- }
- return Vector4.zero;
- }
- }
-
- Vector4 GetCameraCorner(float dis)
- {
- Vector4 corner = Vector4.zero;
- corner.z = dis * halfFovTan.z; // Top
- corner.w = dis * halfFovTan.w; // Bottom
- #if UNITY_EDITOR
- corner.x = corner.y = corner.z * renderCamera.aspect;
- #else
- corner.x = dis * halfFovTan.x; // Left
- corner.y = dis * halfFovTan.y; // Right
- #endif
- return corner;
- }
- protected void LimitInViewField()
- {
- transform.position = renderCamera.transform.position;
- Vector3 pointPosition = transform.forward + transform.position;
- Vector3 pointInCamera = renderCamera.transform.InverseTransformPoint(pointPosition);
- //点在相机forward上的距离
- float dis = pointInCamera.z;
- if (dis < 0)
- {
- dis = -dis;
- pointInCamera.z = dis;
- }
-
- Vector4 corner = GetCameraCorner(dis);
- if (pointInCamera.x < -corner.x + cursorSize.x) // LEFT
- {
- pointInCamera.x = -corner.x + cursorSize.x;
- }
- else if (pointInCamera.x > corner.y - cursorSize.w) // Right
- {
- pointInCamera.x = corner.y - cursorSize.w;
- }
- if (pointInCamera.y > corner.z - cursorSize.y) // Top
- {
- pointInCamera.y = corner.z - cursorSize.y;
- }
- else if (pointInCamera.y < -corner.w + cursorSize.z) // Bottom
- {
- pointInCamera.y = -corner.w + cursorSize.z;
- }
-
- pointPosition = renderCamera.transform.TransformPoint(pointInCamera);
- transform.forward = pointPosition - transform.position;
- }
-
- #endregion
-
- }
- }
|