public static EBWorldPainterData DataForCurrentScene() { EBWorldPainterData data = null; var path = DataPathForCurrentScene(); //try to load it if (path != null) { GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)); if (prefab) { //found it, load the data GameObject worldPainterGO = (GameObject)Instantiate(prefab); worldPainterGO.name = "WorldPainterData"; data = worldPainterGO.GetComponent <EBWorldPainterData>(); data.Unpack(); } } if (data == null) { //didn't end up with data, create a new one GameObject worldPainterGO = new GameObject("WorldPainterData", typeof(EBWorldPainterData)); data = worldPainterGO.GetComponent <EBWorldPainterData>(); var renderers = (MeshRenderer[])FindObjectsOfType(typeof(MeshRenderer)); data.SetWorldBounds(renderers); data.SetRegionBounds(renderers); } return(data); }
void InitWorldPainter() { if (inited) { return; } worldPainterData = DataForCurrentScene(); if (worldPainterData == null) { Debug.LogError("World Painter needs to be opened within a scene that has some MeshRenders in it"); return; } wantsMouseMove = true; var wpc = new GameObject("WorldPainterCamera", typeof(Camera), typeof(Skybox)); wpc.hideFlags = HideFlags.HideAndDontSave; cam = wpc.GetComponent <Camera>(); cam.transform.position = new Vector3(0, 100, 0); cam.transform.LookAt(Vector3.zero); cam.orthographic = true; cam.backgroundColor = Color.black; rt = new RenderTexture(textureSize, textureSize, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default); cam.targetTexture = rt; guiskin = (GUISkin)Resources.Load("EBWorldPainterAssets/wp_gui_skin"); textures = new Texture[(int)TextureFills.Count]; textures[(int)TextureFills.White] = GenerateColorTexture(Color.white); textures[(int)TextureFills.Gray] = GenerateColorTexture(Color.gray); textures[(int)TextureFills.Blue] = GenerateColorTexture(Color.blue); textures[(int)TextureFills.Green] = GenerateColorTexture(Color.green); textures[(int)TextureFills.Red] = GenerateColorTexture(Color.red); inited = true; }
public static void SaveDataForCurrentScene(EBWorldPainterData data) { //update region bounds var renderers = (MeshRenderer[])FindObjectsOfType(typeof(MeshRenderer)); data.SetRegionBounds(renderers); //save var path = DataPathForCurrentScene(); if (path == null) { return; } GameObject worldPainterGO = new GameObject("WorldPainterData", typeof(EBWorldPainterData)); EBWorldPainterData worldPainterData = worldPainterGO.GetComponent <EBWorldPainterData>(); worldPainterData.Clone(data); PrefabUtility.CreatePrefab(path, worldPainterGO, ReplacePrefabOptions.ReplaceNameBased); DestroyImmediate(worldPainterGO); AssetDatabase.SaveAssets(); }
private Dictionary <EBWorldPainterData.Region, Partition> PartitionMeshes(Renderer[] renderers, EBWorldPainterData worldPainterData) { if (renderers.Length == 0) { return(new Dictionary <EBWorldPainterData.Region, Partition>()); } EB.Debug.Log("Partition 1"); Dictionary <EBWorldPainterData.Region, Partition> partitions = new Dictionary <EBWorldPainterData.Region, Partition> (); for (int i = 0; i < worldPainterData.regions.Count; ++i) { Partition partition = new Partition(); partition.name = i.ToString(); partitions.Add(worldPainterData.regions[i], partition); } EB.Debug.Log("Partition 2"); foreach (Renderer renderer in renderers) { if (!RendererIsMergeable(renderer)) { continue; } EBWorldPainterData.Point p = new EBWorldPainterData.Point(new Vector2(renderer.bounds.center.x, renderer.bounds.center.z)); EBWorldPainterData.Region region; EBWorldPainterData.Region[] regions = worldPainterData.RegionsPointIsInside(p); if (regions.Length < 1) { //No regions, just add it to the first one Debug.LogError("Renderer " + renderer.name + " with bounds " + renderer.bounds + " didn't fall into any partitions"); region = worldPainterData.ClosestRegionToPoint(p); } else { region = regions[0]; } Instance instance = new Instance(); instance.renderer = renderer; partitions[region].instances.Add(instance); } EB.Debug.Log("Partition 3"); foreach (var region in worldPainterData.regions) { if (partitions[region].instances.Count == 0) { partitions.Remove(region); } } return(partitions); }
private void MergeWorld(WorldInfoInternal worldInfo, Dictionary <int, Texture2D> lightmaps, EBWorldPainterData worldPainterData) { var world = GameObject.Find("z_track"); if (world == null) { return; } List <MeshFilter> filtersList = new List <MeshFilter> (); List <Transform> transforms = new List <Transform> (); foreach (KeyValuePair <string, PieceInfo> piece in worldInfo.pieces) { //for each prefab GameObject prefab = GetPrefabForCode(piece.Key); if (!prefab) { Debug.LogError("No prefab for code " + piece.Key); continue; } //for each zone in prefab EB.Debug.Log("TEST"); EB.Debug.Log(prefab.name); GameObject zones = EB.Util.GetObjectExactMatch(prefab, "Zones"); for (int i = 0; zones != null && i < zones.transform.childCount; i++) { //Transform child_transform = zones.transform.GetChild (i); //GameObject child = child_transform.gameObject; var unmerged = EB.Util.GetObjectExactMatch(prefab, "z_unmerged"); if (!unmerged) { Debug.LogError("No z_unmerged found in prefab " + prefab.name + ". Not merging this block."); continue; } var meshFilters = EB.Util.FindAllComponents <MeshFilter> (unmerged); foreach (var meshFilter in meshFilters) { if (!meshFilter.GetComponent <Renderer>() || !RendererHasLightmap(meshFilter.GetComponent <Renderer>())) { continue; } meshFilter.GetComponent <Renderer>().lightmapIndex += piece.Value.lightmapOffset; } filtersList.AddRange(meshFilters); transforms.AddRange(EB.Util.FindAllComponents <Transform>(unmerged)); } } EB.Debug.Log(filtersList.Count); return; ////skip hidden meshes //for (int i = filtersList.Count - 1; i >= 0; --i) //{ // MeshFilter filter = filtersList [i]; // if (!filter.gameObject.activeInHierarchy) // { // filtersList.RemoveAt(i); // } //} //var filters = filtersList.ToArray (); //var renderersFull = new MeshRenderer[filters.Length]; //int x = 0; //foreach (var filter in filters) //{ // var renderer = filter.GetComponent<Renderer>() as MeshRenderer; // if (renderer != null) // { // renderersFull[x] = renderer; // ++x; // } //} //var renderers = new MeshRenderer[x]; //System.Array.Copy(renderersFull, renderers, x); ////Paritition the meshes based of the World Painter data //var partitions = PartitionMeshes (renderers, worldPainterData); ////Merge the partitions, creating the new merged geometry and lightmaps //int saved = MergePartitions (partitions, lightmaps, world); //Debug.Log("Merged " + _worldName + ": saved " + saved + " draw calls"); ////remove any game objects in the z_unmerged heirarchy that are just meshes or empty transforms //int childDepth = 5; //for (int i = 0; i < childDepth; ++i) //{ // foreach (var filter in filters) // { // if (filter == null) // { // continue; // } // if (!RendererIsMergeable(filter.GetComponent<Renderer>())) // { // continue; // } // int childCount = filter.gameObject.transform.childCount; // Component[] components = filter.gameObject.GetComponents<Component> (); // if ((childCount == 0) && (components.Length == 3)) // { // //a transform, mesh filter, mesh renderer (which we merged), so kill the parent node // DestroyImmediate(filter.gameObject); // } // else if (i == (childDepth - 1)) // { // //must have other things; just kill the mesh filter and mesh renderer // DestroyImmediate(filter.GetComponent<Renderer>()); // DestroyImmediate(filter); // } // } // foreach (var transform in transforms) // { // if (transform == null) // { // continue; // } // if ((transform.childCount == 0) && (transform.gameObject.GetComponents<Component>().Length == 1)) // { // //empty node // DestroyImmediate(transform.gameObject); // } // } //} //EditorApplication.SaveAssets(); }
private void MergeSkinnedMeshes(WorldInfoInternal worldInfo, EBWorldPainterData worldPainterData) { var world = GameObject.Find("z_track"); if (world == null) { return; } Dictionary <EBWorldPainterData.Region, List <MeshFilter> > meshRegionMap = new Dictionary <EBWorldPainterData.Region, List <MeshFilter> > (); foreach (KeyValuePair <string, PieceInfo> piece in worldInfo.pieces) { GameObject prefab = GetPrefabForCode(piece.Key); if (!prefab) { Debug.LogError("No prefab for code " + piece.Key); continue; } //Deal with decision types+ MergeAdditionalCustom(piece.Key); MeshFilter[] meshFilters = GetSkinnedMeshsFor(piece.Key); if (meshFilters != null && meshFilters.Length > 0) { foreach (MeshFilter meshFilter in meshFilters) { EBWorldPainterData.Point point = new EBWorldPainterData.Point(new Vector2(meshFilter.GetComponent <Renderer>().bounds.center.x, meshFilter.GetComponent <Renderer>().bounds.center.z)); EBWorldPainterData.Region[] regions = worldPainterData.RegionsPointIsInside(point); if (regions.Length > 0) { if (!meshRegionMap.ContainsKey(regions[0])) { meshRegionMap[regions[0]] = new List <MeshFilter>(); } meshRegionMap[regions[0]].Add(meshFilter); } else { Debug.LogError("Meshfilter " + meshFilter.name + " does not fall into any region"); } } } } foreach (KeyValuePair <EBWorldPainterData.Region, List <MeshFilter> > meshRegion in meshRegionMap) { int id = meshRegion.Key.id; GameObject partition = GameObject.Find("Partition_" + id); if (partition == null) { Debug.LogError("NO Partition to parent to " + id); continue; } string savedName = _worldName + "_" + id; List <GameObject> gos = SkinnedMeshMerger.Merge(meshRegion.Value.ToArray(), savedName, _worldName); GameObject mergedBreakableMeshes = new GameObject("MergedBreakableMeshes"); mergedBreakableMeshes.transform.parent = partition.transform; foreach (GameObject g in gos) { g.layer = LayerMask.NameToLayer("environment"); g.transform.parent = mergedBreakableMeshes.transform; } } }
private void BuildWorld(BuildStages stages) { ShowProgressBar(PROGRESS_BAR_STAGE.Assembling); //WillBuildWorld(); //int changelist = 0; //need to bring this back //int changelist = CheckoutFiles(stages, false); //do we really want a new scene?? //EditorApplication.NewScene(); var world = new GameObject("z_track"); WorldInfo worldInfo = AssembleWorld(world); //save early, so that we have a scene name that we can link other data we save to //SaveScene(); //convert to internal representation, so we can carry around extra data that we need WorldInfoInternal worldInfoInternal = new WorldInfoInternal(); worldInfoInternal.pieces = new Dictionary <string, PieceInfo>(); foreach (var code in worldInfo.pieceCodes) { EB.Debug.Log(code); worldInfoInternal.pieces[code] = new PieceInfo(); } //assemble world //RenderSettingsType renderSettings = LoadOrCreateRenderSettings (); Dictionary <int, Texture2D> lightMaps = null; //need to figure out backed lighting /*if (stages.BakeLighting) * { * ShowProgressBar(PROGRESS_BAR_STAGE.Baking_Lighting); * Lightmapping.Bake(); * }*/ //need to gigure out the lightmap path /*if (stages.Merge) * { * lightMaps = LoadLightmaps(worldInfoInternal, stages.BakeLighting || stages.UseGlobalBakeLightmaps); * } * else * { * //reindex the lightmaps as we are going to directly load them * LoadLightmapsDirect(worldInfoInternal); * }*/ //SetupLightProbes(stages.BakeLightProbes, renderSettings); if (stages.Merge) { EBWorldPainterData worldPainterData = EBWorldPainter.DataForCurrentScene(); MergeWorld(worldInfoInternal, lightMaps, worldPainterData); //MergeSkinnedMeshes(worldInfoInternal, worldPainterData); } return; //ShowProgressBar(PROGRESS_BAR_STAGE.Cleaning_Up); //DidMergeWorld(); //SaveScene("Built"); //checkout anything that we created in between when we started and now //CheckoutFiles(stages, true, changelist); //DidBuildWorld(); //P4Connect.Config.PerforceEnabled = true; }
public void Clone(EBWorldPainterData toClone) { worldBounds = toClone.worldBounds; points = new List <Point>(toClone.points); regions = new List <Region>(toClone.regions); }