/****************************************************************************
* Copyright 2019 Nreal Techonology Limited. All rights reserved.
*
* This file is part of NRSDK.
*
* NRSDK is distributed in the hope that it will be usefull
*
* https://www.nreal.ai/
*
*****************************************************************************/
namespace NRKernal
{
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/// A nr multiply screen pointer raycaster.
[DisallowMultipleComponent]
public class NRMultScrPointerRaycaster : NRPointerRaycaster
{
/// The mouse.
public GameObject Mouse;
/// The camera.
private Camera m_UICamera;
/// Width of the screen.
private float m_ScreenWidth;
/// Height of the screen.
private float m_ScreenHeight;
/// The last touch.
private Vector3 m_LastTouch = m_FarAwayPos;
/// The far away position.
private static Vector3 m_FarAwayPos = Vector3.one * 10000f;
/// See MonoBehaviour.Awake.
protected override void Awake()
{
base.Awake();
m_UICamera = gameObject.GetComponent();
//var resolution = NRPhoneScreen.Resolution * NRVirtualDisplayer.ScaleFactor;
var resolution = NRPhoneScreen.Resolution;
m_ScreenWidth = resolution.x;
m_ScreenHeight = resolution.y;
}
/// Updates the screen size described by size.
/// The size.
public void UpdateScreenSize(Vector2 size)
{
m_ScreenWidth = size.x;
m_ScreenHeight = size.y;
}
/// Raycasts this object.
public override void Raycast()
{
sortedRaycastResults.Clear();
breakPoints.Clear();
var zScale = transform.lossyScale.z;
var amountDistance = (FarDistance - NearDistance) * zScale;
float distance;
Ray ray;
RaycastResult firstHit = default(RaycastResult);
distance = amountDistance;
var touch_x = NRVirtualDisplayer.SystemButtonState.originTouch.x;
var touch_y = NRVirtualDisplayer.SystemButtonState.originTouch.y;
var realTouchPos = new Vector3((touch_x + 1) * m_ScreenWidth * 0.5f, (touch_y + 1) * m_ScreenHeight * 0.5f, 0f);
Vector3 touchpos = NRVirtualDisplayer.SystemButtonState.pressing ? realTouchPos : m_LastTouch;
m_LastTouch = NRVirtualDisplayer.SystemButtonState.pressing ? touchpos : m_FarAwayPos;
touchpos = m_UICamera.ScreenToWorldPoint(touchpos);
//NRDebugger.Info("[PhoneDisplay] origin touch:{0} realTouchPos:{1} touchpos:{2} screenWidth:{3} screenHeight:{4}",
// MultiScreenController.SystemButtonState.originTouch, realTouchPos, touchpos, m_ScreenWidth, m_ScreenHeight);
if (Mouse)
Mouse.transform.position = touchpos + m_UICamera.transform.forward * 0.3f;
ray = new Ray(touchpos, m_UICamera.transform.forward);
breakPoints.Add(touchpos);
eventCamera.farClipPlane = eventCamera.nearClipPlane + distance;
eventCamera.orthographicSize = m_UICamera.orthographicSize;
eventCamera.aspect = m_UICamera.aspect;
eventCamera.transform.position = ray.origin - (ray.direction * eventCamera.nearClipPlane);
eventCamera.transform.rotation = Quaternion.LookRotation(ray.direction, transform.up);
Raycast(ray, distance, sortedRaycastResults);
firstHit = FirstRaycastResult();
if (firstHit.isValid && firstHit.gameObject)
{
var button = firstHit.gameObject.GetComponent();
if (button != null)
{
button.OnHover(firstHit);
}
}
breakPoints.Add(firstHit.isValid ? firstHit.worldPosition : ray.GetPoint(distance));
#if UNITY_EDITOR
if (showDebugRay)
Debug.DrawLine(breakPoints[0], breakPoints[1], firstHit.isValid ? Color.green : Color.red);
#endif
}
/// Graphic raycast.
/// The canvas.
/// True to ignore reversed graphics.
/// The ray.
/// The distance.
/// The raycaster.
/// The raycast results.
public override void GraphicRaycast(ICanvasRaycastTarget raycastTarget, bool ignoreReversedGraphics, Ray ray, float distance, NRPointerRaycaster raycaster, List raycastResults)
{
if (raycastTarget.canvas == null) { return; }
var eventCamera = raycaster.eventCamera;
var screenCenterPoint = eventCamera.WorldToScreenPoint(eventCamera.transform.position);
raycastTarget.GraphicRaycast(ignoreReversedGraphics, ray, distance, screenCenterPoint, raycaster, raycastResults);
}
}
}