/**************************************************************************** * 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); } } }