CapturePanorama.CapturePanorama.CubemapToEquirectangularCpu C# (CSharp) Method

CubemapToEquirectangularCpu() private method

private CubemapToEquirectangularCpu ( uint cameraPixels, int cameraWidth, int cameraHeight, byte pixelValues, int stride, int panoramaWidth, int panoramaHeight, int ssaaFactor, bool async ) : IEnumerator
cameraPixels uint
cameraWidth int
cameraHeight int
pixelValues byte
stride int
panoramaWidth int
panoramaHeight int
ssaaFactor int
async bool
return IEnumerator
        IEnumerator CubemapToEquirectangularCpu(uint[] cameraPixels, int cameraWidth, int cameraHeight, byte[] pixelValues,
            int stride, int panoramaWidth, int panoramaHeight, int ssaaFactor, bool async)
        {
            Log("Converting to equirectangular");

            yield return null; // Wait for next frame at beginning - already used up some time capturing snapshot

            float startTime = Time.realtimeSinceStartup;
            float processingTimePerFrame = cpuMillisecondsPerFrame / 1000.0f;
            float maxWidth  = 1.0f - 1.0f / cameraWidth;
            float maxHeight = 1.0f - 1.0f / cameraHeight;
            int numPixelsAveraged = ssaaFactor * ssaaFactor;

            // For efficiency we're going to do a series of rectangles each drawn from only one texture,
            // only using the slow general-case reprojection where necessary.

            int endYPositive   = (int)Mathf.Floor(panoramaHeight * 0.25f);
            int startYNegative = (int)Mathf.Ceil(panoramaHeight * 0.75f);

            // 0.195913f is angle in radians between (1, 0, 1) and (1, 1, 1) over pi
            int endTopMixedRegion      = (int)Mathf.Ceil (panoramaHeight * (0.5f - 0.195913f));
            int startBottomMixedRegion = (int)Mathf.Floor(panoramaHeight * (0.5f + 0.195913f));

            int startXNegative = (int)Mathf.Ceil (panoramaWidth * 1.0f / 8.0f);
            int endXNegative   = (int)Mathf.Floor(panoramaWidth * 3.0f / 8.0f);

            int startZPositive = (int)Mathf.Ceil (panoramaWidth * 3.0f / 8.0f);
            int endZPositive   = (int)Mathf.Floor(panoramaWidth * 5.0f / 8.0f);

            int startXPositive = (int)Mathf.Ceil(panoramaWidth  * 5.0f / 8.0f);
            int endXPositive   = (int)Mathf.Floor(panoramaWidth * 7.0f / 8.0f);

            int startZNegative = (int)Mathf.Ceil(panoramaWidth  * 7.0f / 8.0f);
            int endZNegative   = (int)Mathf.Floor(panoramaWidth * 1.0f / 8.0f); // z negative wraps/loops around

            if (async)
            {
                yield return StartCoroutine(CubemapToEquirectangularCpuPositiveY(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    0, 0, panoramaWidth, endYPositive));
                yield return StartCoroutine(CubemapToEquirectangularCpuNegativeY(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    0, startYNegative, panoramaWidth, panoramaHeight));

                yield return StartCoroutine(CubemapToEquirectangularCpuPositiveX(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    startXPositive, endTopMixedRegion, endXPositive, startBottomMixedRegion));
                yield return StartCoroutine(CubemapToEquirectangularCpuNegativeX(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    startXNegative, endTopMixedRegion, endXNegative, startBottomMixedRegion));
                yield return StartCoroutine(CubemapToEquirectangularCpuPositiveZ(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    startZPositive, endTopMixedRegion, endZPositive, startBottomMixedRegion));

                // Do in two pieces since z negative wraps/loops around
                yield return StartCoroutine(CubemapToEquirectangularCpuNegativeZ(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    startZNegative, endTopMixedRegion, panoramaWidth, startBottomMixedRegion));
                yield return StartCoroutine(CubemapToEquirectangularCpuNegativeZ(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    0, endTopMixedRegion, endZNegative, startBottomMixedRegion));

                // Handle all remaining image areas with the general case
                yield return StartCoroutine(CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                    0, endYPositive, panoramaWidth, endTopMixedRegion));
                yield return StartCoroutine(CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                    0, startBottomMixedRegion, panoramaWidth, startYNegative));

                // If width is not multiple of 8, due to rounding, there may be one-column strips where the X/Z textures mix together
                if (endZNegative < startXNegative)
                    yield return StartCoroutine(CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                        endZNegative, endTopMixedRegion, startXNegative, startBottomMixedRegion));
                if (endXNegative < startZPositive)
                    yield return StartCoroutine(CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                        endXNegative, endTopMixedRegion, startZPositive, startBottomMixedRegion));
                if (endZPositive < startXPositive)
                    yield return StartCoroutine(CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                        endZPositive, endTopMixedRegion, startXPositive, startBottomMixedRegion));
                if (endXPositive < startZNegative)
                    yield return StartCoroutine(CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                        endXPositive, endTopMixedRegion, startZNegative, startBottomMixedRegion));
            }
            else
            {
                IEnumerator enumerator;
                enumerator = CubemapToEquirectangularCpuPositiveY(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    0, 0, panoramaWidth, endYPositive);
                while (enumerator.MoveNext()) { }
                enumerator = CubemapToEquirectangularCpuNegativeY(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    0, startYNegative, panoramaWidth, panoramaHeight);
                while (enumerator.MoveNext()) { }

                enumerator = CubemapToEquirectangularCpuPositiveX(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    startXPositive, endTopMixedRegion, endXPositive, startBottomMixedRegion);
                while (enumerator.MoveNext()) { }
                enumerator = CubemapToEquirectangularCpuNegativeX(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    startXNegative, endTopMixedRegion, endXNegative, startBottomMixedRegion);
                while (enumerator.MoveNext()) { }
                enumerator = CubemapToEquirectangularCpuPositiveZ(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    startZPositive, endTopMixedRegion, endZPositive, startBottomMixedRegion);
                while (enumerator.MoveNext()) { }

                // Do in two pieces since z negative wraps/loops around
                enumerator = CubemapToEquirectangularCpuNegativeZ(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    startZNegative, endTopMixedRegion, panoramaWidth, startBottomMixedRegion);
                while (enumerator.MoveNext()) { }
                enumerator = CubemapToEquirectangularCpuNegativeZ(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, numPixelsAveraged,
                    0, endTopMixedRegion, endZNegative, startBottomMixedRegion);
                while (enumerator.MoveNext()) { }

                // Handle all remaining image areas with the general case
                enumerator = CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                    0, endYPositive, panoramaWidth, endTopMixedRegion);
                while (enumerator.MoveNext()) { }
                enumerator = CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                    0, startBottomMixedRegion, panoramaWidth, startYNegative);
                while (enumerator.MoveNext()) { }

                // If width is not multiple of 8, due to rounding, there may be one-column strips where the X/Z textures mix together
                if (endZNegative < startXNegative)
                {
                    enumerator = CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                        endZNegative, endTopMixedRegion, startXNegative, startBottomMixedRegion);
                    while (enumerator.MoveNext()) { }
                }
                if (endXNegative < startZPositive)
                {
                    enumerator = CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                        endXNegative, endTopMixedRegion, startZPositive, startBottomMixedRegion);
                    while (enumerator.MoveNext()) { }
                }
                if (endZPositive < startXPositive)
                {
                    enumerator = CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                        endZPositive, endTopMixedRegion, startXPositive, startBottomMixedRegion);
                    while (enumerator.MoveNext()) { }
                }
                if (endXPositive < startZNegative)
                {
                    enumerator = CubemapToEquirectangularCpuGeneralCase(cameraPixels, pixelValues, stride, panoramaWidth, panoramaHeight, ssaaFactor, startTime, processingTimePerFrame, maxWidth, maxHeight, numPixelsAveraged,
                        endXPositive, endTopMixedRegion, startZNegative, startBottomMixedRegion);
                    while (enumerator.MoveNext()) { }
                }
            }

            yield return null;
        }