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; }
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; }