예제 #1
0
    /// Writes out the current scene's Sector/Portal graph as a .dot file
    /// which can be visualized in programs like GraphVis and the like.
    public static void WriteGraphDot()
    {
        if (!string.IsNullOrEmpty(EditorApplication.currentScene))
        {
            string sceneDir;
            string sceneName;
            SECTR_Asset.GetCurrentSceneParts(out sceneDir, out sceneName);
            sceneName = sceneName.Replace(".unity", "");

            string graphFile = SECTR_Graph.GetGraphAsDot(sceneName);

            string path = sceneDir + sceneName + "_SECTR_Graph.dot";
            File.WriteAllText(SECTR_Asset.UnityToOSPath(path), graphFile);
            AssetDatabase.Refresh();
            Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(path);
            EditorUtility.FocusProjectWindow();
        }
    }
예제 #2
0
    /// Reverts all imported Sectors into the scene. Safe to call from the command line.
    public static void RevertSceneChunks()
    {
        int numSectors = SECTR_Sector.All.Count;

        for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex)
        {
            SECTR_Sector sector = SECTR_Sector.All[sectorIndex];
            SECTR_Chunk  chunk  = sector.GetComponent <SECTR_Chunk>();
            if (!sector.Frozen && chunk &&
                System.IO.File.Exists(SECTR_Asset.UnityToOSPath(chunk.NodeName)))
            {
                EditorUtility.DisplayProgressBar("Reverting Scene Chunks", "Reverting " + sector.name, (float)sectorIndex / (float)numSectors);
                DeleteExportedSector(sector);
            }
        }
        if (SECTR_VC.CheckOut(EditorApplication.currentScene))
        {
            EditorApplication.SaveScene();
            SECTR_VC.WaitForVC();
        }
        EditorUtility.ClearProgressBar();
    }
    public override void OnInspectorGUI()
    {
        SECTR_Chunk  myChunk  = (SECTR_Chunk)target;
        SECTR_Sector mySector = myChunk.GetComponent <SECTR_Sector>();

        EditorGUILayout.BeginHorizontal();
        bool editMode        = !EditorApplication.isPlaying && !EditorApplication.isPaused;
        bool alreadyExported = myChunk && System.IO.File.Exists(SECTR_Asset.UnityToOSPath(myChunk.NodeName));

        GUI.enabled = editMode;
        if (mySector.Frozen)
        {
            // Import
            if (alreadyExported &&
                GUILayout.Button(new GUIContent("Import", "Imports this Sector into the scene.")))
            {
                modiferMode = ModifierMode.Import;
            }
            // Export
            GUI.enabled = false;
            GUILayout.Button(new GUIContent("Export", "Exports this Sector into a Chunk scene."));
            GUI.enabled = editMode;
        }
        else
        {
            // Revert
            if (alreadyExported &&
                GUILayout.Button(new GUIContent("Revert", "Discards changes to this Sector.")))
            {
                modiferMode = ModifierMode.Revert;
            }
            // Export
            if (GUILayout.Button(new GUIContent("Export", "Exports this Sector into a Chunk scene.")))
            {
                modiferMode = ModifierMode.Export;
            }
        }
        EditorGUILayout.EndHorizontal();

        base.OnInspectorGUI();

        if (!mySector.Frozen)
        {
            proxyFoldout = EditorGUILayout.Foldout(proxyFoldout, "Proxy Mesh Tool");
            if (proxyFoldout)
            {
                EditorGUILayout.BeginVertical();

                _BuildChildControls(myChunk.transform, true);

                if (GUILayout.Button("Create Proxy Mesh"))
                {
                    Dictionary <Material, List <CombineInstance> > meshHash = new Dictionary <Material, List <CombineInstance> >();
                    Matrix4x4 chunkWorldToLocal = myChunk.transform.worldToLocalMatrix;
                    foreach (Renderer renderer in checkState.Keys)
                    {
                        if (checkState[renderer])
                        {
                            MeshFilter meshFilter   = renderer.GetComponent <MeshFilter>();
                            int        numSubMeshes = meshFilter.sharedMesh.subMeshCount;
                            for (int submeshIndex = 0; submeshIndex < numSubMeshes; ++submeshIndex)
                            {
                                Material material = renderer.sharedMaterials[submeshIndex];
                                List <CombineInstance> materialMeshes = null;
                                if (!meshHash.TryGetValue(material, out materialMeshes))
                                {
                                    materialMeshes     = new List <CombineInstance>();
                                    meshHash[material] = materialMeshes;
                                }

                                CombineInstance instance = new CombineInstance();
                                instance.transform    = chunkWorldToLocal * renderer.transform.localToWorldMatrix;
                                instance.mesh         = renderer.GetComponent <MeshFilter>().sharedMesh;
                                instance.subMeshIndex = submeshIndex;
                                materialMeshes.Add(instance);
                            }
                        }
                    }
                    if (meshHash.Count > 0)
                    {
                        List <CombineInstance> combinedMeshes    = new List <CombineInstance>();
                        List <Material>        combinedMaterials = new List <Material>();
                        foreach (Material material in meshHash.Keys)
                        {
                            CombineInstance instance = new CombineInstance();
                            instance.mesh = new Mesh();
                            instance.mesh.CombineMeshes(meshHash[material].ToArray(), true, true);
                            combinedMeshes.Add(instance);
                            combinedMaterials.Add(material);
                        }

                        string sceneDir;
                        string sceneName;
                        string exportFolder = SECTR_Asset.MakeExportFolder("Proxies", false, out sceneDir, out sceneName);
                        myChunk.ProxyMesh = SECTR_Asset.Create <Mesh>(exportFolder, myChunk.name + "_Proxy", new Mesh());
                        myChunk.ProxyMesh.CombineMeshes(combinedMeshes.ToArray(), false, false);
                        myChunk.ProxyMaterials = combinedMaterials.ToArray();

                        int numCombined = combinedMeshes.Count;
                        for (int combinedIndex = 0; combinedIndex < numCombined; ++combinedIndex)
                        {
                            Mesh.DestroyImmediate(combinedMeshes[combinedIndex].mesh);
                        }
                        SECTR_VC.WaitForVC();
                    }
                    else
                    {
                        EditorUtility.DisplayDialog("Proxy Error", "Must have at least one mesh selected to create a proxy.", "Ok");
                    }
                }
                EditorGUILayout.EndVertical();
            }
        }
        GUI.enabled = true;

        if (modiferMode != ModifierMode.None)
        {
            EditorApplication.update += ExportUpdate;
        }
    }
예제 #4
0
    protected override void OnGUI()
    {
        base.OnGUI();

        List <SECTR_Sector> sortedSectors = new List <SECTR_Sector>(SECTR_Sector.All);

        sortedSectors.Sort(delegate(SECTR_Sector a, SECTR_Sector b) { return(a.name.CompareTo(b.name)); });
        int  numSectors      = sortedSectors.Count;
        bool sceneHasSectors = numSectors > 0;

        EditorGUILayout.BeginVertical();
        DrawHeader("SECTORS", ref sectorSearch, 100, true);
        Rect r = EditorGUILayout.BeginVertical();

        r.y           -= lineHeight;
        scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
        bool wasEnabled = GUI.enabled;

        GUI.enabled = false;
        GUI.Button(r, sceneHasSectors ? "" : "Current Scene Has No Sectors");
        GUI.enabled = wasEnabled;
        bool         allExported       = true;
        bool         allImported       = true;
        bool         someImported      = false;
        SECTR_Sector newSelectedSector = Selection.activeGameObject ?  Selection.activeGameObject.GetComponent <SECTR_Sector>() : null;;
        bool         mouseDown         = Event.current.type == EventType.MouseDown && Event.current.button == 0;

        if (mouseDown)
        {
            newSelectedSector = null;
        }

        for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex)
        {
            SECTR_Sector sector = sortedSectors[sectorIndex];
            if (sector.name.ToLower().Contains(sectorSearch.ToLower()))
            {
                bool selected = sector == selectedSector;
                Rect clipRect = EditorGUILayout.BeginHorizontal();
                if (selected)
                {
                    Rect selectionRect = clipRect;
                    selectionRect.y      += 1;
                    selectionRect.height -= 1;
                    GUI.Box(selectionRect, "", selectionBoxStyle);
                }
                if (sector.Frozen)
                {
                    allImported = false;
                }
                else
                {
                    if (sector.GetComponent <SECTR_Chunk>())
                    {
                        someImported = true;
                    }
                    allExported = false;
                }

                elementStyle.normal.textColor = selected ? Color.white : UnselectedItemColor;
                elementStyle.alignment        = TextAnchor.MiddleCenter;
                EditorGUILayout.LabelField(sector.name, elementStyle);

                EditorGUILayout.EndHorizontal();

                if (sector.gameObject.isStatic)
                {
                    float       buttonWidth     = 50;
                    SECTR_Chunk chunk           = sector.GetComponent <SECTR_Chunk>();
                    bool        alreadyExported = chunk && System.IO.File.Exists(SECTR_Asset.UnityToOSPath(chunk.NodeName));
                    if (sector.Frozen)
                    {
                        // Import
                        if (alreadyExported &&
                            GUI.Button(new Rect(0, clipRect.yMin, buttonWidth, clipRect.height), new GUIContent("Import", "Imports this Sector into the scene.")))
                        {
                            SECTR_StreamExport.ImportFromChunk(sector);
                            break;
                        }
                    }
                    else
                    {
                        // Revert
                        if (alreadyExported &&
                            GUI.Button(new Rect(0, clipRect.yMin, buttonWidth, clipRect.height), new GUIContent("Revert", "Discards changes to this Sector.")))
                        {
                            SECTR_StreamExport.DeleteExportedSector(sector);
                            chunk.enabled = true;
                            break;
                        }
                        // Export
                        if (GUI.Button(new Rect(clipRect.xMax - buttonWidth, clipRect.yMin, buttonWidth, clipRect.height), new GUIContent("Export", "Exports this Sector into a Chunk scene.")))
                        {
                            SECTR_StreamExport.ExportToChunk(sector);
                            break;
                        }
                    }
                }

                if (mouseDown && clipRect.Contains(Event.current.mousePosition))
                {
                    newSelectedSector = sector;
                }
            }
        }
        if (newSelectedSector != selectedSector)
        {
            selectedSector             = newSelectedSector;
            Selection.activeGameObject = selectedSector ? selectedSector.gameObject : null;
            if (SceneView.lastActiveSceneView)
            {
                SceneView.lastActiveSceneView.FrameSelected();
            }
            Repaint();
        }
        EditorGUILayout.EndScrollView();
        EditorGUILayout.EndVertical();

        string nullSearch = null;

        GUI.enabled = true;
        DrawHeader("EXPORT AND IMPORT", ref nullSearch, 0, true);
        wasEnabled = GUI.enabled;
        bool editMode = !EditorApplication.isPlaying && !EditorApplication.isPaused;

        GUI.enabled = sceneHasSectors && !allExported && wasEnabled && editMode;
        if (GUILayout.Button(new GUIContent("Export All Sectors", "Exports all static Sectors into Chunk scenes and prepares them for streaming.")))
        {
            SECTR_StreamExport.ExportSceneChunksUI();
            Repaint();
        }
        GUI.enabled = sceneHasSectors && !allImported && wasEnabled && editMode;
        if (GUILayout.Button(new GUIContent("Import All Sectors", "Imports all exported Chunks back into the scene.")))
        {
            SECTR_StreamExport.ImportSceneChunksUI();
            Repaint();
        }
        GUI.enabled = sceneHasSectors && !allExported && someImported && wasEnabled && editMode;
        if (GUILayout.Button(new GUIContent("Revert All Sectors", "Reverts all exported Chunks to their exported state.")))
        {
            SECTR_StreamExport.RevertSceneChunksUI();
            Repaint();
        }

        GUI.enabled = true;
        DrawHeader("LIGHTMAPPING", ref nullSearch, 0, true);
#if UNITY_5_LATE
        GUI.enabled = sceneHasSectors && selectedSector && allExported && wasEnabled && editMode;
        if (GUILayout.Button(new GUIContent("Lightmap Selected Sector", "Lightmaps selected Sector in isolation.")))
        {
            if (EditorUtility.DisplayDialog("Confirm Lightmap Bake", "Are you sure you want to bake lightmaps for " + selectedSector.name +
                                            "? Its lighting will not be affected by any other Sectors.", "Yes", "No"))
            {
                string[] paths = new string[2];
                paths[0] = EditorApplication.currentScene;
                paths[1] = selectedSector.GetComponent <SECTR_Chunk>().NodeName;
                Lightmapping.BakeMultipleScenes(paths);
            }
        }

        GUI.enabled = sceneHasSectors && allExported && wasEnabled && editMode;
        if (GUILayout.Button(new GUIContent("Lightmap All Sectors", "Lightmaps all exported Chunks.")))
        {
            if (EditorUtility.DisplayDialog("Confirm Lightmap Bake", "Are you sure you want to bake lightmaps for all subscenes? This may take quite a while.", "Yes", "No"))
            {
                string[] paths = new string[numSectors + 1];
                paths[0] = EditorApplication.currentScene;
                for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex)
                {
                    paths[sectorIndex + 1] = sortedSectors[sectorIndex].GetComponent <SECTR_Chunk>().NodeName;
                }
                Lightmapping.BakeMultipleScenes(paths);
            }
        }
#endif
        GUI.enabled = true;
        DrawHeader("EXTRA", ref nullSearch, 0, true);
        GUI.enabled = sceneHasSectors;
        if (GUILayout.Button(new GUIContent("Export Sector Graph Visualization", "Writes out a .dot file of the Sector/Portal graph, which can be visualized in GraphViz.")))
        {
            SECTR_StreamExport.WriteGraphDot();
        }
        GUI.enabled = wasEnabled;
        EditorGUILayout.EndVertical();
    }