public List <SliceCameraDescription> CreateSliceCameras(float[] sliceSeams, GameObject parent,
                                                                StereoCameraInterface stereoCameraInterface,
                                                                Camera copySliceCameraFrom)
        {
            int   numSlices; // number of slices visible to this projector
            int   firstSeam = -1;
            int   lastSeam  = -1;
            float projStart = projectorMesh.MeshStart % 1.0f;
            float projEnd   = projectorMesh.MeshEnd % 1.0f;

//            float projWidth = (projectorMesh.MeshStart > projectorMesh.MeshEnd)
//            ? (1.0f + projectorMesh.MeshEnd - projectorMesh.MeshStart)
//            : (projectorMesh.MeshEnd - projectorMesh.MeshStart);
            float[] contextSeams = new float[sliceSeams.Length]; // create a local version of slice seams that may be modified

            sliceSeams.CopyTo(contextSeams, 0);

            //Debug.Log("Projector Start: " + projStart.ToString() + ". Projector End: " + projEnd.ToString());

            for (int i = 0; i < contextSeams.Length; i++)
            {
                float testLeftSeam = contextSeams[i];
                // The 0.0 seam must also act as 1.0 if it is at the end.
                float testRightSeam = ((i + 1) == contextSeams.Length) ? 1.0f : contextSeams[i + 1];
                if (testLeftSeam <= projStart && testRightSeam > projStart)
                {
                    // Left Projector edge is between these two seams
                    firstSeam = i;
                    //Debug.Log("Found first seam: " + contextSeams[i].ToString());
                }
                else if (testLeftSeam < projEnd && testRightSeam >= projEnd)
                {
                    // Right Projector edge is between these two seams
                    lastSeam = (i + 1) % contextSeams.Length;
                    //Debug.Log("Found last seam: " + contextSeams[(i + 1) % contextSeams.Length].ToString());
                }
            }

            if (firstSeam == -1 || lastSeam == -1)
            {
                // For some reason, couldn't find seams
                throw new Exception("Couldn't find slice seams on either side of the projector");
            }
            if (lastSeam > firstSeam)
            {
                numSlices = (lastSeam - firstSeam) % contextSeams.Length;
            }
            else
            {
                // this projector wraps around the 0 seam
                //Debug.Log("This Projector touches the 0 seam, fixing values");
                numSlices = (lastSeam + (contextSeams.Length - firstSeam));

                for (int i = 0; i < contextSeams.Length; i++)
                {
                    if (i >= 0 && i <= lastSeam)
                    {
                        contextSeams[i] += 1.0f;
                    }
                }

                if (projEnd < projStart)
                {
                    projEnd += 1.0f;
                }
            }

            // Make a camera per slice (clone the main camera's position and orientation)
            for (int i = 0; i < numSlices; i++)
            {
                float leftSeam  = contextSeams[(firstSeam + i) % contextSeams.Length];
                float rightSeam = contextSeams[(firstSeam + i + 1) % contextSeams.Length];
                float decAngle  = (rightSeam < leftSeam) ? (leftSeam + rightSeam + 1.0f) / 2.0f : (leftSeam + rightSeam) / 2.0f;
                float angle     = decAngle * 360.0f;
                SliceCameraDescription sliceCamera = new SliceCameraDescription(i, angle, leftSeam, rightSeam, this, parent, copySliceCameraFrom);
                sliceCameras.Add(sliceCamera);

                // Add eye callback script to slice camera
                CameraEyeCallback callbackScript = sliceCamera.cameraObject.AddComponent <CameraEyeCallback>();
                callbackScript.stereoCameraInterface = stereoCameraInterface;
                StereoMode stereoMode = this.stereoType == ProjectorStereoType.Left ? StereoMode.LEFT : StereoMode.RIGHT;
                callbackScript.stereoMode = stereoMode;

                Camera camera = sliceCamera.cameraObject.camera;

                StereoMode oppositeStereo = stereoMode == StereoMode.LEFT ? StereoMode.RIGHT : StereoMode.LEFT;
                camera.cullingMask = camera.cullingMask & ~(1 << ToolbeltManager.FirstInstance.GetStereoLayer(oppositeStereo));
            }
            return(sliceCameras);
        }
        public List<SliceCameraDescription> CreateSliceCameras(float[] sliceSeams, GameObject parent, 
																StereoCameraInterface stereoCameraInterface, 
																Camera copySliceCameraFrom)
        {
            int numSlices; // number of slices visible to this projector
            int firstSeam = -1;
            int lastSeam = -1;
            float projStart = projectorMesh.MeshStart % 1.0f;
            float projEnd = projectorMesh.MeshEnd % 1.0f;
            //            float projWidth = (projectorMesh.MeshStart > projectorMesh.MeshEnd)
            //            ? (1.0f + projectorMesh.MeshEnd - projectorMesh.MeshStart)
            //            : (projectorMesh.MeshEnd - projectorMesh.MeshStart);
            float[] contextSeams = new float[sliceSeams.Length]; // create a local version of slice seams that may be modified

            sliceSeams.CopyTo(contextSeams, 0);

            //Debug.Log("Projector Start: " + projStart.ToString() + ". Projector End: " + projEnd.ToString());

            for (int i = 0; i < contextSeams.Length; i++)
            {
                float testLeftSeam = contextSeams[i];
                // The 0.0 seam must also act as 1.0 if it is at the end.
                float testRightSeam = ((i + 1) == contextSeams.Length) ? 1.0f : contextSeams[i + 1];
                if (testLeftSeam <= projStart && testRightSeam > projStart)
                {
                    // Left Projector edge is between these two seams
                    firstSeam = i;
                    //Debug.Log("Found first seam: " + contextSeams[i].ToString());
                }
                else if (testLeftSeam < projEnd && testRightSeam >= projEnd)
                {
                    // Right Projector edge is between these two seams
                    lastSeam = (i + 1) % contextSeams.Length;
                    //Debug.Log("Found last seam: " + contextSeams[(i + 1) % contextSeams.Length].ToString());
                }
            }

            if (firstSeam == -1 || lastSeam == -1)
            {
                // For some reason, couldn't find seams
                throw new Exception("Couldn't find slice seams on either side of the projector");
            }
            if (lastSeam > firstSeam)
            {
                numSlices = (lastSeam - firstSeam) % contextSeams.Length;
            }
            else
            {
                // this projector wraps around the 0 seam
                //Debug.Log("This Projector touches the 0 seam, fixing values");
                numSlices = (lastSeam + (contextSeams.Length - firstSeam));

                for (int i = 0; i < contextSeams.Length; i++)
                {
                    if (i >= 0 && i <= lastSeam)
                    {
                        contextSeams[i] += 1.0f;
                    }
                }

                if (projEnd < projStart)
                {
                    projEnd += 1.0f;
                }
            }

            // Make a camera per slice (clone the main camera's position and orientation)
            for (int i = 0; i < numSlices; i++)
            {
                float leftSeam = contextSeams[(firstSeam + i) % contextSeams.Length];
                float rightSeam = contextSeams[(firstSeam + i + 1) % contextSeams.Length];
                float decAngle = (rightSeam < leftSeam) ? (leftSeam + rightSeam + 1.0f) / 2.0f : (leftSeam + rightSeam) / 2.0f;
                float angle = decAngle * 360.0f;
                SliceCameraDescription sliceCamera = new SliceCameraDescription(i, angle, leftSeam, rightSeam, this, parent, copySliceCameraFrom);
                sliceCameras.Add(sliceCamera);

                // Add eye callback script to slice camera
                CameraEyeCallback callbackScript = sliceCamera.cameraObject.AddComponent<CameraEyeCallback>();
                callbackScript.stereoCameraInterface = stereoCameraInterface;
                StereoMode stereoMode = this.stereoType == ProjectorStereoType.Left ? StereoMode.LEFT : StereoMode.RIGHT;
                callbackScript.stereoMode = stereoMode;

                Camera camera = sliceCamera.cameraObject.camera;

                StereoMode oppositeStereo = stereoMode == StereoMode.LEFT ? StereoMode.RIGHT : StereoMode.LEFT;
                camera.cullingMask = camera.cullingMask & ~(1 << ToolbeltManager.FirstInstance.GetStereoLayer(oppositeStereo));
            }
            return sliceCameras;
        }
        protected void SliceCameraRenderDepthBuffer(SliceCameraDescription sliceCam)
        {
            RenderTexture projDepthBuffer = this.projectorDepthBuffers[sliceCam.Projector];
            RenderTexture old = RenderTexture.active;
            RenderTexture.active = projDepthBuffer;

            GL.PushMatrix();
            GL.LoadPixelMatrix(0, projDepthBuffer.width, projDepthBuffer.height, 0);

            Rect drawRect = sliceCam.cameraObject.camera.rect;
            drawRect.xMin *= projDepthBuffer.width;
            drawRect.xMax *= projDepthBuffer.width;
            drawRect.yMin *= projDepthBuffer.height;
            drawRect.yMax *= projDepthBuffer.height;

            Graphics.DrawTexture(drawRect, new Texture2D(1, 1),
                            new Rect(0, 0, 1, 1),
                            0, 0, 0, 0,
                            this.depthToColourMat);

            GL.PopMatrix();
            RenderTexture.active = old;
        }