private static void GeneratePackTextureImpl(CNode node, ref PackTextureAttrSet packTextureAttrSet) { if (node != null && packTextureAttrSet != null && packTextureAttrSet.packTexture) { if (node.IsFilled) { TextureVertexAttr attri = node.refTextureInfo; CalcVertexAtrribute( packTextureAttrSet.packTexWidth, packTextureAttrSet.packTexHeight, ref attri ); packTextureAttrSet.texVertexAttrList.Add(attri); Fill2PackTexture(packTextureAttrSet.packTexture, attri); } if (node.leftChild != null) { GeneratePackTextureImpl(node.leftChild, ref packTextureAttrSet); } if (node.rightChild != null) { GeneratePackTextureImpl(node.rightChild, ref packTextureAttrSet); } } }
public CNode Insert(Texture2D texture) { CNode retNode = null; if (texture != null) { int texWidth = texture.width; int texHeight = texture.height; if (!IsLeaf) //不是叶子结点了 { if (leftChild != null) { retNode = leftChild.Insert(texture); } if (retNode == null && rightChild != null) { retNode = rightChild.Insert(texture); } } else { bool bNeedFliped = false; if (IsFilled) { retNode = null; } else if (CanFillIn(texWidth, texHeight, out bNeedFliped)) { bool bPerfectFillIn = bNeedFliped ? CanPerfectFillIn(texHeight, texWidth) : CanPerfectFillIn(texWidth, texHeight); //如果完美匹配 if (bPerfectFillIn) { retNode = this; Fill(ref retNode, texture, bNeedFliped); } else { int fillWidth = (bNeedFliped ? texHeight : texWidth); int fillHeight = (bNeedFliped ? texWidth : texHeight); SplitNode(fillWidth, fillHeight, out leftChild, out rightChild); if (leftChild != null) { retNode = leftChild.Insert(texture); } } } } } return(retNode); }
private void Fill(ref CNode retNode, Texture2D texture, bool bNeedFliped) { if (retNode != null) { string assetPath = AssetDatabase.GetAssetPath(texture); retNode.refTextureInfo.blockDetail.IsFilped = bNeedFliped; //翻转的 retNode.refTextureInfo.refSprite = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Sprite)) as Sprite; retNode.refTextureInfo.refTexture = texture; retNode.refTextureInfo.szGUID = AssetDatabase.AssetPathToGUID(assetPath); retNode.refTextureInfo.spriteName = Path.GetFileNameWithoutExtension(assetPath); } }
private static void GeneratePackTexture(CNode root, out PackTextureAttrSet outPackTextureAttrSet) { outPackTextureAttrSet = null; if (root != null) { outPackTextureAttrSet = ScriptableObject.CreateInstance <PackTextureAttrSet>(); outPackTextureAttrSet.texVertexAttrList = new List <TextureVertexAttr>(); //后面的格式指定 outPackTextureAttrSet.packTexture = new Texture2D(root.refTextureInfo.blockDetail.rect.w, root.refTextureInfo.blockDetail.rect.h, TextureFormat.RGBA32, false); SetDefaultColor(ref outPackTextureAttrSet.packTexture, mDefaultColor); GeneratePackTextureImpl(root, ref outPackTextureAttrSet); } }
//随便的算法,不是最优的 public static CNode GenerateRootNode(Texture2D[] splitTexs, int packTexWidth, int packTexHeight) { CNode rootNode = null; if (splitTexs != null) { //统计一下所有图片的总像素数量 //找出最长的宽和高 int pixelCnt = 0; int maxWidth = 0; int maxHeight = 0; for (int i = 0; i < splitTexs.Length; ++i) { int tWidth = splitTexs[i].width; int tHeight = splitTexs[i].height; pixelCnt += tWidth * tHeight; if (tWidth > maxWidth) { maxWidth = tWidth; } if (tHeight > maxHeight) { maxHeight = tHeight; } } int packTexSize = packTexWidth * packTexHeight; if (packTexSize >= pixelCnt) { if ((packTexWidth >= maxWidth && packTexHeight >= maxHeight) || (packTexWidth >= maxHeight && packTexHeight >= maxWidth)) { rootNode = new CNode(); rootNode.refTextureInfo.blockDetail.rect.Set(0, 0, packTexWidth, packTexHeight); } else { Debug.LogError("width or height too small"); } } else { Debug.LogError("Size too small"); } } return(rootNode); }
private void SplitNode(int fillWidth, int fillHeight, out CNode outLeftChild, out CNode outRightChild) { outLeftChild = new CNode(); outRightChild = new CNode(); int dw = refTextureInfo.blockDetail.rect.w - fillWidth; int dh = refTextureInfo.blockDetail.rect.h - fillHeight; if (dw >= dh) //左右分割 { outLeftChild.refTextureInfo.blockDetail.rect.Set( refTextureInfo.blockDetail.rect.x, refTextureInfo.blockDetail.rect.y, fillWidth, refTextureInfo.blockDetail.rect.h ); outRightChild.refTextureInfo.blockDetail.rect.Set( refTextureInfo.blockDetail.rect.x + fillWidth, refTextureInfo.blockDetail.rect.y, dw, refTextureInfo.blockDetail.rect.h ); } else //上下分割 { outLeftChild.refTextureInfo.blockDetail.rect.Set( refTextureInfo.blockDetail.rect.x, refTextureInfo.blockDetail.rect.y, refTextureInfo.blockDetail.rect.w, fillHeight ); outRightChild.refTextureInfo.blockDetail.rect.Set( refTextureInfo.blockDetail.rect.x, refTextureInfo.blockDetail.rect.y + fillHeight, refTextureInfo.blockDetail.rect.w, dh ); } }
public static void Pack(Texture2D[] splitTexs, int width, int height, out PackTextureAttrSet outPackTextureAttrSet) { outPackTextureAttrSet = null; if (splitTexs != null) { SortTexture(ref splitTexs); CNode rootNode = GenerateRootNode(splitTexs, width, height); if (rootNode != null) { //插一插 for (int i = 0; i < splitTexs.Length; ++i) { if (rootNode.Insert(splitTexs[i]) == null) { string assetPath = AssetDatabase.GetAssetPath(splitTexs[i]); Debug.LogWarning(string.Format("no suitable area:{0}", assetPath)); } } //遍历一下节点树生成图集 GeneratePackTexture(rootNode, out outPackTextureAttrSet); } } }