Пример #1
0
        public static void DrawCameraBounds(LeiaCamera controller, GizmoType gizmoType)
        {
#if UNITY_4_6 || UNITY_4_7 || UNITY_5_0_0 || UNITY_5_0_1
            GizmoType notSelected = GizmoType.NotSelected;
#elif UNITY_5_0_2 || UNITY_5_0_3 || UNITY_5_0_4
            GizmoType notSelected = GizmoType.NotInSelectionHierarchy;
#else
            GizmoType notSelected = GizmoType.NonSelected;
#endif
            if ((gizmoType & notSelected) != 0 && controller.DrawCameraBounds == false)
            {
                return;
            }

            var camera = controller.GetComponent <Camera>();

            if (camera == null)
            {
                return;
            }

            DisplayConfig displayConfig;

            if (Application.isPlaying)
            {
                displayConfig = LeiaDisplay.Instance.GetDisplayConfig();
            }
            else
            {
                displayConfig = Object.FindObjectOfType <LeiaDisplay>().GetDisplayConfig();
            }

            LeiaCameraData leiaCameraData = LeiaCameraUtils.ComputeLeiaCamera(
                camera,
                controller.ConvergenceDistance,
                controller.BaselineScaling,
                displayConfig);

            LeiaBoundsData leiaBoundsData = LeiaCameraUtils.ComputeLeiaBounds(camera, leiaCameraData, controller.ConvergenceDistance, controller.CameraShift, displayConfig);

            if (((gizmoType & notSelected) != 0 && controller.DrawCameraBounds) || (gizmoType & GizmoType.Selected) != 0)
            {
                // draw convergence plane in editor play mode
                Handles.DrawSolidRectangleWithOutline(leiaBoundsData.screen, _leiaScreenPlaneColor, _leiaScreenWireColor);
            }

            if (((gizmoType & notSelected) != 0 && controller.DrawCameraBounds) || (gizmoType & GizmoType.Selected) != 0)
            {
                // draw frustum outline in white
                Handles.DrawSolidRectangleWithOutline(leiaBoundsData.north, _leiaBoundsPlaneColor, _leiaBoundsWireColor);
                Handles.DrawSolidRectangleWithOutline(leiaBoundsData.south, _leiaBoundsPlaneColor, _leiaBoundsWireColor);
                Handles.DrawSolidRectangleWithOutline(leiaBoundsData.east, _leiaBoundsPlaneColor, _leiaBoundsWireColor);
                Handles.DrawSolidRectangleWithOutline(leiaBoundsData.west, _leiaBoundsPlaneColor, _leiaBoundsWireColor);
                Handles.DrawSolidRectangleWithOutline(leiaBoundsData.top, _leiaBoundsPlaneColor, _leiaBoundsWireColor);
                Handles.DrawSolidRectangleWithOutline(leiaBoundsData.bottom, _leiaBoundsPlaneColor, _leiaBoundsWireColor);
            }
        }
Пример #2
0
        public static LeiaCameraData ComputeLeiaCamera(Camera camera, float convergenceDistance, float baselineScaling, DisplayConfig displayConfig)
        {
            LeiaCameraData leiaCameraData = new LeiaCameraData();

            displayConfig.UserOrientationIsLandscape = camera.pixelWidth > camera.pixelHeight;

            float f = displayConfig.UserViewResolution.y / 2f / Mathf.Tan(camera.fieldOfView * Mathf.PI / 360f);

            leiaCameraData.baseline         = displayConfig.SystemDisparityPixels * baselineScaling * convergenceDistance / f;
            leiaCameraData.screenHalfHeight = convergenceDistance * Mathf.Tan(camera.fieldOfView * Mathf.PI / 360.0f);
            leiaCameraData.screenHalfWidth  = camera.aspect * leiaCameraData.screenHalfHeight;
            leiaCameraData.baselineScaling  = baselineScaling;

            return(leiaCameraData);
        }
Пример #3
0
        public static LeiaBoundsData ComputeLeiaBounds(Camera camera, LeiaCameraData leiaCamera, float convergenceDistance, Vector2 cameraShift, DisplayConfig displayConfig)
        {
            LeiaBoundsData leiaBounds         = new LeiaBoundsData();
            var            localToWorldMatrix = camera.transform.localToWorldMatrix;

            localToWorldMatrix.SetColumn(0, localToWorldMatrix.GetColumn(0).normalized);
            localToWorldMatrix.SetColumn(1, localToWorldMatrix.GetColumn(1).normalized);
            localToWorldMatrix.SetColumn(2, localToWorldMatrix.GetColumn(2).normalized);

            if (camera.orthographic)
            {
                // assumes baseline = (baseline scaling) * (width of view in world units) * (system disparity in pixels) * (convergence distance) / (view width in pixels)

                float halfSizeY = camera.orthographicSize;
                float halfSizeX = halfSizeY * camera.aspect;


                Vector3 screenTopLeft     = localToWorldMatrix.MultiplyPoint(new Vector3(-halfSizeX, halfSizeY, convergenceDistance));
                Vector3 screenTopRight    = localToWorldMatrix.MultiplyPoint(new Vector3(halfSizeX, halfSizeY, convergenceDistance));
                Vector3 screenBottomLeft  = localToWorldMatrix.MultiplyPoint(new Vector3(-halfSizeX, -halfSizeY, convergenceDistance));
                Vector3 screenBottomRight = localToWorldMatrix.MultiplyPoint(new Vector3(halfSizeX, -halfSizeY, convergenceDistance));


                float negativeSystemDisparityZ = convergenceDistance - 1.0f / leiaCamera.baselineScaling;

                Vector3 nearTopLeft     = localToWorldMatrix.MultiplyPoint(new Vector3(-halfSizeX, halfSizeY, negativeSystemDisparityZ));
                Vector3 nearTopRight    = localToWorldMatrix.MultiplyPoint(new Vector3(halfSizeX, halfSizeY, negativeSystemDisparityZ));
                Vector3 nearBottomLeft  = localToWorldMatrix.MultiplyPoint(new Vector3(-halfSizeX, -halfSizeY, negativeSystemDisparityZ));
                Vector3 nearBottomRight = localToWorldMatrix.MultiplyPoint(new Vector3(halfSizeX, -halfSizeY, negativeSystemDisparityZ));


                float positiveSystemDisparityZ = convergenceDistance + 1.0f / leiaCamera.baselineScaling;

                Vector3 farTopLeft     = localToWorldMatrix.MultiplyPoint(new Vector3(-halfSizeX, halfSizeY, positiveSystemDisparityZ));
                Vector3 farTopRight    = localToWorldMatrix.MultiplyPoint(new Vector3(halfSizeX, halfSizeY, positiveSystemDisparityZ));
                Vector3 farBottomLeft  = localToWorldMatrix.MultiplyPoint(new Vector3(-halfSizeX, -halfSizeY, positiveSystemDisparityZ));
                Vector3 farBottomRight = localToWorldMatrix.MultiplyPoint(new Vector3(halfSizeX, -halfSizeY, positiveSystemDisparityZ));


                leiaBounds.screen = new [] { screenTopLeft, screenTopRight, screenBottomRight, screenBottomLeft };
                leiaBounds.south  = new [] { nearTopLeft, nearTopRight, nearBottomRight, nearBottomLeft };
                leiaBounds.north  = new [] { farTopLeft, farTopRight, farBottomRight, farBottomLeft };
                leiaBounds.top    = new [] { nearTopLeft, nearTopRight, farTopRight, farTopLeft };
                leiaBounds.bottom = new [] { nearBottomLeft, nearBottomRight, farBottomRight, farBottomLeft };
                leiaBounds.east   = new [] { nearTopRight, nearBottomRight, farBottomRight, farTopRight };
                leiaBounds.west   = new [] { nearTopLeft, nearBottomLeft, farBottomLeft, farTopLeft };
            }

            else
            {
                cameraShift = leiaCamera.baseline * cameraShift;

                Vector3 screenTopLeft     = localToWorldMatrix.MultiplyPoint(new Vector3(-leiaCamera.screenHalfWidth, leiaCamera.screenHalfHeight, convergenceDistance));
                Vector3 screenTopRight    = localToWorldMatrix.MultiplyPoint(new Vector3(leiaCamera.screenHalfWidth, leiaCamera.screenHalfHeight, convergenceDistance));
                Vector3 screenBottomLeft  = localToWorldMatrix.MultiplyPoint(new Vector3(-leiaCamera.screenHalfWidth, -leiaCamera.screenHalfHeight, convergenceDistance));
                Vector3 screenBottomRight = localToWorldMatrix.MultiplyPoint(new Vector3(leiaCamera.screenHalfWidth, -leiaCamera.screenHalfHeight, convergenceDistance));

                float nearPlaneZ     = (leiaCamera.baselineScaling * convergenceDistance) / (leiaCamera.baselineScaling + 1f);
                float nearRatio      = nearPlaneZ / convergenceDistance;
                float nearShiftRatio = 1f - nearRatio;

                Bounds localNearPlaneBounds = new Bounds(
                    new Vector3(nearShiftRatio * cameraShift.x, nearShiftRatio * cameraShift.y, nearPlaneZ),
                    new Vector3(leiaCamera.screenHalfWidth * nearRatio * 2, leiaCamera.screenHalfHeight * nearRatio * 2, 0));

                Vector3 nearTopLeft     = localToWorldMatrix.MultiplyPoint(new Vector3(localNearPlaneBounds.min.x, localNearPlaneBounds.max.y, localNearPlaneBounds.center.z));
                Vector3 nearTopRight    = localToWorldMatrix.MultiplyPoint(new Vector3(localNearPlaneBounds.max.x, localNearPlaneBounds.max.y, localNearPlaneBounds.center.z));
                Vector3 nearBottomLeft  = localToWorldMatrix.MultiplyPoint(new Vector3(localNearPlaneBounds.min.x, localNearPlaneBounds.min.y, localNearPlaneBounds.center.z));
                Vector3 nearBottomRight = localToWorldMatrix.MultiplyPoint(new Vector3(localNearPlaneBounds.max.x, localNearPlaneBounds.min.y, localNearPlaneBounds.center.z));

                float farPlaneZ = (leiaCamera.baselineScaling * convergenceDistance) / (leiaCamera.baselineScaling - 1f);
                farPlaneZ = 1f / Mathf.Max(1f / farPlaneZ, 1e-5f);

                float farRatio      = farPlaneZ / convergenceDistance;
                float farShiftRatio = 1f - farRatio;

                Bounds localFarPlaneBounds = new Bounds(
                    new Vector3(farShiftRatio * cameraShift.x, farShiftRatio * cameraShift.y, farPlaneZ),
                    new Vector3(leiaCamera.screenHalfWidth * farRatio * 2, leiaCamera.screenHalfHeight * farRatio * 2, 0));

                Vector3 farTopLeft     = localToWorldMatrix.MultiplyPoint(new Vector3(localFarPlaneBounds.min.x, localFarPlaneBounds.max.y, localFarPlaneBounds.center.z));
                Vector3 farTopRight    = localToWorldMatrix.MultiplyPoint(new Vector3(localFarPlaneBounds.max.x, localFarPlaneBounds.max.y, localFarPlaneBounds.center.z));
                Vector3 farBottomLeft  = localToWorldMatrix.MultiplyPoint(new Vector3(localFarPlaneBounds.min.x, localFarPlaneBounds.min.y, localFarPlaneBounds.center.z));
                Vector3 farBottomRight = localToWorldMatrix.MultiplyPoint(new Vector3(localFarPlaneBounds.max.x, localFarPlaneBounds.min.y, localFarPlaneBounds.center.z));

                leiaBounds.screen = new [] { screenTopLeft, screenTopRight, screenBottomRight, screenBottomLeft };
                leiaBounds.south  = new [] { nearTopLeft, nearTopRight, nearBottomRight, nearBottomLeft };
                leiaBounds.north  = new [] { farTopLeft, farTopRight, farBottomRight, farBottomLeft };
                leiaBounds.top    = new [] { nearTopLeft, nearTopRight, farTopRight, farTopLeft };
                leiaBounds.bottom = new [] { nearBottomLeft, nearBottomRight, farBottomRight, farBottomLeft };
                leiaBounds.east   = new [] { nearTopRight, nearBottomRight, farBottomRight, farTopRight };
                leiaBounds.west   = new [] { nearTopLeft, nearBottomLeft, farBottomLeft, farTopLeft };
            }

            return(leiaBounds);
        }