Exemple #1
0
    //1. R靠紧容器矩形的左上角排放
    //2. R靠紧容器矩形的左下角排放
    //3. A点放置在R1的左上角
    //4. A点放置在R1的右下角
    //5. R的左上角对齐R1的右上角排放
    private static void  _ComputerRectPngPart(PngPartInfo info, List <PngPartInfo> infos, int num)
    {
        if (infos.Count == 0)
        {
            info.bound.center = new Vector3(info.bound.extents.x, info.bound.extents.y, 0);
            return;
        }
        List <PngPartInfo> newInfos = new List <PngPartInfo>(infos);

        newInfos.Add(info);
        List <Bounds> bounds = new List <Bounds>();

        System.Action <PngPartInfo> CallBack = (f) =>
        {
            Vector3 rect = info.bound.center - info.bound.extents;
            if (rect.x >= 0 && rect.y >= 0)
            {
                for (int i = 0; i < infos.Count; i++)
                {
                    if (infos[i].bound.Intersects(info.bound))
                    {
                        return;
                    }
                }
                bounds.Add(info.bound);
            }
        };

        for (int i = 0; i < infos.Count; i++)
        {
            var temp = infos[i];
            //1. R靠紧容器矩形的左上角排放
            info.bound.center = temp.bound.center + new Vector3(-temp.bound.extents.x + info.bound.extents.x, info.bound.extents.y + temp.bound.extents.y + MaxChink, 0);
            CallBack(info);
            //2. R靠紧容器矩形的左下角排放
            info.bound.center = temp.bound.center + new Vector3(-temp.bound.extents.x + info.bound.extents.x, -info.bound.extents.y - temp.bound.extents.y - MaxChink, 0);
            CallBack(info);
            //3. A点放置在R1的左上角
            info.bound.center = temp.bound.center + new Vector3(temp.bound.extents.x + info.bound.extents.x + MaxChink, info.bound.extents.y + temp.bound.extents.y + MaxChink, 0);
            CallBack(info);
            //4. A点放置在R1的右下角
            info.bound.center = temp.bound.center + new Vector3(temp.bound.extents.x + info.bound.extents.x + MaxChink, info.bound.extents.y - temp.bound.extents.y, 0);
            CallBack(info);
            //5. R的左上角对齐R1的右上角排放
            info.bound.center = temp.bound.center + new Vector3(temp.bound.extents.x + info.bound.extents.x + MaxChink, -info.bound.extents.y + temp.bound.extents.y, 0);
            CallBack(info);
        }
        info.bound = bounds[num % bounds.Count];
    }
Exemple #2
0
    private static void CreateFitImag(string sourceImg, string fileName)
    {
        string filepath     = Application.dataPath + "/" + sourceImg + "/";
        string texturePath  = filepath + fileName + "_texture.png";
        string materialPath = filepath.Replace(Application.dataPath, "Assets") + fileName + "_mat.mat";
        string fontPath     = filepath.Replace(Application.dataPath, "Assets") + fileName + "_font.fontsettings";

        string[] pngs = FEPath.GetFiles(Application.dataPath + "/" + sourceImg, "*.png");

        float maxX = 0;
        float maxY = 0;
        List <PngPartInfo> ppInfos = new List <PngPartInfo>();

        foreach (string path in pngs)
        {
            string subPngPath = path.Replace(Application.dataPath, "Assets");
            if (subPngPath.IndexOf("texture") == -1)
            {
                SetTextureImporter(subPngPath);
                PngPartInfo info  = new PngPartInfo();
                Texture2D   tex2D = AssetDatabase.LoadAssetAtPath(subPngPath, typeof(Texture2D)) as Texture2D;
                info.text2D        = tex2D;
                info.index         = Uncode(tex2D.name);
                info.bound         = new Bounds();
                info.bound.extents = new Vector3(tex2D.width / 2 + 2, tex2D.height / 2 + 2, 0);
                maxX += tex2D.width;
                maxY += tex2D.height;
                ppInfos.Add(info);
            }
        }

        float maxFitValue = maxY + maxX;

        var mGeneOnlyData = NeuralAlgorithm.CreateNormalGene(50, ppInfos.Count, 20, (t) =>
        {
            List <PngPartInfo> tempInfo = new List <PngPartInfo>();
            for (int i = 0; i < t._Code.Count; i++)
            {
                _ComputerRectPngPart(ppInfos[i], tempInfo, t._Code[i]);
                tempInfo.Add(ppInfos[i]);
            }
            Vector2 tempSize = GetFitValue(tempInfo);
            return(1 - (Mathf.Max(tempSize.x, tempSize.y)) / maxFitValue);
        });

        //100次选出最优的图集方式
        mGeneOnlyData.EvolveGenes(20);
        var gen = mGeneOnlyData.GetBestFit();

        List <PngPartInfo> desInfo = new List <PngPartInfo>();

        for (int i = 0; i < gen._Code.Count; i++)
        {
            _ComputerRectPngPart(ppInfos[i], desInfo, gen._Code[i]);
            desInfo.Add(ppInfos[i]);
        }
        Vector2 mapSize = GetFitValue(desInfo);

        int       mapX        = (int)(mapSize.x) + 1;
        int       mapY        = (int)(mapSize.y) + 1;
        Texture2D fullTexture = new Texture2D(mapX, mapY, TextureFormat.RGBA32, false);

        Color[] fullTcolors = fullTexture.GetPixels();
        for (int i = 0; i < fullTcolors.Length; i++)
        {
            fullTcolors[i].a = 0;
            fullTcolors[i].r = 0;
            fullTcolors[i].g = 0;
            fullTcolors[i].b = 0;
        }
        fullTexture.SetPixels(fullTcolors);

        //合并图集
        for (int i = 0; i < desInfo.Count; i++)
        {
            var     info   = desInfo[i];
            Color[] colors = info.text2D.GetPixels();
            fullTexture.SetPixels((int)(info.bound.center.x - info.bound.extents.x), (int)(info.bound.center.y - info.bound.extents.y), info.text2D.width, info.text2D.height, colors);
        }

        byte[] full = fullTexture.EncodeToPNG();
        File.WriteAllBytes(texturePath, full);
        AssetDatabase.Refresh();
        texturePath = texturePath.Replace(Application.dataPath, "Assets");
        SetTextureImporter(texturePath);

        Texture texture = AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture)) as Texture;
        //生成字体
        Material fontMaterial = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material;

        if (fontMaterial == null)
        {
            fontMaterial             = new Material(Shader.Find("UI/Default"));
            fontMaterial.mainTexture = texture;
            AssetDatabase.CreateAsset(fontMaterial, materialPath);
        }
        else
        {
            fontMaterial.mainTexture = texture;
        }

        Font   assetFont           = AssetDatabase.LoadAssetAtPath(fontPath, typeof(Font)) as Font;
        string ApplicationDataPath = Application.dataPath.Replace("Assets", "") + fontPath;

        if (assetFont == null)
        {
            assetFont = new Font();
            AssetDatabase.CreateAsset(assetFont, fontPath);
        }

        assetFont.material = fontMaterial;

        CharacterInfo[] characters = new CharacterInfo[desInfo.Count];
        for (int i = 0; i < desInfo.Count; i++)
        {
            PngPartInfo   ppInfo = desInfo[i];
            CharacterInfo info   = new CharacterInfo();
            info.index        = ppInfo.index;
            info.uvBottomLeft = new Vector2((ppInfo.bound.center.x - ppInfo.bound.extents.x) / mapX, (ppInfo.bound.center.y - ppInfo.bound.extents.y) / mapY);
            info.uvTopRight   = new Vector2((ppInfo.bound.center.x + ppInfo.bound.extents.x) / mapX, (ppInfo.bound.center.y + ppInfo.bound.extents.y) / mapY);
            info.minX         = 0;
            info.minY         = -(int)ppInfo.text2D.height;
            info.maxX         = (int)ppInfo.text2D.width;
            info.maxY         = 0;
            info.advance      = (int)ppInfo.text2D.width;
            characters[i]     = info;
        }

        assetFont.characterInfo = characters;
        EditorUtility.SetDirty(assetFont);
        AssetDatabase.SaveAssets();
    }