FocusSquare.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.XR.iOS;
  5. public class FocusSquare : MonoBehaviour {
  6. public enum FocusState {
  7. Initializing,
  8. Finding,
  9. Found
  10. }
  11. public GameObject findingSquare;
  12. public GameObject foundSquare;
  13. //for editor version
  14. public float maxRayDistance = 30.0f;
  15. public LayerMask collisionLayerMask;
  16. public float findingSquareDist = 0.5f;
  17. private FocusState squareState;
  18. public FocusState SquareState {
  19. get {
  20. return squareState;
  21. }
  22. set {
  23. squareState = value;
  24. foundSquare.SetActive (squareState == FocusState.Found);
  25. findingSquare.SetActive (squareState != FocusState.Found);
  26. }
  27. }
  28. bool trackingInitialized;
  29. // Use this for initialization
  30. void Start () {
  31. SquareState = FocusState.Initializing;
  32. trackingInitialized = true;
  33. }
  34. bool HitTestWithResultType (ARPoint point, ARHitTestResultType resultTypes)
  35. {
  36. List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface ().HitTest (point, resultTypes);
  37. if (hitResults.Count > 0) {
  38. foreach (var hitResult in hitResults) {
  39. foundSquare.transform.position = UnityARMatrixOps.GetPosition (hitResult.worldTransform);
  40. foundSquare.transform.rotation = UnityARMatrixOps.GetRotation (hitResult.worldTransform);
  41. Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", foundSquare.transform.position.x, foundSquare.transform.position.y, foundSquare.transform.position.z));
  42. return true;
  43. }
  44. }
  45. return false;
  46. }
  47. // Update is called once per frame
  48. void Update () {
  49. //use center of screen for focusing
  50. Vector3 center = new Vector3(Screen.width/2, Screen.height/2, findingSquareDist);
  51. #if UNITY_EDITOR
  52. Ray ray = Camera.main.ScreenPointToRay (center);
  53. RaycastHit hit;
  54. //we'll try to hit one of the plane collider gameobjects that were generated by the plugin
  55. //effectively similar to calling HitTest with ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent
  56. if (Physics.Raycast (ray, out hit, maxRayDistance, collisionLayerMask)) {
  57. //we're going to get the position from the contact point
  58. foundSquare.transform.position = hit.point;
  59. Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", foundSquare.transform.position.x, foundSquare.transform.position.y, foundSquare.transform.position.z));
  60. //and the rotation from the transform of the plane collider
  61. SquareState = FocusState.Found;
  62. foundSquare.transform.rotation = hit.transform.rotation;
  63. return;
  64. }
  65. #else
  66. var screenPosition = Camera.main.ScreenToViewportPoint(center);
  67. ARPoint point = new ARPoint {
  68. x = screenPosition.x,
  69. y = screenPosition.y
  70. };
  71. // prioritize reults types
  72. ARHitTestResultType[] resultTypes = {
  73. ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent,
  74. // if you want to use infinite planes use this:
  75. //ARHitTestResultType.ARHitTestResultTypeExistingPlane,
  76. //ARHitTestResultType.ARHitTestResultTypeHorizontalPlane,
  77. //ARHitTestResultType.ARHitTestResultTypeFeaturePoint
  78. };
  79. foreach (ARHitTestResultType resultType in resultTypes)
  80. {
  81. if (HitTestWithResultType (point, resultType))
  82. {
  83. SquareState = FocusState.Found;
  84. return;
  85. }
  86. }
  87. #endif
  88. //if you got here, we have not found a plane, so if camera is facing below horizon, display the focus "finding" square
  89. if (trackingInitialized) {
  90. SquareState = FocusState.Finding;
  91. //check camera forward is facing downward
  92. if (Vector3.Dot(Camera.main.transform.forward, Vector3.down) > 0)
  93. {
  94. //position the focus finding square a distance from camera and facing up
  95. findingSquare.transform.position = Camera.main.ScreenToWorldPoint(center);
  96. //vector from camera to focussquare
  97. Vector3 vecToCamera = findingSquare.transform.position - Camera.main.transform.position;
  98. //find vector that is orthogonal to camera vector and up vector
  99. Vector3 vecOrthogonal = Vector3.Cross(vecToCamera, Vector3.up);
  100. //find vector orthogonal to both above and up vector to find the forward vector in basis function
  101. Vector3 vecForward = Vector3.Cross(vecOrthogonal, Vector3.up);
  102. findingSquare.transform.rotation = Quaternion.LookRotation(vecForward,Vector3.up);
  103. }
  104. else
  105. {
  106. //we will not display finding square if camera is not facing below horizon
  107. findingSquare.SetActive(false);
  108. }
  109. }
  110. }
  111. }