bool ProbeMultiAtlas(ImageAreaInAtlas[] imgsToAdd, int idealAtlasW, int idealAtlasH, float imgArea, int maxAtlasDimX, int maxAtlasDimY, ProbeResult pr) { int numAtlases = 0; AtalsAreaNode root = new AtalsAreaNode(NodeType.maxDim); root.nodeAreaRect = new AtalsAreaPixRect(0, 0, idealAtlasW, idealAtlasH); for (int i = 0; i < imgsToAdd.Length; i++) { AtalsAreaNode n = root.Insert(imgsToAdd[i], false); if (n == null) { if (imgsToAdd[i].x > idealAtlasW && imgsToAdd[i].y > idealAtlasH) { return(false); } else { // create a new root node wider than previous atlas AtalsAreaNode newRoot = new AtalsAreaNode(NodeType.Container); newRoot.nodeAreaRect = new AtalsAreaPixRect(0, 0, root.nodeAreaRect.w + idealAtlasW, idealAtlasH); // create a new right child AtalsAreaNode newRight = new AtalsAreaNode(NodeType.maxDim); newRight.nodeAreaRect = new AtalsAreaPixRect(root.nodeAreaRect.w, 0, idealAtlasW, idealAtlasH); newRoot.child[1] = newRight; // insert root as a new left child newRoot.child[0] = root; root = newRoot; n = root.Insert(imgsToAdd[i], false); numAtlases++; } } } pr.numAtlases = numAtlases; pr.root = root; //todo atlas may not be maxDim * maxDim. Do some checking to see what actual needed sizes are and update pr.totalArea pr.totalAtlasArea = numAtlases * maxAtlasDimX * maxAtlasDimY; Debug.Log("Probe success efficiency numAtlases=" + numAtlases + " totalArea=" + pr.totalAtlasArea); return(true); }
bool ProbeSingleAtlas(ImageAreaInAtlas[] imgsToAdd, int idealAtlasW, int idealAtlasH, float imgArea, int maxAtlasDimX, int maxAtlasDimY, ProbeResult pr) { AtalsAreaNode root = new AtalsAreaNode(NodeType.maxDim); root.nodeAreaRect = new AtalsAreaPixRect(0, 0, idealAtlasW, idealAtlasH); for (int i = 0; i < imgsToAdd.Length; i++) { AtalsAreaNode n = root.Insert(imgsToAdd[i], false); if (n == null) { return(false); } else if (i == imgsToAdd.Length - 1) { int usedW = 0; int usedH = 0; GetExtent(root, ref usedW, ref usedH); float efficiency, squareness; bool fitsInMaxDim; int atlasW = usedW; int atlasH = usedH; if (atlasMustBePowerOfTwo) { atlasW = Mathf.Min(CeilToNearestPowerOfTwo(usedW), maxAtlasDimX); atlasH = Mathf.Min(CeilToNearestPowerOfTwo(usedH), maxAtlasDimY); if (atlasH < atlasW / 2) { atlasH = atlasW / 2; } if (atlasW < atlasH / 2) { atlasW = atlasH / 2; } fitsInMaxDim = usedW <= maxAtlasDimX && usedH <= maxAtlasDimY; float scaleW = Mathf.Max(1f, ((float)usedW) / maxAtlasDimX); float scaleH = Mathf.Max(1f, ((float)usedH) / maxAtlasDimY); float atlasArea = atlasW * scaleW * atlasH * scaleH; //area if we scaled it up to something large enough to contain images efficiency = 1f - (atlasArea - imgArea) / atlasArea; squareness = 1f; //don't care about squareness in power of two case } else { efficiency = 1f - (usedW * usedH - imgArea) / (usedW * usedH); if (usedW < usedH) { squareness = (float)usedW / (float)usedH; } else { squareness = (float)usedH / (float)usedW; } fitsInMaxDim = usedW <= maxAtlasDimX && usedH <= maxAtlasDimY; } pr.Set(usedW, usedH, atlasW, atlasH, root, fitsInMaxDim, efficiency, squareness); Debug.Log("Probe success efficiency w=" + usedW + " h=" + usedH + " e=" + efficiency + " sq=" + squareness + " fits=" + fitsInMaxDim); return(true); } } Debug.LogError("Should never get here."); return(false); }