Exemple #1
0
    public void DoClustering(SA3TextureCombine combine)
    {
        if (clusterGrouper == null)
        {
            Debug.LogError("Cluster Grouper was null.");
            return;
        }

        //todo warn for no objects and no material bake result
        Dictionary <string, List <Renderer> > cell2objs = clusterGrouper.FilterIntoGroups(combine.GetObjectsToCombine());

        Debug.Log("Found " + cell2objs.Count + " cells with Renderers. Creating bakers.");
        if (clusterOnLMIndex)
        {
            Dictionary <string, List <Renderer> > cell2objsNew = new Dictionary <string, List <Renderer> >();
            foreach (string key in cell2objs.Keys)
            {
                List <Renderer> gaws = cell2objs[key];
                Dictionary <int, List <Renderer> > idx2objs = GroupByLightmapIndex(gaws);
                foreach (int keyIdx in idx2objs.Keys)
                {
                    string keyNew = key + "-LM-" + keyIdx;
                    cell2objsNew.Add(keyNew, idx2objs[keyIdx]);
                }
            }
            cell2objs = cell2objsNew;
        }
        foreach (string key in cell2objs.Keys)
        {
            List <Renderer> gaws = cell2objs[key];
            AddCombine(combine, key, gaws);
        }
    }
Exemple #2
0
    void AddCombine(SA3TextureCombine tb, string key, List <Renderer> gaws)
    {
        int numVerts = 0;

        for (int i = 0; i < gaws.Count; i++)
        {
            Mesh m = SAUtility.GetMesh(gaws[i].gameObject);
            if (m != null)
            {
                numVerts += m.vertexCount;
            }
        }

        GameObject nmb = new GameObject("CombineIn." + key);

        nmb.transform.position = Vector3.zero;
        SA3MeshCombineCommon newCombine;

        if (numVerts >= 65535)
        {
            newCombine = nmb.AddComponent <SA3MultiMeshCombine>();
            newCombine.useObjsToMeshFromTexBaker = false;
        }
        else
        {
            newCombine = nmb.AddComponent <SA3MeshCombine>();
            newCombine.useObjsToMeshFromTexBaker = false;
        }
        newCombine.textureBakeResults = tb.textureBakeResults;
        newCombine.transform.parent   = tb.transform;
        for (int i = 0; i < gaws.Count; i++)
        {
            newCombine.GetObjectsToCombine().Add(gaws[i].gameObject);
        }
    }
Exemple #3
0
 public override List <GameObject> GetObjectsToCombine()
 {
     if (useObjsToMeshFromTexBaker)
     {
         SA3TextureCombine tb = gameObject.GetComponent <SA3TextureCombine>();
         if (tb == null)
         {
             tb = gameObject.transform.parent.GetComponent <SA3TextureCombine>();
         }
         if (tb != null)
         {
             return(tb.GetObjectsToCombine());
         }
         else
         {
             Debug.LogWarning("Use Objects To Mesh From Texture Baker was checked but no texture baker");
             return(new List <GameObject>());
         }
     }
     else
     {
         if (objsToMesh == null)
         {
             objsToMesh = new List <GameObject>();
         }
         return(objsToMesh);
     }
 }
Exemple #4
0
    public void CreateCombinedMaterialAssets(SA3TextureCombine combine, string pth)
    {
        string baseName = Path.GetFileNameWithoutExtension(pth);

        if (baseName == null || baseName.Length == 0)
        {
            return;
        }
        string folderPath = pth.Substring(0, pth.Length - baseName.Length - 6);

        List <string> matNames = new List <string>();

        if (combine.doMultiMaterial)
        {
            for (int i = 0; i < combine.resultMaterials.Length; i++)
            {
                matNames.Add(folderPath + baseName + "-mat" + i + ".mat");
                AssetDatabase.CreateAsset(new Material(Shader.Find("Diffuse")), matNames[i]);
                combine.resultMaterials[i].combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matNames[i], typeof(Material));
            }
        }
        else
        {
            matNames.Add(folderPath + baseName + "-mat.mat");
            Material newMat = new Material(Shader.Find("Diffuse"));
            if (combine.GetObjectsToCombine().Count > 0 && combine.GetObjectsToCombine()[0] != null)
            {
                Renderer r = combine.GetObjectsToCombine()[0].GetComponent <Renderer>();
                if (r == null)
                {
                    Debug.LogWarning("Object " + combine.GetObjectsToCombine()[0] + " does not have a Renderer on it.");
                }
                else
                {
                    if (r.sharedMaterial != null)
                    {
                        newMat.shader = r.sharedMaterial.shader;
                        SA3TextureCombine.ConfigureNewMaterialToMatchOld(newMat, r.sharedMaterial);
                    }
                }
            }
            else
            {
                Debug.Log("If you add objects to be combined before creating the Combined Material Assets. Then Mesh Baker will create a result material that is a duplicate of the material on the first object to be combined. This saves time configuring the shader.");
            }
            AssetDatabase.CreateAsset(newMat, matNames[0]);
            combine.resultMaterial = (Material)AssetDatabase.LoadAssetAtPath(matNames[0], typeof(Material));
        }
        //create the SA2TextureBakeResults
        AssetDatabase.CreateAsset(ScriptableObject.CreateInstance <SA2TextureCombineResults>(), pth);
        combine.textureBakeResults = (SA2TextureCombineResults)AssetDatabase.LoadAssetAtPath(pth, typeof(SA2TextureCombineResults));
        AssetDatabase.Refresh();
    }
Exemple #5
0
    /// <summary>
    /// Gets the texture baker on this component or its parent if it exists
    /// </summary>
    /// <returns>The texture baker.</returns>
    public SA3TextureCombine GetTextureBaker()
    {
        SA3TextureCombine tb = GetComponent <SA3TextureCombine>();

        if (tb != null)
        {
            return(tb);
        }
        if (transform.parent != null)
        {
            return(transform.parent.GetComponent <SA3TextureCombine>());
        }
        return(null);
    }
Exemple #6
0
    public static GameObject CreateMeshCombineController()
    {
        SA3TextureCombine[] mbs = (SA3TextureCombine[])GameObject.FindObjectsOfType(typeof(SA3TextureCombine));
        Regex regex             = new Regex(@"(\d+)$", RegexOptions.Compiled | RegexOptions.CultureInvariant);
        int   largest           = 0;

        try
        {
            for (int i = 0; i < mbs.Length; i++)
            {
                Match match = regex.Match(mbs[i].name);
                if (match.Success)
                {
                    int val = Convert.ToInt32(match.Groups[1].Value);
                    if (val >= largest)
                    {
                        largest = val + 1;
                    }
                }
            }
        }
        catch (Exception e)
        {
            if (e == null)
            {
                e = null;            //Do nothing supress compiler warning
            }
        }
        GameObject combine = new GameObject("SACombine" + largest);

        combine.transform.position = Vector3.zero;
        SA3TextureCombine tCombine = combine.AddComponent <SA3TextureCombine>();

        tCombine.packingAlgorithm = SA2PackingAlgorithmEnum.Mesh;

        //combine.AddComponent<SA3MeshCombineGrouper>();
        //GameObject meshCombine = new GameObject("SACombine");
        //meshCombine.AddComponent<SA3MeshCombine>();
        //meshCombine.transform.parent = combine.transform;
        return(combine.gameObject);
    }
Exemple #7
0
    public static bool DoCombinedValidate(SA3MeshCombineRoot mom, SAObjsToCombineTypes objToCombineType, SA2EditorMethodsInterface editorMethods)
    {
        if (mom.textureBakeResults == null)
        {
            Debug.LogError("Need to set Material Bake Result on " + mom);
            return(false);
        }
        if (!(mom is SA3TextureCombine))
        {
            SA3TextureCombine tb = mom.GetComponent <SA3TextureCombine>();
            if (tb != null && tb.textureBakeResults != mom.textureBakeResults)
            {
                Debug.LogWarning("Material Bake Result on this component is not the same as the Material Bake Result on the SA3TextureCombine.");
            }
        }

        List <GameObject> objsToMesh = mom.GetObjectsToCombine();

        for (int i = 0; i < objsToMesh.Count; i++)
        {
            GameObject go = objsToMesh[i];
            if (go == null)
            {
                Debug.LogError("The list of objects to combine contains a null at position." + i + " Select and use [shift] delete to remove");
                return(false);
            }
            for (int j = i + 1; j < objsToMesh.Count; j++)
            {
                if (objsToMesh[i] == objsToMesh[j])
                {
                    Debug.LogError("The list of objects to combine contains duplicates.");
                    return(false);
                }
            }
            if (SAUtility.GetGOMaterials(go) == null)
            {
                Debug.LogError("Object " + go + " in the list of objects to be combined does not have a material");
                return(false);
            }
            if (SAUtility.GetMesh(go) == null)
            {
                Debug.LogError("Object " + go + " in the list of objects to be combined does not have a mesh");
                return(false);
            }
        }

        if (mom.textureBakeResults.doMultiMaterial)
        {
            if (!validateSubmeshOverlap(mom))
            {//only warns currently
                return(false);
            }
        }

        List <GameObject> objs = objsToMesh;

        if (mom is SA3MeshCombine)
        {
            objs = mom.GetObjectsToCombine();
            //if (((SA3MeshCombine)mom).useObjsToMeshFromTexBaker && tb != null) objs = tb.GetObjectsToCombine();
            if (objs == null || objs.Count == 0)
            {
                Debug.LogError("No meshes to combine. Please assign some meshes to combine.");
                return(false);
            }
            if (mom is SA3MeshCombine && ((SA3MeshCombine)mom).meshCombiner.renderType == SARenderType.skinnedMeshRenderer)
            {
                if (!editorMethods.ValidateSkinnedMeshes(objs))
                {
                    return(false);
                }
            }
        }

        if (editorMethods != null)
        {
            editorMethods.CheckPrefabTypes(objToCombineType, objsToMesh);
        }
        return(true);
    }
Exemple #8
0
    private void texturesController()
    {
        SA3TextureCombine combine = target as SA3TextureCombine;

        textureCombine           = new SerializedObject(target);
        objsToMesh               = textureCombine.FindProperty("objsToMesh");
        textureBakeResults       = textureCombine.FindProperty("_textureBakeResults");
        resultMaterial           = textureCombine.FindProperty("_resultMaterial");
        atlasPadding             = textureCombine.FindProperty("_atlasPadding");
        resizePowerOfTwoTextures = textureCombine.FindProperty("_resizePowerOfTwoTextures");
        //customShaderPropNames = textureCombine.FindProperty("_customShaderPropNames");
        maxTilingBakeSize       = textureCombine.FindProperty("_maxTilingBakeSize");
        fixOutOfBoundsUVs       = textureCombine.FindProperty("_fixOutOfBoundsUVs");
        texturePackingAlgorithm = textureCombine.FindProperty("_packingAlgorithm");
        forcePowerOfTwoAtlas    = textureCombine.FindProperty("_combineTexturePackerForcePowerOfTwo");

        //tbe.DrawGUI((SA3TextureCombine)target, typeof(SA3MeshCombineEditorWindow));

        EditorGUILayout.Separator();
        EditorGUILayout.LabelField("待合并的对象", EditorStyles.boldLabel);

        if (GUILayout.Button(exportGameObject))
        {
            List <GameObject> newMomObjs = GetFilteredList();
            SAEditorUtil.RegisterUndo(combine, "Add Objects");
            List <GameObject> momObjs = combine.GetObjectsToCombine();
            int numAdded = 0;
            for (int i = 0; i < newMomObjs.Count; i++)
            {
                if (!momObjs.Contains(newMomObjs[i]))
                {
                    momObjs.Add(newMomObjs[i]);
                    numAdded++;
                }
            }
        }
        EditorGUILayout.PropertyField(objsToMesh, objectsToCombineGUIContent, true);

        EditorGUILayout.Separator();
        EditorGUILayout.Separator();
        EditorGUILayout.LabelField("材质和网格的合并文件", EditorStyles.boldLabel);
        if (GUILayout.Button(createPrefabAndMaterialLabelContent))
        {
            string newPrefabPath = EditorUtility.SaveFilePanelInProject("Asset name", "", "asset", "Enter a name for the baked texture results");
            if (newPrefabPath != null)
            {
                CreateCombinedMaterialAssets(combine, newPrefabPath);
            }
        }

        EditorGUILayout.PropertyField(textureBakeResults, textureBakeResultsGUIContent);
        if (textureBakeResults.objectReferenceValue != null)
        {
            //显示需要合并的shader信息
            //showContainsReport = EditorGUILayout.Foldout(showContainsReport, "Shaders & Materials Contained");
            //if (showContainsReport)
            //{
            //    EditorGUILayout.HelpBox(((SA2TextureBakeResults)textureBakeResults.objectReferenceValue).GetDescription(), MessageType.Info);
            //}
        }

        EditorGUILayout.PropertyField(resultMaterial, new GUIContent("合并后的网格材质"));

        EditorGUILayout.Separator();
        //材质烘焙选项
        EditorGUILayout.LabelField("材质Bake选项", EditorStyles.boldLabel);
        EditorGUILayout.PropertyField(atlasPadding, new GUIContent("图集填充间距"));//图集 填充
        EditorGUILayout.PropertyField(resizePowerOfTwoTextures, resizePowerOfTwoGUIContent);
        //EditorGUILayout.PropertyField(customShaderPropNames, customShaderPropertyNamesGUIContent, true);//自定义材质球名称
        EditorGUILayout.PropertyField(maxTilingBakeSize, maxTilingBakeSizeGUIContent); //最大Tiling烘焙尺寸
        EditorGUILayout.PropertyField(fixOutOfBoundsUVs, fixOutOfBoundsGUIContent);    //修复UVs范围

        EditorGUILayout.PropertyField(texturePackingAlgorithm, texturePackingAgorithmGUIContent);
        if (texturePackingAlgorithm.intValue == (int)SA2PackingAlgorithmEnum.Mesh)
        {
            EditorGUILayout.PropertyField(forcePowerOfTwoAtlas, forcePowerOfTwoAtlasContent);
        }
        EditorGUILayout.Separator();
        if (GUILayout.Button("合并多个材质"))
        {
            combine.CreateAtlases(updateProgressBar, true, new SA3EditorMethods());
            EditorUtility.ClearProgressBar();
            if (combine.textureBakeResults != null)
            {
                EditorUtility.SetDirty(combine.textureBakeResults);
            }
        }
        textureCombine.ApplyModifiedProperties();
        textureCombine.SetIsDifferentCacheDirty();
    }
Exemple #9
0
    ///
    ///以下是网格操作
    ///
    private void meshController()
    {
        SA3TextureCombine combine = target as SA3TextureCombine;

        grouper = new SerializedObject(target);
        SerializedProperty grp            = grouper.FindProperty("grouper");
        SerializedProperty clusterGrouper = grp.FindPropertyRelative("clusterGrouper");

        clusterType      = clusterGrouper.FindPropertyRelative("clusterType");
        gridOrigin       = clusterGrouper.FindPropertyRelative("origin");
        cellSize         = clusterGrouper.FindPropertyRelative("cellSize");
        numSegments      = clusterGrouper.FindPropertyRelative("pieNumSegments");
        pieAxis          = clusterGrouper.FindPropertyRelative("pieAxis");
        clusterOnLMIndex = grp.FindPropertyRelative("clusterOnLMIndex");

        EditorGUILayout.LabelField("网格合并", EditorStyles.boldLabel);
        EditorGUILayout.PropertyField(clusterType, gc_ClusterType);
        //cg.clusterType = (SA3MeshCombineGrouperCore.ClusterType) EditorGUILayout.EnumPopup(gc_ClusterType,cg.clusterType);
        if (clusterType.enumValueIndex == (int)SA3MeshCombineGrouperCore.ClusterType.grid)
        {
            EditorGUILayout.PropertyField(gridOrigin, gc_GridOrigin);
            EditorGUILayout.PropertyField(cellSize, gc_CellSize);
        }
        else if (clusterType.enumValueIndex == (int)SA3MeshCombineGrouperCore.ClusterType.pie)
        {
            EditorGUILayout.PropertyField(gridOrigin, gc_GridOrigin);
            EditorGUILayout.PropertyField(numSegments, gc_NumSegements);
            EditorGUILayout.PropertyField(pieAxis, gc_PieAxis);
        }
        EditorGUILayout.PropertyField(clusterOnLMIndex, gc_ClusterOnLMIndex);

        if (GUILayout.Button("生成prefab数据模型"))
        {
            if (combine.GetObjectsToCombine().Count == 0)
            {
                Debug.LogError("没有需要合并的网格");
                return;
            }
            if (combine.transform.childCount > 0)
            {
                Debug.LogWarning("请删除当前SACombine子项后,再次点击\'生成prefab数据模型\'");
            }
            combine.grouper.DoClustering(combine);
        }

        if (GUILayout.Button("生成全部prefab网格对象"))
        {
            try
            {
                SA3MeshCombineCommon[] mBakers = combine.GetComponentsInChildren <SA3MeshCombineCommon>();
                for (int i = 0; i < mBakers.Length; i++)
                {
                    if (mBakers[i].textureBakeResults != null)
                    {
                        SA3MeshCombineEditorFunctions.BakeIntoCombined(mBakers[i]);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }
        }
        //隐藏子对象
        //string buttonTextEnableRenderers = "Disable Renderers On All Child Combines";
        //bool enableRenderers = false;
        //if (combine != null && combine.GetObjectsToCombine().Count > 0)
        //{
        //    GameObject go = combine.GetObjectsToCombine()[0];
        //    if (go != null && go.GetComponent<Renderer>() != null && go.GetComponent<Renderer>().enabled == false)
        //    {
        //        buttonTextEnableRenderers = "Enable Renderers On All Child Combine";
        //        enableRenderers = true;
        //    }
        //}
        //if (GUILayout.Button(buttonTextEnableRenderers))
        //{
        //    try
        //    {
        //        SA3MeshCombineCommon[] mBakers = combine.GetComponentsInChildren<SA3MeshCombineCommon>();
        //        for (int i = 0; i < mBakers.Length; i++)
        //        {
        //            for (int j = 0; j < mBakers[i].GetObjectsToCombine().Count; j++)
        //            {
        //                GameObject go = mBakers[i].GetObjectsToCombine()[j];
        //                if (go != null && go.GetComponent<Renderer>() != null)
        //                {
        //                    go.GetComponent<Renderer>().enabled = enableRenderers;
        //                }
        //            }
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        Debug.LogError(e);
        //    }
        //    finally
        //    {
        //        EditorUtility.ClearProgressBar();
        //    }
        //}

        //防止暴力点击
        //if (DateTime.UtcNow.Ticks - lastBoundsCheckRefreshTime > 10000000 && combine != null)
        //{
        //    List<GameObject> gos = combine.GetObjectsToCombine();
        //    Bounds b = new Bounds(Vector3.zero, Vector3.one);
        //    if (gos.Count > 0 && gos[0] != null && gos[0].GetComponent<Renderer>() != null)
        //    {
        //        b = gos[0].GetComponent<Renderer>().bounds;
        //    }
        //    for (int i = 0; i < gos.Count; i++)
        //    {
        //        if (gos[i] != null && gos[i].GetComponent<Renderer>() != null)
        //        {
        //            b.Encapsulate(gos[i].GetComponent<Renderer>().bounds);
        //        }
        //    }
        //    combine.sourceObjectBounds = b;
        //    lastBoundsCheckRefreshTime = DateTime.UtcNow.Ticks;
        //}

        grouper.ApplyModifiedProperties();
    }
Exemple #10
0
    public static void BakeIntoCombined(SA3MeshCombineCommon mom)
    {
        SA2OutputOptions prefabOrSceneObject = mom.meshCombiner.outputOption;

        if (SA3MeshCombiner.EVAL_VERSION && prefabOrSceneObject == SA2OutputOptions.bakeIntoPrefab)
        {
            Debug.LogError("Cannot BakeIntoPrefab with evaluation version.");
            return;
        }
        if (prefabOrSceneObject != SA2OutputOptions.bakeIntoPrefab && prefabOrSceneObject != SA2OutputOptions.bakeIntoSceneObject)
        {
            Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject");
            return;
        }

        SA3TextureCombine tb = mom.GetComponent <SA3TextureCombine>();

        if (mom.textureBakeResults == null && tb != null)
        {
            mom.textureBakeResults = tb.textureBakeResults;
        }

        if (!SA3MeshCombineRoot.DoCombinedValidate(mom, SAObjsToCombineTypes.sceneObjOnly, new SA3EditorMethods()))
        {
            return;
        }
        if (prefabOrSceneObject == SA2OutputOptions.bakeIntoPrefab &&
            mom.resultPrefab == null)
        {
            Debug.LogError("Need to set the Combined Mesh Prefab field. Create a prefab asset, drag an empty game object into it, and drag it to the 'Combined Mesh Prefab' field.");
            return;
        }
        if (mom.meshCombiner.resultSceneObject != null &&
            (PrefabUtility.GetPrefabType(mom.meshCombiner.resultSceneObject) == PrefabType.ModelPrefab ||
             PrefabUtility.GetPrefabType(mom.meshCombiner.resultSceneObject) == PrefabType.Prefab))
        {
            Debug.LogWarning("Result Game Object was a project asset not a scene object instance. Clearing this field.");
            mom.meshCombiner.resultSceneObject = null;
        }

        mom.ClearMesh();
        if (mom.AddDeleteGameObjects(mom.GetObjectsToCombine().ToArray(), null, false))
        {
            mom.Apply(Unwrapping.GenerateSecondaryUVSet);
            Debug.Log(String.Format("Successfully baked {0} meshes", mom.GetObjectsToCombine().Count));
            if (prefabOrSceneObject == SA2OutputOptions.bakeIntoSceneObject)
            {
                PrefabType pt = PrefabUtility.GetPrefabType(mom.meshCombiner.resultSceneObject);
                if (pt == PrefabType.Prefab || pt == PrefabType.ModelPrefab)
                {
                    Debug.LogError("Combined Mesh Object is a prefab asset. If output option bakeIntoSceneObject then this must be an instance in the scene.");
                    return;
                }
            }
            else if (prefabOrSceneObject == SA2OutputOptions.bakeIntoPrefab)
            {
                string prefabPth = AssetDatabase.GetAssetPath(mom.resultPrefab);
                if (prefabPth == null || prefabPth.Length == 0)
                {
                    Debug.LogError("Could not save result to prefab. Result Prefab value is not an Asset.");
                    return;
                }
                string baseName    = Path.GetFileNameWithoutExtension(prefabPth);
                string folderPath  = prefabPth.Substring(0, prefabPth.Length - baseName.Length - 7);
                string newFilename = folderPath + baseName + "-mesh";
                SaveMeshsToAssetDatabase(mom, folderPath, newFilename);

                if (mom.meshCombiner.renderType == SARenderType.skinnedMeshRenderer)
                {
                    Debug.LogWarning("Render type is skinned mesh renderer. " +
                                     "Can't create prefab until all bones have been added to the combined mesh object " + mom.resultPrefab +
                                     " Add the bones then drag the combined mesh object to the prefab.");
                }
                else
                {
                    RebuildPrefab(mom);
                }
            }
            else
            {
                Debug.LogError("Unknown parameter");
            }
        }
    }