Beispiel #1
0
    /// <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;
            }
        }
    }