private void PositionFloorCamera(Camera cam, SurfaceInfo floor, float vFOVWalls)
        {
            //Set Initial Camera Rotation relative to main camera
            cam.transform.localRotation = mainCamera.transform.localRotation;

            // 1. Rotate Camera
            //Rotation in the Y-axis for a camera
            var horizontalRotation = 0;
            //Rotation in the X-axis for a camera
            var verticalRotation = 90;

            //Rotate camera
            cam.transform.Rotate(new Vector3(verticalRotation, horizontalRotation, 0));

            // 2. Calculate Field Of View for cameras
            var vFOVFloor = CalculateVerticalFOV(floor, 180f - vFOVWalls);

            cam.fieldOfView = vFOVFloor;

            // 3. Obliqueness of floor
            Matrix4x4 mat = cam.projectionMatrix;

            ////How much to shift cameras
            //Cannot remember why this works but it does.
            var a           = (Mathf.Deg2Rad * (90f - vFOVWalls / 2));
            var b           = (Mathf.Deg2Rad * vFOVFloor) / 2f;
            var obliqueness = (Mathf.Tan(b) - Mathf.Tan(a)) / (Mathf.Tan(b));

            mat[1, 2]            = -obliqueness;
            cam.projectionMatrix = mat;
        }
        /// <summary>
        /// Calculates the Vertical Field Of View of a given surface
        /// to achieve a desired Vertical Field Of View
        /// </summary>
        private float CalculateHorizontalFOV(SurfaceInfo surface, float vFOV)
        {
            var vFOVRad = vFOV * Mathf.Deg2Rad;
            var hFOVRad = 2f * Mathf.Atan(Mathf.Tan(vFOVRad / 2f) * (surface.rect.width / surface.rect.height));

            return((float)(Mathf.Rad2Deg * hFOVRad));
        }
        /// <summary>
        /// Calculates the Vertical Field Of View of a given surface
        /// to achieve a desired Horizontal Field Of View
        /// </summary>
        private float CalculateVerticalFOV(SurfaceInfo surface, float hFOV)
        {
            //Desired Horizontal Field of View in Radians
            var hFOVRad = hFOV * Mathf.Deg2Rad;
            //Vertical Field of View required to get desired horizontal field of view at current aspect ratio
            var vFOVRad = 2.0f * Mathf.Atan(Mathf.Tan(hFOVRad / 2) * (surface.rect.height / surface.rect.width));

            //Vertical Field of View in Degrees
            return((float)(Mathf.Rad2Deg * vFOVRad));
        }
        private float CalculateCenterVerticalFieldOfView(SurfaceInfo surface)
        {
            //If fixed horizontal field of view, side have same vFOV as center
            if (scalingMode == ScalingMode.FixedHorizontalFOV)
            {
                return(CalculateVerticalFOV(surface, 90f));
            }

            //Fixed Vertical Field Of View

            //This is the field of view of a 16x9 surface with 90 degress horizontal field of view
            return(58.71551f);
        }
        /// <summary>
        /// Positions a camera
        /// </summary>
        /// <param name="cam"></param>
        /// <param name="surface"></param>
        private void PositionWallCamera(Camera cam, SurfaceInfo surface)
        {
            if (walls.Count == 1)
            {
                return;
            }

            if (cagType == CAGType.Exterior)
            {
                cam.transform.localPosition = GetWallCameraPositionCAGE(surface);
            }
            else if (cagType == CAGType.Interior)
            {
                cam.transform.localPosition = GetWallCameraPositionCAGI(surface);
            }
        }
        private void PositionFloorOrthographic(Camera cam, SurfaceInfo floor)
        {
            //Set Initial Camera Rotation relative to main camera
            cam.transform.localRotation = mainCamera.transform.localRotation;

            // 1. Rotate Camera
            //Rotation in the Y-axis for a camera
            var horizontalRotation = 0;
            //Rotation in the X-axis for a camera
            var verticalRotation = 90;

            //Rotate camera
            cam.transform.Rotate(new Vector3(verticalRotation, horizontalRotation, 0));

            cam.orthographic     = true;
            cam.orthographicSize = 1;
            cam.nearClipPlane    = 1;
        }
        private Vector3 GetWallCameraPositionCAGI(SurfaceInfo surface)
        {
            float x = 0;

            switch (surface.position)
            {
            case SurfacePosition.Left:
                x = -2 * TargetAspectRatioFloat * ScaleFactor;
                break;

            case SurfacePosition.Right:
                x = 2 * TargetAspectRatioFloat * ScaleFactor;
                break;

            case SurfacePosition.Back:
                x = 4 * TargetAspectRatioFloat * ScaleFactor;
                break;
            }
            return(new Vector3(x, 0, 0));
        }
        private Vector3 GetWallCameraPositionCAGE(SurfaceInfo surface)
        {
            float mainCameraWidth  = centerSurface.aspectRatio * height * 2;
            float rightCameraWidth = rightSurface.aspectRatio * height * 2;
            float x = 0;

            switch (surface.position)
            {
            case SurfacePosition.Left:
                x = -(mainCameraWidth / 2 + surface.aspectRatio * height);
                break;

            case SurfacePosition.Right:
                x = (mainCameraWidth / 2 + surface.aspectRatio * height);
                break;

            case SurfacePosition.Back:
                x = mainCameraWidth / 2 + rightCameraWidth + surface.aspectRatio * height;
                break;
            }
            return(new Vector3(x, 0, 0));
        }
        protected override void PositionCameras()
        {
            for (var i = 0; i < surfaces.Count; i++)
            {
                Camera      cam     = cameras[i];
                SurfaceInfo surface = surfaces[i];

                if (surface.position == SurfacePosition.Floor)
                {
                    PositionFloorCamera(cam);
                    continue;
                }
                else
                {
                    PositionWallCamera(cam, surface);
                }
            }

            ScaleStage();

            //For Rotation Camera Buttons
            startPosition  = transform.localPosition;
            targetPosition = startPosition;
        }
Example #10
0
        public void LayoutSurfaces(List <SurfaceInfo> surfacesInfo, List <RenderTexture> renderTextures)
        {
            // 1. Calculate the width of the central screen and maximum width of a side wall.
            float centerWidth = 0;
            float sideWidth   = 0;

            foreach (SurfaceInfo surfaceInfo in surfacesInfo)
            {
                switch (surfaceInfo.position)
                {
                case SurfacePosition.Center:
                case SurfacePosition.Back:
                    var newCenterWidth = surfaceInfo.aspectRatio * wallHeight;
                    centerWidth = Mathf.Max(centerWidth, newCenterWidth);
                    break;

                case SurfacePosition.Left:
                case SurfacePosition.Right:
                    var newSideWidth = surfaceInfo.aspectRatio * wallHeight;
                    sideWidth = Mathf.Max(sideWidth, newSideWidth);
                    break;
                }
            }

            if (sideWidth == 0)
            {
                sideWidth = centerWidth;
            }
            if (centerWidth == 0)
            {
                centerWidth = sideWidth;
            }

            //Keep track of surfaces which are in use
            List <SurfacePosition> surfacePositions = new List <SurfacePosition>();

            //Resize all screens
            for (int i = 0; i < surfacesInfo.Count; i++)
            {
                SurfaceInfo   surfaceInfo   = surfacesInfo[i];
                RenderTexture renderTexture = renderTextures[i];

                surfacePositions.Add(surfaceInfo.position);
                switch (surfaceInfo.position)
                {
                case SurfacePosition.Left:
                    var left  = screens.GetChild(0);
                    var width = surfaceInfo.aspectRatio * wallHeight;
                    left.localPosition = new Vector3(-centerWidth / 2, 0, (sideWidth - width) / 2);
                    left.localScale    = new Vector3(width, wallHeight, 1);
                    SetScreenTexture(renderTexture, left);
                    break;

                case SurfacePosition.Center:
                    var center = screens.GetChild(1);
                    center.localPosition = new Vector3(0, 0, sideWidth / 2f);
                    center.localScale    = new Vector3(centerWidth, wallHeight, 1);
                    SetScreenTexture(renderTexture, center);
                    break;

                case SurfacePosition.Right:
                    var right = screens.GetChild(2);
                    width = surfaceInfo.aspectRatio * wallHeight;
                    right.localPosition = new Vector3(centerWidth / 2, 0, (sideWidth - width) / 2);
                    right.localScale    = new Vector3(width, wallHeight, 1);
                    SetScreenTexture(renderTexture, right);
                    break;

                case SurfacePosition.Back:
                    var back = screens.GetChild(3);
                    width = surfaceInfo.aspectRatio * wallHeight;
                    back.localPosition = new Vector3(0, 0, -sideWidth / 2);
                    back.localScale    = new Vector3(width, wallHeight, 1);
                    SetScreenTexture(renderTexture, back);
                    break;

                case SurfacePosition.Floor:
                    var floor  = screens.GetChild(4);
                    var height = centerWidth / surfaceInfo.aspectRatio;
                    floor.localPosition = new Vector3(0, -wallHeight / 2, (sideWidth - height) / 2);
                    floor.localScale    = new Vector3(centerWidth, height, 1);
                    SetScreenTexture(renderTexture, floor);
                    break;
                }
            }


            //Disable Screens which are not in used
            screens.GetChild(0).gameObject.SetActive(surfacePositions.Contains(SurfacePosition.Left));
            screens.GetChild(1).gameObject.SetActive(surfacePositions.Contains(SurfacePosition.Center));
            screens.GetChild(2).gameObject.SetActive(surfacePositions.Contains(SurfacePosition.Right));
            screens.GetChild(3).gameObject.SetActive(surfacePositions.Contains(SurfacePosition.Back));
            screens.GetChild(4).gameObject.SetActive(surfacePositions.Contains(SurfacePosition.Floor));

            //Resize Walls
            var leftWall = walls.GetChild(0);

            leftWall.localPosition = new Vector3(-centerWidth / 2, 0, 0);
            leftWall.localScale    = new Vector3(sideWidth, wallHeight, 1);

            var centerWall = walls.GetChild(1);

            centerWall.localPosition = new Vector3(0, 0, sideWidth / 2);
            centerWall.localScale    = new Vector3(centerWidth, wallHeight, 1);

            var rightWall = walls.GetChild(2);

            rightWall.localPosition = new Vector3(centerWidth / 2, 0, 0);
            rightWall.localScale    = new Vector3(sideWidth, wallHeight, 1);

            var backWall = walls.GetChild(3);

            backWall.localPosition = new Vector3(0, 0, -sideWidth / 2);
            backWall.localScale    = new Vector3(centerWidth, wallHeight, 1);

            var floorSurface = walls.GetChild(4);

            floorSurface.localPosition = new Vector3(0, -wallHeight / 2, 0);
            floorSurface.localScale    = new Vector3(centerWidth, sideWidth, 1);

            var ceilingSurface = walls.GetChild(5);

            ceilingSurface.localPosition = new Vector3(0, wallHeight / 2, 0);
            ceilingSurface.localScale    = new Vector3(centerWidth, sideWidth, 1);

            //Position Camera
            if (isFirstScene)
            {
                isFirstScene = false;
                cam.transform.localPosition = new Vector3(0, -wallHeight / 2 + 1, 0);
            }
            else
            {
                cam.transform.position = camPosition;
                cam.transform.rotation = camRotation;
            }


            //Move light just above the room
            roomLight.transform.localPosition = new Vector3(0, wallHeight / 2 + 0.01f, 0);
            roomLight.range = centerWidth * 20f;
        }