/// <summary> /// Submit the draw call using the current geometry. /// </summary> void SubmitDrawCall(UIDrawCall dc) { dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); }
private void Fill(Material mat) { int index = 0; while (index < this.mWidgets.size) { UIWidget widget = this.mWidgets.buffer[index]; if (widget == null) { this.mWidgets.RemoveAt(index); } else { if ((widget.material == mat) && widget.isVisible) { if (widget.panel == this) { if (this.generateNormals) { widget.WriteToBuffers(this.mVerts, this.mUvs, this.mCols, this.mNorms, this.mTans); } else { widget.WriteToBuffers(this.mVerts, this.mUvs, this.mCols, null, null); } } else { this.mWidgets.RemoveAt(index); continue; } } index++; } } if (this.mVerts.size > 0) { UIDrawCall drawCall = this.GetDrawCall(mat, true); drawCall.depthPass = this.depthPass && (this.mClipping == UIDrawCall.Clipping.None); drawCall.Set(this.mVerts, !this.generateNormals ? null : this.mNorms, !this.generateNormals ? null : this.mTans, this.mUvs, this.mCols); } else { UIDrawCall item = this.GetDrawCall(mat, false); if (item != null) { this.mDrawCalls.Remove(item); NGUITools.DestroyImmediate(item.gameObject); } } this.mVerts.Clear(); this.mNorms.Clear(); this.mTans.Clear(); this.mUvs.Clear(); this.mCols.Clear(); }
/// <summary> /// Submit the draw call using the current geometry. /// </summary> void SubmitDrawCall(UIDrawCall dc) { dc.clipping = clipping; dc.alwaysOnScreen = alwaysOnScreen && (clipping == UIDrawCall.Clipping.None || clipping == UIDrawCall.Clipping.ConstrainButDontClip); dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); }
private void Fill(Material mat) { int i = 0; while (i < this.mWidgets.size) { UIWidget uiwidget = this.mWidgets.buffer[i]; if (uiwidget == null) { this.mWidgets.RemoveAt(i); } else { if (uiwidget.material == mat && uiwidget.isVisible) { if (!(uiwidget.panel == this)) { this.mWidgets.RemoveAt(i); continue; } if (this.generateNormals) { uiwidget.WriteToBuffers(this.mVerts, this.mUvs, this.mCols, this.mNorms, this.mTans); } else { uiwidget.WriteToBuffers(this.mVerts, this.mUvs, this.mCols, null, null); } } i++; } } if (this.mVerts.size > 0) { UIDrawCall drawCall = this.GetDrawCall(mat, true); drawCall.depthPass = (this.depthPass && this.mClipping == UIDrawCall.Clipping.None); drawCall.Set(this.mVerts, (!this.generateNormals) ? null : this.mNorms, (!this.generateNormals) ? null : this.mTans, this.mUvs, this.mCols); } else { UIDrawCall drawCall2 = this.GetDrawCall(mat, false); if (drawCall2 != null) { this.mDrawCalls.Remove(drawCall2); NGUITools.DestroyImmediate(drawCall2.gameObject); } } this.mVerts.Clear(); this.mNorms.Clear(); this.mTans.Clear(); this.mUvs.Clear(); this.mCols.Clear(); }
private void Fill(Material mat) { int num = 0; while (num < mWidgets.size) { UIWidget uIWidget = mWidgets.buffer[num]; if (uIWidget == null) { mWidgets.RemoveAt(num); continue; } if (uIWidget.material == mat && uIWidget.isVisible) { if (!(uIWidget.panel == this)) { mWidgets.RemoveAt(num); continue; } if (generateNormals) { uIWidget.WriteToBuffers(mVerts, mUvs, mCols, mNorms, mTans); } else { uIWidget.WriteToBuffers(mVerts, mUvs, mCols, null, null); } } num++; } if (mVerts.size > 0) { UIDrawCall drawCall = GetDrawCall(mat, createIfMissing: true); drawCall.depthPass = (depthPass && mClipping == UIDrawCall.Clipping.None); drawCall.Set(mVerts, (!generateNormals) ? null : mNorms, (!generateNormals) ? null : mTans, mUvs, mCols); } else { UIDrawCall drawCall2 = GetDrawCall(mat, createIfMissing: false); if (drawCall2 != null) { mDrawCalls.Remove(drawCall2); NGUITools.DestroyImmediate(drawCall2.gameObject); } } mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); }
/// <summary> /// Submit the draw call using the current geometry. /// </summary> void SubmitDrawCall(int index, Material mat) { UIDrawCall dc = GetDrawCall(index, mat); dc.renderQueue = index; dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); dc.mainTexture = mat.mainTexture; mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); }
private void Fill(UIMaterial mat) { int count = this.mWidgets.Count; while (count > 0) { int num = count - 1; count = num; if (this.mWidgets[num] != null) { continue; } this.mWidgets.RemoveAt(count); } int num1 = 0; int count1 = this.mWidgets.Count; while (num1 < count1) { UIWidget item = this.mWidgets[num1]; if (item.visibleFlag == 1 && item.material == mat) { if (this.GetNode(item.cachedTransform) == null) { Debug.LogError(string.Concat("No transform found for ", NGUITools.GetHierarchy(item.gameObject)), this); } else { item.WriteToBuffers(this.mCacheBuffer); } } num1++; } if (this.mCacheBuffer.vSize <= 0) { UIDrawCall.Iterator drawCall = this.GetDrawCall(mat, false); if (drawCall.Has) { this.Delete(ref drawCall); } } else { UIDrawCall current = this.GetDrawCall(mat, true).Current; current.depthPass = this.depthPass; current.panelPropertyBlock = this.propertyBlock; current.Set(this.mCacheBuffer); } this.mCacheBuffer.Clear(); }
/// <summary> /// Fill the geometry for the specified draw call. /// </summary> static bool Fill(UIDrawCall dc) { if (dc != null) { dc.isDirty = false; for (int i = 0; i < UIWidget.list.size;) { UIWidget w = UIWidget.list[i]; if (w == null) { UIWidget.list.RemoveAt(i); continue; } if (w.drawCall == dc) { if (w.isVisible) { if (dc.manager.generateNormals) { w.WriteToBuffers(mVerts, mUvs, mCols, mNorms, mTans); } else { w.WriteToBuffers(mVerts, mUvs, mCols, null, null); } } else { w.drawCall = null; } } ++i; } if (mVerts.size != 0) { dc.Set(mVerts, dc.manager.generateNormals ? mNorms : null, dc.manager.generateNormals ? mTans : null, mUvs, mCols); mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); return(true); } } return(false); }
private void Fill(UIMaterial mat) { int count = this.mWidgets.Count; while (count > 0) { if (this.mWidgets[--count] == null) { this.mWidgets.RemoveAt(count); } } int num2 = 0; int num3 = this.mWidgets.Count; while (num2 < num3) { UIWidget widget = this.mWidgets[num2]; if ((widget.visibleFlag == 1) && (widget.material == mat)) { if (this.GetNode(widget.cachedTransform) != null) { widget.WriteToBuffers(this.mCacheBuffer); } else { Debug.LogError("No transform found for " + NGUITools.GetHierarchy(widget.gameObject), this); } } num2++; } if (this.mCacheBuffer.vSize > 0) { UIDrawCall current = this.GetDrawCall(mat, true).Current; current.depthPass = this.depthPass; current.panelPropertyBlock = this.propertyBlock; current.Set(this.mCacheBuffer); } else { UIDrawCall.Iterator drawCall = this.GetDrawCall(mat, false); if (drawCall.Has) { this.Delete(ref drawCall); } } this.mCacheBuffer.Clear(); }
public UIDrawCall GetDrawCall(UISprite uisprite) { GameObject obj = new GameObject(); obj.transform.parent = minMapRender.transform; obj.transform.localPosition = Vector3.zero; obj.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); UIDrawCall dc = obj.AddComponent <UIDrawCall>(); obj.layer = LayerMask.NameToLayer("2D"); BetterList <Vector3> verts = new BetterList <Vector3>(); BetterList <Vector2> uvs = new BetterList <Vector2>(); BetterList <Color32> cols = new BetterList <Color32>(); dc.material = uisprite.material; uisprite.UpdateUVs(true); uisprite.OnFill(verts, uvs, cols); dc.Set(verts, null, null, uvs, cols); dc.renderQueue = mainHeroSprite.renderQueue; return(dc); }
/// <summary> /// Convenience function that figures out the panel's correct change flag by searching the parents. /// </summary> int GetChangeFlag(UINode start) { int flag = start.changeFlag; if (flag == -1) { Transform trans = start.trans.parent; UINode sub; // Keep going until we find a set flag for (;;) { // Check the parent's flag #if UNITY_FLASH if (trans != null && mChildren.TryGetValue(trans, out sub)) { #else if (trans != null && mChildren.Contains(trans)) { sub = (UINode)mChildren[trans]; #endif flag = sub.changeFlag; trans = trans.parent; // If the flag hasn't been set either, add this child to the hierarchy if (flag == -1) { mHierarchy.Add(sub); } else { break; } } else { flag = 0; break; } } // Update the parent flags for (int i = 0, imax = mHierarchy.size; i < imax; ++i) { UINode pc = mHierarchy.buffer[i]; pc.changeFlag = flag; } mHierarchy.Clear(); } return(flag); } /// <summary> /// Update the world-to-local transform matrix as well as clipping bounds. /// </summary> void UpdateTransformMatrix() { float time = Time.realtimeSinceStartup; if (time == 0f || mMatrixTime != time) { mMatrixTime = time; mWorldToLocal = cachedTransform.worldToLocalMatrix; if (mClipping != UIDrawCall.Clipping.None) { Vector2 size = new Vector2(mClipRange.z, mClipRange.w); if (size.x == 0f) { size.x = mScreenSize.x; } if (size.y == 0f) { size.y = mScreenSize.y; } size *= 0.5f; mMin.x = mClipRange.x - size.x; mMin.y = mClipRange.y - size.y; mMax.x = mClipRange.x + size.x; mMax.y = mClipRange.y + size.y; } } } /// <summary> /// Run through all managed transforms and see if they've changed. /// </summary> void UpdateTransforms() { mChangedLastFrame = false; bool transformsChanged = false; #if UNITY_EDITOR bool shouldCull = !Application.isPlaying || Time.realtimeSinceStartup > mCullTime; if (!Application.isPlaying || !widgetsAreStatic || mWidgetsAdded || shouldCull != mCulled) #else bool shouldCull = Time.realtimeSinceStartup > mCullTime; if (!widgetsAreStatic || mWidgetsAdded || shouldCull != mCulled) #endif { #if UNITY_FLASH foreach (KeyValuePair <Transform, UINode> child in mChildren) { UINode node = child.Value; #else for (int i = 0, imax = mChildren.Count; i < imax; ++i) { UINode node = (UINode)mChildren[i]; #endif if (node.trans == null) { mRemoved.Add(node.trans); continue; } if (node.HasChanged()) { node.changeFlag = 1; transformsChanged = true; } else { node.changeFlag = -1; } } // Clean up the deleted transforms for (int i = 0, imax = mRemoved.Count; i < imax; ++i) { mChildren.Remove(mRemoved[i]); } mRemoved.Clear(); } // If the children weren't culled but should be, check their visibility if (!mCulled && shouldCull) { mCheckVisibility = true; } // If something has changed, propagate the changes *down* the tree hierarchy (to children). // An alternative (but slower) approach would be to do a pc.trans.GetComponentsInChildren<UIWidget>() // in the loop above, and mark each one as dirty. if (mCheckVisibility || transformsChanged || mRebuildAll) { #if UNITY_FLASH foreach (KeyValuePair <Transform, UINode> child in mChildren) { UINode pc = child.Value; #else for (int i = 0, imax = mChildren.Count; i < imax; ++i) { UINode pc = (UINode)mChildren[i]; #endif if (pc.widget != null) { int visibleFlag = 1; // No sense in checking the visibility if we're not culling anything (as the visibility is always 'true') if (shouldCull || transformsChanged) { // If the change flag has not yet been determined... if (pc.changeFlag == -1) { pc.changeFlag = GetChangeFlag(pc); } // Is the widget visible? if (shouldCull) { visibleFlag = (mCheckVisibility || pc.changeFlag == 1) ? (IsVisible(pc.widget) ? 1 : 0) : pc.visibleFlag; } } // If visibility changed, mark the node as changed as well if (pc.visibleFlag != visibleFlag) { pc.changeFlag = 1; } // If the node has changed and the widget is visible (or was visible before) if (pc.changeFlag == 1 && (visibleFlag == 1 || pc.visibleFlag != 0)) { // Update the visibility flag pc.visibleFlag = visibleFlag; Material mat = pc.widget.material; // Add this material to the list of changed materials if (!mChanged.Contains(mat)) { mChanged.Add(mat); mChangedLastFrame = true; } } } } } mCulled = shouldCull; mCheckVisibility = false; mWidgetsAdded = false; } /// <summary> /// Update all widgets and rebuild their geometry if necessary. /// </summary> void UpdateWidgets() { #if UNITY_FLASH foreach (KeyValuePair <Transform, UINode> c in mChildren) { UINode pc = c.Value; #else for (int i = 0, imax = mChildren.Count; i < imax; ++i) { UINode pc = (UINode)mChildren[i]; #endif UIWidget w = pc.widget; // If the widget is visible, update it if (pc.visibleFlag == 1 && w != null && w.UpdateGeometry(ref mWorldToLocal, (pc.changeFlag == 1), generateNormals)) { // We will need to refill this buffer if (!mChanged.Contains(w.material)) { mChanged.Add(w.material); mChangedLastFrame = true; } } pc.changeFlag = 0; } } /// <summary> /// Update the clipping rect in the shaders and draw calls' positions. /// </summary> public void UpdateDrawcalls() { Vector4 range = Vector4.zero; if (mClipping != UIDrawCall.Clipping.None) { range = new Vector4(mClipRange.x, mClipRange.y, mClipRange.z * 0.5f, mClipRange.w * 0.5f); } if (range.z == 0f) { range.z = mScreenSize.x * 0.5f; } if (range.w == 0f) { range.w = mScreenSize.y * 0.5f; } RuntimePlatform platform = Application.platform; if (platform == RuntimePlatform.WindowsPlayer || platform == RuntimePlatform.WindowsWebPlayer || platform == RuntimePlatform.WindowsEditor) { range.x -= 0.5f; range.y += 0.5f; } Transform t = cachedTransform; for (int i = 0, imax = mDrawCalls.size; i < imax; ++i) { UIDrawCall dc = mDrawCalls.buffer[i]; dc.clipping = mClipping; dc.clipRange = range; dc.clipSoftness = mClipSoftness; dc.depthPass = depthPass; // Set the draw call's transform to match the panel's. // Note that parenting directly to the panel causes unity to crash as soon as you hit Play. Transform dt = dc.transform; dt.position = t.position; dt.rotation = t.rotation; dt.localScale = t.lossyScale; } } /// <summary> /// Set the draw call's geometry responsible for the specified material. /// </summary> void Fill(Material mat) { // Cleanup deleted widgets for (int i = mWidgets.size; i > 0;) { if (mWidgets[--i] == null) { mWidgets.RemoveAt(i); } } // Fill the buffers for the specified material for (int i = 0, imax = mWidgets.size; i < imax; ++i) { UIWidget w = mWidgets.buffer[i]; if (w.visibleFlag == 1 && w.material == mat) { UINode node = GetNode(w.cachedTransform); if (node != null) { if (generateNormals) { w.WriteToBuffers(mVerts, mUvs, mCols, mNorms, mTans); } else { w.WriteToBuffers(mVerts, mUvs, mCols, null, null); } } else { Debug.LogError("No transform found for " + NGUITools.GetHierarchy(w.gameObject), this); } } } if (mVerts.size > 0) { // Rebuild the draw call's mesh UIDrawCall dc = GetDrawCall(mat, true); dc.depthPass = depthPass; dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); } else { // There is nothing to draw for this material -- eliminate the draw call UIDrawCall dc = GetDrawCall(mat, false); if (dc != null) { mDrawCalls.Remove(dc); NGUITools.DestroyImmediate(dc.gameObject); } } // Cleanup mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); } /// <summary> /// Main update function /// </summary> void LateUpdate() { UpdateTransformMatrix(); UpdateTransforms(); // Always move widgets to the panel's layer if (mLayer != gameObject.layer) { mLayer = gameObject.layer; UICamera uic = UICamera.FindCameraForLayer(mLayer); mCam = (uic != null) ? uic.cachedCamera : NGUITools.FindCameraForLayer(mLayer); SetChildLayer(cachedTransform, mLayer); for (int i = 0, imax = drawCalls.size; i < imax; ++i) { mDrawCalls.buffer[i].gameObject.layer = mLayer; } } UpdateWidgets(); // If the depth has changed, we need to re-sort the widgets if (mDepthChanged) { mDepthChanged = false; mWidgets.Sort(UIWidget.CompareFunc); } // Fill the draw calls for all of the changed materials for (int i = 0, imax = mChanged.size; i < imax; ++i) { Fill(mChanged.buffer[i]); } // Update the clipping rects UpdateDrawcalls(); mChanged.Clear(); mRebuildAll = false; #if UNITY_EDITOR mScreenSize = new Vector2(Screen.width, Screen.height); UIRoot root = NGUITools.FindInParents <UIRoot>(gameObject); if (root != null) { mScreenSize *= root.GetPixelSizeAdjustment(Screen.height); } #endif }
/// <summary> /// Fill the geometry for the specified draw call. /// </summary> bool FillDrawCall (UIDrawCall dc) { if (dc != null) { dc.isDirty = false; for (int i = 0; i < widgets.size; ) { UIWidget w = widgets[i]; if (w == null) { #if UNITY_EDITOR Debug.LogError("This should never happen"); #endif widgets.RemoveAt(i); continue; } if (w.drawCall == dc) { if (w.isVisible && w.hasVertices) { if (generateNormals) w.WriteToBuffers(mVerts, mUvs, mCols, mNorms, mTans); else w.WriteToBuffers(mVerts, mUvs, mCols, null, null); } else w.drawCall = null; } ++i; } if (mVerts.size != 0) { dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); return true; } } return false; }
/// <summary> /// Convenience function that figures out the panel's correct change flag by searching the parents. /// </summary> int GetChangeFlag(UINode start) { int flag = start.changeFlag; if (flag == -1) { Transform trans = start.trans.parent; UINode sub; // Keep going until we find a set flag for (;;) { // Check the parent's flag #if USE_SIMPLE_DICTIONARY if (trans != null && mChildren.TryGetValue(trans, out sub)) { #else if (trans != null && mChildren.Contains(trans)) { sub = (UINode)mChildren[trans]; #endif flag = sub.changeFlag; trans = trans.parent; // If the flag hasn't been set either, add this child to the hierarchy if (flag == -1) { mHierarchy.Add(sub); } else { break; } } else { flag = 0; break; } } // Update the parent flags for (int i = 0, imax = mHierarchy.size; i < imax; ++i) { UINode pc = mHierarchy.buffer[i]; pc.changeFlag = flag; } mHierarchy.Clear(); } return(flag); } /// <summary> /// Run through all managed transforms and see if they've changed. /// </summary> void UpdateTransforms() { bool transformsChanged = false; bool shouldCull = false; #if UNITY_EDITOR shouldCull = (clipping != UIDrawCall.Clipping.None) && (!Application.isPlaying || (cullWhileDragging || mUpdateTime > mCullTime)); if (!Application.isPlaying || !widgetsAreStatic || mWidgetsAdded || shouldCull != mCulled) #else shouldCull = (clipping != UIDrawCall.Clipping.None) && (mUpdateTime > mCullTime); if (!widgetsAreStatic || mWidgetsAdded || shouldCull != mCulled) #endif { #if USE_SIMPLE_DICTIONARY foreach (KeyValuePair <Transform, UINode> child in mChildren) { UINode node = child.Value; #else for (int i = 0, imax = mChildren.Count; i < imax; ++i) { UINode node = (UINode)mChildren[i]; #endif if (node.trans == null) { mRemoved.Add(node.trans); continue; } if (node.HasChanged()) { node.changeFlag = 1; transformsChanged = true; #if UNITY_EDITOR Vector3 s = node.trans.lossyScale; float min = Mathf.Abs(Mathf.Min(s.x, s.y)); if (min == 0f) { Debug.LogError("Scale of 0 is invalid! Zero cannot be divided by, which causes problems. Use a small value instead, such as 0.01\n" + node.trans.lossyScale, node.trans); } #endif } else { node.changeFlag = -1; } } // Clean up the deleted transforms for (int i = 0, imax = mRemoved.Count; i < imax; ++i) { mChildren.Remove(mRemoved[i]); } mRemoved.Clear(); } // If the children weren't culled but should be, check their visibility if (!mCulled && shouldCull) { mCheckVisibility = true; } // If something has changed, propagate the changes *down* the tree hierarchy (to children). // An alternative (but slower) approach would be to do a pc.trans.GetComponentsInChildren<UIWidget>() // in the loop above, and mark each one as dirty. if (mCheckVisibility || transformsChanged || mRebuildAll) { #if USE_SIMPLE_DICTIONARY foreach (KeyValuePair <Transform, UINode> child in mChildren) { UINode pc = child.Value; #else for (int i = 0, imax = mChildren.Count; i < imax; ++i) { UINode pc = (UINode)mChildren[i]; #endif if (pc.widget != null) { int visibleFlag = 1; // No sense in checking the visibility if we're not culling anything (as the visibility is always 'true') if (shouldCull || transformsChanged) { // If the change flag has not yet been determined... if (pc.changeFlag == -1) { pc.changeFlag = GetChangeFlag(pc); } // Is the widget visible? if (shouldCull) { visibleFlag = (mCheckVisibility || pc.changeFlag == 1) ? (IsVisible(pc.widget) ? 1 : 0) : pc.visibleFlag; } } // If visibility changed, mark the node as changed as well if (pc.visibleFlag != visibleFlag) { pc.changeFlag = 1; } // If the node has changed and the widget is visible (or was visible before) if (pc.changeFlag == 1 && (visibleFlag == 1 || pc.visibleFlag != 0)) { // Update the visibility flag pc.visibleFlag = visibleFlag; Material mat = pc.widget.material; // Add this material to the list of changed materials if (!mChanged.Contains(mat)) { mChanged.Add(mat); } } } } } mCulled = shouldCull; mCheckVisibility = false; mWidgetsAdded = false; } /// <summary> /// Update all widgets and rebuild their geometry if necessary. /// </summary> void UpdateWidgets() { #if USE_SIMPLE_DICTIONARY foreach (KeyValuePair <Transform, UINode> c in mChildren) { UINode pc = c.Value; #else for (int i = 0, imax = mChildren.Count; i < imax; ++i) { UINode pc = (UINode)mChildren[i]; #endif UIWidget w = pc.widget; // If the widget is visible, update it if (pc.visibleFlag == 1 && w != null && w.UpdateGeometry(this, ref worldToLocal, (pc.changeFlag == 1), generateNormals)) { // We will need to refill this buffer if (!mChanged.Contains(w.material)) { mChanged.Add(w.material); } } pc.changeFlag = 0; } } #endif /// <summary> /// Update the clipping rect in the shaders and draw calls' positions. /// </summary> public void UpdateDrawcalls() { Vector4 range = Vector4.zero; if (mClipping != UIDrawCall.Clipping.None) { range = new Vector4(mClipRange.x, mClipRange.y, mClipRange.z * 0.5f, mClipRange.w * 0.5f); } if (range.z == 0f) { range.z = Screen.width * 0.5f; } if (range.w == 0f) { range.w = Screen.height * 0.5f; } RuntimePlatform platform = Application.platform; if (platform == RuntimePlatform.WindowsPlayer || platform == RuntimePlatform.WindowsWebPlayer || platform == RuntimePlatform.WindowsEditor) { range.x -= 0.5f; range.y += 0.5f; } Transform t = cachedTransform; UIDrawCall dc; Transform dt; for (int i = 0, imax = mDrawCalls.size; i < imax; ++i) { dc = mDrawCalls.buffer[i]; dc.clipping = mClipping; dc.clipRange = range; dc.clipSoftness = mClipSoftness; dc.depthPass = depthPass && mClipping == UIDrawCall.Clipping.None; // Set the draw call's transform to match the panel's. // Note that parenting directly to the panel causes unity to crash as soon as you hit Play. dt = dc.transform; dt.position = t.position; dt.rotation = t.rotation; dt.localScale = t.lossyScale; } } /// <summary> /// Set the draw call's geometry responsible for the specified material. /// </summary> void Fill(Material mat) { int highest = -100; // Fill the buffers for the specified material for (int i = 0; i < mWidgets.size;) { UIWidget w = mWidgets.buffer[i]; if (w == null) { mWidgets.RemoveAt(i); continue; } #if OLD_UNITY else if (w.visibleFlag == 1 && w.material == mat) #else else if (w.material == mat && w.isVisible) #endif { if (w.panel == this) { int depth = w.depth; if (depth > highest) { highest = depth; } if (generateNormals) { w.WriteToBuffers(mVerts, mUvs, mCols, mNorms, mTans); } else { w.WriteToBuffers(mVerts, mUvs, mCols, null, null); } } else { mWidgets.RemoveAt(i); continue; } } ++i; } if (mVerts.size > 0) { // Rebuild the draw call's mesh UIDrawCall dc = GetDrawCall(mat, true); dc.depthPass = depthPass && mClipping == UIDrawCall.Clipping.None; dc.depth = sortByDepth ? highest : 0; dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); dc.mainTexture = mat.mainTexture; } else { // There is nothing to draw for this material -- eliminate the draw call UIDrawCall dc = GetDrawCall(mat, false); if (dc != null) { mDrawCalls.Remove(dc); NGUITools.DestroyImmediate(dc.gameObject); } } // Cleanup mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); } /// <summary> /// Main update function /// </summary> void LateUpdate() { mUpdateTime = Time.realtimeSinceStartup; UpdateTransformMatrix(); #if OLD_UNITY UpdateTransforms(); #endif // Always move widgets to the panel's layer if (mLayer != cachedGameObject.layer) { mLayer = mGo.layer; UICamera uic = UICamera.FindCameraForLayer(mLayer); mCam = (uic != null) ? uic.cachedCamera : NGUITools.FindCameraForLayer(mLayer); SetChildLayer(cachedTransform, mLayer); for (int i = 0, imax = drawCalls.size; i < imax; ++i) { mDrawCalls.buffer[i].gameObject.layer = mLayer; } } #if OLD_UNITY UpdateWidgets(); #else #if UNITY_EDITOR bool forceVisible = cullWhileDragging ? false : (clipping == UIDrawCall.Clipping.None) || (Application.isPlaying && mCullTime > mUpdateTime); #else bool forceVisible = cullWhileDragging ? false : (clipping == UIDrawCall.Clipping.None) || (mCullTime > mUpdateTime); #endif // Update all widgets for (int i = 0, imax = mWidgets.size; i < imax; ++i) { UIWidget w = mWidgets[i]; // If the widget is visible, update it if (w.UpdateGeometry(this, forceVisible)) { // We will need to refill this buffer if (!mChanged.Contains(w.material)) { mChanged.Add(w.material); } } } #endif // Inform the changed event listeners if (mChanged.size != 0 && onChange != null) { onChange(); } // If the depth has changed, we need to re-sort the widgets if (mDepthChanged) { mDepthChanged = false; mWidgets.Sort(UIWidget.CompareFunc); } // Fill the draw calls for all of the changed materials for (int i = 0, imax = mChanged.size; i < imax; ++i) { Fill(mChanged.buffer[i]); } // Update the clipping rects UpdateDrawcalls(); mChanged.Clear(); #if OLD_UNITY mRebuildAll = false; #endif #if UNITY_EDITOR mScreenSize = new Vector2(Screen.width, Screen.height); #endif }
private void SubmitDrawCall(UIDrawCall dc) { dc.clipping = this.clipping; dc.Set(mVerts, !this.generateNormals ? null : mNorms, !this.generateNormals ? null : mTans, mUvs, mCols); mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); }
/// <summary> /// Submit the draw call using the current geometry. /// </summary> void SubmitDrawCall (UIDrawCall dc) { drawCalls.Add(dc); dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); }
/// <summary> /// Convenience function that figures out the panel's correct change flag by searching the parents. /// </summary> int GetChangeFlag(UINode start) { int flag = start.changeFlag; if (flag == -1) { Transform trans = start.trans.parent; UINode sub; // Keep going until we find a set flag for (;;) { // Check the parent's flag #if USE_SIMPLE_DICTIONARY if (trans != null && mChildren.TryGetValue(trans, out sub)) { #else if (trans != null && mChildren.Contains(trans)) { sub = (UINode)mChildren[trans]; #endif flag = sub.changeFlag; trans = trans.parent; // If the flag hasn't been set either, add this child to the hierarchy if (flag == -1) { mHierarchy.Add(sub); } else { break; } } else { flag = 0; break; } } // Update the parent flags for (int i = 0, imax = mHierarchy.size; i < imax; ++i) { UINode pc = mHierarchy.buffer[i]; pc.changeFlag = flag; } mHierarchy.Clear(); } return(flag); } /// <summary> /// Update the world-to-local transform matrix as well as clipping bounds. /// </summary> void UpdateTransformMatrix() { if (mUpdateTime == 0f || mMatrixTime != mUpdateTime) { mMatrixTime = mUpdateTime; mWorldToLocal = cachedTransform.worldToLocalMatrix; if (mClipping != UIDrawCall.Clipping.None) { Vector2 size = new Vector2(mClipRange.z, mClipRange.w); if (size.x == 0f) { size.x = (mCam == null) ? Screen.width : mCam.pixelWidth; } if (size.y == 0f) { size.y = (mCam == null) ? Screen.height : mCam.pixelHeight; } size *= 0.5f; mMin.x = mClipRange.x - size.x; mMin.y = mClipRange.y - size.y; mMax.x = mClipRange.x + size.x; mMax.y = mClipRange.y + size.y; } } } /// <summary> /// Run through all managed transforms and see if they've changed. /// </summary> void UpdateTransforms() { mChangedLastFrame = false; bool transformsChanged = false; bool shouldCull = false; #if UNITY_EDITOR shouldCull = (clipping != UIDrawCall.Clipping.None) && (!Application.isPlaying || mUpdateTime > mCullTime); if (!Application.isPlaying || !widgetsAreStatic || mWidgetsAdded || shouldCull != mCulled) #else shouldCull = (clipping != UIDrawCall.Clipping.None) && (mUpdateTime > mCullTime); if (!widgetsAreStatic || mWidgetsAdded || shouldCull != mCulled) #endif { #if USE_SIMPLE_DICTIONARY foreach (KeyValuePair <Transform, UINode> child in mChildren) { UINode node = child.Value; #else for (int i = 0, imax = mChildren.Count; i < imax; ++i) { UINode node = (UINode)mChildren[i]; #endif if (node.trans == null) { mRemoved.Add(node.trans); continue; } if (node.HasChanged()) { node.changeFlag = 1; transformsChanged = true; #if UNITY_EDITOR Vector3 s = node.trans.lossyScale; float min = Mathf.Abs(Mathf.Min(s.x, s.y)); if (min == 0f) { Debug.LogError("Scale of 0 is invalid! Zero cannot be divided by, which causes problems. Use a small value instead, such as 0.01\n" + node.trans.lossyScale, node.trans); } #endif } else { node.changeFlag = -1; } } // Clean up the deleted transforms for (int i = 0, imax = mRemoved.Count; i < imax; ++i) { mChildren.Remove(mRemoved[i]); } mRemoved.Clear(); } // If the children weren't culled but should be, check their visibility if (!mCulled && shouldCull) { mCheckVisibility = true; } // If something has changed, propagate the changes *down* the tree hierarchy (to children). // An alternative (but slower) approach would be to do a pc.trans.GetComponentsInChildren<UIWidget>() // in the loop above, and mark each one as dirty. if (mCheckVisibility || transformsChanged || mRebuildAll) { #if USE_SIMPLE_DICTIONARY foreach (KeyValuePair <Transform, UINode> child in mChildren) { UINode pc = child.Value; #else for (int i = 0, imax = mChildren.Count; i < imax; ++i) { UINode pc = (UINode)mChildren[i]; #endif if (pc.widget != null) { int visibleFlag = 1; // No sense in checking the visibility if we're not culling anything (as the visibility is always 'true') if (shouldCull || transformsChanged) { // If the change flag has not yet been determined... if (pc.changeFlag == -1) { pc.changeFlag = GetChangeFlag(pc); } // Is the widget visible? if (shouldCull) { visibleFlag = (mCheckVisibility || pc.changeFlag == 1) ? (IsVisible(pc.widget) ? 1 : 0) : pc.visibleFlag; } } // If visibility changed, mark the node as changed as well if (pc.visibleFlag != visibleFlag) { pc.changeFlag = 1; } // If the node has changed and the widget is visible (or was visible before) if (pc.changeFlag == 1 && (visibleFlag == 1 || pc.visibleFlag != 0)) { // Update the visibility flag pc.visibleFlag = visibleFlag; Material mat = pc.widget.material; // Add this material to the list of changed materials if (!mChanged.Contains(mat)) { mChanged.Add(mat); mChangedLastFrame = true; } } } } } mCulled = shouldCull; mCheckVisibility = false; mWidgetsAdded = false; } /// <summary> /// Update all widgets and rebuild their geometry if necessary. /// </summary> void UpdateWidgets() { #if USE_SIMPLE_DICTIONARY foreach (KeyValuePair <Transform, UINode> c in mChildren) { UINode pc = c.Value; #else for (int i = 0, imax = mChildren.Count; i < imax; ++i) { UINode pc = (UINode)mChildren[i]; #endif UIWidget w = pc.widget; // If the widget is visible, update it if (pc.visibleFlag == 1 && w != null && w.UpdateGeometry(ref mWorldToLocal, (pc.changeFlag == 1), generateNormals)) { // We will need to refill this buffer if (!mChanged.Contains(w.material)) { mChanged.Add(w.material); mChangedLastFrame = true; } } pc.changeFlag = 0; } } /// <summary> /// Update the clipping rect in the shaders and draw calls' positions. /// </summary> bool nestingClip = false; Vector4 newClipRange = Vector4.zero; public void UpdateDrawcalls() { Vector4 range = Vector4.zero; if (mClipping != UIDrawCall.Clipping.None) { UIDraggablePanel dragPanel = gameObject.GetComponent <UIDraggablePanel>(); if (dragPanel != null && gameObject.transform.parent != null) { UIPanel parentPanel = NGUITools.FindInParents <UIPanel>(gameObject.transform.parent.gameObject); if (parentPanel != null && parentPanel.transform.parent != null && parentPanel.clipping != UIDrawCall.Clipping.None) { Vector3 worldPos = transform.TransformPoint(Vector3.zero); Vector3 localPos = parentPanel.transform.parent.InverseTransformPoint(worldPos); newClipRange = mClipRange; Vector4 parentRect = new Vector4(-localPos.x - parentPanel.clipRange.z / 2 , -localPos.y - parentPanel.clipRange.w / 2 , -localPos.x + parentPanel.clipRange.z / 2 , -localPos.y + parentPanel.clipRange.w / 2); Vector4 selfRect = new Vector4(newClipRange.x - newClipRange.z / 2 , newClipRange.y - newClipRange.w / 2 , newClipRange.x + newClipRange.z / 2 , newClipRange.y + newClipRange.w / 2 ); if (selfRect.x < parentRect.x) { selfRect.x = parentRect.x; nestingClip = true; } if (selfRect.y < parentRect.y) { selfRect.y = parentRect.y; nestingClip = true; } if (selfRect.z > parentRect.z) { selfRect.z = parentRect.z; nestingClip = true; } if (selfRect.w > parentRect.w) { selfRect.w = parentRect.w; nestingClip = true; } float xLength = selfRect.z - selfRect.x; if (xLength < 0) { xLength = 0.0001f; } float yLength = selfRect.w - selfRect.y; if (yLength < 0) { yLength = 0.0001f; } newClipRange = new Vector4(selfRect.x + xLength / 2 , selfRect.y + yLength / 2 , xLength , yLength); //if (newClipRange.x < -localPos.x - Mathf.Abs(parentPanel.clipRange.z - newClipRange.z)/2) //{ // float offset = -localPos.x - Mathf.Abs(parentPanel.clipRange.z - newClipRange.z)/2; // newClipRange.x = offset / 2; // newClipRange.z -= offset; // nestingClip = true; //} //else if (newClipRange.x > -localPos.x + Mathf.Abs(parentPanel.clipRange.z - newClipRange.z)/2) //{ // float offset = localPos.x + Mathf.Abs(parentPanel.clipRange.z - newClipRange.z)/2; // newClipRange.x -= offset / 2; // newClipRange.z = offset; // nestingClip = true; //} //else //{ // nestingClip = false; //} //if (newClipRange.y < -localPos.y) //{ // newClipRange.y = -localPos.y; // newClipRange.w = parentPanel.clipRange.w; //} } } if (nestingClip) { range = new Vector4(newClipRange.x, newClipRange.y, newClipRange.z * 0.5f, newClipRange.w * 0.5f); } else { range = new Vector4(mClipRange.x, mClipRange.y, mClipRange.z * 0.5f, mClipRange.w * 0.5f); } } if (range.z == 0f) { range.z = Screen.width * 0.5f; } if (range.w == 0f) { range.w = Screen.height * 0.5f; } RuntimePlatform platform = Application.platform; if (platform == RuntimePlatform.WindowsPlayer || platform == RuntimePlatform.WindowsWebPlayer || platform == RuntimePlatform.WindowsEditor) { range.x -= 0.5f; range.y += 0.5f; } Transform t = cachedTransform; for (int i = 0, imax = mDrawCalls.size; i < imax; ++i) { UIDrawCall dc = mDrawCalls.buffer[i]; dc.clipping = mClipping; dc.clipRange = range; dc.clipSoftness = mClipSoftness; dc.depthPass = depthPass; // Set the draw call's transform to match the panel's. // Note that parenting directly to the panel causes unity to crash as soon as you hit Play. Transform dt = dc.transform; dt.position = t.position; dt.rotation = t.rotation; dt.localScale = t.lossyScale; } } /// <summary> /// Set the draw call's geometry responsible for the specified material. /// </summary> void Fill(Material mat) { // Cleanup deleted widgets for (int i = mWidgets.size; i > 0;) { if (mWidgets[--i] == null) { mWidgets.RemoveAt(i); } } // Fill the buffers for the specified material for (int i = 0, imax = mWidgets.size; i < imax; ++i) { UIWidget w = mWidgets.buffer[i]; if (w.visibleFlag == 1 && w.material == mat) { UINode node = GetNode(w.cachedTransform); if (node != null) { if (generateNormals) { w.WriteToBuffers(mVerts, mUvs, mCols, mNorms, mTans); } else { w.WriteToBuffers(mVerts, mUvs, mCols, null, null); } } else { Debug.LogError("No transform found for " + NGUITools.GetHierarchy(w.gameObject), this); } } } if (mVerts.size > 0) { // Rebuild the draw call's mesh UIDrawCall dc = GetDrawCall(mat, true); dc.depthPass = depthPass; dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); } else { // There is nothing to draw for this material -- eliminate the draw call UIDrawCall dc = GetDrawCall(mat, false); if (dc != null) { mDrawCalls.Remove(dc); NGUITools.DestroyImmediate(dc.gameObject); } } // Cleanup mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); }
/// <summary> /// Set the draw call's geometry responsible for the specified material. /// </summary> void Fill(Material mat) { // Cleanup deleted widgets for (int i = mWidgets.Count; i > 0;) { if (mWidgets[--i] == null) { mWidgets.RemoveAt(i); } } // Fill the buffers for the specified material foreach (UIWidget w in mWidgets) { if (w.visibleFlag == 1 && w.material == mat) { UINode node = GetNode(w.cachedTransform); if (node != null) { if (generateNormals) { w.WriteToBuffers(mVerts, mUvs, mCols, mNorms, mTans); } else { w.WriteToBuffers(mVerts, mUvs, mCols, null, null); } } else { Debug.LogError("No transform found for " + NGUITools.GetHierarchy(w.gameObject), this); } } } if (mVerts.size > 0) { // Rebuild the draw call's mesh UIDrawCall dc = GetDrawCall(mat, true); dc.depthPass = depthPass; dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); } else { // There is nothing to draw for this material -- eliminate the draw call UIDrawCall dc = GetDrawCall(mat, false); if (dc != null) { mDrawCalls.Remove(dc); DestroyImmediate(dc.gameObject); } } // Cleanup mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); }
/// <summary> /// Submit the draw call using the current geometry. /// </summary> void SubmitDrawCall (UIDrawCall dc) { dc.clipping = clipping; dc.alwaysOnScreen = alwaysOnScreen && (clipping == UIDrawCall.Clipping.None || clipping == UIDrawCall.Clipping.ConstrainButDontClip); dc.Set(mVerts, generateNormals ? mNorms : null, generateNormals ? mTans : null, mUvs, mCols); mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); }
/// <summary> /// Fill the geometry for the specified draw call. /// </summary> static bool Fill (UIDrawCall dc) { if (dc != null) { dc.isDirty = false; for (int i = 0; i < UIWidget.list.size; ) { UIWidget w = UIWidget.list[i]; if (w == null) { UIWidget.list.RemoveAt(i); continue; } if (w.renderQueue == dc.renderQueue) { if (w.isVisible && w.hasVertices) { if (dc.panel.generateNormals) w.WriteToBuffers(mVerts, mUvs, mCols, mNorms, mTans); else w.WriteToBuffers(mVerts, mUvs, mCols, null, null); } else { w.renderQueue = -1; } } ++i; } if (mVerts.size != 0) { dc.Set(mVerts, dc.panel.generateNormals ? mNorms : null, dc.panel.generateNormals ? mTans : null, mUvs, mCols); mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); return true; } } return false; }
private static bool Fill(UIDrawCall dc) { if (dc != null) { dc.isDirty = false; int index = 0; while (index < UIWidget.list.size) { UIWidget widget = UIWidget.list[index]; if (widget == null) { UIWidget.list.RemoveAt(index); } else { if (widget.drawCall == dc) { if (widget.isVisible && widget.hasVertices) { if (dc.manager.generateNormals) { widget.WriteToBuffers(mVerts, mUvs, mCols, mNorms, mTans); } else { widget.WriteToBuffers(mVerts, mUvs, mCols, null, null); } } else { widget.drawCall = null; } } index++; } } if (mVerts.size != 0) { dc.Set(mVerts, !dc.manager.generateNormals ? null : mNorms, !dc.manager.generateNormals ? null : mTans, mUvs, mCols); mVerts.Clear(); mNorms.Clear(); mTans.Clear(); mUvs.Clear(); mCols.Clear(); return true; } } return false; }