/// <summary> /// Returns the object under the specified position. /// </summary> static public bool Raycast(Vector3 inPos, out RaycastHit hit) { for (int i = 0; i < mList.Count; ++i) { UICamera cam = mList[i]; // Skip inactive scripts if (!cam.enabled || !NGUITools.GetActive(cam.gameObject)) { continue; } // Convert to view space currentCamera = cam.cachedCamera; Vector3 pos = currentCamera.ScreenToViewportPoint(inPos); if (float.IsNaN(pos.x) || float.IsNaN(pos.y)) { continue; } // CORE HACK by Tuukka Takala // If it's outside the camera's viewport, do nothing // if (pos.x < 0f || pos.x > 1f || pos.y < 0f || pos.y > 1f) continue; Ray ray; // if(ruisCamera != null && ruisCamera.associatedDisplay != null) { if (UnityEngine.VR.VRSettings.enabled && currentCamera.stereoTargetEye != StereoTargetEyeMask.None) // if(ruisCamera.associatedDisplay.isHmdDisplay) { // *** TODO remove this hack when Camera.ScreenPointToRay() works again ray = RUISDisplayManager.HMDScreenPointToRay(inPos, currentCamera); } else { ray = currentCamera.ScreenPointToRay(inPos); if (ruisCamera && ruisCamera.associatedDisplay != null && ruisCamera.associatedDisplay.isObliqueFrustum) { Quaternion outerRot = ruisCamera.transform.rotation; Quaternion wallOrientation = Quaternion.LookRotation(-ruisCamera.associatedDisplay.DisplayNormal, ruisCamera.associatedDisplay.DisplayUp); // *** HACK why is this sign flip necessary to keep the menu at right place?? outerRot = new Quaternion(outerRot.x, outerRot.y, -outerRot.z, outerRot.w); ray.origin += outerRot * ruisCamera.KeystoningHeadTrackerPosition; if (displayManager) { ray.origin -= outerRot * (new Vector3(displayManager.guiX, displayManager.guiY, displayManager.guiZ)); } // ray.direction = wallOrientation * ray.direction; } } } // else // ray = currentCamera.ScreenPointToRay(inPos); // END CORE HACK // Cast a ray into the screen // Ray ray = currentCamera.ScreenPointToRay(inPos); // Raycast into the screen int mask = currentCamera.cullingMask & (int)cam.eventReceiverMask; float dist = (cam.rangeDistance > 0f) ? cam.rangeDistance : currentCamera.farClipPlane - currentCamera.nearClipPlane; // If raycasts should be clipped by panels, we need to find a panel for each hit if (cam.clipRaycasts) { RaycastHit[] hits = Physics.RaycastAll(ray, dist, mask); if (hits.Length > 1) { System.Array.Sort(hits, delegate(RaycastHit r1, RaycastHit r2) { return(r1.distance.CompareTo(r2.distance)); }); for (int b = 0, bmax = hits.Length; b < bmax; ++b) { if (IsVisible(ref hits[b])) { hit = hits[b]; return(true); } } } else if (hits.Length == 1 && IsVisible(ref hits[0])) { hit = hits[0]; return(true); } continue; } if (Physics.Raycast(ray, out hit, dist, mask)) { return(true); } } hit = mEmpty; return(false); }
void LateUpdate() { // If we are in calibration scene, disable 3d cursor if (this.transform.parent == null) { this.enabled = false; return; } // TODO: instead of searching hierarchy on every frame, find the UICameras more efficiently uiCamera = ruisCamera.transform.GetComponentInChildren <UICamera>(); //menuScript.transform.parent.parent.GetComponentsInChildren<UICamera>(); if (menuScript.menuIsVisible && !instancedCursor) { instancedCursor = Instantiate(this.markerObject) as GameObject; } if (!menuScript.menuIsVisible && instancedCursor) { Destroy(instancedCursor); } if (!menuScript.menuIsVisible) { return; } mouseInputCoordinates = Input.mousePosition; if (ruisCamera.centerCamera) { if (instancedCursor) { instancedCursor.transform.rotation = ruisCamera.centerCamera.transform.rotation; } } else { if (instancedCursor) { instancedCursor.transform.rotation = ruisCamera.transform.rotation; } } // HACK for MecanimBlendedCharacter: Keep cursor visible size even if character is scaled if (menuScript.transform.parent) { instancedCursor.transform.localScale = originalLocalScale * Mathf.Max(menuScript.transform.parent.lossyScale.x, menuScript.transform.parent.lossyScale.y); } RaycastHit hit; if (uiCamera) { /* * if(!ruisCamera.associatedDisplay.isStereo * && (camera.gameObject.name == "CameraLeft" || camera.gameObject.name == "CameraRight" || camera.gameObject.name == "guiCameraForRift" ||)) ||{ || camera.enabled = false; || continue; ||} || ||if(ruisCamera.associatedDisplay.isStereo || && !ruisCamera.associatedDisplay.enableOculusRift || && !(camera.gameObject.name == "CameraLeft" || camera.gameObject.name == "CameraRight" || )) || { || camera.enabled = false; || continue; || } ||if(ruisCamera.associatedDisplay.enableOculusRift || && camera.gameObject.name != "guiCameraForRift") || { || camera.enabled = false; || continue; || } */ Ray ray; Camera rayCamera = uiCamera.GetComponent <Camera>(); if (rayCamera) { if (UnityEngine.XR.XRSettings.enabled && rayCamera.stereoTargetEye != StereoTargetEyeMask.None) // if(ruisCamera.associatedDisplay != null && ruisCamera.associatedDisplay.isHmdDisplay) { // *** TODO remove this hack when Camera.ScreenPointToRay() works again ray = RUISDisplayManager.HMDScreenPointToRay(mouseInputCoordinates, rayCamera); } else { ray = rayCamera.ScreenPointToRay(mouseInputCoordinates); } } else { ray = new Ray(); } if (ruisCamera.associatedDisplay != null && ruisCamera.associatedDisplay.isObliqueFrustum) { Quaternion outerRot = ruisCamera.transform.rotation; wallOrientation = Quaternion.LookRotation(-ruisCamera.associatedDisplay.DisplayNormal, ruisCamera.associatedDisplay.DisplayUp); // *** HACK why is this sign flip necessary to keep the menu at right place?? outerRot = new Quaternion(outerRot.x, outerRot.y, -outerRot.z, outerRot.w); instancedCursor.transform.rotation = outerRot * wallOrientation; trackerPosition = outerRot * ruisCamera.KeystoningHeadTrackerPosition; ray.origin += trackerPosition - outerRot * (new Vector3(ruisDisplayManager.guiX, ruisDisplayManager.guiY, ruisDisplayManager.guiZ)); // ray.direction = wallOrientation * ray.direction; } if (Physics.Raycast(ray, out hit, Mathf.Infinity, LayerMask.GetMask(LayerMask.LayerToName(ruisDisplayManager.menuLayer)))) { if (instancedCursor) { instancedCursor.transform.position = hit.point; if (!wasVisible) { instancedCursor.SetActive(true); } wasVisible = true; } #if UNITY_EDITOR Debug.DrawLine(ray.origin, hit.point); #endif } else { if (wasVisible) { instancedCursor.SetActive(false); } wasVisible = false; } } }