void OnGUI()
    {
        GUILayout.Label("Time to bake textures: " + elapsedTime);
        if (GUILayout.Button("Combine textures & build combined mesh"))
        {
            MB3_MeshBaker    meshbaker    = target.GetComponent <MB3_MeshBaker>();
            MB3_TextureBaker textureBaker = target.GetComponent <MB3_TextureBaker>();

            //These can be assets configured at runtime or you can create them
            // on the fly like this
            textureBaker.textureBakeResults = ScriptableObject.CreateInstance <MB2_TextureBakeResults>();
            textureBaker.resultMaterial     = new Material(Shader.Find("Diffuse"));

            float t1 = Time.realtimeSinceStartup;
            textureBaker.CreateAtlases();
            elapsedTime = Time.realtimeSinceStartup - t1;

            meshbaker.ClearMesh();             //only necessary if your not sure whats in the combined mesh
            meshbaker.textureBakeResults = textureBaker.textureBakeResults;
            //Add the objects to the combined mesh
            meshbaker.AddDeleteGameObjects(textureBaker.GetObjectsToCombine().ToArray(), null);

            meshbaker.Apply();
        }
    }
	public static void SaveMeshsToAssetDatabase(MB3_MeshBakerCommon mom, string folderPath, string newFileNameBase){
		if (MB3_MeshCombiner.EVAL_VERSION) return;
		if (mom is MB3_MeshBaker){
			MB3_MeshBaker mb = (MB3_MeshBaker) mom;
			string newFilename = newFileNameBase + ".asset";
			string ap = AssetDatabase.GetAssetPath(((MB3_MeshCombinerSingle) mb.meshCombiner).GetMesh());
			if (ap == null || ap.Equals("")){
				Debug.Log("Saving mesh asset to " + newFilename);
				AssetDatabase.CreateAsset(((MB3_MeshCombinerSingle) mb.meshCombiner).GetMesh(), newFilename);
			} else {
				Debug.Log("Mesh is an asset at " + ap);	
			}
		} else if (mom is MB3_MultiMeshBaker){
			MB3_MultiMeshBaker mmb = (MB3_MultiMeshBaker) mom;
			List<MB3_MultiMeshCombiner.CombinedMesh> combiners = ((MB3_MultiMeshCombiner) mmb.meshCombiner).meshCombiners;
			for (int i = 0; i < combiners.Count; i++){
				string newFilename = newFileNameBase + i + ".asset";
				Mesh mesh = combiners[i].combinedMesh.GetMesh();
				string ap = AssetDatabase.GetAssetPath(mesh);
				if (ap == null || ap.Equals("")){
					Debug.Log("Saving mesh asset to " + newFilename);
					AssetDatabase.CreateAsset(mesh, newFilename);
				} else {
					Debug.Log("Mesh is an asset at " + ap);	
				}			
			}				
		} else {
			Debug.LogError("Argument was not a MB3_MeshBaker or an MB3_MultiMeshBaker.");	
		}
	}
Пример #3
0
    public static void MigrateMeshBakerToVersion3Component(GameObject go)
    {
        MB2_MeshBaker tb2 = go.GetComponent <MB2_MeshBaker>();

        if (tb2 == null)
        {
            return;
        }
        Debug.Log("Migrating Mesh Baker");
        MB3_MeshBaker tb3 = go.AddComponent <MB3_MeshBaker>();

        tb3.textureBakeResults          = tb2.textureBakeResults;
        tb3.bakeAssetsInPlaceFolderPath = tb2.bakeAssetsInPlaceFolderPath;
        tb3.objsToMesh   = tb2.objsToMesh;
        tb3.resultPrefab = tb2.resultPrefab;
        tb3.useObjsToMeshFromTexBaker      = tb2.useObjsToMeshFromTexBaker;
        tb3.meshCombiner.doCol             = tb2.doCol;
        tb3.meshCombiner.doNorm            = tb2.doNorm;
        tb3.meshCombiner.doTan             = tb2.doTan;
        tb3.meshCombiner.doUV              = tb2.doUV;
        tb3.meshCombiner.doUV1             = tb2.doUV1;
        tb3.meshCombiner.lightmapOption    = tb2.lightmapOption;
        tb3.meshCombiner.outputOption      = tb2.outputOption;
        tb3.meshCombiner.resultSceneObject = tb2.resultSceneObject;
        tb3.meshCombiner.renderType        = tb2.renderType;
        tb3.meshCombiner.targetRenderer    = tb2.meshCombiner.targetRenderer;

        DestroyImmediate(tb2);
    }
Пример #4
0
    void Start()
    {
        mbd = GetComponentInChildren <MB3_MeshBaker>();

        // instantiate game objects
        int dim = 25;

        GameObject[] gos = new GameObject[dim * dim];
        for (int i = 0; i < dim; i++)
        {
            for (int j = 0; j < dim; j++)
            {
                GameObject go = (GameObject)Instantiate(prefab);
                gos[i * dim + j]      = go.GetComponentInChildren <MeshRenderer>().gameObject;
                go.transform.position = (new Vector3(9f * i, 0, 9f * j));
                //put every third object in a list so we can add and delete it later
                if ((i * dim + j) % 3 == 0)
                {
                    objsInCombined.Add(gos[i * dim + j]);
                }
            }
        }
        //add objects to combined mesh
        mbd.AddDeleteGameObjects(gos, null, true);
        mbd.Apply();

        objs = objsInCombined.ToArray();
        //start routine which will periodically add and delete objects
        StartCoroutine(largeNumber());
    }
	void Start(){
		mbd = GetComponentInChildren<MB3_MeshBaker>(); 
		
		// instantiate game objects
		int dim = 25;
		GameObject[] gos = new GameObject[dim * dim];
		for (int i = 0; i < dim; i++){
			for (int j = 0; j < dim; j++){
				GameObject go = (GameObject) Instantiate(prefab);
				gos[i*dim + j] = go.GetComponentInChildren<MeshRenderer>().gameObject;
				go.transform.position = (new Vector3(9f*i,0,9f * j));
				//put every third object in a list so we can add and delete it later
				if ((i*dim + j) % 3 == 0){
					objsInCombined.Add(gos[i*dim + j]);
				}
			}
		}
		//add objects to combined mesh
		mbd.AddDeleteGameObjects(gos, null, true);
		mbd.Apply();
		
		objs = objsInCombined.ToArray();
		//start routine which will periodically add and delete objects
		StartCoroutine(largeNumber());
	}
    private bool InitBaker(string[] paths, MB3_TextureBaker textureBaker, MB3_MeshBaker meshBaker)
    {
        bool result = false;

        Material material = ResourcesManagerMediator.
                            GetNoGameObjectFromResourcesManager <Material>(paths[1]);

        if (material == null)
        {
            Debug.LogError("加载合并材质资源失败" + paths[1]);
            return(result);
        }

        MB2_TextureBakeResults textureBakeResults = ResourcesManagerMediator.
                                                    GetNoGameObjectFromResourcesManager <MB2_TextureBakeResults>(paths[2]);

        if (textureBakeResults == null)
        {
            Debug.LogError("加载MB2_TextureBakeResults资源失败" + paths[2]);
            return(result);
        }

        textureBaker.resultMaterial     = material;
        textureBaker.textureBakeResults = textureBakeResults;
        meshBaker.textureBakeResults    = textureBakeResults;

        result = true;
        return(result);
    }
	public static void RebuildPrefab(MB3_MeshBakerCommon mom){
		if (MB3_MeshCombiner.EVAL_VERSION) return;
		if (mom is MB3_MeshBaker){
			MB3_MeshBaker mb = (MB3_MeshBaker) mom;
			MB3_MeshCombinerSingle mbs = (MB3_MeshCombinerSingle) mb.meshCombiner;
			GameObject prefabRoot = mom.resultPrefab;
			GameObject rootGO = (GameObject) PrefabUtility.InstantiatePrefab(prefabRoot);
			MB3_MeshCombinerSingle.BuildSceneHierarch(mbs, rootGO, mbs.GetMesh());		
			string prefabPth = AssetDatabase.GetAssetPath(prefabRoot);
			PrefabUtility.ReplacePrefab(rootGO,AssetDatabase.LoadAssetAtPath(prefabPth,typeof(GameObject)),ReplacePrefabOptions.ConnectToPrefab);
			Editor.DestroyImmediate(rootGO);
		} else if (mom is MB3_MultiMeshBaker){
			MB3_MultiMeshBaker mmb = (MB3_MultiMeshBaker) mom;
			MB3_MultiMeshCombiner mbs = (MB3_MultiMeshCombiner) mmb.meshCombiner;
			GameObject prefabRoot = mom.resultPrefab;
			GameObject rootGO = (GameObject) PrefabUtility.InstantiatePrefab(prefabRoot);
			for (int i = 0; i < mbs.meshCombiners.Count; i++){
				MB3_MeshCombinerSingle.BuildSceneHierarch(mbs.meshCombiners[i].combinedMesh, rootGO, mbs.meshCombiners[i].combinedMesh.GetMesh(),true);
			}
			string prefabPth = AssetDatabase.GetAssetPath(prefabRoot);
			PrefabUtility.ReplacePrefab(rootGO,AssetDatabase.LoadAssetAtPath(prefabPth,typeof(GameObject)),ReplacePrefabOptions.ConnectToPrefab);
			Editor.DestroyImmediate(rootGO);				
		} else {
			Debug.LogError("Argument was not a MB3_MeshBaker or an MB3_MultiMeshBaker.");	
		}				
	}
Пример #8
0
    // The serialized object reference is necessary to work around a nasty unity bug.
    public static void RebuildPrefab(MB3_MeshBakerCommon mom, ref SerializedObject so)
    {
        if (MB3_MeshCombiner.EVAL_VERSION)
        {
            return;
        }

        if (mom.meshCombiner.LOG_LEVEL >= MB2_LogLevel.debug)
        {
            Debug.Log("Rebuilding Prefab: " + mom.resultPrefab);
        }
        GameObject prefabRoot = mom.resultPrefab;
        GameObject rootGO     = (GameObject)PrefabUtility.InstantiatePrefab(prefabRoot);

        //remove all renderer childeren of rootGO
        MBVersionEditor.UnpackPrefabInstance(rootGO, ref so);
        Renderer[] rs = rootGO.GetComponentsInChildren <Renderer>();
        for (int i = 0; i < rs.Length; i++)
        {
            if (rs[i] != null && rs[i].transform.parent == rootGO.transform)
            {
                MB_Utility.Destroy(rs[i].gameObject);
            }
        }

        if (mom is MB3_MeshBaker)
        {
            MB3_MeshBaker          mb  = (MB3_MeshBaker)mom;
            MB3_MeshCombinerSingle mbs = (MB3_MeshCombinerSingle)mb.meshCombiner;
            MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs, rootGO, mbs.GetMesh());
        }
        else if (mom is MB3_MultiMeshBaker)
        {
            MB3_MultiMeshBaker    mmb = (MB3_MultiMeshBaker)mom;
            MB3_MultiMeshCombiner mbs = (MB3_MultiMeshCombiner)mmb.meshCombiner;
            for (int i = 0; i < mbs.meshCombiners.Count; i++)
            {
                MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs.meshCombiners[i].combinedMesh, rootGO, mbs.meshCombiners[i].combinedMesh.GetMesh(), true);
            }
        }
        else
        {
            Debug.LogError("Argument was not a MB3_MeshBaker or an MB3_MultiMeshBaker.");
        }

        string prefabPth = AssetDatabase.GetAssetPath(prefabRoot);

        MBVersionEditor.ReplacePrefab(rootGO, prefabPth, MB_ReplacePrefabOption.connectToPrefab);
        if (mom.meshCombiner.renderType != MB_RenderType.skinnedMeshRenderer)
        {
            // For Skinned meshes, leave the prefab instance in the scene so source game objects can moved into the prefab.
            Editor.DestroyImmediate(rootGO);
        }
    }
    public static void RebuildPrefab(MB3_MeshBakerCommon mom)
    {
        if (MB3_MeshCombiner.EVAL_VERSION)
        {
            return;
        }
        GameObject prefabRoot = mom.resultPrefab;
        GameObject rootGO     = (GameObject)PrefabUtility.InstantiatePrefab(prefabRoot);

        //remove all renderer childeren of rootGO
        Renderer[] rs = rootGO.GetComponentsInChildren <Renderer>();
        for (int i = 0; i < rs.Length; i++)
        {
            if (rs[i] != null && rs[i].transform.parent == rootGO.transform)
            {
                MB_Utility.Destroy(rs[i].gameObject);
            }
        }
        if (mom is MB3_MeshBaker)
        {
            MB3_MeshBaker          mb  = (MB3_MeshBaker)mom;
            MB3_MeshCombinerSingle mbs = (MB3_MeshCombinerSingle)mb.meshCombiner;
            MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs, rootGO, mbs.GetMesh());
        }
        else if (mom is MB3_MultiMeshBaker)
        {
            MB3_MultiMeshBaker    mmb = (MB3_MultiMeshBaker)mom;
            MB3_MultiMeshCombiner mbs = (MB3_MultiMeshCombiner)mmb.meshCombiner;
            for (int i = 0; i < mbs.meshCombiners.Count; i++)
            {
                MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs.meshCombiners[i].combinedMesh, rootGO, mbs.meshCombiners[i].combinedMesh.GetMesh(), true);
            }
        }
        else
        {
            Debug.LogError("Argument was not a MB3_MeshBaker or an MB3_MultiMeshBaker.");
        }
        string prefabPth = AssetDatabase.GetAssetPath(prefabRoot);

        PrefabUtility.ReplacePrefab(rootGO, AssetDatabase.LoadAssetAtPath(prefabPth, typeof(GameObject)), ReplacePrefabOptions.ConnectToPrefab);
        if (mom.meshCombiner.renderType != MB_RenderType.skinnedMeshRenderer)
        {
            Editor.DestroyImmediate(rootGO);
        }
    }
    void OnBuiltAtlasesSuccess()
    {
        Debug.Log("Calling success callback. baking meshes");
        MB3_MeshBaker    meshbaker    = target.GetComponentInChildren <MB3_MeshBaker>();
        MB3_TextureBaker textureBaker = target.GetComponent <MB3_TextureBaker>();

        //elapsedTime = Time.realtimeSinceStartup - t1;

        if (result.isFinished &&
            result.success)
        {
            meshbaker.ClearMesh(); //only necessary if your not sure whats in the combined mesh
            meshbaker.textureBakeResults = textureBaker.textureBakeResults;
            //Add the objects to the combined mesh
            meshbaker.AddDeleteGameObjects(textureBaker.GetObjectsToCombine().ToArray(), null, true);
            meshbaker.Apply();
        }
        Debug.Log("Completed baking textures on frame " + Time.frameCount);
    }
        public static GameObject CreateNewMeshBaker()
        {
            MB3_TextureBaker[] mbs = (MB3_TextureBaker[])GameObject.FindObjectsOfType(typeof(MB3_TextureBaker));
            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 nmb = new GameObject("TextureBaker (" + largest + ")");

            nmb.transform.position = Vector3.zero;
            MB3_TextureBaker tb = nmb.AddComponent <MB3_TextureBaker>();

            tb.packingAlgorithm = MB2_PackingAlgorithmEnum.MeshBakerTexturePacker;
            MB3_MeshBakerGrouper mbg       = nmb.AddComponent <MB3_MeshBakerGrouper>();
            GameObject           meshBaker = new GameObject("MeshBaker");
            MB3_MeshBaker        mb        = meshBaker.AddComponent <MB3_MeshBaker>();

            meshBaker.transform.parent     = nmb.transform;
            mb.meshCombiner.settingsHolder = mbg;
            return(nmb.gameObject);
        }
    void OnGUI()
    {
        GUILayout.Label("Time to bake textures: " + elapsedTime);
        if (GUILayout.Button("Combine textures & build combined mesh all at once"))
        {
            MB3_MeshBaker    meshbaker    = target.GetComponentInChildren <MB3_MeshBaker>();
            MB3_TextureBaker textureBaker = target.GetComponent <MB3_TextureBaker>();

            //These can be assets configured at runtime or you can create them
            // on the fly like this
            textureBaker.textureBakeResults = ScriptableObject.CreateInstance <MB2_TextureBakeResults>();
            textureBaker.resultMaterial     = new Material(Shader.Find(GetShaderNameForPipeline()));

            float t1 = Time.realtimeSinceStartup;
            textureBaker.CreateAtlases();
            elapsedTime = Time.realtimeSinceStartup - t1;

            meshbaker.ClearMesh();             //only necessary if your not sure whats in the combined mesh
            meshbaker.textureBakeResults = textureBaker.textureBakeResults;

            //Add the objects to the combined mesh
            meshbaker.AddDeleteGameObjects(textureBaker.GetObjectsToCombine().ToArray(), null, true);

            meshbaker.Apply();
        }

        if (GUILayout.Button("Combine textures & build combined mesh using coroutine"))
        {
            Debug.Log("Starting to bake textures on frame " + Time.frameCount);
            MB3_TextureBaker textureBaker = target.GetComponent <MB3_TextureBaker>();

            //These can be assets configured at runtime or you can create them
            // on the fly like this
            textureBaker.textureBakeResults = ScriptableObject.CreateInstance <MB2_TextureBakeResults>();
            textureBaker.resultMaterial     = new Material(Shader.Find(GetShaderNameForPipeline()));

            //register an OnSuccess function to be called when texture baking is complete
            textureBaker.onBuiltAtlasesSuccess = new MB3_TextureBaker.OnCombinedTexturesCoroutineSuccess(OnBuiltAtlasesSuccess);
            StartCoroutine(textureBaker.CreateAtlasesCoroutine(null, result, false, null, .01f));
        }
    }
    void Start()
    {
        mbd = GetComponentInChildren <MB3_MeshBaker>();

        // instantiate game objects
        int dim = 25;

        GameObject[] gos = new GameObject[dim * dim];
        for (int i = 0; i < dim; i++)
        {
            for (int j = 0; j < dim; j++)
            {
                GameObject go = (GameObject)Instantiate(prefab);
                gos[i * dim + j] = go.GetComponentInChildren <MeshRenderer>().gameObject;
                float randx = Random.Range(-4f, 4f);
                float randz = Random.Range(-4f, 4f);
                go.transform.position = (new Vector3(9f * i + randx, 0, 9f * j + randz));
                float randrot = Random.Range(0, 360);
                go.transform.rotation = Quaternion.Euler(0, randrot, 0);
                Vector3 randscale = Vector3.one + Vector3.one * GaussianValue() * .15f;
                go.transform.localScale = randscale;
                //put every third object in a list so we can add and delete it later
                if ((i * dim + j) % 3 == 0)
                {
                    objsInCombined.Add(gos[i * dim + j]);
                }
            }
        }
        //add objects to combined mesh
        mbd.AddDeleteGameObjects(gos, null, true);
        mbd.Apply();

        objs = objsInCombined.ToArray();
        //start routine which will periodically add and delete objects
        StartCoroutine(largeNumber());
    }
Пример #14
0
 void Start()
 {
     meshbaker = GetComponent <MB3_MeshBaker> ();
     stringId  = gameObject.name + Random.Range(0, 100000);         // unique name thing
 }
    private static bool ProcessMesh(Renderer r, Mesh m, List <UnityTransform> unityTransforms, MB3_MeshBaker mb)
    {
        unityTransforms.Clear();
        // position rotation and scale are baked into combined mesh.
        // Remember all the transforms settings then
        // record transform values to root of hierarchy
        Transform t = r.transform;

        if (t != t.root)
        {
            do
            {
                unityTransforms.Add(new UnityTransform(t));
                t = t.parent;
            } while (t != null && t != t.root);
        }

        //add the root
        unityTransforms.Add(new UnityTransform(t.root));

        //position at identity
        for (int k = 0; k < unityTransforms.Count; k++)
        {
            unityTransforms[k].t.localPosition = Vector3.zero;
            unityTransforms[k].t.localRotation = Quaternion.identity;
            unityTransforms[k].t.localScale    = Vector3.one;
        }

        //bake the mesh
        MB3_MeshCombinerSingle mc = (MB3_MeshCombinerSingle)mb.meshCombiner;

        if (!MB3_BakeInPlace.BakeOneMesh(mc, m, r.gameObject))
        {
            return(false);
        }

        //replace the mesh
        if (r is MeshRenderer)
        {
            MeshFilter mf = r.gameObject.GetComponent <MeshFilter>();
            mf.sharedMesh = m;
        }
        else
        { //skinned mesh
            SkinnedMeshRenderer smr = r.gameObject.GetComponent <SkinnedMeshRenderer>();
            smr.sharedMesh = m;
            smr.bones      = ((SkinnedMeshRenderer)mc.targetRenderer).bones;
        }

        if (mc.targetRenderer != null)
        {
            SetMaterials(mc.targetRenderer.sharedMaterials, r);
        }

        //restore the transforms
        for (int k = 0; k < unityTransforms.Count; k++)
        {
            unityTransforms[k].t.localPosition = unityTransforms[k].p;
            unityTransforms[k].t.localRotation = unityTransforms[k].q;
            unityTransforms[k].t.localScale    = unityTransforms[k].s;
        }

        mc.SetMesh(null);
        return(true);
    }
    private static void ProcessPrefabRowReplaceTargetPrefab(MB3_BatchPrefabBaker pb, MB3_BatchPrefabBaker.MB3_PrefabBakerRow pr, MB2_TextureBakeResults tbr, List <UnityTransform> unityTransforms, MB3_MeshBaker mb)
    {
        if (pb.LOG_LEVEL >= MB2_LogLevel.info)
        {
            Debug.Log("==== Processing Source Prefab " + pr.sourcePrefab);
        }

        GameObject srcPrefab        = pr.sourcePrefab;
        GameObject targetPrefab     = pr.resultPrefab;
        string     targetPrefabName = AssetDatabase.GetAssetPath(targetPrefab);
        GameObject prefabInstance   = GameObject.Instantiate(srcPrefab);

        Renderer[] rs = prefabInstance.GetComponentsInChildren <Renderer>();
        if (rs.Length < 1)
        {
            Debug.LogWarning("Prefab " + pr.sourcePrefab + " does not have a renderer");
            DestroyImmediate(prefabInstance);
            return;
        }

        Renderer[] sourceRenderers = prefabInstance.GetComponentsInChildren <Renderer>();

        Dictionary <Mesh, List <ProcessedMeshInfo> > processedMeshesSrcToTargetMap = new Dictionary <Mesh, List <ProcessedMeshInfo> >();

        for (int i = 0; i < sourceRenderers.Length; i++)
        {
            if (!IsGoodToBake(sourceRenderers[i], tbr))
            {
                continue;
            }

            Mesh sourceMesh = MB_Utility.GetMesh(sourceRenderers[i].gameObject);

            if (pb.LOG_LEVEL >= MB2_LogLevel.debug)
            {
                Debug.Log("== Visiting renderer: " + sourceRenderers[i]);
            }
            // Try to find an existing mesh in the target that we can re-use
            Mesh      targetMeshAsset = null;
            Transform tr = FindCorrespondingTransform(prefabInstance.transform, sourceRenderers[i].transform, targetPrefab.transform);
            if (tr != null)
            {
                Mesh targMesh = MB_Utility.GetMesh(tr.gameObject);

                // Only replace target meshes if they are part of the target prefab.
                if (AssetDatabase.GetAssetPath(targMesh) == AssetDatabase.GetAssetPath(targetPrefab))
                {
                    targetMeshAsset = MB_Utility.GetMesh(tr.gameObject);
                    if (pb.LOG_LEVEL >= MB2_LogLevel.trace)
                    {
                        Debug.Log("Found correspoinding transform in target prefab: " + tr + " mesh: " + targetMeshAsset);
                    }
                }
            }

            // Check that we haven't processed this mesh already.
            List <ProcessedMeshInfo> lpmi;
            if (processedMeshesSrcToTargetMap.TryGetValue(sourceMesh, out lpmi))
            {
                Material[] srcMats = MB_Utility.GetGOMaterials(sourceRenderers[i].gameObject);
                for (int j = 0; j < lpmi.Count; j++)
                {
                    if (ComapreMaterials(srcMats, lpmi[j].srcMaterials))
                    {
                        if (pb.LOG_LEVEL >= MB2_LogLevel.trace)
                        {
                            Debug.Log("Found already processed mesh that uses the same mats");
                        }
                        targetMeshAsset = lpmi[j].targetMesh;
                        break;
                    }
                }
            }

            Material[]          sourceMaterials     = MB_Utility.GetGOMaterials(sourceRenderers[i].gameObject);
            TargetMeshTreatment targetMeshTreatment = TargetMeshTreatment.createNewMesh;
            string newMeshName = sourceMesh.name;
            if (targetMeshAsset != null)
            {
                // check if this mesh has already been processed
                processedMeshesSrcToTargetMap.TryGetValue(sourceMesh, out lpmi);
                if (lpmi != null)
                {
                    // check if this mesh uses the same materials as one of the processed meshs
                    bool       foundMatch            = false;
                    bool       targetMeshHasBeenUsed = false;
                    Material[] foundMatchMaterials   = null;
                    for (int j = 0; j < lpmi.Count; j++)
                    {
                        if (lpmi[j].targetMesh == targetMeshAsset)
                        {
                            targetMeshHasBeenUsed = true;
                        }
                        if (ComapreMaterials(sourceMaterials, lpmi[j].srcMaterials))
                        {
                            foundMatchMaterials = lpmi[j].targMaterials;
                            foundMatch          = true;
                            break;
                        }
                    }

                    if (foundMatch)
                    {
                        // If materials match then we can re-use this processed mesh don't process.
                        if (pb.LOG_LEVEL >= MB2_LogLevel.trace)
                        {
                            Debug.Log(" we can re-use this processed mesh don't process. " + targetMeshAsset);
                        }
                        targetMeshTreatment = TargetMeshTreatment.reuseMesh;
                        MB_Utility.SetMesh(sourceRenderers[i].gameObject, targetMeshAsset);
                        SetMaterials(foundMatchMaterials, sourceRenderers[i]);
                        continue;
                    }
                    else
                    {
                        if (targetMeshHasBeenUsed)
                        {
                            // we need a new target mesh with a safe different name
                            if (pb.LOG_LEVEL >= MB2_LogLevel.trace)
                            {
                                Debug.Log(" we can't re-use this processed mesh create new with different name. " + targetMeshAsset);
                            }
                            newMeshName         = GetNameForNewMesh(AssetDatabase.GetAssetPath(targetPrefab), newMeshName);
                            targetMeshTreatment = TargetMeshTreatment.createNewMesh;
                            targetMeshAsset     = null;
                        }
                        else
                        {
                            // is it safe to reuse the target mesh
                            // we need a new target mesh with a safe different name
                            if (pb.LOG_LEVEL >= MB2_LogLevel.trace)
                            {
                                Debug.Log(" we can replace this processed mesh. " + targetMeshAsset);
                            }
                            targetMeshTreatment = TargetMeshTreatment.replaceMesh;
                        }
                    }
                }
                else
                {
                    // source mesh has not been processed can reuse the target mesh
                    targetMeshTreatment = TargetMeshTreatment.replaceMesh;
                }
            }

            if (targetMeshTreatment == TargetMeshTreatment.replaceMesh)
            {
                if (pb.LOG_LEVEL >= MB2_LogLevel.debug)
                {
                    Debug.Log("Replace mesh " + targetMeshAsset);
                }
                EditorUtility.CopySerialized(sourceMesh, targetMeshAsset);
                AssetDatabase.SaveAssets();
                AssetDatabase.ImportAsset(targetPrefabName);
            }
            else if (targetMeshTreatment == TargetMeshTreatment.createNewMesh)
            {
                if (pb.LOG_LEVEL >= MB2_LogLevel.debug)
                {
                    Debug.Log("Create new mesh " + newMeshName);
                }
                targetMeshAsset      = GameObject.Instantiate <Mesh>(sourceMesh);
                targetMeshAsset.name = newMeshName;
                AssetDatabase.AddObjectToAsset(targetMeshAsset, targetPrefab);
#if UNITY_2018_3_OR_NEWER
                PrefabUtility.SavePrefabAsset(targetPrefab);
#endif
                Debug.Assert(targetMeshAsset != null);
                // need a new mesh
            }

            if (targetMeshTreatment == TargetMeshTreatment.createNewMesh || targetMeshTreatment == TargetMeshTreatment.replaceMesh)
            {
                if (ProcessMesh(sourceRenderers[i], targetMeshAsset, unityTransforms, mb))
                {
                    if (pb.LOG_LEVEL >= MB2_LogLevel.debug)
                    {
                        Debug.Log("Done processing mesh " + targetMeshAsset + " verts " + targetMeshAsset.vertexCount);
                    }
                    ProcessedMeshInfo pmi = new ProcessedMeshInfo();
                    pmi.targetMesh    = targetMeshAsset;
                    pmi.srcMaterials  = sourceMaterials;
                    pmi.targMaterials = sourceRenderers[i].sharedMaterials;
                    AddToDictionary(sourceMesh, pmi, processedMeshesSrcToTargetMap);
                }
                else
                {
                    Debug.LogError("Error processing mesh " + targetMeshAsset);
                }
            }

            MB_Utility.SetMesh(sourceRenderers[i].gameObject, targetMeshAsset);
        }

        // TODO replace this with MBVersionEditor.ReplacePrefab I tried to do this, but when I did,
        // ProcessedMeshInfo.targetMesh becomes null, not sure what is going on there.
        GameObject obj = (GameObject)AssetDatabase.LoadAssetAtPath(targetPrefabName, typeof(GameObject));
        PrefabUtility.ReplacePrefab(prefabInstance, obj, ReplacePrefabOptions.ReplaceNameBased);
        GameObject.DestroyImmediate(prefabInstance);

        // Destroy obsolete meshes
        UnityEngine.Object[] allAssets    = AssetDatabase.LoadAllAssetsAtPath(targetPrefabName);
        HashSet <Mesh>       usedByTarget = new HashSet <Mesh>();
        foreach (List <ProcessedMeshInfo> ll in processedMeshesSrcToTargetMap.Values)
        {
            for (int i = 0; i < ll.Count; i++)
            {
                usedByTarget.Add(ll[i].targetMesh);
            }
        }
        int numDestroyed = 0;
        for (int i = 0; i < allAssets.Length; i++)
        {
            if (allAssets[i] is Mesh)
            {
                if (!usedByTarget.Contains((Mesh)allAssets[i]) && AssetDatabase.GetAssetPath(allAssets[i]) == AssetDatabase.GetAssetPath(targetPrefab))
                {
                    numDestroyed++;
                    GameObject.DestroyImmediate(allAssets[i], true);
                }
            }
        }

        if (pb.LOG_LEVEL >= MB2_LogLevel.debug)
        {
            Debug.Log("Destroyed " + numDestroyed + " meshes");
        }
        AssetDatabase.SaveAssets();
        //--------------------------
    }
    public static void BakePrefabs(MB3_BatchPrefabBaker pb, bool doReplaceTargetPrefab)
    {
        if (pb.LOG_LEVEL >= MB2_LogLevel.info)
        {
            Debug.Log("Batch baking prefabs");
        }
        if (Application.isPlaying)
        {
            Debug.LogError("The BatchPrefabBaker cannot be run in play mode.");
            return;
        }

        MB3_MeshBaker mb = pb.GetComponent <MB3_MeshBaker>();

        if (mb == null)
        {
            Debug.LogError("Prefab baker needs to be attached to a Game Object with a MB3_MeshBaker component.");
            return;
        }

        if (mb.textureBakeResults == null)
        {
            Debug.LogError("Texture Bake Results is not set");
            return;
        }

        if (mb.meshCombiner.outputOption != MB2_OutputOptions.bakeMeshAssetsInPlace)
        {
            mb.meshCombiner.outputOption = MB2_OutputOptions.bakeMeshAssetsInPlace;
        }

        MB2_TextureBakeResults tbr = mb.textureBakeResults;

        HashSet <Mesh> sourceMeshes    = new HashSet <Mesh>();
        HashSet <Mesh> allResultMeshes = new HashSet <Mesh>();

        //validate prefabs
        for (int i = 0; i < pb.prefabRows.Length; i++)
        {
            if (pb.prefabRows[i] == null || pb.prefabRows[i].sourcePrefab == null)
            {
                Debug.LogError("Source Prefab on row " + i + " is not set.");
                return;
            }
            if (pb.prefabRows[i].resultPrefab == null)
            {
                Debug.LogError("Result Prefab on row " + i + " is not set.");
                return;
            }
            for (int j = i + 1; j < pb.prefabRows.Length; j++)
            {
                if (pb.prefabRows[i].sourcePrefab == pb.prefabRows[j].sourcePrefab)
                {
                    Debug.LogError("Rows " + i + " and " + j + " contain the same source prefab");
                    return;
                }
            }
            for (int j = 0; j < pb.prefabRows.Length; j++)
            {
                if (pb.prefabRows[i].sourcePrefab == pb.prefabRows[j].resultPrefab)
                {
                    Debug.LogError("Row " + i + " source prefab is the same as row " + j + " result prefab");
                    return;
                }
            }
            if (MBVersionEditor.GetPrefabType(pb.prefabRows[i].sourcePrefab) != MB_PrefabType.modelPrefab &&
                MBVersionEditor.GetPrefabType(pb.prefabRows[i].sourcePrefab) != MB_PrefabType.prefab)
            {
                Debug.LogError("Row " + i + " source prefab is not a prefab asset ");
                return;
            }
            if (MBVersionEditor.GetPrefabType(pb.prefabRows[i].resultPrefab) != MB_PrefabType.modelPrefab &&
                MBVersionEditor.GetPrefabType(pb.prefabRows[i].resultPrefab) != MB_PrefabType.prefab)
            {
                Debug.LogError("Row " + i + " result prefab is not a prefab asset");
                return;
            }

            GameObject so = (GameObject)Instantiate(pb.prefabRows[i].sourcePrefab);
            GameObject ro = (GameObject)Instantiate(pb.prefabRows[i].resultPrefab);
            Renderer[] rs = (Renderer[])so.GetComponentsInChildren <Renderer>();

            for (int j = 0; j < rs.Length; j++)
            {
                if (IsGoodToBake(rs[j], tbr))
                {
                    sourceMeshes.Add(MB_Utility.GetMesh(rs[j].gameObject));
                }
            }
            rs = (Renderer[])ro.GetComponentsInChildren <Renderer>();

            for (int j = 0; j < rs.Length; j++)
            {
                Renderer r = rs[j];
                if (r is MeshRenderer || r is SkinnedMeshRenderer)
                {
                    Mesh m = MB_Utility.GetMesh(r.gameObject);
                    if (m != null)
                    {
                        allResultMeshes.Add(m);
                    }
                }
            }
            DestroyImmediate(so); //todo should cache these and have a proper cleanup at end
            DestroyImmediate(ro);
        }

        sourceMeshes.IntersectWith(allResultMeshes);
        HashSet <Mesh> sourceMeshesThatAreUsedByResult = sourceMeshes;

        if (sourceMeshesThatAreUsedByResult.Count > 0)
        {
            foreach (Mesh m in sourceMeshesThatAreUsedByResult)
            {
                Debug.LogWarning("Mesh " + m + " is used by both the source and result prefabs. New meshes will be created.");
            }
            //return;
        }

        List <UnityTransform> unityTransforms = new List <UnityTransform>();

        // Bake the meshes using the meshBaker component one prefab at a time
        for (int prefabIdx = 0; prefabIdx < pb.prefabRows.Length; prefabIdx++)
        {
            if (doReplaceTargetPrefab)
            {
                ProcessPrefabRowReplaceTargetPrefab(pb, pb.prefabRows[prefabIdx], tbr, unityTransforms, mb);
            }
            else
            {
                ProcessPrefabRowOnlyMeshesAndMaterials(pb, pb.prefabRows[prefabIdx], tbr, unityTransforms, mb);
            }
        }
        AssetDatabase.Refresh();
        mb.ClearMesh();
    }
    public void _bakePrefabs()
    {
        Debug.Log("Batch baking prefabs");
        if (Application.isPlaying)
        {
            Debug.LogError("The BatchPrefabBaker cannot be run in play mode.");
            return;
        }
        MB3_BatchPrefabBaker pb = (MB3_BatchPrefabBaker)target;
        MB3_MeshBaker        mb = pb.GetComponent <MB3_MeshBaker>();

        if (mb == null)
        {
            Debug.LogError("Prefab baker needs to be attached to a Game Object with a MB3_MeshBaker component.");
            return;
        }

        if (mb.textureBakeResults == null)
        {
            Debug.LogError("Texture Bake Results is not set");
            return;
        }

        if (mb.meshCombiner.outputOption != MB2_OutputOptions.bakeMeshAssetsInPlace)
        {
            mb.meshCombiner.outputOption = MB2_OutputOptions.bakeMeshAssetsInPlace;
        }

        MB2_TextureBakeResults tbr = mb.textureBakeResults;

        HashSet <Mesh> sourceMeshes    = new HashSet <Mesh>();
        HashSet <Mesh> allResultMeshes = new HashSet <Mesh>();

        //validate prefabs
        for (int i = 0; i < pb.prefabRows.Length; i++)
        {
            if (pb.prefabRows[i] == null || pb.prefabRows[i].sourcePrefab == null)
            {
                Debug.LogError("Source Prefab on row " + i + " is not set.");
                return;
            }
            if (pb.prefabRows[i].resultPrefab == null)
            {
                Debug.LogError("Result Prefab on row " + i + " is not set.");
                return;
            }
            for (int j = i + 1; j < pb.prefabRows.Length; j++)
            {
                if (pb.prefabRows[i].sourcePrefab == pb.prefabRows[j].sourcePrefab)
                {
                    Debug.LogError("Rows " + i + " and " + j + " contain the same source prefab");
                    return;
                }
            }
            for (int j = 0; j < pb.prefabRows.Length; j++)
            {
                if (pb.prefabRows[i].sourcePrefab == pb.prefabRows[j].resultPrefab)
                {
                    Debug.LogError("Row " + i + " source prefab is the same as row " + j + " result prefab");
                    return;
                }
            }
            if (PrefabUtility.GetPrefabType(pb.prefabRows[i].sourcePrefab) != PrefabType.ModelPrefab &&
                PrefabUtility.GetPrefabType(pb.prefabRows[i].sourcePrefab) != PrefabType.Prefab)
            {
                Debug.LogError("Row " + i + " source prefab is not a prefab asset");
                return;
            }
            if (PrefabUtility.GetPrefabType(pb.prefabRows[i].resultPrefab) != PrefabType.ModelPrefab &&
                PrefabUtility.GetPrefabType(pb.prefabRows[i].resultPrefab) != PrefabType.Prefab)
            {
                Debug.LogError("Row " + i + " result prefab is not a prefab asset");
                return;
            }

            GameObject so = (GameObject)Instantiate(pb.prefabRows[i].sourcePrefab);
            GameObject ro = (GameObject)Instantiate(pb.prefabRows[i].resultPrefab);
            Renderer[] rs = (Renderer[])so.GetComponentsInChildren <Renderer>();

            for (int j = 0; j < rs.Length; j++)
            {
                if (IsGoodToBake(rs[j], tbr))
                {
                    sourceMeshes.Add(MB_Utility.GetMesh(rs[j].gameObject));
                }
            }
            rs = (Renderer[])ro.GetComponentsInChildren <Renderer>();

            for (int j = 0; j < rs.Length; j++)
            {
                Renderer r = rs[j];
                if (r is MeshRenderer || r is SkinnedMeshRenderer)
                {
                    Mesh m = MB_Utility.GetMesh(r.gameObject);
                    if (m != null)
                    {
                        allResultMeshes.Add(m);
                    }
                }
            }
            DestroyImmediate(so);             //todo should cache these and have a proper cleanup at end
            DestroyImmediate(ro);
        }

        sourceMeshes.IntersectWith(allResultMeshes);
        HashSet <Mesh> sourceMeshesThatAreUsedByResult = sourceMeshes;

        if (sourceMeshesThatAreUsedByResult.Count > 0)
        {
            foreach (Mesh m in sourceMeshesThatAreUsedByResult)
            {
                Debug.LogWarning("Mesh " + m + " is used by both the source and result prefabs. New meshes will be created.");
            }
            //return;
        }

        Dictionary <string, string> createdMeshPaths = new Dictionary <string, string>();

        // Bake the meshes using the meshBaker component one prefab at a time
        for (int prefabIdx = 0; prefabIdx < pb.prefabRows.Length; prefabIdx++)
        {
            Debug.Log("==== Processing Source Prefab " + pb.prefabRows[prefabIdx].sourcePrefab);
            GameObject sceneObj     = (GameObject)Instantiate(pb.prefabRows[prefabIdx].sourcePrefab);
            GameObject resultPrefab = (GameObject)Instantiate(pb.prefabRows[prefabIdx].resultPrefab);

            Renderer[] rs = sceneObj.GetComponentsInChildren <Renderer>();
            if (rs.Length < 1)
            {
                Debug.LogWarning("Prefab " + prefabIdx + " does not have a renderer");
                DestroyImmediate(sceneObj);
                DestroyImmediate(resultPrefab);
                continue;
            }

            List <Mesh>           usedMeshes      = new List <Mesh>();
            List <UnityTransform> unityTransforms = new List <UnityTransform>();
            for (int j = 0; j < rs.Length; j++)
            {
                unityTransforms.Clear();
                Renderer r = rs[j];

                if (!IsGoodToBake(r, tbr))
                {
                    continue;
                }

                //find the corresponding mesh in the result prefab
                string resultFolderPath = AssetDatabase.GetAssetPath(pb.prefabRows[prefabIdx].resultPrefab);
                resultFolderPath = Path.GetDirectoryName(resultFolderPath);

                Mesh      m    = null;
                Transform tRes = FindCorrespondingTransform(sceneObj.transform, r.transform, resultPrefab.transform);
                if (tRes != null)
                {
                    m = MB_Utility.GetMesh(tRes.gameObject);
                }

                //if the meshes on source and result are the same we want to remove mesh so will create a new one
                if (sourceMeshesThatAreUsedByResult.Contains(m))
                {
                    Debug.LogWarning("Source and result prefabs share a mesh. Creating a new mesh for " + m);
                    MB_Utility.SetMesh(tRes.gameObject, null);
                    m = null;
                }


                string meshPath;
                //check that the mesh is an asset and that we have not used it already
                if (m != null && AssetDatabase.IsMainAsset(m.GetInstanceID()) && !usedMeshes.Contains(m))
                {
                    meshPath = AssetDatabase.GetAssetPath(m);
                    if (createdMeshPaths.ContainsKey(meshPath))
                    {
                        Debug.LogWarning("Different result prefabs share a mesh." + meshPath);
                    }
                }
                else                     //create a new mesh asset with a unique name
                {
                    string resultPrefabFilename = AssetDatabase.GetAssetPath(pb.prefabRows[prefabIdx].resultPrefab);
                    resultPrefabFilename = resultPrefabFilename.Substring(0, resultPrefabFilename.Length - ".prefab".Length) + ".asset";
                    meshPath             = AssetDatabase.GenerateUniqueAssetPath(resultPrefabFilename);
                    m = new Mesh();
                    AssetDatabase.CreateAsset(m, meshPath);
                    m = (Mesh)AssetDatabase.LoadAssetAtPath(meshPath, typeof(Mesh));
                }
                Debug.Log("  creating new mesh asset at path " + meshPath);
                if (!createdMeshPaths.ContainsKey(meshPath))
                {
                    createdMeshPaths.Add(meshPath, meshPath);
                }

                // position rotation and scale are baked into combined mesh.
                // Remember all the transforms settings then
                // record transform values to root of hierarchy
                Transform t = r.transform;
                if (t != t.root)
                {
                    do
                    {
                        unityTransforms.Add(new UnityTransform(t));
                        t = t.parent;
                    } while (t != null && t != t.root);
                }
                //add the root
                unityTransforms.Add(new UnityTransform(t.root));

                //position at identity
                for (int k = 0; k < unityTransforms.Count; k++)
                {
                    unityTransforms[k].t.localPosition = Vector3.zero;
                    unityTransforms[k].t.localRotation = Quaternion.identity;
                    unityTransforms[k].t.localScale    = Vector3.one;
                }

                //throw new Exception("");
                //bake the mesh
                mb.ClearMesh();
                MB3_MeshCombiner mc = mb.meshCombiner;
                m = MB3_BakeInPlace.BakeOneMesh((MB3_MeshCombinerSingle)mc, meshPath, r.gameObject);

                //replace the mesh
                if (r is MeshRenderer)
                {
                    MeshFilter mf = r.gameObject.GetComponent <MeshFilter>();
                    mf.sharedMesh = m;
                }
                else                     //skinned mesh
                {
                    SkinnedMeshRenderer smr = r.gameObject.GetComponent <SkinnedMeshRenderer>();
                    smr.sharedMesh = m;
                    smr.bones      = ((SkinnedMeshRenderer)mc.targetRenderer).bones;
                }

                //replace the result material(s)
                if (mb.textureBakeResults.doMultiMaterial)
                {
                    Material[] rss = new Material[mb.textureBakeResults.resultMaterials.Length];
                    for (int k = 0; k < rss.Length; k++)
                    {
                        rss[k] = mb.textureBakeResults.resultMaterials[k].combinedMaterial;
                    }
                    r.sharedMaterials = rss;
                }
                else
                {
                    Material[] originalMats = r.sharedMaterials;
                    Material[] rss          = new Material[originalMats.Length];
                    for (int k = 0; k < originalMats.Length; k++)
                    {
                        if (tbr.ContainsMaterial(originalMats[k]))
                        {
                            rss[k] = mb.textureBakeResults.resultMaterial;
                        }
                        else
                        {
                            rss[k] = originalMats[k];
                        }
                    }

                    r.sharedMaterials = rss;
                }

                //restore the transforms
                for (int k = 0; k < unityTransforms.Count; k++)
                {
                    unityTransforms[k].t.localPosition = unityTransforms[k].p;
                    unityTransforms[k].t.localRotation = unityTransforms[k].q;
                    unityTransforms[k].t.localScale    = unityTransforms[k].s;
                }
            }

            //replace the result prefab with the source object
            //duplicate the sceneObj so we can replace the clone into the prefab, not the source
            GameObject clone = (GameObject)Instantiate(sceneObj);
            PrefabUtility.ReplacePrefab(clone, pb.prefabRows[prefabIdx].resultPrefab, ReplacePrefabOptions.ReplaceNameBased);
            DestroyImmediate(clone);
            DestroyImmediate(sceneObj);
            DestroyImmediate(resultPrefab);
        }
        AssetDatabase.Refresh();
        mb.ClearMesh();
    }
    void OnGUI()
    {
        scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width), GUILayout.Height(position.height));

        EditorGUILayout.LabelField("Generate Report", EditorStyles.boldLabel);
        EditorGUILayout.HelpBox("List shaders in scene prints a report to the console of shaders and which objects use them. This is useful for planning which objects to combine.", UnityEditor.MessageType.None);

        if (GUILayout.Button("List Shaders In Scene"))
        {
            listMaterialsInScene(false);
        }

        EditorGUILayout.Separator();
        MB_EditorUtil.DrawSeparator();

        EditorGUILayout.HelpBox("This feature is experimental. It should be safe to use as all it does is generate game objects with Mesh and Material bakers " +
                                "on them and assets for the combined materials.\n\n" +
                                "Creates bakers and combined material assets in your scene based on the groupings in 'Generate Report'." +
                                "Some configuration may still be required after bakers are generated. Groups are created for objects that " +
                                "use the same material(s), shader(s) and lightmap. These groups should produce good results when baked.\n\n" +
                                "This feature groups objects conservatively so bakes almost always work.   This is not the only way to group objects. Objects with different shaders can also be grouped but results are" +
                                " less preditable. Meshes with submeshes are only" +
                                "grouped if all meshes use the same set of shaders.", UnityEditor.MessageType.None);

        EditorGUILayout.LabelField(autoGenerateGUIContent, EditorStyles.boldLabel);
        autoGenerateMeshBakers = EditorGUILayout.Foldout(autoGenerateMeshBakers, "Show Tools");
        if (autoGenerateMeshBakers)
        {
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Select Folder For Combined Material Assets"))
            {
                generate_AssetsFolder = EditorUtility.SaveFolderPanel("Create Combined Material Assets In Folder", "", "");
                generate_AssetsFolder = "Assets" + generate_AssetsFolder.Replace(Application.dataPath, "") + "/";
            }
            EditorGUILayout.LabelField("Folder: " + generate_AssetsFolder);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Included Objects Must Be Static", GUILayout.Width(200));
            generate_IncludeStaticObjects = EditorGUILayout.Toggle(GUIContent.none, generate_IncludeStaticObjects);
            EditorGUILayout.EndHorizontal();
            generate_LightmapOption = (LightMapOption)EditorGUILayout.EnumPopup("Lightmapping", generate_LightmapOption);
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Generate Mesh Bakers"))
            {
                listMaterialsInScene(true);
            }
            if (GUILayout.Button("Bake Every MeshBaker In Scene"))
            {
                try{
                    MB3_TextureBaker[] texBakers = (MB3_TextureBaker[])FindObjectsOfType(typeof(MB3_TextureBaker));
                    for (int i = 0; i < texBakers.Length; i++)
                    {
                        texBakers[i].CreateAtlases(updateProgressBar, true, new MB3_EditorMethods());
                    }
                    MB3_MeshBaker[] mBakers = (MB3_MeshBaker[])FindObjectsOfType(typeof(MB3_MeshBaker));
                    for (int i = 0; i < mBakers.Length; i++)
                    {
                        if (mBakers[i].textureBakeResults != null)
                        {
                            MB3_MeshBakerEditorFunctions.BakeIntoCombined(mBakers[i]);
                        }
                    }
                } catch (Exception e) {
                    Debug.LogError(e);
                }finally{
                    EditorUtility.ClearProgressBar();
                }
            }
            EditorGUILayout.EndHorizontal();
        }
        MB_EditorUtil.DrawSeparator();
        EditorGUILayout.Separator();

        EditorGUILayout.LabelField("Add Selected Meshes To Bakers", EditorStyles.boldLabel);
        EditorGUILayout.HelpBox("Select one or more objects in the hierarchy view. Child Game Objects with MeshRender will be added. Use the fields below to filter what is added.", UnityEditor.MessageType.None);
        target = (MB3_MeshBakerRoot)EditorGUILayout.ObjectField("Target to add objects to", target, typeof(MB3_MeshBakerRoot), true);

        if (target != null)
        {
            targetGO = target.gameObject;
        }
        else
        {
            targetGO = null;
        }

        if (targetGO != oldTargetGO)
        {
            textureBaker = targetGO.GetComponent <MB3_TextureBaker>();
            meshBaker    = targetGO.GetComponent <MB3_MeshBaker>();
            tbe          = new MB3_TextureBakerEditorInternal();
            mbe          = new MB3_MeshBakerEditorInternal();
            oldTargetGO  = targetGO;
        }

        onlyStaticObjects = EditorGUILayout.Toggle("Only Static Objects", onlyStaticObjects);

        onlyEnabledObjects = EditorGUILayout.Toggle("Only Enabled Objects", onlyEnabledObjects);

        excludeMeshesWithOBuvs = EditorGUILayout.Toggle("Exclude meshes with out-of-bounds UVs", excludeMeshesWithOBuvs);

        mat       = (Material)EditorGUILayout.ObjectField("Using Material", mat, typeof(Material), true);
        shaderMat = (Material)EditorGUILayout.ObjectField("Using Shader", shaderMat, typeof(Material), true);

        string[] lightmapDisplayValues = new string[257];
        int[]    lightmapValues        = new int[257];
        lightmapValues[0]        = -2;
        lightmapValues[1]        = -1;
        lightmapDisplayValues[0] = "don't filter on lightmapping";
        lightmapDisplayValues[1] = "not lightmapped";
        for (int i = 2; i < lightmapDisplayValues.Length; i++)
        {
            lightmapDisplayValues[i] = "" + i;
            lightmapValues[i]        = i;
        }
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Using Lightmap Index ");
        lightmapIndex = EditorGUILayout.IntPopup(lightmapIndex,
                                                 lightmapDisplayValues,
                                                 lightmapValues);
        EditorGUILayout.EndHorizontal();

        if (GUILayout.Button("Add Selected Meshes"))
        {
            addSelectedObjects();
        }

        /*
         * if (GUILayout.Button("Add LOD To Selected")){
         *      addLODToSelected();
         * }
         *
         * if (GUILayout.Button("Remove LOD From All")){
         *      LODInternal[] lods = (LODInternal[]) FindObjectsOfType(typeof(LODInternal));
         *      for (int i = 0; i < lods.Length; i++){
         *              DestroyImmediate(lods[i]);
         *      }
         * }
         */

        if (textureBaker != null)
        {
            MB_EditorUtil.DrawSeparator();
            tbFoldout = EditorGUILayout.Foldout(tbFoldout, "Texture Baker");
            if (tbFoldout)
            {
                tbe.DrawGUI((MB3_TextureBaker)textureBaker, typeof(MB3_MeshBakerEditorWindow));
            }
        }
        if (meshBaker != null)
        {
            MB_EditorUtil.DrawSeparator();
            mbFoldout = EditorGUILayout.Foldout(mbFoldout, "Mesh Baker");
            if (mbFoldout)
            {
                mbe.DrawGUI((MB3_MeshBaker)meshBaker, typeof(MB3_MeshBakerEditorWindow));
            }
        }
        EditorGUILayout.EndScrollView();
    }
	void drawTabAddObjectsToBakers(){
		EditorGUILayout.HelpBox("Select one or more objects in the hierarchy view. Child Game Objects with MeshRender will be added. Use the fields below to filter what is added.", UnityEditor.MessageType.None);
		target = (MB3_MeshBakerRoot) EditorGUILayout.ObjectField("Target to add objects to",target,typeof(MB3_MeshBakerRoot),true);
		
		if (target != null){
			targetGO = target.gameObject;
		} else {
			targetGO = null;	
		}
		
		if (targetGO != oldTargetGO && targetGO != null){
			textureBaker = targetGO.GetComponent<MB3_TextureBaker>();
			meshBaker = targetGO.GetComponent<MB3_MeshBaker>();
			tbe = new MB3_TextureBakerEditorInternal();
			mbe = new MB3_MeshBakerEditorInternal();
			oldTargetGO = targetGO;
		}

		EditorGUIUtility.labelWidth = 300;
		onlyStaticObjects = EditorGUILayout.Toggle("Only Static Objects", onlyStaticObjects);
		
		onlyEnabledObjects = EditorGUILayout.Toggle("Only Enabled Objects", onlyEnabledObjects);
		
		excludeMeshesWithOBuvs = EditorGUILayout.Toggle("Exclude meshes with out-of-bounds UVs", excludeMeshesWithOBuvs);

		excludeMeshesAlreadyAddedToBakers = EditorGUILayout.Toggle("Exclude GameObjects already added to bakers", excludeMeshesAlreadyAddedToBakers);

		mat = (Material) EditorGUILayout.ObjectField("Using Material",mat,typeof(Material),true);
		shaderMat = (Material) EditorGUILayout.ObjectField("Using Shader",shaderMat,typeof(Material),true);
		
		string[] lightmapDisplayValues = new string[257];
		int[] lightmapValues = new int[257];
		lightmapValues[0] = -2;
		lightmapValues[1] = -1;
		lightmapDisplayValues[0] = "don't filter on lightmapping";
		lightmapDisplayValues[1] = "not lightmapped";
		for (int i = 2; i < lightmapDisplayValues.Length; i++){
			lightmapDisplayValues[i] = "" + i;
			lightmapValues[i] = i;
		}
		EditorGUILayout.BeginHorizontal();
		EditorGUILayout.LabelField("Using Lightmap Index ");
		lightmapIndex = EditorGUILayout.IntPopup(lightmapIndex,
		                                         lightmapDisplayValues,
		                                         lightmapValues);
		EditorGUILayout.EndHorizontal();
		EditorGUILayout.Separator();
		
		if (GUILayout.Button("Add Selected Meshes To Target")){
			addSelectedObjects();
		}
		
		if (textureBaker != null){
			MB_EditorUtil.DrawSeparator();
			tbFoldout = EditorGUILayout.Foldout(tbFoldout,"Texture Baker");
			if (tbFoldout){
				tbe.DrawGUI((MB3_TextureBaker) textureBaker, typeof(MB3_MeshBakerEditorWindow));
			}
			
		}
		if (meshBaker != null){
			MB_EditorUtil.DrawSeparator();
			mbFoldout = EditorGUILayout.Foldout(mbFoldout,"Mesh Baker");
			if (mbFoldout){
				mbe.DrawGUI((MB3_MeshBaker) meshBaker, typeof(MB3_MeshBakerEditorWindow));
			}
		}
	}
Пример #21
0
    void drawTabAddObjectsToBakers()
    {
        if (helpBoxString == null)
        {
            helpBoxString = "";
        }
        EditorGUILayout.HelpBox("To add, select one or more objects in the hierarchy view. Child Game Objects with MeshRender or SkinnedMeshRenderer will be added. Use the fields below to filter what is added." +
                                "To remove, use the fields below to filter what is removed.\n" + helpBoxString, UnityEditor.MessageType.None);
        target = (MB3_MeshBakerRoot)EditorGUILayout.ObjectField("Target to add objects to", target, typeof(MB3_MeshBakerRoot), true);

        if (target != null)
        {
            targetGO = target.gameObject;
        }
        else
        {
            targetGO = null;
        }

        if (targetGO != oldTargetGO && targetGO != null)
        {
            textureBaker = targetGO.GetComponent <MB3_TextureBaker>();
            meshBaker    = targetGO.GetComponent <MB3_MeshBaker>();
            tbe          = new MB3_TextureBakerEditorInternal();
            mbe          = new MB3_MeshBakerEditorInternal();
            oldTargetGO  = targetGO;
            if (textureBaker != null)
            {
                serializedObject = new SerializedObject(textureBaker);
                tbe.OnEnable(serializedObject);
            }
            else if (meshBaker != null)
            {
                serializedObject = new SerializedObject(meshBaker);
                mbe.OnEnable(serializedObject);
            }
        }


        EditorGUIUtility.labelWidth = 300;
        onlyStaticObjects           = EditorGUILayout.Toggle("Only Static Objects", onlyStaticObjects);

        onlyEnabledObjects = EditorGUILayout.Toggle("Only Enabled Objects", onlyEnabledObjects);

        excludeMeshesWithOBuvs = EditorGUILayout.Toggle("Exclude meshes with out-of-bounds UVs", excludeMeshesWithOBuvs);

        excludeMeshesAlreadyAddedToBakers = EditorGUILayout.Toggle("Exclude GameObjects already added to bakers", excludeMeshesAlreadyAddedToBakers);

        mat       = (Material)EditorGUILayout.ObjectField("Using Material", mat, typeof(Material), true);
        shaderMat = (Material)EditorGUILayout.ObjectField("Using Shader", shaderMat, typeof(Material), true);

        string[] lightmapDisplayValues = new string[257];
        int[]    lightmapValues        = new int[257];
        lightmapValues[0]        = -2;
        lightmapValues[1]        = -1;
        lightmapDisplayValues[0] = "don't filter on lightmapping";
        lightmapDisplayValues[1] = "not lightmapped";
        for (int i = 2; i < lightmapDisplayValues.Length; i++)
        {
            lightmapDisplayValues[i] = "" + i;
            lightmapValues[i]        = i;
        }
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Using Lightmap Index ");
        lightmapIndex = EditorGUILayout.IntPopup(lightmapIndex,
                                                 lightmapDisplayValues,
                                                 lightmapValues);
        EditorGUILayout.EndHorizontal();
        if (regExParseError != null && regExParseError.Length > 0)
        {
            EditorGUILayout.HelpBox("Error In Regular Expression:\n" + regExParseError, MessageType.Error);
        }
        searchRegEx = EditorGUILayout.TextField(GUIContentRegExpression, searchRegEx);


        EditorGUILayout.Separator();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Add Selected Meshes To Target"))
        {
            addSelectedObjects();
        }
        if (GUILayout.Button("Remove Matching Meshes From Target"))
        {
            removeSelectedObjects();
        }
        EditorGUILayout.EndHorizontal();

        if (textureBaker != null)
        {
            MB_EditorUtil.DrawSeparator();
            tbFoldout = EditorGUILayout.Foldout(tbFoldout, "Texture Baker");
            if (tbFoldout)
            {
                tbe.DrawGUI(serializedObject, (MB3_TextureBaker)textureBaker, typeof(MB3_MeshBakerEditorWindow));
            }
        }
        if (meshBaker != null)
        {
            MB_EditorUtil.DrawSeparator();
            mbFoldout = EditorGUILayout.Foldout(mbFoldout, "Mesh Baker");
            if (mbFoldout)
            {
                mbe.DrawGUI(serializedObject, (MB3_MeshBaker)meshBaker, typeof(MB3_MeshBakerEditorWindow));
            }
        }
    }
 // Use this for initialization
 void Start()
 {
     meshbaker = GetComponent <MB3_MeshBaker> ();
 }