//---------------------------------------------- // NGUI: Next-Gen UI kit // Copyright © 2011-2015 Tasharen Entertainment //---------------------------------------------- using UnityEngine; using System.Collections.Generic; /// /// Generated geometry class. All widgets have one. /// This class separates the geometry creation into several steps, making it possible to perform /// actions selectively depending on what has changed. For example, the widget doesn't need to be /// rebuilt unless something actually changes, so its geometry can be cached. Likewise, the widget's /// transformed coordinates only change if the widget's transform moves relative to the panel, /// so that can be cached as well. In the end, using this class means using more memory, but at /// the same time it allows for significant performance gains, especially when using widgets that /// spit out a lot of vertices, such as UILabels. /// public class UIGeometry { /// /// Widget's vertices (before they get transformed). /// public BetterList verts = new BetterList(); /// /// Widget's texture coordinates for the geometry's vertices. /// public BetterList uvs = new BetterList(); /// /// Array of colors for the geometry's vertices. /// public BetterList cols = new BetterList(); // Relative-to-panel vertices, normal, and tangent public BetterList mRtpVerts = new BetterList(); Vector3 mRtpNormal; Vector4 mRtpTan; /// /// Whether the geometry contains usable vertices. /// public bool hasVertices { get { return (verts != null && verts.size > 0); } } /// /// Whether the geometry has usable transformed vertex data. /// public bool hasTransformed { get { return (mRtpVerts != null) && (mRtpVerts.size > 0) && (mRtpVerts.size == verts.size); } } /// /// Step 1: Prepare to fill the buffers -- make them clean and valid. /// public void Clear() { if (verts != null) verts.Clear(); if (uvs != null) uvs.Clear(); if (cols != null) cols.Clear(); if (mRtpVerts != null) mRtpVerts.Clear(); } /// /// Step 2: Transform the vertices by the provided matrix. /// public void ApplyTransform(Matrix4x4 widgetToPanel, bool generateNormals, float height, float width) { mRtpVerts.Clear(); if (verts.size > 0) { //如果不是整体处理 mRtpVerts.AddRange(verts); var buffer = mRtpVerts.buffer; for (int i = 0, imax = verts.size; i < imax; ++i) { buffer[i] = widgetToPanel.MultiplyPoint3x4(buffer[i]); } // Calculate the widget's normal and tangent if (generateNormals) { mRtpNormal = widgetToPanel.MultiplyVector(Vector3.back).normalized; Vector3 tangent = widgetToPanel.MultiplyVector(Vector3.right).normalized; mRtpTan = new Vector4(tangent.x, tangent.y, tangent.z, -1f); } } } /// /// Step 3: Fill the specified buffer using the transformed values. /// public void WriteToBuffers(BetterList v, BetterList u, BetterList c, BetterList n, BetterList t, float alpha) { if (mRtpVerts != null && mRtpVerts.size > 0) { v.AddRange(mRtpVerts); u.AddRange(uvs); var cOriSize = c.size; c.AddRange(cols); var colBuffer = c.buffer; for(int i = cOriSize; i < c.size; ++i) { colBuffer[i].a = (byte)(colBuffer[i].a * alpha); } if(n != null) { for (int i = 0; i < mRtpVerts.size; ++i) { n.Add(mRtpNormal); t.Add(mRtpTan); } } } } //清理缓存 public void FreeCache() { CachedGeometries.Free(verts); CachedGeometries.Free(uvs); CachedGeometries.Free(cols); CachedGeometries.Free(mRtpVerts); verts = null; uvs = null; cols = null; mRtpVerts = null; } //检查缓存 public void CheckCacke(int vecCount) { if (verts == null || verts.buffer == null || verts.buffer.Length < vecCount) { FreeCache(); CachedGeometries.Get(vecCount, ref verts); CachedGeometries.Get(vecCount, ref uvs); CachedGeometries.Get(vecCount, ref cols); CachedGeometries.Get(vecCount, ref mRtpVerts); } } }