Ejemplo n.º 1
0
        private void CleanUp()
        {
            foreach (RenderTexture rt in ReflRenderTextures.Values)
            {
                if (rt == null)
                {
                    continue;
                }
                rt.Release();
                PUtilities.DestroyObject(rt);
            }

            foreach (Camera cam in ReflCameras.Values)
            {
                if (cam == null)
                {
                    continue;
                }
                PUtilities.DestroyGameobject(cam.gameObject);
            }

            if (mesh != null)
            {
                PUtilities.DestroyObject(mesh);
            }

            if (spline != null)
            {
                spline.Dispose();
            }
        }
Ejemplo n.º 2
0
        public static float GetValueBilinear(float[] data, int width, int height, Vector2 uv)
        {
            float   value      = 0;
            Vector2 pixelCoord = new Vector2(
                Mathf.Lerp(0, width - 1, uv.x),
                Mathf.Lerp(0, height - 1, uv.y));
            //apply a bilinear filter
            int xFloor = Mathf.FloorToInt(pixelCoord.x);
            int xCeil  = Mathf.CeilToInt(pixelCoord.x);
            int yFloor = Mathf.FloorToInt(pixelCoord.y);
            int yCeil  = Mathf.CeilToInt(pixelCoord.y);

            float f00 = data[PUtilities.To1DIndex(xFloor, yFloor, width)];
            float f01 = data[PUtilities.To1DIndex(xFloor, yCeil, width)];
            float f10 = data[PUtilities.To1DIndex(xCeil, yFloor, width)];
            float f11 = data[PUtilities.To1DIndex(xCeil, yCeil, width)];

            Vector2 unitCoord = new Vector2(
                pixelCoord.x - xFloor,
                pixelCoord.y - yFloor);

            value =
                f00 * (1 - unitCoord.x) * (1 - unitCoord.y) +
                f01 * (1 - unitCoord.x) * unitCoord.y +
                f10 * unitCoord.x * (1 - unitCoord.y) +
                f11 * unitCoord.x * unitCoord.y;

            return(value);
        }
Ejemplo n.º 3
0
 public static void FillTexture(Texture2D t, Color c)
 {
     Color[] colors = new Color[t.width * t.height];
     PUtilities.Fill(colors, c);
     t.SetPixels(colors);
     t.Apply();
 }
Ejemplo n.º 4
0
 public void Dispose()
 {
     if (mesh != null)
     {
         PUtilities.DestroyObject(mesh);
     }
 }
Ejemplo n.º 5
0
 private void Update()
 {
     if (Water == null)
     {
         PUtilities.DestroyGameobject(gameObject);
     }
 }
Ejemplo n.º 6
0
        public static Color GetColorBilinear(Color[] textureData, int width, int height, Vector2 uv)
        {
            Color   color      = Color.clear;
            Vector2 pixelCoord = new Vector2(
                Mathf.Lerp(0, width - 1, uv.x),
                Mathf.Lerp(0, height - 1, uv.y));
            //apply a bilinear filter
            int xFloor = Mathf.FloorToInt(pixelCoord.x);
            int xCeil  = Mathf.CeilToInt(pixelCoord.x);
            int yFloor = Mathf.FloorToInt(pixelCoord.y);
            int yCeil  = Mathf.CeilToInt(pixelCoord.y);

            Color f00 = textureData[PUtilities.To1DIndex(xFloor, yFloor, width)];
            Color f01 = textureData[PUtilities.To1DIndex(xFloor, yCeil, width)];
            Color f10 = textureData[PUtilities.To1DIndex(xCeil, yFloor, width)];
            Color f11 = textureData[PUtilities.To1DIndex(xCeil, yCeil, width)];

            Vector2 unitCoord = new Vector2(
                pixelCoord.x - xFloor,
                pixelCoord.y - yFloor);

            color =
                f00 * (1 - unitCoord.x) * (1 - unitCoord.y) +
                f01 * (1 - unitCoord.x) * unitCoord.y +
                f10 * unitCoord.x * (1 - unitCoord.y) +
                f11 * unitCoord.x * unitCoord.y;

            return(color);
        }
Ejemplo n.º 7
0
        public static RenderTexture CopyToRT(Texture src, int startX, int startY, int width, int height, Color defaultColor)
        {
            int     endX    = startX + width - 1;
            int     endY    = startY + height - 1;
            Vector2 startUV = new Vector2(
                PUtilities.InverseLerpUnclamped(0, src.width - 1, startX),
                PUtilities.InverseLerpUnclamped(0, src.height - 1, startY));
            Vector2 endUV = new Vector2(
                PUtilities.InverseLerpUnclamped(0, src.width - 1, endX),
                PUtilities.InverseLerpUnclamped(0, src.height - 1, endY));
            Material mat = PInternalMaterials.CopyTextureMaterial;

            mat.SetTexture("_MainTex", src);
            mat.SetVector("_StartUV", startUV);
            mat.SetVector("_EndUV", endUV);
            mat.SetColor("_DefaultColor", defaultColor);
            mat.SetPass(0);
            RenderTexture rt = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);

            RenderTexture.active = rt;
            Graphics.Blit(src, mat);
            RenderTexture.active = null;

            return(rt);
        }
Ejemplo n.º 8
0
        private bool Clip(Vector4 v0, Vector4 v1, Vector4 v2)
        {
            float mask0 = PUtilities.GetValueBilinear(mask, MASK_RESOLUTION, MASK_RESOLUTION, GetMaskUV(v0));
            float mask1 = PUtilities.GetValueBilinear(mask, MASK_RESOLUTION, MASK_RESOLUTION, GetMaskUV(v1));
            float mask2 = PUtilities.GetValueBilinear(mask, MASK_RESOLUTION, MASK_RESOLUTION, GetMaskUV(v2));

            return(mask0 == 0 && mask1 == 0 && mask2 == 0);
        }
Ejemplo n.º 9
0
        public static void FillTexture(RenderTexture rt, Color c)
        {
            Texture2D tex = new Texture2D(1, 1, TextureFormat.ARGB32, false);

            tex.SetPixel(0, 0, c);
            tex.Apply();
            CopyToRT(tex, rt);
            PUtilities.DestroyObject(tex);
        }
Ejemplo n.º 10
0
        public static void CopyTexture(Texture2D src, Texture2D des)
        {
            RenderTexture rt = new RenderTexture(des.width, des.height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Default);

            CopyToRT(src, rt);
            CopyFromRT(des, rt);
            rt.Release();
            PUtilities.DestroyObject(rt);
        }
Ejemplo n.º 11
0
        public static Texture2D CreateTexture(int resolution, Color fill, TextureFormat format = TextureFormat.ARGB32)
        {
            Texture2D t = new Texture2D(resolution, resolution, format, false);

            Color[] colors = new Color[resolution * resolution];
            PUtilities.Fill(colors, fill);
            t.SetPixels(colors);
            t.Apply();
            return(t);
        }
Ejemplo n.º 12
0
 public static void ResetArray <T>(ref T[] array, int count, T defaultValue)
 {
     if (array != null && array.Length == count)
     {
         PUtilities.Fill(array, defaultValue);
     }
     else
     {
         array = new T[count];
     }
 }
Ejemplo n.º 13
0
        private void Update()
        {
            for (int i = 0; i < ObsoletedGameObject.Count; ++i)
            {
                GameObject o = ObsoletedGameObject[i];
                if (o != null)
                {
                    PUtilities.DestroyGameobject(o);
                }
            }
            ObsoletedGameObject.Clear();

            SetUpSelfLayer();
            SetUpDummyComponents();

            if (MeshType == PWaterMeshType.TileablePlane && TilesFollowMainCamera && Camera.main != null)
            {
                SnapPosition(Camera.main.transform.position);
            }
        }
Ejemplo n.º 14
0
        private RenderTexture GetReflectionRt(Camera cam)
        {
            if (!ReflRenderTextures.ContainsKey(cam))
            {
                ReflRenderTextures.Add(cam, null);
            }

            int resolution = 128;

            if (Profile != null)
            {
                resolution = Profile.ReflectionTextureResolution;
            }
            RenderTexture rt = ReflRenderTextures[cam];

            if (rt == null)
            {
                rt = new RenderTexture(resolution, resolution, 16, RenderTextureFormat.ARGB32);
            }
            if (rt.width != resolution || rt.height != resolution)
            {
                Camera reflCam;
                if (ReflCameras.TryGetValue(cam, out reflCam))
                {
                    reflCam.targetTexture = null;
                }

                rt.Release();
                PUtilities.DestroyObject(rt);
                rt = new RenderTexture(resolution, resolution, 16, RenderTextureFormat.ARGB32);
            }
            rt.name = string.Format("~ReflectionRt_{0}_{1}", cam.name, resolution);
            ReflRenderTextures[cam] = rt;

            if (cam.stereoEnabled)
            {
                rt.Release();
            }

            return(rt);
        }
Ejemplo n.º 15
0
        public static Texture2D CreateTextureFromCurve(AnimationCurve curve, int width, int height)
        {
            Texture2D t = new Texture2D(width, height, TextureFormat.ARGB32, false);

            t.wrapMode = TextureWrapMode.Clamp;
            Color[] colors = new Color[width * height];
            for (int x = 0; x < width; ++x)
            {
                float f     = Mathf.InverseLerp(0, width - 1, x);
                float value = curve.Evaluate(f);
                Color c     = new Color(value, value, value, value);
                for (int y = 0; y < height; ++y)
                {
                    colors[PUtilities.To1DIndex(x, y, width)] = c;
                }
            }
            t.filterMode = FilterMode.Bilinear;
            t.SetPixels(colors);
            t.Apply();
            return(t);
        }
Ejemplo n.º 16
0
        private void FillLine(int lineIndex, List <float> intersectX)
        {
            intersectX.Sort();

            List <int> columnIndices = new List <int>();

            for (int i = 0; i < intersectX.Count; ++i)
            {
                columnIndices.Add((int)(intersectX[i] * MASK_RESOLUTION));
            }

            int pairCount = columnIndices.Count / 2;

            for (int p = 0; p < pairCount; ++p)
            {
                int c0 = columnIndices[p * 2 + 0];
                int c1 = columnIndices[p * 2 + 1];
                for (int c = c0; c <= c1; ++c)
                {
                    mask[PUtilities.To1DIndex(c, lineIndex, MASK_RESOLUTION)] = 1.0f;
                }
            }
        }
Ejemplo n.º 17
0
        private void HandleAddRemoveTiles()
        {
            Plane plane    = new Plane(Vector3.up, water.transform.position);
            Ray   r        = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
            float distance = -1;

            if (plane.Raycast(r, out distance))
            {
                Vector3  hitWorldPos = r.origin + r.direction * distance;
                Vector3  hitLocalPos = water.transform.InverseTransformPoint(hitWorldPos);
                PIndex2D index       = new PIndex2D(
                    Mathf.FloorToInt(hitLocalPos.x / water.TileSize.x),
                    Mathf.FloorToInt(hitLocalPos.z / water.TileSize.y));

                Vector3 rectCenter = water.transform.TransformPoint(new Vector3(
                                                                        (index.X + 0.5f) * water.TileSize.x,
                                                                        hitLocalPos.y,
                                                                        (index.Z + 0.5f) * water.TileSize.y));
                Vector3 rectSize = water.transform.TransformVector(new Vector3(
                                                                       water.TileSize.x,
                                                                       0,
                                                                       water.TileSize.y));

                if (Event.current.type == EventType.MouseDrag || Event.current.type == EventType.MouseUp)
                {
                    if (Event.current.button != 0)
                    {
                        return;
                    }
                    if (Event.current.control)
                    {
                        water.TileIndices.Remove(index);
                        water.ReCalculateBounds();
                    }
                    else if (Event.current.shift)
                    {
                        if (!water.TileIndices.Contains(index))
                        {
                            water.TileIndices.Add(index);
                            water.ReCalculateBounds();
                        }
                    }
                    PUtilities.MarkCurrentSceneDirty();
                    EditorUtility.SetDirty(water);
                }

                Handles.color = Handles.selectedColor;
                Handles.DrawWireCube(rectCenter, rectSize);

                string s = string.Format(
                    "{0}" +
                    "{1}" +
                    "{2}",
                    index.ToString(),
                    "\nShift+Click to pin, Ctrl+Click to unpin water planes.",
                    "\nClick End Editing Tiles when done.");

                GUIContent mouseMessage = new GUIContent(s);
                PEditorCommon.SceneViewMouseMessage(mouseMessage);
            }
        }
Ejemplo n.º 18
0
        private void RenderReflectionTexture(Camera cam)
        {
            if (MeshType == PWaterMeshType.Spline)
            {
                return;
            }

            bool isBackface = cam.transform.position.y < transform.position.y;

            if (isBackface)
            {
                return;
            }

            if (cam.stereoEnabled)
            {
                return;
            }

            //prepare reflection camera
            if (!ReflCameras.ContainsKey(cam))
            {
                ReflCameras.Add(cam, null);
            }
            if (ReflCameras[cam] == null)
            {
                GameObject g = new GameObject();
                g.name      = "~ReflectionCamera_" + cam.name;
                g.hideFlags = HideFlags.HideAndDontSave;

                Camera rCam = g.AddComponent <Camera>();
                rCam.enabled = false;

                g.AddComponent <Skybox>();
                g.AddComponent <FlareLayer>();

                PUtilities.ResetTransform(g.transform, transform);
                ReflCameras[cam] = rCam;
            }

            //define reflection plane by position & normal in world space
            Vector3 planePos    = transform.position;
            Vector3 planeNormal = Vector3.up;

            //disable pixel light if needed
            int oldPixelLightCount = QualitySettings.pixelLightCount;

            if (!Profile.EnableReflectionPixelLight)
            {
                QualitySettings.pixelLightCount = 0;
            }

            //set up camera and render
            Camera reflectionCamera = ReflCameras[cam];

            reflectionCamera.enabled       = false;
            reflectionCamera.targetTexture = GetReflectionRt(cam);
            MatchCameraSettings(cam, reflectionCamera);

            // Reflect camera around reflection plane
            float   d = -Vector3.Dot(planeNormal, planePos) - Profile.ReflectionClipPlaneOffset;
            Vector4 reflectionPlane = new Vector4(planeNormal.x, planeNormal.y, planeNormal.z, d);

            Matrix4x4 reflection = CalculateReflectionMatrix(reflectionPlane);
            Vector3   oldpos     = cam.transform.position;
            Vector3   newpos     = reflection.MultiplyPoint(oldpos);

            reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;

            // Setup oblique projection matrix so that near plane is our reflection
            // plane. This way we clip everything below/above it for free.
            bool    isBackFace = cam.transform.position.y < transform.position.y;
            Vector4 clipPlane  = CameraSpacePlane(reflectionCamera, planePos, planeNormal, Profile.ReflectionClipPlaneOffset, isBackFace ? -1.0f : 1.0f);

            reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane);

            // Set custom culling matrix from the current camera
            reflectionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix;

            reflectionCamera.cullingMask = ~(1 << 4) & Profile.ReflectionLayers.value; // never render water layer
            //reflectionCamera.targetTexture = m_ReflectionTexture;
            bool oldCulling = GL.invertCulling;

            GL.invertCulling = !oldCulling;
            reflectionCamera.transform.position = newpos;
            Vector3 euler = cam.transform.eulerAngles;

            reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z);
            reflectionCamera.Render();

            reflectionCamera.transform.position = oldpos;
            GL.invertCulling = oldCulling;

            //restore pixel light
            if (!Profile.EnableReflectionPixelLight)
            {
                QualitySettings.pixelLightCount = oldPixelLightCount;
            }
        }
Ejemplo n.º 19
0
        public int[] SmoothTangents(params int[] anchorIndices)
        {
            int[]     anchorRanks    = new int[Anchors.Count];
            Vector3[] directions     = new Vector3[Anchors.Count];
            float[]   segmentLengths = new float[Segments.Count];

            for (int i = 0; i < Segments.Count; ++i)
            {
                PSplineSegment s = Segments[i];
                anchorRanks[s.StartIndex] += 1;
                anchorRanks[s.EndIndex]   += 1;

                PSplineAnchor aStart = Anchors[s.StartIndex];
                PSplineAnchor aEnd   = Anchors[s.EndIndex];

                Vector3 startToEnd = aEnd.Position - aStart.Position;
                Vector3 d          = Vector3.Normalize(startToEnd);
                directions[s.StartIndex] += d;
                directions[s.EndIndex]   += d;

                segmentLengths[i] = startToEnd.magnitude;
            }

            for (int i = 0; i < directions.Length; ++i)
            {
                if (anchorRanks[i] == 0)
                {
                    continue;
                }
                directions[i] = Vector3.Normalize(directions[i] / anchorRanks[i]);
            }

            if (anchorIndices == null || anchorIndices.Length == 0)
            {
                anchorIndices = PUtilities.GetIndicesArray(Anchors.Count);
            }

            for (int i = 0; i < anchorIndices.Length; ++i)
            {
                int index = anchorIndices[i];
                if (anchorRanks[index] > 0)
                {
                    Quaternion rot = Quaternion.LookRotation(directions[index], Vector3.up);
                    Anchors[index].Rotation = rot;
                }
            }

            List <int> segmentIndices = new List <int>();

            for (int i = 0; i < Segments.Count; ++i)
            {
                PSplineSegment s = Segments[i];
                for (int j = 0; j < anchorIndices.Length; ++j)
                {
                    int anchorIndex = anchorIndices[j];
                    if (s.StartIndex == anchorIndex || s.EndIndex == anchorIndex)
                    {
                        segmentIndices.Add(i);
                    }
                }
            }

            for (int i = 0; i < segmentIndices.Count; ++i)
            {
                int            index  = segmentIndices[i];
                PSplineSegment s      = Segments[index];
                PSplineAnchor  aStart = Anchors[s.StartIndex];
                PSplineAnchor  aEnd   = Anchors[s.EndIndex];

                float   sLength       = segmentLengths[index];
                float   tangentLength = sLength * 0.33f;
                Vector3 dirStart      = directions[s.StartIndex];
                Vector3 dirEnd        = directions[s.EndIndex];
                s.StartTangent = aStart.Position + dirStart * tangentLength;
                s.EndTangent   = aEnd.Position - dirEnd * tangentLength;
            }
            return(segmentIndices.ToArray());
        }
Ejemplo n.º 20
0
        private void RenderReflectionTextureSRP(ScriptableRenderContext context, Camera cam)
        {
            if (MeshType == PWaterMeshType.Spline)
            {
                return;
            }

            bool isBackface = cam.transform.position.y < transform.position.y;

            if (isBackface)
            {
                return;
            }

            if (cam.stereoEnabled)
            {
                return;
            }

            //prepare reflection camera
            if (!ReflCameras.ContainsKey(cam))
            {
                ReflCameras.Add(cam, null);
            }
            if (ReflCameras[cam] == null)
            {
                GameObject g = new GameObject();
                g.name = "~ReflectionCamera_" + cam.name;
                //g.hideFlags = HideFlags.HideAndDontSave;

                Camera rCam = g.AddComponent <Camera>();
                rCam.enabled = false;

                g.AddComponent <Skybox>();
                g.AddComponent <FlareLayer>();

                ////TODO: Remove on release
                //if (cam.cameraType == CameraType.Game)
                //{
                //    PCameraFrustumVisualizer vis = g.AddComponent<PCameraFrustumVisualizer>(); ;
                //    vis.drawGizmos = true;
                //    vis.leftEye = true;
                //    vis.rightEye = true;
                //    vis.monoEye = true;
                //    vis.alpha = 0.2f;
                //    vis.cam = rCam;
                //}

                PUtilities.ResetTransform(g.transform, transform);
                ReflCameras[cam] = rCam;
            }

            //define reflection plane by position & normal in world space
            Vector3 planePos    = transform.position;
            Vector3 planeNormal = transform.up;

            int lastPixelLightCount = QualitySettings.pixelLightCount;

            if (!Profile.EnableReflectionPixelLight)
            {
                QualitySettings.pixelLightCount = 0;
            }

            bool lastInvertCulling = GL.invertCulling;

            GL.invertCulling = !lastInvertCulling;

            //set up camera and render
            Camera reflectionCamera = ReflCameras[cam];

            reflectionCamera.enabled       = false;
            reflectionCamera.targetTexture = GetReflectionRt(cam);
            MatchCameraSettings(cam, reflectionCamera);

            // Reflect camera around reflection plane
            float   d = -Vector3.Dot(planeNormal, planePos) - Profile.ReflectionClipPlaneOffset;
            Vector4 reflectionPlane = new Vector4(planeNormal.x, planeNormal.y, planeNormal.z, d);

            Matrix4x4 reflection = CalculateReflectionMatrix(reflectionPlane, Camera.MonoOrStereoscopicEye.Mono);
            Vector3   oldpos     = cam.transform.position;
            Vector3   newpos     = reflection.MultiplyPoint(oldpos);

            reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;

            // Setup oblique projection matrix so that near plane is our reflection
            // plane. This way we clip everything below/above it for free.
            bool      isBackFace    = cam.transform.position.y < transform.position.y;
            Vector4   clipPlane     = CameraSpacePlane(reflectionCamera, planePos, planeNormal, Profile.ReflectionClipPlaneOffset, isBackFace && ShouldRenderBackface ? -1.0f : 1.0f);
            Matrix4x4 obliqueMatrix = cam.CalculateObliqueMatrix(clipPlane);

            reflectionCamera.projectionMatrix = obliqueMatrix;

            // Set custom culling matrix from the current camera
            reflectionCamera.cullingMatrix      = cam.projectionMatrix * cam.worldToCameraMatrix;
            reflectionCamera.cullingMask        = ~(1 << 4) & Profile.ReflectionLayers.value; // never render water layer
            reflectionCamera.transform.position = newpos;
            Vector3 euler = cam.transform.eulerAngles;

            reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z);

            UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera);

            QualitySettings.pixelLightCount = lastPixelLightCount;
            GL.invertCulling = lastInvertCulling;
        }
Ejemplo n.º 21
0
        public static IEnumerable <Rect> CompareHeightMap(int gridSize, Color[] oldValues, Color[] newValues)
        {
            if (oldValues.LongLength != newValues.LongLength)
            {
                return(new Rect[1] {
                    new Rect(0, 0, 1, 1)
                });
            }
            Rect[] rects = new Rect[gridSize * gridSize];
            for (int x = 0; x < gridSize; ++x)
            {
                for (int z = 0; z < gridSize; ++z)
                {
                    rects[PUtilities.To1DIndex(x, z, gridSize)] = GetUvRange(gridSize, x, z);
                }
            }

            HashSet <Rect> dirtyRects = new HashSet <Rect>();

            int index      = 0;
            int resolution = Mathf.RoundToInt(Mathf.Sqrt(newValues.LongLength));

            for (int rectIndex = 0; rectIndex < rects.Length; ++rectIndex)
            {
                Rect r      = rects[rectIndex];
                int  startX = (int)Mathf.Lerp(0, resolution - 1, r.min.x);
                int  startY = (int)Mathf.Lerp(0, resolution - 1, r.min.y);
                int  endX   = (int)Mathf.Lerp(0, resolution - 1, r.max.x);
                int  endY   = (int)Mathf.Lerp(0, resolution - 1, r.max.y);
                for (int x = startX; x <= endX; ++x)
                {
                    for (int y = startY; y <= endY; ++y)
                    {
                        index = PUtilities.To1DIndex(x, y, resolution);
                        if (oldValues[index].r == newValues[index].r &&
                            oldValues[index].g == newValues[index].g &&
                            oldValues[index].b == newValues[index].b &&
                            oldValues[index].a == newValues[index].a)
                        {
                            continue;
                        }
                        dirtyRects.Add(r);

                        Rect hRect = new Rect();
                        hRect.size   = new Vector2(r.width * 1.2f, r.height);
                        hRect.center = r.center;
                        dirtyRects.Add(hRect);

                        Rect vRect = new Rect();
                        vRect.size   = new Vector2(r.width, r.height * 1.2f);
                        vRect.center = r.center;
                        dirtyRects.Add(vRect);
                        break;
                    }
                    if (dirtyRects.Contains(r))
                    {
                        break;
                    }
                }
            }

            return(dirtyRects);
        }