CapturePanorama.CapturePanorama.ReinitializeBody C# (CSharp) Method

ReinitializeBody() public method

public ReinitializeBody ( ) : void
return void
        void ReinitializeBody()
        {
            Log("Settings changed, calling Reinitialize()");

            initializeFailed = true;

            if (!SystemInfo.supportsComputeShaders)
            {
                Debug.LogWarning("CapturePanorama requires compute shaders. Your system does not support them. " +
                    "On PC, compute shaders require DirectX 11, Windows Vista or later, and a GPU capable of Shader Model 5.0.");
                return;
            }

            lastConfiguredCaptureStereoscopic = captureStereoscopic;
            lastConfiguredPanoramaWidth = panoramaWidth;
            lastConfiguredInterpupillaryDistance = interpupillaryDistance;
            lastConfiguredNumCirclePoints = numCirclePoints;
            lastConfiguredSsaaFactor = ssaaFactor;
            lastConfiguredAntiAliasing = antiAliasing;
            lastConfiguredSaveCubemap = saveCubemap;
            lastConfiguredUseGpuTransform = useGpuTransform;

            Cleanup();

            faces = new CubemapFace[] {
                CubemapFace.PositiveX, CubemapFace.NegativeX,
                CubemapFace.PositiveY, CubemapFace.NegativeY,
                CubemapFace.PositiveZ, CubemapFace.NegativeZ };

            for (int i = 0; i < faces.Length; i++)
                Debug.Assert((int)faces[i] == i); // Required for ConvertPanoramaShader

            panoramaHeight = panoramaWidth / 2;

            // We have a tower of 3 nested GameObjects. First gets the original camera position,
            // second gets the eye rotation/position relative to it, and third holds the camera with default position/rotation.
            camGos = new GameObject[3];
            for (int i = 0; i < 3; i++)
            {
                camGos[i] = new GameObject("PanoramaCaptureCamera" + i);
                camGos[i].hideFlags = HideFlags.HideAndDontSave;
                if (i > 0) camGos[i].transform.parent = camGos[i - 1].transform;
            }

            camGos[2].AddComponent<Camera>();
            cam = camGos[2].GetComponent<Camera>();
            cam.enabled = false;
            camGos[2].AddComponent<ImageEffectCopyCamera>();
            copyCameraScript = camGos[2].GetComponent<ImageEffectCopyCamera>();
            copyCameraScript.enabled = false;

            numCameras = faces.Length;
            hFov = vFov = 90.0f;
            if (captureStereoscopic)
            {
                // For stereoscopic rendering, there are a set of points lying on a horizontal circle around the origin.
                // Will have four cameras per circle point, one turned left 45 deg, one turned right 45 deg,
                // one turned up 45 deg, one turned down 45 deg. Allows covering >= 180 deg horizontal and 180 deg vertical.
                // To be able to resolve all rays, we need to choose a large enough horizontal FOV for each camera.

                float maxAngleError = 360.0f / numCirclePoints;

                // TODO: Use different hFov/vFov for top/bottom cameras and left/right cameras (vFov of top/bottom cameras especially is a lot less)

                // Given our ipd adjustment scaling f(x), the IPD range of the top/bottom cameras will be up to f(0.5)
                // of the original IPD. Hence the necessary hFov is given by 2*(pi/2 - acos(f(0.5))), usually in the 90-115 deg range.
                float extraFovForRoundingErrors = 0.001f;
                float hFovTopBottom = 2.0f * (Mathf.PI / 2.0f - Mathf.Acos(IpdScaleFunction(0.5f))) * 360.0f / (2.0f * Mathf.PI);
                hFov = Mathf.Max(90f + maxAngleError, hFovTopBottom) + extraFovForRoundingErrors; // These will usually be similar so just use max for simplicity
                vFov = 90.0f;
                numCameras = 2 + numCirclePoints * CamerasPerCirclePoint; // 2 + for top/bottom
                circleRadius = interpupillaryDistance / 2.0f;
                hFovAdjustDegrees = hFov / 2.0f;
                vFovAdjustDegrees = vFov / 2.0f;
            }

            double ppd90 = panoramaWidth * 90.0 / 360.0;
            // Match PPD at 90 degrees - if it's larger, central 90 degree section should match PPD
            cameraWidth = (int)Math.Ceiling(Math.Tan(hFov * (2.0f*Mathf.PI)/360.0f / 2.0f) * ppd90 * ssaaFactor);
            cameraHeight = (int)Math.Ceiling(Math.Tan(vFov * (2.0f * Mathf.PI) / 360.0f / 2.0f) * ppd90 * ssaaFactor);

            Log("Number of cameras: " + numCameras);
            Log("Camera dimensions: " + cameraWidth + "x" + cameraHeight);

            usingGpuTransform = useGpuTransform && convertPanoramaShader != null;

            cubemapRenderTexture = new RenderTexture(cameraWidth, cameraHeight, /*depth*/24, RenderTextureFormat.ARGB32);
            cubemapRenderTexture.antiAliasing = (int)antiAliasing;
            cubemapRenderTexture.Create();

            if (usingGpuTransform)
            {
                convertPanoramaKernelIdx = convertPanoramaShader.FindKernel("CubeMapToEquirectangular");
                convertPanoramaYPositiveKernelIdx = convertPanoramaShader.FindKernel("CubeMapToEquirectangularPositiveY");
                convertPanoramaYNegativeKernelIdx = convertPanoramaShader.FindKernel("CubeMapToEquirectangularNegativeY");
                convertPanoramaKernelIdxs = new int[] { convertPanoramaKernelIdx, convertPanoramaYPositiveKernelIdx, convertPanoramaYNegativeKernelIdx };
                convertPanoramaShader.SetInt("equirectangularWidth", panoramaWidth);
                convertPanoramaShader.SetInt("equirectangularHeight", panoramaHeight);
                convertPanoramaShader.SetInt("ssaaFactor", ssaaFactor);
                convertPanoramaShader.SetInt("cameraWidth", cameraWidth);
                convertPanoramaShader.SetInt("cameraHeight", cameraHeight);

                int sliceHeight = (panoramaHeight + ResultBufferSlices - 1) / ResultBufferSlices;
                int bitmapWidth = panoramaWidth;
                int bitmapHeight = (captureStereoscopic ? 2 * panoramaHeight : sliceHeight);
                resultPixels = new uint[bitmapWidth * bitmapHeight + 1]; // + 1 for sentinel
            }

            textureToBufferIdx = textureToBufferShader.FindKernel("TextureToBuffer");
            textureToBufferShader.SetInt("width", cameraWidth);
            textureToBufferShader.SetInt("height", cameraHeight);
            textureToBufferShader.SetFloat("gamma", QualitySettings.activeColorSpace == ColorSpace.Linear ? 1.0f/2.2f : 1.0f);

            renderStereoIdx = convertPanoramaStereoShader.FindKernel("RenderStereo");

            if ((saveCubemap || !usingGpuTransform) &&
                (cameraPixels == null || cameraPixels.Length != numCameras * cameraWidth * cameraHeight))
            {
                // Allocate once to avoid GC fragmentation
                cameraPixels = new uint[numCameras * cameraWidth * cameraHeight + 1]; // + 1 for sentinel
            }

            tanHalfHFov = Mathf.Tan(hFov * (2 * Mathf.PI) / 360.0f / 2.0f);
            tanHalfVFov = Mathf.Tan(vFov * (2 * Mathf.PI) / 360.0f / 2.0f);
            hFovAdjust = hFovAdjustDegrees * (2 * Mathf.PI) / 360.0f;
            vFovAdjust = vFovAdjustDegrees * (2 * Mathf.PI) / 360.0f;

            if (captureStereoscopic && usingGpuTransform)
            {
                convertPanoramaStereoShader.SetFloat("tanHalfHFov", tanHalfHFov);
                convertPanoramaStereoShader.SetFloat("tanHalfVFov", tanHalfVFov);
                convertPanoramaStereoShader.SetFloat("hFovAdjust", hFovAdjust);
                convertPanoramaStereoShader.SetFloat("vFovAdjust", vFovAdjust);
                convertPanoramaStereoShader.SetFloat("interpupillaryDistance", interpupillaryDistance);
                convertPanoramaStereoShader.SetFloat("circleRadius", circleRadius);
                convertPanoramaStereoShader.SetInt("numCirclePoints", numCirclePoints);
                convertPanoramaStereoShader.SetInt("equirectangularWidth", panoramaWidth);
                convertPanoramaStereoShader.SetInt("equirectangularHeight", panoramaHeight);
                convertPanoramaStereoShader.SetInt("cameraWidth", cameraWidth);
                convertPanoramaStereoShader.SetInt("cameraHeight", cameraHeight);
                convertPanoramaStereoShader.SetInt("ssaaFactor", ssaaFactor);
            }

            initializeFailed = false;
        }