Beispiel #1
0
    //TODO fix the filename of the textures as constant
    private void BuildBaseData()
    {
        #region Step1: Create Script

        GameObject pathDataObj = new GameObject();
        pathDataObj.name = "PathData";
        pathDataObj.transform.position = Vector3.zero;

        APahtData pathData = pathDataObj.AddComponent <APahtData>();

        #endregion

        #region Step2: Load HeightData and Obstacle 1

        EditorUtility.DisplayProgressBar("创建中", "正在创建行走数据以及高度法线数据, 1/34", 1 / 34.0f);

        Texture2D hTx = (Texture2D)EditorCommonFunctions.GetReadWritable(m_pGroundHeightmap);
        Texture2D nTx = (Texture2D)EditorCommonFunctions.GetReadWritable(m_pGroundNormalmap);
        pathData.m_fGridHeightData = new float[SceneConstant.m_iSceneSize * SceneConstant.m_iSceneSize];
        pathData.m_byGridStateData = new byte[SceneConstant.m_iSceneSize * SceneConstant.m_iSceneSize];
        pathData.m_v3NormalData    = new Vector3[SceneConstant.m_iSceneSize * SceneConstant.m_iSceneSize];

        for (int i = 0; i < SceneConstant.m_iSceneSize; ++i)
        {
            for (int j = 0; j < SceneConstant.m_iSceneSize; ++j)
            {
                pathData.m_fGridHeightData[i * SceneConstant.m_iSceneSize + j] = 4.0f * SceneConstant.m_fHighgroundHeight * (hTx.GetPixel(i, j).r - 0.5f);
                pathData.m_byGridStateData[i * SceneConstant.m_iSceneSize + j] = hTx.GetPixel(i, j).g > hTx.GetPixel(i, j).b
                    ? GridMath.m_byWalkable
                    : GridMath.m_byNoWalkable;
                Color cNormal = nTx.GetPixel(i, j);
                pathData.m_v3NormalData[i * SceneConstant.m_iSceneSize + j] = new Vector3(cNormal.r, cNormal.g, cNormal.b);
                pathData.m_v3NormalData[i * SceneConstant.m_iSceneSize + j] = (pathData.m_v3NormalData[i * SceneConstant.m_iSceneSize + j] - new Vector3(0.5f, 0.5f, 0.5f)) * 2.0f;
                pathData.m_v3NormalData[i * SceneConstant.m_iSceneSize + j].Normalize();
            }
        }

        #endregion

        #region Step3: Do Generate

        pathData.GenerateOptimaztion();

        #endregion

        EditorUtility.ClearProgressBar();
    }
    public static Texture2D GetTexture2DWithColor(Texture2D pMain, Texture2D pColor, Texture2D pShadow, Color cMain, Color cSub, bool bIsInv)
    {
        Texture2D pMainR = (Texture2D)EditorCommonFunctions.GetReadWritable(pMain);

        Color32[] pxMainR = pMainR.GetPixels32();
        Texture2D pColorR = (Texture2D)EditorCommonFunctions.GetReadWritable(pColor);

        Color32[] pxColorR = pColorR.GetPixels32();
        Texture2D pShadowR = (Texture2D)EditorCommonFunctions.GetReadWritable(pShadow);

        Color32[] pxShadowR = pShadowR.GetPixels32();
        int       iWidth    = Mathf.Max(pMainR.width, pColorR.width);
        int       iHeight   = Mathf.Max(pMainR.height, pColorR.height);
        Texture2D ret1      = new Texture2D(iWidth, iHeight, TextureFormat.RGB24, false);

        Color32[] res132_1 = new Color32[iWidth * iHeight];

        for (int i = 0; i < iWidth; ++i)
        {
            for (int j = 0; j < iHeight; ++j)
            {
                Color cMainTex   = pxMainR[(i * pMainR.width / iWidth) * pMainR.height + j * pMainR.height / iHeight];
                Color cColorTex  = pxColorR[(i * pColorR.width / iWidth) * pColorR.height + j * pColorR.height / iHeight];
                Color cShadowTex = pxShadowR[(i * pShadowR.width / iWidth) * pShadowR.height + j * pShadowR.height / iHeight];

                float shadowcol = Mathf.Clamp01((cShadowTex.r + 0.2f) * (1.0f + cColorTex.b * cColorTex.r));
                float rate      = cColorTex.b;
                float srate     = cColorTex.r;
                Color cor       = cSub * cColorTex.g + cMain * cColorTex.r;
                Color realC     = cMainTex * (1.0f - rate) + cor * rate;
                realC   = 1.5f * shadowcol * realC;
                realC.a = 1.0f;

                if (bIsInv)
                {
                    realC = (new Color(realC.r - 0.5f, realC.g - 0.5f, realC.b - 0.5f) * Mathf.Clamp(srate, 0.2f, 0.8f) + new Color(0.5f, 0.5f, 0.5f)) * 0.3f + 0.1f * cMain + 0.1f * Color.white;
                }

                res132_1[i * iHeight + j] = realC;
            }
        }
        ret1.SetPixels32(res132_1);
        return(ret1);
    }
Beispiel #3
0
    void OnWizardCreate()
    {
        #region Step1: Check files

        if (string.IsNullOrEmpty(TemplateName))
        {
            CRuntimeLogger.LogError("必须有个模板名称");
            return;
        }

        Texture2D heighttx = (Texture2D)EditorCommonFunctions.GetReadWritable(HeightMap);
        if (null == heighttx || SceneConstant.m_iHightmapSize != heighttx.width || SceneConstant.m_iHightmapSize != heighttx.height)
        {
            CRuntimeLogger.LogError(string.Format("必须是{0}x{0}的高度贴图,如果你的图片正确,可以检查下导入设置是否是Editor/GUI", SceneConstant.m_iHightmapSize));
            return;
        }
        Texture2D groundtx = (Texture2D)EditorCommonFunctions.GetReadWritable(GroundMap);
        if (null == groundtx || SceneConstant.m_iHightmapSize != groundtx.width || SceneConstant.m_iHightmapSize != groundtx.height)
        {
            CRuntimeLogger.LogError(string.Format("必须是{0}x{0}的地皮贴图,如果你的图片正确,可以检查下导入设置是否是Editor/GUI", SceneConstant.m_iHightmapSize));
            return;
        }
        Texture2D doctx = (Texture2D)EditorCommonFunctions.GetReadWritable(DocMap);
        if (null == doctx || SceneConstant.m_iDecoratemapSize != doctx.width || SceneConstant.m_iDecoratemapSize != doctx.height)
        {
            CRuntimeLogger.LogError(string.Format("必须是{0}x{0}的装饰贴图", SceneConstant.m_iDecoratemapSize));
            return;
        }

        #endregion

        #region Step2: Create

        string sGroundFileName = SceneConstant.m_sArtworkPath + "Templates/"
                                 + string.Format("T{0}X{0}", SceneConstant.m_iHightmapSize)
                                 + "/GenerateMesh/" + TemplateName + ".asset";

        Texture2D wmap, nmap;
        SceneEditorUtility.CreateGround(heighttx, groundtx, doctx, sGroundFileName, GroundType, false, out wmap, out nmap);


        CSceneTexture sceneTx = new CSceneTexture {
            m_sSceneType = GroundType
        };
        if (!sceneTx.Load() || 81 != sceneTx.m_pElement.Count)
        {
            CRuntimeLogger.LogError(GroundType + "贴图配置文件有问题");
            return;
        }

        CSceneGroudTemplate groundTemplate = new CSceneGroudTemplate {
            m_sSceneType = GroundType
        };
        if (!groundTemplate.Load())
        {
            CRuntimeLogger.LogError(GroundType + "贴图配置文件有问题");
            return;
        }

        CSceneType type = new CSceneType();
        type.Load();
        if (null == type[GroundType])
        {
            CRuntimeLogger.LogError(GroundType + "的配置找不到?");
            return;
        }

        #endregion

        #region Step3: Make Record

        CSceneTemplate templates = new CSceneTemplate();
        templates.Load();
        CSceneTemplateElement element = templates[TemplateName];
        if (null == element)
        {
            element = templates.CreateElement(TemplateName);
        }

        element.m_sDecoratePath = AssetDatabase.GetAssetPath(DocMap);
        element.m_sGroundPath   = AssetDatabase.GetAssetPath(GroundMap);
        element.m_sHeightPath   = AssetDatabase.GetAssetPath(HeightMap);

        templates.Save();

        #endregion
    }
Beispiel #4
0
    protected void BuildTextureDataWithFolder()
    {
        #region Step1: Find all files

        string sFolderTx = Application.dataPath + "/"
                           + SceneConstant.m_sArtworkPath
                           + TypeName
                           + SceneConstant.m_sSceneTexturesPath;
        string sFolderDoc = Application.dataPath + "/"
                            + SceneConstant.m_sArtworkPath
                            + TypeName
                            + SceneConstant.m_sDecoratesPath;

        CRuntimeLogger.Log("将从" + sFolderTx + "和" + sFolderDoc + "收集信息");
        DirectoryInfo dirtx  = new DirectoryInfo(sFolderTx);
        DirectoryInfo dirdoc = new DirectoryInfo(sFolderDoc);
        if (!dirtx.Exists || !dirdoc.Exists)
        {
            CRuntimeLogger.LogWarning("你选择目录内容不太对吧!");
            return;
        }

        List <FileInfo> allTextures = new List <FileInfo>();
        allTextures.AddRange(dirtx.GetFiles("*.png", SearchOption.AllDirectories));
        allTextures.AddRange(dirdoc.GetFiles("*.png", SearchOption.AllDirectories));
        List <FileInfo> allModels = dirdoc.GetFiles("*.fbx", SearchOption.AllDirectories).ToList();

        #endregion

        #region Step2: Create SceneType

        CSceneType scenetypes = new CSceneType();
        scenetypes.Load();
        if (null == scenetypes[TypeName])
        {
            CSceneTypeElement newType = scenetypes.CreateElement(TypeName);
            newType.m_bCanRot          = CanRotate;
            newType.m_eEdgeType        = EdgeType;
            newType.m_iCliffType       = CliffType;
            newType.m_bHasGroundOffset = HasGroundOffset;
        }
        else
        {
            scenetypes[TypeName].m_bCanRot          = CanRotate;
            scenetypes[TypeName].m_eEdgeType        = EdgeType;
            scenetypes[TypeName].m_iCliffType       = CliffType;
            scenetypes[TypeName].m_bHasGroundOffset = HasGroundOffset;
        }
        scenetypes.Save();

        #endregion

        #region Step3: Bake Texture Atlas

        Dictionary <int, int>          codes = new Dictionary <int, int>(new IntEqualityComparer());
        Dictionary <string, Texture2D> txDic = new Dictionary <string, Texture2D>();
        foreach (FileInfo fileInfo in allTextures)
        {
            string    sFileName  = CommonFunctions.GetLastName(fileInfo.FullName);
            string[]  twoparts   = sFileName.Split('_');
            string    sAssetPath = "Assets" + fileInfo.FullName.Replace("\\", "/").Replace(Application.dataPath.Replace("\\", "/"), "");
            Texture2D t1         = AssetDatabase.LoadAssetAtPath(sAssetPath, typeof(Texture2D)) as Texture2D;
            txDic.Add(sFileName, (Texture2D)EditorCommonFunctions.GetReadWritable(t1));

            //Check whether is a template texture
            int iCode, iRepeat;
            if (2 == twoparts.Length &&
                !string.IsNullOrEmpty(twoparts[0]) &&
                int.TryParse(twoparts[0].Substring(1, twoparts[0].Length - 1), out iCode) &&
                int.TryParse(twoparts[1], out iRepeat))
            {
                if (codes.ContainsKey(iCode))
                {
                    if (codes[iCode] < iRepeat)
                    {
                        codes[iCode] = iRepeat;
                    }
                }
                else
                {
                    codes.Add(iCode, iRepeat);
                }
            }
        }

        Dictionary <string, Rect> textureDic = EditorCommonFunctions.PackTexture(
            txDic,
            SceneConstant.m_sArtworkPath
            + TypeName
            + SceneConstant.m_sSceneTexturesPath,
            Shader.Find("Mobile/Unlit (Supports Lightmap)"), EditorCommonFunctions.EPackColorFormat.ForcePng);

        #endregion

        #region Step4: Make template

        CSceneGroudTemplate tamplate = new CSceneGroudTemplate {
            m_sSceneType = TypeName
        };

        foreach (KeyValuePair <string, Rect> kvp in textureDic)
        {
            CSceneGroudTemplateElement newGT = tamplate.CreateElement();
            tamplate.ChangeName(newGT.m_sElementName, kvp.Key);
            newGT.m_vUV = CommonFunctions.Rect2V4(kvp.Value);
        }
        tamplate.Save();

        #endregion

        #region Step5: Make Scene Texture

        CSceneTexture newT = new CSceneTexture {
            m_sSceneType = TypeName
        };

        for (int lt = 0; lt < 3; ++lt)
        {
            for (int rt = 0; rt < 3; ++rt)
            {
                for (int rb = 0; rb < 3; ++rb)
                {
                    for (int lb = 0; lb < 3; ++lb)
                    {
                        int  iCode, iRots;
                        bool bFlip;
                        FindCodeAndRot(codes, lt, rt, rb, lb, out iCode, out iRots, out bFlip);
                        if (iCode < 0)
                        {
                            CRuntimeLogger.LogError(string.Format("组合没有找到{0}-{1}-{2}-{3}", lt, rt, rb, lb));
                            return;
                        }

                        CSceneTextureElement newE = newT.CreateElement();

                        int iCode2 = lt * CommonFunctions.IntPow(3, 0)
                                     + rt * CommonFunctions.IntPow(3, 1)
                                     + rb * CommonFunctions.IntPow(3, 2)
                                     + lb * CommonFunctions.IntPow(3, 3);
                        newT.ChangeName(newE.m_sElementName, "T" + iCode2);
                        if (iCode2 != newE.m_iID)
                        {
                            newT.ChangeId(newE.m_iID, iCode2);
                        }

                        newE.m_iTemplate     = iCode;
                        newE.m_iRotNumber    = iRots;
                        newE.m_iTextureCount = codes[iCode];
                        newE.m_bReflect      = bFlip;
                    }
                }
            }
        }

        newT.Save();

        #endregion

        #region Step6: Make Decorate

        Dictionary <int, string> modelTemplates = new Dictionary <int, string>(new IntEqualityComparer());
        Dictionary <int, int>    modelRepeates  = new Dictionary <int, int>(new IntEqualityComparer());
        foreach (FileInfo fileInfo in allModels)
        {
            string   sFileName  = CommonFunctions.GetLastName(fileInfo.FullName);
            string[] twoparts   = sFileName.Split('_');
            string   sAssetPath = "Assets" + fileInfo.FullName.Replace("\\", "/").Replace(Application.dataPath.Replace("\\", "/"), "");

            //Check whether is a template texture
            int iCode, iRepeat;
            if (3 == twoparts.Length &&
                int.TryParse(twoparts[1], out iCode) &&
                int.TryParse(twoparts[2], out iRepeat) &&
                iCode < 3 && iCode >= 0)
            {
                //Make template data
                if (!modelTemplates.ContainsKey(iCode))
                {
                    modelTemplates.Add(iCode, twoparts[0] + "_" + iCode);
                }

                if (!modelRepeates.ContainsKey(iCode))
                {
                    modelRepeates.Add(iCode, iRepeat);
                }
                else if (modelRepeates[iCode] < iRepeat)
                {
                    modelRepeates[iCode] = iRepeat;
                }

                //Make the mesh
                List <Vector3> verts    = new List <Vector3>();
                List <Vector2> uvs      = new List <Vector2>();
                List <int>     trangles = new List <int>();

                GameObject go = AssetDatabase.LoadMainAssetAtPath(sAssetPath) as GameObject;
                if (null != go)
                {
                    foreach (MeshFilter mf in go.GetComponentsInChildren <MeshFilter>(true))
                    {
                        Mesh editablemesh = (Mesh)EditorCommonFunctions.GetReadWritable(mf.sharedMesh);
                        int  iVertCount   = verts.Count;
                        Rect rct;

                        MeshRenderer mr = mf.gameObject.GetComponent <MeshRenderer>();
                        if (null != mr && null != mr.sharedMaterial && null != mr.sharedMaterial.mainTexture &&
                            textureDic.ContainsKey(mr.sharedMaterial.mainTexture.name))
                        {
                            rct = textureDic[mr.sharedMaterial.mainTexture.name];
                        }
                        else if (textureDic.ContainsKey(editablemesh.name))
                        {
                            rct = textureDic[editablemesh.name];
                        }
                        else
                        {
                            CRuntimeLogger.LogWarning("Mesh找不到贴图:" + sAssetPath);
                            return;
                        }

                        if (mf.transform == go.transform)
                        {
                            verts.AddRange(editablemesh.vertices);
                        }
                        else
                        {
                            for (int i = 0; i < editablemesh.vertices.Length; ++i)
                            {
                                Vector3 worldPos = mf.transform.localToWorldMatrix.MultiplyVector(editablemesh.vertices[i]) + mf.transform.position;
                                verts.Add(go.transform.worldToLocalMatrix.MultiplyVector(worldPos - go.transform.position));
                            }
                        }
                        for (int i = 0; i < editablemesh.uv.Length; ++i)
                        {
                            float fX = Mathf.Clamp01(editablemesh.uv[i].x);
                            float fY = Mathf.Clamp01(editablemesh.uv[i].y);
                            uvs.Add(new Vector2(rct.xMin + rct.width * fX, rct.yMin + rct.height * fY));
                        }
                        for (int i = 0; i < editablemesh.triangles.Length; ++i)
                        {
                            trangles.Add(iVertCount + editablemesh.triangles[i]);
                        }
                    }
                }
                Mesh theMesh = new Mesh {
                    vertices = verts.ToArray(), uv = uvs.ToArray(), triangles = trangles.ToArray()
                };
                theMesh.RecalculateNormals();
                Unwrapping.GenerateSecondaryUVSet(theMesh);
                ;
                AssetDatabase.CreateAsset(theMesh, "Assets/"
                                          + SceneConstant.m_sArtworkPath + TypeName
                                          + SceneConstant.m_sDecoratesPath
                                          + "/Generate/" + sFileName + ".asset");
            }
        }

        CSceneDecorate doc = new CSceneDecorate {
            m_sSceneType = TypeName
        };
        CSceneDecorate olddoc = new CSceneDecorate {
            m_sSceneType = TypeName
        };
        olddoc.Load();
        foreach (KeyValuePair <int, string> kvp in modelTemplates)
        {
            CSceneDecorateElement element = doc.CreateElement(kvp.Value);
            if (element.m_iID != kvp.Key)
            {
                doc.ChangeId(element.m_iID, kvp.Key);
            }
            element.m_iDecrateRepeat = modelRepeates[kvp.Key];
            if (null != olddoc[kvp.Key])
            {
                element.m_bBlockPathfinding = olddoc[kvp.Key].m_bBlockPathfinding;
                element.m_iDecrateSize      = olddoc[kvp.Key].m_iDecrateSize;
                element.m_bOnlyRotateY      = olddoc[kvp.Key].m_bOnlyRotateY;
            }
        }
        doc.Save();
        AssetDatabase.Refresh();

        #endregion
    }
Beispiel #5
0
    protected void OnGUI()
    {
        if (null == m_pAllTemplates || null == m_sTemplateChooses || 0 == m_sTemplateChooses.Length)
        {
            EditorGUILayout.HelpBox("创建的模板并没有找到!", MessageType.Error);
            return;
        }

        int iIndex1 = 0;
        int iIndex2 = 0;

        for (int i = 0; i < m_sTemplateChooses.Length; ++i)
        {
            if (!string.IsNullOrEmpty(m_sT1) && m_sT1.Equals(m_sTemplateChooses[i]))
            {
                iIndex1 = i;
            }
            if (!string.IsNullOrEmpty(m_sT2) && m_sT2.Equals(m_sTemplateChooses[i]))
            {
                iIndex2 = i;
            }
        }

        //Choose Template 1
        EditorGUILayout.BeginHorizontal();
        int iChoose1 = EditorGUILayout.Popup("选择模板1", iIndex1, m_sTemplateChooses);

        m_sT1    = m_sTemplateChooses[iChoose1];
        m_iRot1  = EditorGUILayout.IntField("旋转次数", m_iRot1);
        m_bFlip1 = EditorGUILayout.Toggle("是否翻转", m_bFlip1);
        EditorGUILayout.EndHorizontal();

        //Choose Template 2
        EditorGUILayout.BeginHorizontal();
        int iChoose2 = EditorGUILayout.Popup("选择模板2", iIndex2, m_sTemplateChooses);

        m_sT2    = m_sTemplateChooses[iChoose2];
        m_iRot2  = EditorGUILayout.IntField("旋转次数", m_iRot2);
        m_bFlip2 = EditorGUILayout.Toggle("是否翻转", m_bFlip2);
        EditorGUILayout.EndHorizontal();

        bool bGenerateLittleMap = false;

        if (GUILayout.Button("随机生成"))
        {
            bGenerateLittleMap = true;
            m_sT1    = m_sTemplateChooses[Random.Range(0, m_sTemplateChooses.Length)];
            m_sT2    = m_sTemplateChooses[Random.Range(0, m_sTemplateChooses.Length)];
            m_iRot1  = Random.Range(0, 4);
            m_iRot2  = Random.Range(0, 4);
            m_bFlip1 = Random.Range(0.0f, 1.0f) > 0.5f;
            m_bFlip2 = Random.Range(0.0f, 1.0f) > 0.5f;
        }

        if (GUILayout.Button("看看小地图") || bGenerateLittleMap)
        {
            m_pHTexture = new Texture2D(SceneConstant.m_iSceneHeightMapSize, SceneConstant.m_iSceneHeightMapSize, TextureFormat.RGB565, false);
            m_pGTexture = new Texture2D(SceneConstant.m_iSceneHeightMapSize, SceneConstant.m_iSceneHeightMapSize, TextureFormat.RGB565, false);
            m_pDTexture = new Texture2D(SceneConstant.m_iSceneSize, SceneConstant.m_iSceneSize, TextureFormat.RGB565, false);

            Texture2D ht1 = (Texture2D)EditorCommonFunctions.GetReadWritable(
                AssetDatabase.LoadAssetAtPath <Texture2D>(m_pAllTemplates[m_sT1].m_sHeightPath));
            Texture2D ht2 = (Texture2D)EditorCommonFunctions.GetReadWritable(
                AssetDatabase.LoadAssetAtPath <Texture2D>(m_pAllTemplates[m_sT2].m_sHeightPath));

            Texture2D gt1 = (Texture2D)EditorCommonFunctions.GetReadWritable(
                AssetDatabase.LoadAssetAtPath <Texture2D>(m_pAllTemplates[m_sT1].m_sGroundPath));
            Texture2D gt2 = (Texture2D)EditorCommonFunctions.GetReadWritable(
                AssetDatabase.LoadAssetAtPath <Texture2D>(m_pAllTemplates[m_sT2].m_sGroundPath));

            Texture2D dt1 = (Texture2D)EditorCommonFunctions.GetReadWritable(
                AssetDatabase.LoadAssetAtPath <Texture2D>(m_pAllTemplates[m_sT1].m_sDecoratePath));
            Texture2D dt2 = (Texture2D)EditorCommonFunctions.GetReadWritable(
                AssetDatabase.LoadAssetAtPath <Texture2D>(m_pAllTemplates[m_sT2].m_sDecoratePath));

            for (int i = 0; i < 2 * SceneConstant.m_iHightmapSize - 1; ++i)
            {
                for (int j = 0; j < 2 * SceneConstant.m_iHightmapSize - 1; ++j) //0-64
                {
                    //0-31, 0-31
                    if (i < SceneConstant.m_iHightmapSize - 1 && j < SceneConstant.m_iHightmapSize - 1)
                    {
                        m_pHTexture.SetPixel(i, j, GetPixel(ht2, i, j, m_iRot2 + 2, m_bFlip2));
                        m_pGTexture.SetPixel(i, j, GetPixel(gt2, i, j, m_iRot2 + 2, m_bFlip2));
                    }
                    //33-64, 0-31
                    else if (i > SceneConstant.m_iHightmapSize - 1 && j < SceneConstant.m_iHightmapSize - 1)
                    {
                        m_pHTexture.SetPixel(i, j, GetPixel(ht1, i - SceneConstant.m_iHightmapSize + 1, j, m_iRot1 + 2, m_bFlip1));
                        m_pGTexture.SetPixel(i, j, GetPixel(gt1, i - SceneConstant.m_iHightmapSize + 1, j, m_iRot1 + 2, m_bFlip1));
                    }
                    else if (i > SceneConstant.m_iHightmapSize - 1 && j > SceneConstant.m_iHightmapSize - 1)
                    {
                        m_pHTexture.SetPixel(i, j, GetPixel(ht2, i - SceneConstant.m_iHightmapSize + 1, j - SceneConstant.m_iHightmapSize + 1, m_iRot2, m_bFlip2));
                        m_pGTexture.SetPixel(i, j, GetPixel(gt2, i - SceneConstant.m_iHightmapSize + 1, j - SceneConstant.m_iHightmapSize + 1, m_iRot2, m_bFlip2));
                    }
                    else if (i < SceneConstant.m_iHightmapSize - 1 && j > SceneConstant.m_iHightmapSize - 1)
                    {
                        m_pHTexture.SetPixel(i, j, GetPixel(ht1, i, j - SceneConstant.m_iHightmapSize + 1, m_iRot1, m_bFlip1));
                        m_pGTexture.SetPixel(i, j, GetPixel(gt1, i, j - SceneConstant.m_iHightmapSize + 1, m_iRot1, m_bFlip1));
                    }

                    else if (i == SceneConstant.m_iHightmapSize - 1 && j < SceneConstant.m_iHightmapSize - 1)
                    {
                        Color hc1 = GetPixel(ht2, i, j, m_iRot2 + 2, m_bFlip2);
                        Color hc2 = GetPixel(ht1, i - SceneConstant.m_iHightmapSize + 1, j, m_iRot1 + 2, m_bFlip1);
                        m_pHTexture.SetPixel(i, j, hc1 * 0.5f + hc2 * 0.5f);
                        Color gc1 = GetPixel(gt2, i, j, m_iRot2 + 2, m_bFlip2);
                        Color gc2 = GetPixel(gt1, i - SceneConstant.m_iHightmapSize + 1, j, m_iRot1 + 2, m_bFlip1);
                        m_pGTexture.SetPixel(i, j, gc1 * 0.5f + gc2 * 0.5f);
                    }
                    else if (i == SceneConstant.m_iHightmapSize - 1 && j > SceneConstant.m_iHightmapSize - 1)
                    {
                        Color hc1 = GetPixel(ht2, i - SceneConstant.m_iHightmapSize + 1, j - SceneConstant.m_iHightmapSize + 1, m_iRot2, m_bFlip2);
                        Color hc2 = GetPixel(ht1, i, j - SceneConstant.m_iHightmapSize + 1, m_iRot1, m_bFlip1);
                        m_pHTexture.SetPixel(i, j, hc1 * 0.5f + hc2 * 0.5f);
                        Color gc1 = GetPixel(gt2, i - SceneConstant.m_iHightmapSize + 1, j - SceneConstant.m_iHightmapSize + 1, m_iRot2, m_bFlip2);
                        Color gc2 = GetPixel(gt1, i, j - SceneConstant.m_iHightmapSize + 1, m_iRot1, m_bFlip1);
                        m_pGTexture.SetPixel(i, j, gc1 * 0.5f + gc2 * 0.5f);
                    }
                    else if (i > SceneConstant.m_iHightmapSize - 1 && j == SceneConstant.m_iHightmapSize - 1)
                    {
                        Color hc1 = GetPixel(ht1, i - SceneConstant.m_iHightmapSize + 1, j, m_iRot1 + 2, m_bFlip1);
                        Color hc2 = GetPixel(ht2, i - SceneConstant.m_iHightmapSize + 1, j - SceneConstant.m_iHightmapSize + 1, m_iRot2, m_bFlip2);
                        m_pHTexture.SetPixel(i, j, hc1 * 0.5f + hc2 * 0.5f);
                        Color gc1 = GetPixel(gt1, i - SceneConstant.m_iHightmapSize + 1, j, m_iRot1 + 2, m_bFlip1);
                        Color gc2 = GetPixel(gt2, i - SceneConstant.m_iHightmapSize + 1, j - SceneConstant.m_iHightmapSize + 1, m_iRot2, m_bFlip2);
                        m_pGTexture.SetPixel(i, j, gc1 * 0.5f + gc2 * 0.5f);
                    }
                    else if (i < SceneConstant.m_iHightmapSize - 1 && j == SceneConstant.m_iHightmapSize - 1)
                    {
                        Color hc1 = GetPixel(ht2, i, j, m_iRot2 + 2, m_bFlip2);
                        Color hc2 = GetPixel(ht1, i, j - SceneConstant.m_iHightmapSize + 1, m_iRot1, m_bFlip1);
                        m_pHTexture.SetPixel(i, j, hc1 * 0.5f + hc2 * 0.5f);
                        Color gc1 = GetPixel(gt2, i, j, m_iRot2 + 2, m_bFlip2);
                        Color gc2 = GetPixel(gt1, i, j - SceneConstant.m_iHightmapSize + 1, m_iRot1, m_bFlip1);
                        m_pGTexture.SetPixel(i, j, gc1 * 0.5f + gc2 * 0.5f);
                    }

                    else if (i == SceneConstant.m_iHightmapSize - 1 && j == SceneConstant.m_iHightmapSize - 1)
                    {
                        Color hc1 = GetPixel(ht2, i, j, m_iRot2 + 2, m_bFlip2);
                        Color hc2 = GetPixel(ht1, i - SceneConstant.m_iHightmapSize + 1, j, m_iRot1 + 2, m_bFlip1);
                        Color hc3 = GetPixel(ht2, i - SceneConstant.m_iHightmapSize + 1, j - SceneConstant.m_iHightmapSize + 1, m_iRot2, m_bFlip2);
                        Color hc4 = GetPixel(ht1, i, j - SceneConstant.m_iHightmapSize + 1, m_iRot1, m_bFlip1);
                        m_pHTexture.SetPixel(i, j, hc1 * 0.25f + hc2 * 0.25f + hc3 * 0.25f + hc4 * 0.25f);

                        Color gc1 = GetPixel(gt2, i, j, m_iRot2 + 2, m_bFlip2);
                        Color gc2 = GetPixel(gt1, i - SceneConstant.m_iHightmapSize + 1, j, m_iRot1 + 2, m_bFlip1);
                        Color gc3 = GetPixel(gt2, i - SceneConstant.m_iHightmapSize + 1, j - SceneConstant.m_iHightmapSize + 1, m_iRot2, m_bFlip2);
                        Color gc4 = GetPixel(gt1, i, j - SceneConstant.m_iHightmapSize + 1, m_iRot1, m_bFlip1);
                        m_pGTexture.SetPixel(i, j, gc1 * 0.25f + gc2 * 0.25f + gc3 * 0.25f + gc4 * 0.25f);
                    }

                    if (i < 2 * SceneConstant.m_iHightmapSize - 2 && j < 2 * SceneConstant.m_iHightmapSize - 2)
                    {
                        //0-31, 0-31
                        if (i < SceneConstant.m_iHightmapSize - 1 && j < SceneConstant.m_iHightmapSize - 1)
                        {
                            m_pDTexture.SetPixel(i, j, GetPixel(dt2, i, j, m_iRot2 + 2, m_bFlip2));
                        }
                        //32-63, 0-31
                        else if (i >= SceneConstant.m_iHightmapSize - 1 && j < SceneConstant.m_iHightmapSize - 1)
                        {
                            m_pDTexture.SetPixel(i, j, GetPixel(dt1, i - SceneConstant.m_iHightmapSize + 1, j, m_iRot1 + 2, m_bFlip1));
                        }
                        else if (i >= SceneConstant.m_iHightmapSize - 1 && j >= SceneConstant.m_iHightmapSize - 1)
                        {
                            m_pDTexture.SetPixel(i, j, GetPixel(dt2, i - SceneConstant.m_iHightmapSize + 1, j - SceneConstant.m_iHightmapSize + 1, m_iRot2, m_bFlip2));
                        }
                        else if (i < SceneConstant.m_iHightmapSize - 1 && j >= SceneConstant.m_iHightmapSize - 1)
                        {
                            m_pDTexture.SetPixel(i, j, GetPixel(dt1, i, j - SceneConstant.m_iHightmapSize + 1, m_iRot1, m_bFlip1));
                        }
                    }
                }
            }

            m_pHTexture.Apply();
            m_pGTexture.Apply();
            m_pDTexture.Apply();
        }

        EditorGUILayout.BeginHorizontal();

        if (null != m_pHTexture)
        {
            GUILayout.Box(m_pHTexture);
        }
        if (null != m_pGTexture)
        {
            GUILayout.Box(m_pGTexture);
        }
        if (null != m_pDTexture)
        {
            GUILayout.Box(m_pDTexture);
        }

        EditorGUILayout.EndHorizontal();

        if (null != m_pHTexture && null != m_pGTexture && null != m_pDTexture)
        {
            m_sGroundType      = EditorGUILayout.TextField("地图类型:", m_sGroundType);
            m_eSceneEdge       = (ESceneEdgeType)EditorGUILayout.EnumPopup("包边", m_eSceneEdge);
            m_sBattleFieldName = EditorGUILayout.TextField("战场文件名称:", m_sBattleFieldName);
            if (!string.IsNullOrEmpty(m_sBattleFieldName) && null != m_pSceneType[m_sGroundType])
            {
                if (GUILayout.Button("生成场景"))
                {
                    BakeEdge(m_pHTexture, m_pGTexture, m_pDTexture, m_eSceneEdge);

                    m_pWTexture = new Texture2D(SceneConstant.m_iSceneSize, SceneConstant.m_iSceneSize, TextureFormat.RGB565, false);
                    m_pNTexture = new Texture2D(SceneConstant.m_iSceneSize, SceneConstant.m_iSceneSize, TextureFormat.RGB565, false);

                    //Save textures
                    CommonFunctions.CreateFolder(Application.dataPath + "/" + SceneConstant.m_sArtworkPath + "BattleFields/" + m_sBattleFieldName + "/?");
                    File.WriteAllBytes(Application.dataPath + "/" + SceneConstant.m_sArtworkPath + "BattleFields/" + m_sBattleFieldName + "/Heightmap.png", m_pHTexture.EncodeToPNG());
                    File.WriteAllBytes(Application.dataPath + "/" + SceneConstant.m_sArtworkPath + "BattleFields/" + m_sBattleFieldName + "/Griundmap.png", m_pGTexture.EncodeToPNG());
                    File.WriteAllBytes(Application.dataPath + "/" + SceneConstant.m_sArtworkPath + "BattleFields/" + m_sBattleFieldName + "/Decoratemap.png", m_pDTexture.EncodeToPNG());

                    Texture2D wmap, nmap;
                    SceneEditorUtility.CreateGround(m_pHTexture, m_pGTexture, m_pDTexture, SceneConstant.m_sArtworkPath + "BattleFields/" + m_sBattleFieldName + ".asset", m_sGroundType, true, out wmap, out nmap);

                    File.WriteAllBytes(Application.dataPath + "/" + SceneConstant.m_sArtworkPath + "BattleFields/" + m_sBattleFieldName + "/Walkmap.png", wmap.EncodeToPNG());
                    File.WriteAllBytes(Application.dataPath + "/" + SceneConstant.m_sArtworkPath + "BattleFields/" + m_sBattleFieldName + "/Normalmap.png", nmap.EncodeToPNG());
                }
            }
        }
    }
    public static void MakeAtlasReplaceWithCloth(GameObject pObj, string sParentFolder)
    {
        #region Step0: Count Progress

        int             iMC            = (int)ECharactorMainColor.ECMC_Max;
        int             iSC            = (int)ECharactorSubColor.ECSC_Max + 1;
        List <string[]> combineList    = GetHumanoidCombineList();
        int             iProgressCount = pObj.GetComponentsInChildren <MeshRenderer>(true).Length + combineList.Count;
        int             iProgressFull  = iProgressCount * (2 + 3 * iMC * iSC);
        int             iProgressNow   = 0;

        #endregion

        #region Step1: make gameobject table and make dirs (1x)

        CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Textures/?");
        for (int i = 0; i < iMC; ++i)
        {
            for (int j = 0; j < iSC; ++j)
            {
                CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Resources/CharMesh/" + string.Format("M{0}S{1}/?", i, j));
            }
        }

        List <SCharRendererFullInfo>     info = new List <SCharRendererFullInfo>();
        Dictionary <string, Texture2D[]> contextureCombine = new Dictionary <string, Texture2D[]>();
        Dictionary <string, int>         infoIndex         = new Dictionary <string, int>();
        foreach (MeshRenderer renderer in pObj.GetComponentsInChildren <MeshRenderer>(true))
        {
            ++iProgressNow;
            EditorUtility.DisplayProgressBar("正在收集Renderer信息", string.Format("{0}/{1}", iProgressNow, iProgressFull),
                                             iProgressNow / (float)iProgressFull);

            Texture2D mainTex  = renderer.sharedMaterial.GetTexture("_MainTex") as Texture2D;
            Texture2D colorTex = renderer.sharedMaterial.GetTexture("_ColorTex") as Texture2D;
            Texture2D shaTex   = renderer.sharedMaterial.GetTexture("_ShadowTex") as Texture2D;

            if (null == mainTex || null == colorTex || null == shaTex)
            {
                CRuntimeLogger.LogError("有的材质没有贴图: " + CommonFunctions.FindFullName(pObj, renderer.gameObject));
                EditorUtility.ClearProgressBar();
                return;
            }

            string sTextureName = CommonFunctions.BuildStringOrder(new[] { mainTex.name, colorTex.name, shaTex.name });
            Mesh   mesh         = renderer.gameObject.GetComponent <MeshFilter>().sharedMesh;

            info.Add(new SCharRendererFullInfo
            {
                m_sFullTexName     = sTextureName,
                m_pMesh            = mesh,
                m_sMeshFilterName  = AssetDatabase.GetAssetPath(mesh),
                m_sMeshName        = mesh.name,
                m_pObj             = renderer.gameObject,
                m_sObjectPath      = CommonFunctions.FindFullName(pObj, renderer.gameObject),
                m_pMainTexture     = mainTex,
                m_pColorTexture    = colorTex,
                m_pShaTexture      = shaTex,
                m_pCombinedMesh    = new Mesh[0],
                m_bDiscard         = false,
                m_pCombinedMeshObj = null,
                m_bCombine         = false,
            });
            infoIndex.Add(CommonFunctions.FindFullName(pObj, renderer.gameObject), info.Count - 1);
            if (!contextureCombine.ContainsKey(sTextureName))
            {
                contextureCombine.Add(sTextureName, new[] { mainTex, colorTex, shaTex });
            }
        }

        iProgressNow = iProgressCount;

        #endregion

        #region Step2: make colored textures (20x)

        CCharactorColor colors = new CCharactorColor();
        colors.Load();
        Dictionary <string, Texture2D> outTexture = new Dictionary <string, Texture2D>();
        for (int i = 0; i < iMC; ++i)
        {
            for (int j = 0; j < iSC; ++j)
            {
                Color mainC = colors[string.Format("M{0}", i + 1)].m_cColor;
                Color subC  = Color.white * 0.7f;
                if (j < (int)ECharactorSubColor.ECSC_Max)
                {
                    subC = colors[string.Format("S{0}", j + 1)].m_cColor;
                }

                foreach (KeyValuePair <string, Texture2D[]> kvp in contextureCombine)
                {
                    ++iProgressNow;
                    EditorUtility.DisplayProgressBar("正在阵营着色", string.Format("{0}/{1}", iProgressNow, iProgressFull),
                                                     iProgressNow / (float)iProgressFull);
                    Texture2D outPutT = GetTexture2DWithColor(kvp.Value[0], kvp.Value[1], kvp.Value[2], mainC, subC, j == (int)ECharactorSubColor.ECSC_Max);
                    outTexture.Add(string.Format("{0}_M{1}S{2}", kvp.Key, i, j), outPutT);
                }
                iProgressNow = (i * iSC + j + 2) * iProgressCount;
            }
        }

        Shader unlit                     = Shader.Find("Unlit/Texture");
        string sPackTextureName          = sParentFolder + "/Textures/" + unlit.name.Replace("/", "_").Replace(".", "_");
        Dictionary <string, Rect> packed = EditorCommonFunctions.PackTexture(outTexture, sPackTextureName, unlit, EditorCommonFunctions.EPackColorFormat.ForcePng);

        #endregion

        #region Step3: Combine Batch (1x)

        List <string> sDisableList = new List <string>();
        foreach (string[] combines in combineList)
        {
            ++iProgressNow;
            EditorUtility.DisplayProgressBar("正在收集合并Batch信息", string.Format("{0}/{1}", iProgressNow, iProgressFull),
                                             iProgressNow / (float)iProgressFull);

            GameObject            parent = info[infoIndex[pObj.name + "/" + combines[0]]].m_pObj;
            SCharRendererFullInfo cmb    = new SCharRendererFullInfo
            {
                m_sObjectPath       = CommonFunctions.FindFullName(pObj, parent.transform.parent.gameObject) + "/",
                m_bDiscard          = false,
                m_pObj              = null,
                m_pTransfParentPath = pObj.name + "/" + combines[0],
                m_bCombine          = true,
            };
            string            sMeshFilterName = "";
            List <GameObject> cmbobjs         = new List <GameObject>();
            List <Mesh>       cmbmeshes       = new List <Mesh>();
            List <string>     cmbtextures     = new List <string>();

            foreach (string t in combines)
            {
                if (!sDisableList.Contains(pObj.name + "/" + t))
                {
                    sDisableList.Add(pObj.name + "/" + t);
                }
                GameObject theObj = info[infoIndex[pObj.name + "/" + t]].m_pObj;
                cmb.m_sObjectPath += theObj.name;
                sMeshFilterName   += theObj.name;
                cmbobjs.Add(theObj);
                cmbmeshes.Add(info[infoIndex[pObj.name + "/" + t]].m_pMesh);
                cmbtextures.Add(info[infoIndex[pObj.name + "/" + t]].m_sFullTexName);
            }
            cmb.m_pCombinedMeshObj = cmbobjs.ToArray();
            cmb.m_pCombinedMesh    = cmbmeshes.ToArray();
            cmb.m_sTextureNames    = cmbtextures.ToArray();
            cmb.m_sMeshFilterName  = sMeshFilterName;
            info.Add(cmb);
        }

        foreach (string namecmbdisable in sDisableList)
        {
            info[infoIndex[namecmbdisable]].m_bDiscard = true;
        }

        iProgressNow = (2 + iMC * iSC) * iProgressCount;

        #endregion

        #region Step4: Create Meshes (20x)

        Dictionary <string, string> meshDic = CreateMeshes(info.ToArray(), packed,
                                                           sParentFolder + "/Resources/CharMesh/", iProgressNow, iProgressFull, iMC, iSC);
        AssetDatabase.Refresh();
        iProgressNow = (2 + iMC * iSC * 2) * iProgressCount;

        #endregion

        #region Step5: Assemble Game Objects (20x)

        //Create the matrix
        for (int i = 0; i < iMC; ++i)
        {
            for (int j = 0; j < iSC; ++j)
            {
                CreateObj(i, j, info, meshDic, "Assets/" + sPackTextureName + ".mat", pObj, iProgressNow, iProgressFull);
                iProgressNow = ((2 + iMC * iSC * 2) + ((i * iSC) + j + 1)) * iProgressCount;
            }
        }

        #endregion

        EditorUtility.ClearProgressBar();
    }
    public static Dictionary <string, string> CreateMeshes(SRendererInfo[] mesh, Dictionary <string, Rect> rectList, string sFileName, int iProgress, int iProgressFull)
    {
        Dictionary <string, string> ret = new Dictionary <string, string>();

        //Load Mesh
        foreach (SRendererInfo info in mesh)
        {
            Mesh theMesh  = EditorCommonFunctions.LoadMeshAtPathWithName(info.m_sMeshFilterName, info.m_pMesh.name);
            Mesh theMesh2 = new Mesh();
            ++iProgress;
            EditorUtility.DisplayProgressBar("正在生成Atlas模型", string.Format("{0}/{1}", iProgress, iProgressFull),
                                             iProgress / (float)iProgressFull);
            List <Vector3> list1 = new List <Vector3>();
            for (int i = 0; i < theMesh.vertices.Length; ++i)
            {
                list1.Add(theMesh.vertices[i]);
            }
            theMesh2.vertices = list1.ToArray();

            List <int> list2 = new List <int>();
            for (int i = 0; i < theMesh.triangles.Length; ++i)
            {
                list2.Add(theMesh.triangles[i]);
            }
            theMesh2.triangles = list2.ToArray();

            List <Vector2> list3 = new List <Vector2>();
            for (int i = 0; i < theMesh.uv.Length; ++i)
            {
                Vector2 vUV = theMesh.uv[i];
                if (theMesh.uv[i].x <-0.01f || theMesh.uv[i].y <-0.01f || theMesh.uv[i].x> 1.01f || theMesh.uv[i].y> 1.01f)
                {
                    CRuntimeLogger.LogWarning("UV is not in 0 - 1, clampled!: FBX:" +
                                              CommonFunctions.GetLastName(info.m_sMeshFilterName)
                                              + " Model:" + info.m_pMesh.name);
                    vUV.x = Mathf.Repeat(theMesh.uv[i].x, 1.0f);
                    vUV.y = Mathf.Repeat(theMesh.uv[i].y, 1.0f);
                }
                else
                {
                    vUV.x = Mathf.Clamp01(theMesh.uv[i].x);
                    vUV.y = Mathf.Clamp01(theMesh.uv[i].y);
                }
                Rect rect = rectList[info.m_sTextureName];
                list3.Add(new Vector2(vUV.x * rect.width + rect.xMin, vUV.y * rect.height + rect.yMin));
            }
            theMesh2.uv = list3.ToArray();

            List <Vector2> list4 = new List <Vector2>();
            for (int i = 0; i < theMesh.uv2.Length; ++i)
            {
                list4.Add(theMesh.uv2[i]);
            }
            theMesh2.uv2 = list4.ToArray();

            List <Vector3> list5 = new List <Vector3>();
            for (int i = 0; i < theMesh.normals.Length; ++i)
            {
                list5.Add(theMesh.normals[i]);
            }
            theMesh2.normals = list5.ToArray();

            List <Color> list6 = new List <Color>();
            for (int i = 0; i < theMesh.colors.Length; ++i)
            {
                list6.Add(theMesh.colors[i]);
            }
            theMesh2.colors = list6.ToArray();

            List <Vector4> list7 = new List <Vector4>();
            for (int i = 0; i < theMesh.tangents.Length; ++i)
            {
                list7.Add(theMesh.tangents[i]);
            }
            theMesh2.tangents = list7.ToArray();

            ;

            //Create Mesh
            string sName   = "f_" + CommonFunctions.GetLastName(info.m_sMeshFilterName) + "_m_" + info.m_pMesh.name + "_t_" + info.m_pTexture.name;
            string thePath = "Assets/" + sFileName + sName + ".asset";
            AssetDatabase.CreateAsset(theMesh2, thePath);
            AssetDatabase.Refresh();
            if (ret.ContainsKey(sName))
            {
                CRuntimeLogger.LogError("有mesh的FBX文件重名!");
            }
            else
            {
                ret.Add(sName, thePath);
            }
        }

        return(ret);
    }
    public static void MakeAtlasReplace(GameObject pObj, string sParentFolder, bool bForceTransparent = false)
    {
        int iProgressFull = pObj.GetComponentsInChildren <MeshRenderer>(true).Length;

        iProgressFull = iProgressFull * 3;
        int iProgressNow = 0;

        //========================================
        //Step 1, find all renderes need to atlas
        Dictionary <Shader, List <SRendererInfo> > typedRenderers = new Dictionary <Shader, List <SRendererInfo> >();

        foreach (MeshRenderer renderer in pObj.GetComponentsInChildren <MeshRenderer>(true))
        {
            ++iProgressNow;
            EditorUtility.DisplayProgressBar("正在收集Renderer信息", string.Format("{0}/{1}", iProgressNow, iProgressFull),
                                             iProgressNow / (float)iProgressFull);
            if (!typedRenderers.ContainsKey(renderer.sharedMaterial.shader))
            {
                typedRenderers.Add(renderer.sharedMaterial.shader, new List <SRendererInfo>());
            }
            typedRenderers[renderer.sharedMaterial.shader].Add(new SRendererInfo
            {
                m_sTextureName    = AssetDatabase.GetAssetPath(renderer.sharedMaterial.mainTexture),
                m_sMeshFilterName = AssetDatabase.GetAssetPath(renderer.gameObject.GetComponent <MeshFilter>().sharedMesh),
                m_pShader         = renderer.sharedMaterial.shader,
                m_sObjectPath     = CommonFunctions.FindFullName(pObj, renderer.gameObject),
                m_pTexture        = (Texture2D)renderer.sharedMaterial.mainTexture,
                m_pMesh           = renderer.gameObject.GetComponent <MeshFilter>().sharedMesh,
                m_pObj            = renderer.gameObject,
            });

            if (null == renderer.sharedMaterial.mainTexture)
            {
                CRuntimeLogger.LogError("有的材质没有贴图: " + CommonFunctions.FindFullName(pObj, renderer.gameObject));
                EditorUtility.ClearProgressBar();
                return;
            }
        }

        CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Textures/?");
        CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Meshes/?");
        GameObject copy = Object.Instantiate(pObj, pObj.transform.position + Vector3.left * 3.0f, pObj.transform.rotation) as GameObject;

        Debug.Assert(copy != null, "copy != null");
        copy.name = pObj.name + "_Atlas";

        foreach (KeyValuePair <Shader, List <SRendererInfo> > kvp in typedRenderers)
        {
            //========================================
            //Create Texture and Material
            Dictionary <string, Texture2D> uniqueTextures = new Dictionary <string, Texture2D>();
            foreach (SRendererInfo info in kvp.Value)
            {
                if (!uniqueTextures.ContainsKey(info.m_sTextureName))
                {
                    uniqueTextures.Add(info.m_sTextureName, info.m_pTexture);
                }
            }
            Texture2D[] allTextures              = uniqueTextures.Values.ToArray();
            string      sTextureFileName         = sParentFolder + "/Textures/" + kvp.Key.name.Replace("/", "_").Replace(".", "_");
            Dictionary <string, Rect> textureDic = EditorCommonFunctions.PackTextureInDataBase(allTextures,
                                                                                               sTextureFileName,
                                                                                               kvp.Key,
                                                                                               EditorCommonFunctions.EPackColorFormat.ForcePng);

            //========================================
            //Create Mesh with new UV
            Dictionary <string, SRendererInfo> uniqueMeshes = new Dictionary <string, SRendererInfo>();
            foreach (SRendererInfo info in kvp.Value)
            {
                string sName = "f_" + CommonFunctions.GetLastName(info.m_sMeshFilterName) + "_m_" + info.m_pMesh.name + "_t_" + info.m_pTexture.name;
                if (!uniqueMeshes.ContainsKey(sName))
                {
                    uniqueMeshes.Add(sName, info);
                }
            }

            Dictionary <string, string> oldNewMeshDic = CreateMeshes(
                uniqueMeshes.Values.ToArray(),
                textureDic,
                sParentFolder + "/Meshes/",
                iProgressNow,
                iProgressFull);

            iProgressNow += oldNewMeshDic.Count;

            //========================================
            //Create a new gameobject and replace the material and mesh filter
            foreach (SRendererInfo info in kvp.Value)
            {
                ++iProgressNow;
                EditorUtility.DisplayProgressBar("正在组装", string.Format("{0}/{1}", iProgressNow, iProgressFull),
                                                 iProgressNow / (float)iProgressFull);
                string     sName     = "f_" + CommonFunctions.GetLastName(info.m_sMeshFilterName) + "_m_" + info.m_pMesh.name + "_t_" + info.m_pTexture.name;
                string     sPath     = oldNewMeshDic[sName];
                GameObject toReplace = GameObject.Find(info.m_sObjectPath.Replace(pObj.name, pObj.name + "_Atlas"));
                toReplace.GetComponent <Renderer>().sharedMaterial       = AssetDatabase.LoadAssetAtPath("Assets/" + sTextureFileName + ".mat", typeof(Material)) as Material;
                toReplace.GetComponent <Renderer>().lightProbeUsage      = LightProbeUsage.Off;
                toReplace.GetComponent <Renderer>().shadowCastingMode    = ShadowCastingMode.Off;
                toReplace.GetComponent <Renderer>().receiveShadows       = false;
                toReplace.GetComponent <Renderer>().reflectionProbeUsage = ReflectionProbeUsage.Off;
                toReplace.GetComponent <MeshFilter>().sharedMesh         = AssetDatabase.LoadAssetAtPath(sPath, typeof(Mesh)) as Mesh;
            }

            iProgressNow += oldNewMeshDic.Count;
        }
        EditorUtility.ClearProgressBar();
    }
    public static Dictionary <string, string> CreateMeshes(SCharRendererFullInfo[] mesh, Dictionary <string, Rect> rectList,
                                                           string sFileName, int iProgress, int iProgressFull, int iMc, int iSc)
    {
        Dictionary <string, string> ret = new Dictionary <string, string>();

        //Load Mesh
        foreach (SCharRendererFullInfo info in mesh)
        {
            if (!info.m_bDiscard)
            {
                for (int i = 0; i < iMc; ++i)
                {
                    for (int j = 0; j < iSc; ++j)
                    {
                        ++iProgress;
                        EditorUtility.DisplayProgressBar("正在生成Atlas模型", string.Format("{0}/{1}", iProgress, iProgressFull),
                                                         iProgress / (float)iProgressFull);


                        if (!info.m_bCombine)
                        {
                            #region Not Combine

                            string sTexture1 = string.Format("{0}_M{1}S{2}", info.m_sFullTexName, i, j);

                            Mesh theMesh  = (Mesh)EditorCommonFunctions.GetReadWritable(info.m_pMesh);
                            Mesh theMesh1 = new Mesh();

                            theMesh1.SetVertices(theMesh.vertices.ToList());
                            theMesh1.SetTriangles(theMesh.triangles.ToList(), 0);

                            List <Vector2> list1 = new List <Vector2>();
                            for (int k = 0; k < theMesh.uv.Length; ++k)
                            {
                                Vector2 vUV = theMesh.uv[k];
                                if (theMesh.uv[k].x <-0.01f || theMesh.uv[k].y <-0.01f || theMesh.uv[k].x> 1.01f ||
                                                     theMesh.uv[k].y> 1.01f)
                                {
                                    CRuntimeLogger.LogWarning("UV is not in 0 - 1, clampled!: FBX:" +
                                                              CommonFunctions.GetLastName(info.m_sMeshFilterName)
                                                              + " Model:" + info.m_pMesh.name);
                                }

                                vUV.x = Mathf.Clamp01(theMesh.uv[k].x);
                                vUV.y = Mathf.Clamp01(theMesh.uv[k].y);

                                Rect rect1 = rectList[sTexture1];
                                list1.Add(new Vector2(vUV.x * rect1.width + rect1.xMin, vUV.y * rect1.height + rect1.yMin));
                            }
                            theMesh1.uv = list1.ToArray();

                            theMesh1.uv2      = null;
                            theMesh1.normals  = null;
                            theMesh1.colors   = null;
                            theMesh1.tangents = null;

                            ;

                            //Create Mesh
                            string sName1 = string.Format("M{0}S{1}/", i, j) +
                                            CommonFunctions.GetLastName(info.m_sMeshFilterName)
                                            + "_" + info.m_pMesh.name
                                            + "_" + info.m_sFullTexName;

                            AssetDatabase.CreateAsset(theMesh1, "Assets/" + sFileName + sName1 + ".asset");
                            if (ret.ContainsKey(sName1))
                            {
                                CRuntimeLogger.LogWarning("有mesh的FBX文件重名!" + sName1);
                            }
                            else
                            {
                                ret.Add(sName1, "Assets/" + sFileName + sName1 + ".asset");
                            }
                            #endregion
                        }
                        else
                        {
                            #region Combine

                            List <Vector3> poses   = new List <Vector3>();
                            List <int>     indexes = new List <int>();
                            List <Vector2> uvs1    = new List <Vector2>();

                            for (int objIndex = 0; objIndex < info.m_pCombinedMeshObj.Length; ++objIndex)
                            {
                                string sTexture1  = string.Format("{0}_M{1}S{2}", info.m_sTextureNames[objIndex], i, j);
                                Mesh   theMesh    = (Mesh)EditorCommonFunctions.GetReadWritable(info.m_pCombinedMesh[objIndex]);
                                int    iOldPosNum = poses.Count;

                                if (0 == objIndex)
                                {
                                    poses = theMesh.vertices.ToList();
                                }
                                else
                                {
                                    foreach (Vector3 vets in theMesh.vertices)
                                    {
                                        Vector3 worldPos = info.m_pCombinedMeshObj[objIndex].transform.localToWorldMatrix.MultiplyVector(vets) + info.m_pCombinedMeshObj[objIndex].transform.position;
                                        poses.Add(info.m_pCombinedMeshObj[0].transform.worldToLocalMatrix.MultiplyVector(worldPos - info.m_pCombinedMeshObj[0].transform.position));
                                    }
                                }

                                if (0 == objIndex)
                                {
                                    indexes = theMesh.triangles.ToList();
                                }
                                else
                                {
                                    foreach (int oneind in theMesh.triangles)
                                    {
                                        indexes.Add(oneind + iOldPosNum);
                                    }
                                }

                                for (int k = 0; k < theMesh.uv.Length; ++k)
                                {
                                    Vector2 vUV = theMesh.uv[k];
                                    vUV.x = Mathf.Clamp01(theMesh.uv[k].x);
                                    vUV.y = Mathf.Clamp01(theMesh.uv[k].y);
                                    Rect rect1 = rectList[sTexture1];

                                    uvs1.Add(new Vector2(vUV.x * rect1.width + rect1.xMin, vUV.y * rect1.height + rect1.yMin));
                                }
                            }

                            Mesh theMesh1 = new Mesh();

                            theMesh1.SetVertices(poses);
                            theMesh1.SetTriangles(indexes, 0);
                            theMesh1.uv = uvs1.ToArray();

                            theMesh1.uv2      = null;
                            theMesh1.normals  = null;
                            theMesh1.colors   = null;
                            theMesh1.tangents = null;

                            ;

                            //Create Mesh
                            string sName1 = string.Format("M{0}S{1}/cmb_", i, j) +
                                            CommonFunctions.GetLastName(info.m_sMeshFilterName);

                            AssetDatabase.CreateAsset(theMesh1, "Assets/" + sFileName + sName1 + ".asset");
                            if (ret.ContainsKey(sName1))
                            {
                                CRuntimeLogger.LogWarning("有mesh的FBX文件重名!" + sName1);
                            }
                            else
                            {
                                ret.Add(sName1, "Assets/" + sFileName + sName1 + ".asset");
                            }
                            #endregion
                        }
                    }
                }
            }
        }

        return(ret);
    }