Utility class to help when clipping using IClipper.
public static Rect FindCullAndClipWorldRect(List <RectMask2D> rectMaskParents, out bool validRect) { Rect result; if (rectMaskParents.Count == 0) { validRect = false; result = default(Rect); } else { Rect a = rectMaskParents[0].canvasRect; for (int i = 0; i < rectMaskParents.Count; i++) { a = Clipping.RectIntersect(a, rectMaskParents[i].canvasRect); } bool flag = a.width <= 0f || a.height <= 0f; if (flag) { validRect = false; result = default(Rect); } else { Vector3 vector = new Vector3(a.x, a.y, 0f); Vector3 vector2 = new Vector3(a.x + a.width, a.y + a.height, 0f); validRect = true; result = new Rect(vector.x, vector.y, vector2.x - vector.x, vector2.y - vector.y); } } return(result); }
/// <summary> /// 进行裁剪 /// </summary> public virtual void PerformClipping() { // if the parents are changed // or something similar we // do a recalculate here //重新计算物体的裁剪组件 if (m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, m_Clippers); m_ShouldRecalculateClipRects = false; } // get the compound rects from // the clippers that are valid bool validRect = true; Rect clipRect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); if (clipRect != m_LastClipRectCanvasSpace) { for (int i = 0; i < m_ClipTargets.Count; ++i) { m_ClipTargets[i].SetClipRect(clipRect, validRect); } m_LastClipRectCanvasSpace = clipRect; m_LastClipRectValid = validRect; } for (int i = 0; i < m_ClipTargets.Count; ++i) { m_ClipTargets[i].Cull(m_LastClipRectCanvasSpace, m_LastClipRectValid); } }
public virtual void PerformClipping() { if (this.m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, this.m_Clippers); this.m_ShouldRecalculateClipRects = false; } bool flag = true; Rect rect = Clipping.FindCullAndClipWorldRect(this.m_Clippers, out flag); bool flag2 = rect != this.m_LastClipRectCanvasSpace; if (flag2 || this.m_ForceClip) { foreach (IClippable current in this.m_ClipTargets) { current.SetClipRect(rect, flag); } this.m_LastClipRectCanvasSpace = rect; this.m_LastValidClipRect = flag; } foreach (IClippable current2 in this.m_ClipTargets) { MaskableGraphic maskableGraphic = current2 as MaskableGraphic; if (!(maskableGraphic != null) || maskableGraphic.canvasRenderer.hasMoved || flag2) { current2.Cull(this.m_LastClipRectCanvasSpace, this.m_LastValidClipRect); } } }
public virtual void PerformClipping() { if (m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, m_Clippers); m_ShouldRecalculateClipRects = false; } bool validRect = true; Rect rect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); bool flag = rect != m_LastClipRectCanvasSpace; if (flag || m_ForceClip) { foreach (IClippable clipTarget in m_ClipTargets) { clipTarget.SetClipRect(rect, validRect); } m_LastClipRectCanvasSpace = rect; m_LastValidClipRect = validRect; } foreach (IClippable clipTarget2 in m_ClipTargets) { MaskableGraphic maskableGraphic = clipTarget2 as MaskableGraphic; if (!(maskableGraphic != null) || maskableGraphic.canvasRenderer.hasMoved || flag) { clipTarget2.Cull(m_LastClipRectCanvasSpace, m_LastValidClipRect); } } }
public virtual void PerformClipping() { if (ReferenceEquals(Canvas, null)) { return; } //TODO See if an IsActive() test would work well here or whether it might cause unexpected side effects (re case 776771) // if the parents are changed // or something similar we // do a recalculate here if (m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, m_Clippers); m_ShouldRecalculateClipRects = false; } // get the compound rects from // the clippers that are valid bool validRect = true; Rect clipRect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); // If the mask is in ScreenSpaceOverlay/Camera render mode, its content is only rendered when its rect // overlaps that of the root canvas. RenderMode renderMode = Canvas.rootCanvas.renderMode; bool maskIsCulled = (renderMode == RenderMode.ScreenSpaceCamera || renderMode == RenderMode.ScreenSpaceOverlay) && !clipRect.Overlaps(rootCanvasRect, true); // 和上次裁剪的矩形比较是否改变 bool clipRectChanged = clipRect != m_LastClipRectCanvasSpace; bool forceClip = m_ForceClip; // Avoid looping multiple times. foreach (IClippable clipTarget in m_ClipTargets) { if (clipRectChanged || forceClip) { //设置矩形裁剪框,若无效则禁用 clipTarget.SetClipRect(clipRect, validRect); } var maskable = clipTarget as MaskableGraphic; if (maskable != null && !maskable.canvasRenderer.hasMoved && !clipRectChanged) { continue; } // Children are only displayed when inside the mask. If the mask is culled, then the children // inside the mask are also culled. In that situation, we pass an invalid rect to allow callees // to avoid some processing. clipTarget.Cull( maskIsCulled ? Rect.zero : clipRect, maskIsCulled ? false : validRect); } m_LastClipRectCanvasSpace = clipRect; m_ForceClip = false; }
public void PerformClipping() { if (m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMaskForClip(this, m_Clippers); m_ShouldRecalculateClipRects = false; } bool validRect = true; Rect clipRect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); bool clipRectChanged = clipRect != m_LastClipRectCanvasSpace; if (clipRectChanged || m_ForceClip) { foreach (var clipTarget in m_ClipTargets) { clipTarget.SetClipRect(clipRect, validRect); } m_LastClipRectCanvasSpace = clipRect; m_LastValidClipRect = validRect; } foreach (var clipTarget in m_ClipTargets) { var maskable = clipTarget as MaskableGraphic; if (maskable != null && !maskable.canvasRenderer.hasMoved && !clipRectChanged) { continue; } clipTarget.Cull(m_LastClipRectCanvasSpace, m_LastValidClipRect); } }
public virtual void PerformClipping() { //TODO See if an IsActive() test would work well here or whether it might cause unexpected side effects (re case 776771) // if the parents are changed // or something similar we // do a recalculate here if (m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, m_Clippers); m_ShouldRecalculateClipRects = false; } // get the compound rects from // the clippers that are valid bool validRect = true; Rect clipRect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); if (clipRect != m_LastClipRectCanvasSpace || m_ForceClip) { foreach (IClippable clipTarget in m_ClipTargets) { clipTarget.SetClipRect(clipRect, validRect); } m_LastClipRectCanvasSpace = clipRect; m_LastValidClipRect = validRect; } foreach (IClippable clipTarget in m_ClipTargets) { clipTarget.Cull(m_LastClipRectCanvasSpace, m_LastValidClipRect); } }
public virtual void PerformClipping() { if (!object.ReferenceEquals(this.Canvas, null)) { if (this.m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, this.m_Clippers); this.m_ShouldRecalculateClipRects = false; } bool flag = true; Rect rect = Clipping.FindCullAndClipWorldRect(this.m_Clippers, out flag); RenderMode renderMode = this.Canvas.rootCanvas.renderMode; bool flag2 = (renderMode == RenderMode.ScreenSpaceCamera || renderMode == RenderMode.ScreenSpaceOverlay) && !rect.Overlaps(this.rootCanvasRect, true); bool flag3 = rect != this.m_LastClipRectCanvasSpace; bool forceClip = this.m_ForceClip; foreach (IClippable clippable in this.m_ClipTargets) { if (flag3 || forceClip) { clippable.SetClipRect(rect, flag); } MaskableGraphic maskableGraphic = clippable as MaskableGraphic; if (!(maskableGraphic != null) || maskableGraphic.canvasRenderer.hasMoved || flag3) { clippable.Cull((!flag2) ? rect : Rect.zero, !flag2 && flag); } } this.m_LastClipRectCanvasSpace = rect; this.m_ForceClip = false; } }
public static Rect FindCullAndClipWorldRect(List <RectMask2D> rectMaskParents, out bool validRect) { if (rectMaskParents.Count == 0) { validRect = false; return(new Rect()); } Rect a = rectMaskParents[0].canvasRect; for (int index = 0; index < rectMaskParents.Count; ++index) { a = Clipping.RectIntersect(a, rectMaskParents[index].canvasRect); } if ((double)a.width <= 0.0 || (double)a.height <= 0.0) { validRect = false; return(new Rect()); } Vector3 vector3_1 = new Vector3(a.x, a.y, 0.0f); Vector3 vector3_2 = new Vector3(a.x + a.width, a.y + a.height, 0.0f); validRect = true; return(new Rect(vector3_1.x, vector3_1.y, vector3_2.x - vector3_1.x, vector3_2.y - vector3_1.y)); }
/// <summary> /// <para>See: IClipper.PerformClipping.</para> /// </summary> public virtual void PerformClipping() { if (this.m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, this.m_Clippers); this.m_ShouldRecalculateClipRects = false; } bool validRect = true; Rect rect = Clipping.FindCullAndClipWorldRect(this.m_Clippers, out validRect); if ((rect != this.m_LastClipRectCanvasSpace) || this.m_ForceClip) { foreach (IClippable clippable in this.m_ClipTargets) { clippable.SetClipRect(rect, validRect); } this.m_LastClipRectCanvasSpace = rect; this.m_LastValidClipRect = validRect; } foreach (IClippable clippable2 in this.m_ClipTargets) { clippable2.Cull(this.m_LastClipRectCanvasSpace, this.m_LastValidClipRect); } }
/// <summary> /// /// <para> /// See: IClipper.PerformClipping. /// </para> /// /// </summary> public virtual void PerformClipping() { if (this.m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, this.m_Clippers); this.m_ShouldRecalculateClipRects = false; } bool validRect = true; Rect andClipWorldRect = Clipping.FindCullAndClipWorldRect(this.m_Clippers, out validRect); if (andClipWorldRect != this.m_LastClipRectCanvasSpace) { for (int index = 0; index < this.m_ClipTargets.Count; ++index) { this.m_ClipTargets[index].SetClipRect(andClipWorldRect, validRect); } this.m_LastClipRectCanvasSpace = andClipWorldRect; this.m_LastClipRectValid = validRect; } for (int index = 0; index < this.m_ClipTargets.Count; ++index) { this.m_ClipTargets[index].Cull(this.m_LastClipRectCanvasSpace, this.m_LastClipRectValid); } }
public virtual void PerformClipping() { if (m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, m_Clippers); m_ShouldRecalculateClipRects = false; } bool validRect = true; Rect rect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); if (rect != m_LastClipRectCanvasSpace) { for (int i = 0; i < m_ClipTargets.Count; i++) { m_ClipTargets[i].SetClipRect(rect, validRect); } m_LastClipRectCanvasSpace = rect; m_LastClipRectValid = validRect; } for (int j = 0; j < m_ClipTargets.Count; j++) { m_ClipTargets[j].Cull(m_LastClipRectCanvasSpace, m_LastClipRectValid); } }
public virtual void PerformClipping() { if (ReferenceEquals(Canvas, null)) { return; } //TODO See if an IsActive() test would work well here or whether it might cause unexpected side effects (re case 776771) // if the parents are changed // or something similar we // do a recalculate here // 重新计算裁切区域 if (m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, m_Clippers); m_ShouldRecalculateClipRects = false; } // get the compound rects from // the clippers that are valid //由于裁切可能有多个区域,这里会计算出正确包含重复的一个区域 bool validRect = true; Rect clipRect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); // If the mask is in ScreenSpaceOverlay/Camera render mode, its content is only rendered when its rect // overlaps that of the root canvas. RenderMode renderMode = Canvas.rootCanvas.renderMode; bool maskIsCulled = (renderMode == RenderMode.ScreenSpaceCamera || renderMode == RenderMode.ScreenSpaceOverlay) && !clipRect.Overlaps(rootCanvasRect, true); if (maskIsCulled) { // Children are only displayed when inside the mask. If the mask is culled, then the children // inside the mask are also culled. In that situation, we pass an invalid rect to allow callees // to avoid some processing. clipRect = Rect.zero; validRect = false; } if (clipRect != m_LastClipRectCanvasSpace) { foreach (IClippable clipTarget in m_ClipTargets) { clipTarget.SetClipRect(clipRect, validRect); } foreach (MaskableGraphic maskableTarget in m_MaskableTargets) { maskableTarget.SetClipRect(clipRect, validRect); maskableTarget.Cull(clipRect, validRect); } } else if (m_ForceClip) { foreach (IClippable clipTarget in m_ClipTargets) { clipTarget.SetClipRect(clipRect, validRect); } foreach (MaskableGraphic maskableTarget in m_MaskableTargets) { //准备把裁切区域传到每个UI元素的Shader中 maskableTarget.SetClipRect(clipRect, validRect); if (maskableTarget.canvasRenderer.hasMoved) { //准备开始裁切,准备重建裁切的UI maskableTarget.Cull(clipRect, validRect); } } } else { foreach (MaskableGraphic maskableTarget in m_MaskableTargets) { if (maskableTarget.canvasRenderer.hasMoved) { maskableTarget.Cull(clipRect, validRect); } } } m_LastClipRectCanvasSpace = clipRect; m_ForceClip = false; }
/// <summary> /// 19/6 2020 Graphic学习 /// 对子类元素进行剔除和裁剪处理 /// </summary> public virtual void PerformClipping() { if (ReferenceEquals(Canvas, null)) { return; } //TODO See if an IsActive() test would work well here or whether it might cause unexpected side effects (re case 776771) // if the parents are changed // or something similar we // do a recalculate here //当父节点发生改变的时候,或者OnHierarchyCanvasChanged以及添加裁剪或者移除裁剪子类元素的时候 //重新对裁剪的rect进行计算 if (m_ShouldRecalculateClipRects) { MaskUtilities.GetRectMasksForClip(this, m_Clippers); m_ShouldRecalculateClipRects = false; } // get the compound rects from // the clippers that are valid bool validRect = true; Rect clipRect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); // If the mask is in ScreenSpaceOverlay/Camera render mode, its content is only rendered when its rect // overlaps that of the root canvas. //这一步是为了剔除子类元素 RenderMode renderMode = Canvas.rootCanvas.renderMode; //如果Canvas的渲染模式ScreenSpaceCamera或者 ScreenSpaceOverlay时,需要裁剪的cliprect与根节点Canvas的rect没有重叠 //则进行剔除 //这里好像判断是mask是否被剔除了 bool maskIsCulled = (renderMode == RenderMode.ScreenSpaceCamera || renderMode == RenderMode.ScreenSpaceOverlay) && !clipRect.Overlaps(rootCanvasRect, true); //裁剪区域发生改变 bool clipRectChanged = clipRect != m_LastClipRectCanvasSpace; //是否裁剪的子元素发生变化 //添加裁剪子元素或者移除时,都为true bool forceClip = m_ForceClip; // Avoid looping multiple times. foreach (IClippable clipTarget in m_ClipTargets) { if (clipRectChanged || forceClip) { clipTarget.SetClipRect(clipRect, validRect); } var maskable = clipTarget as MaskableGraphic; if (maskable != null && !maskable.canvasRenderer.hasMoved && !clipRectChanged) { continue; } // Children are only displayed when inside the mask. If the mask is culled, then the children // inside the mask are also culled. In that situation, we pass an invalid rect to allow callees // to avoid some processing. clipTarget.Cull( maskIsCulled ? Rect.zero : clipRect, maskIsCulled ? false : validRect); } m_LastClipRectCanvasSpace = clipRect; m_ForceClip = false; }