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); } }
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); } }
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); } }
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(); }
/// <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); }
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); }
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); }
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(); }
/// ///以下是网格操作 /// 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(); }
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"); } } }