コード例 #1
0
    void _applyProgramChanges()
    {
        if (prog == null)
        {
            return;
        }

        prog.importTriggeredByInspector = true;

        // 1st erase the store program
        if (storedProg)
        {
            KMImportSettings.RemoveProgram(storedProg);
        }
        // now store the prog in memory to the asset
        KMImportSettings.AddProgram(prog);

        // Trigger mesh reimport -> import processor will execute program
        EditorUtility.DisplayProgressBar(KMImportProcessor.ProgressTitle(prog), "Unity3D reimports model file", 0.0f);

        KMImportSettings.IncrementMasterImportRevision();

        // float dt = Time.realtimeSinceStartup;
        AssetDatabase.ImportAsset(assetPath);
        // dt = ;
        //Debug.LogError("Reimport took " + (Time.realtimeSinceStartup - dt)*1000.0f + " ms.");

        hasChanges = false;
        EditorUtility.ClearProgressBar();

        // Reload prog
        _initializeProgram();
    }
コード例 #2
0
    static string assetPath = "Assets/MeshProcessors/MeshImportProcessorSettings.asset";     // TODO: make this configurable?

    static void _assureInstance()
    {
        if (_instance == null)
        {
            _instance = AssetDatabase.LoadAssetAtPath(assetPath, typeof(KMImportSettings)) as KMImportSettings;
            if (_instance == null)
            {
                // Create a new file.
                // Maybe this could also search for moved files in the future.
                _instance = ScriptableObject.CreateInstance <KMImportSettings>();
                AssetDatabase.CreateAsset(_instance, assetPath);
                //	AssetDatabase.SaveAssets(); // maybe this crashes on first launch?

                // searching would be similar to this:

                /*	// Search for renamed prefab in project (maybe there's a more efficient way?)
                 *      string[] paths = AssetDatabase.GetAllAssetPaths();
                 *      foreach (string p in paths) {
                 *              GameObject candidate = AssetDatabase.LoadAssetAtPath(p, typeof(GameObject)) as GameObject;
                 *              if (candidate != null && candidate.GetComponent<KMImportSettingsRoot>() != null) {
                 *                      prefabPath = p;
                 *                      return candidate;
                 *              }
                 *      } */
            }
        }
    }
コード例 #3
0
    void _initializeProgram()
    {
        storedProg = null; prog = null; progGUI = null;

        // Look for a program stored in the asset.
        storedProg = KMImportSettings.ProgramForMesh(assetGUID, meshPath);
        if (storedProg != null)
        {
            // Create a copy of the program to work with.
            prog = ScriptableObject.CreateInstance <KMProcessorProgram>();
            EditorUtility.CopySerialized(storedProg, prog);
            int numProcessors = prog.processors.Length;
            for (int i = 0; i < numProcessors; ++i)
            {
                KrablMesh.Processor proc  = prog.processors[i];
                KrablMesh.Processor clone = ScriptableObject.CreateInstance(proc.GetType()) as KrablMesh.Processor;
                EditorUtility.CopySerialized(proc, clone);
                clone.hideFlags    = HideFlags.DontSave;
                prog.processors[i] = clone;
            }

            prog.hideFlags = HideFlags.DontSave;

            progGUI = (KMProcessorProgramGUI)Editor.CreateEditor(prog);

            if (progGUI != null)
            {
                progGUI.usedByMeshImporter = true;
            }
        }
    }
コード例 #4
0
    // Called from progGUI
    public void DeleteProgram()
    {
        if (prog == null)
        {
            return;
        }
        bool del = true;

        if (prog.processors.Length > 0)
        {
            del = EditorUtility.DisplayDialog("Delete Import Program", "Do you want to permanently delete this mesh import program?", "Delete", "Cancel");
        }
        if (del)
        {
            if (storedProg != null)
            {
                EditorUtility.DisplayProgressBar(KMImportProcessor.ProgressTitle(prog), "Unity3D reimports model file", 0.0f);
                KMImportSettings.RemoveProgram(storedProg);

                // Trigger model reimport
                AssetDatabase.ImportAsset(assetPath);
                EditorUtility.ClearProgressBar();
            }
            prog       = null; progGUI = null;
            storedProg = null;
        }
    }
コード例 #5
0
 static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromPath)
 {
     for (int i = 0; i < importedAssets.Length; ++i)
     {
         KMImportSettings kmis = AssetDatabase.LoadAssetAtPath(importedAssets[i], typeof(KMImportSettings)) as KMImportSettings;
         if (kmis != null)
         {
             KMImportSettings.SettingsReimported();
         }
     }
 }
コード例 #6
0
 void AddProgram()
 {
     // Create an empty program in memory
     prog = KMImportSettings.CreateProgram(assetGUID, meshPath, mesh);
     // Now create the GUI
     progGUI = (KMProcessorProgramGUI)Editor.CreateEditor(prog);
     if (progGUI != null)
     {
         progGUI.usedByMeshImporter = true;
     }
     hasChanges = true;
 }
コード例 #7
0
    void OnPostprocessModel(GameObject g)
    {
        dummy.Dummy();         // dummy call to silence the compiler. kmiphelper is needed to get messages if the build target changes
        importRevision = KMImportSettings.GetMasterImportRevision();

        // Collect all the meshes and their paths. -> to find duplicates that annoy me.
        //	List<Mesh> meshes = new List<Mesh>();
        //	List<string> meshnames = new List<string>();

        bool didProcess = false;

        foreach (MeshFilter mf in g.GetComponentsInChildren <MeshFilter>())
        {
            Mesh mesh = mf.sharedMesh;
            if (_processMesh(g, mesh))
            {
                didProcess = true;
            }
            if (mesh != null)
            {
                mf.sharedMesh = mesh;
            }
        }
        foreach (SkinnedMeshRenderer smr in g.GetComponentsInChildren <SkinnedMeshRenderer>())
        {
            Mesh mesh = smr.sharedMesh;
            if (_processMesh(g, mesh))
            {
                didProcess = true;
            }
            if (mesh != null)
            {
                smr.sharedMesh = mesh;
            }
        }

        // Write the revision to the revision database inside the Library folder.
        if (didProcess)
        {
            Dictionary <string, int> db = GetModelImportRevisionDictionary();
            db[AssetDatabase.AssetPathToGUID(assetPath)] = importRevision;
            StoreModelImportRevisionDictionary(db);
        }
    }
コード例 #8
0
    override public void OnInspectorGUI()
    {
        EditorGUILayout.HelpBox("This object holds all the information the Krabl mesh processor framework needs to import meshes.\n\n" +
                                "DO NOT touch this unless you wish to loose your processor programs.\n\n",
                                MessageType.Warning);

        if (KMImportSettings.DoDebug())
        {
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Show Child Assets"))
            {
                _showChildAssets(true);
            }
            if (GUILayout.Button("Hide Child Assets"))
            {
                _showChildAssets(false);
            }
            GUILayout.EndHorizontal();
        }
    }
コード例 #9
0
    public static void SettingsReimported()
    {
        _assureInstance();
        float tm = 0.0f;

        if (KMImportSettings.DoDebug())
        {
            tm = Time.realtimeSinceStartup;
            Debug.Log("Mesh Processor Settings were reimported.");
        }

        Dictionary <string, int> revisionDB = KMImportProcessor.GetModelImportRevisionDictionary();

        KMProcessorProgram[] programs = _instance.programs;
        for (int i = 0; i < programs.Length; ++i)
        {
            KMProcessorProgram prog = programs[i];
            if (prog != null)
            {
                int modelImportRevision = 0;                 // this is the revision number of the import on the running machine
                // prog.importRevision is the revision stored inside the importer asset
                // They need to be the same in order for the mesh to have the correct state.
                revisionDB.TryGetValue(prog.inAssetGUID, out modelImportRevision);
                //Debug.Log("P: " + path + " Rev New: " + rev);
                // If the importsettings changed on a different machine,
                // we need to reimport the changed assets
                if (modelImportRevision != prog.importRevision)
                {
                    string path = AssetDatabase.GUIDToAssetPath(prog.inAssetGUID);
                    if (path != null && path != "")
                    {
                        AssetDatabase.ImportAsset(path);
                    }
                }
            }
        }
        if (KMImportSettings.DoDebug())
        {
            Debug.Log("Settings reimported took " + (Time.realtimeSinceStartup - tm) * 1000.0f + " ms.");
        }
    }
コード例 #10
0
    bool _processMesh(GameObject container, Mesh umesh)
    {
#if UNITY_4_3 || UNITY_4_4 || UNITY_4_5
        if (umesh.blendShapeCount > 0)
        {
            Debug.Log("Krabl Mesh Processors can not yet process meshes with blendshapes.");
            return(false);
        }
#endif

        string assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
        //Debug.Log("Container guid: " + assetGUID);
        string meshPath = KrablMesh.UnityEditorUtils.MeshPathInAsset(umesh, container);
        //Debug.Log("Meshpath: " + meshPath);

        KMProcessorProgram program = KMImportSettings.ProgramForMesh(assetGUID, meshPath);
        if (program == null)
        {
            return(false);
        }
        if (program.bypass)
        {
            return(true);
        }

        //	Debug.Log("KMImportProcessor Process " + container.name + "/" + umesh.name + " PRG: " + ((program == null) ? "NULL" : program.ToString()), umesh);

        KrablMesh.Processor[] processors = program.processors;
        if (true)           //program.importTriggeredByInspector == true) {
        // Set up progress indicators
        {
            program.importTriggeredByInspector = false;
            float numEnabled = 0.0f;
            for (int i = 0; i < processors.Length; ++i)
            {
                if (processors[i].enabled)
                {
                    numEnabled += 1.0f;
                }
            }
            float progStep   = (numEnabled > 0.0f) ? 1.0f / numEnabled : 1.0f;
            float progOffset = 0.0f;

            string title = ProgressTitle(program);
            for (int i = 0; i < processors.Length; ++i)
            {
                if (processors[i].enabled == true)
                {
                    float offset = progOffset;
                    processors[i].progressDelegate = delegate(string text, float val) {
                        EditorUtility.DisplayProgressBar(title, text, val * progStep + offset);
                    };
                    progOffset += progStep;
                }
            }
        }

        Mesh processedMesh = program.Process(umesh, EditorUserBuildSettings.selectedBuildTargetGroup.ToString());
        processedMesh.name = umesh.name;
        if (program.unityOptimizeMesh)
        {
            ;
        }
        EditorUtility.ClearProgressBar();

        // Store Revision to program
        program.importRevision = importRevision;
        EditorUtility.SetDirty(program);
        //AssetDatabase.SaveAssets();

        if (program.targetPath.Equals("replace"))
        {
            umesh.Clear();
            EditorUtility.CopySerialized(processedMesh, umesh);
        }
        else
        {
            _outputToAsset(processedMesh, program.targetPath);
        }
        GameObject.DestroyImmediate(processedMesh);

        return(true);
    }
コード例 #11
0
 public static void buildTargetChanged()
 {
     //Debug.Log("Build Target Changed.");
     KMImportSettings.PlatformChanged();
 }
コード例 #12
0
    public void DrawImporterGUI(KMMeshInspector inspector)
    {
        serializedObject.Update();

        modifiedDuringLastUpdate = false;
        if (prog == null)
        {
            return;
        }

        // Adding processors at the end. Triggered from the menu callback
        // During the callback this does no longer work in Unity 4.3
        if (processorToAddID != null)
        {
            AddProcessor(processorToAddID);
            processorToAddID = null;
        }
        //KrablMesh.Processor[] processors = prog.processors;

        if (titleBoxStyle == null)
        {
            titleBoxStyle         = new GUIStyle("Box");
            titleBoxStyle.margin  = new RectOffset(0, 0, 0, 0);
            titleBoxStyle.padding = new RectOffset(0, 0, 4, 4);
        }
        GUILayout.BeginVertical(titleBoxStyle);

        GUILayout.BeginHorizontal();
        if (titleStyle == null)
        {
            titleStyle           = new GUIStyle(EditorStyles.largeLabel);
            titleStyle.fontStyle = FontStyle.Bold;
        }
        string titleString = "Mesh Import Program";

        if (KMImportSettings.DoDebug())
        {
            titleString += " (r" + prog.importRevision + ")";
        }
        GUILayout.Label(titleString, titleStyle);

        GUILayout.FlexibleSpace();

        if (GUILayout.Button(new GUIContent("Delete", "Delete the mesh import program for this mesh")))
        {
            // Call the inspector as only it can delete the program (and this editor).
            inspector.DeleteProgram();
        }
        GUILayout.EndHorizontal();
        EditorGUILayout.Separator();

        EditorGUILayout.PropertyField(inputToleranceProp, new GUIContent("Input Tolerance", "The maximum difference considered equal for vertices and normals when they are fed into the processor chain. " +
                                                                         "Usually 0 should work fine, but apparently some modelling software produces only nearly equal vertices/normals. " + "" +
                                                                         "If weird topology is produced, try setting the value to something like 1e-6"));


        /*	EditorGUILayout.LabelField("Output Mesh Path");
         *      EditorGUILayout.BeginHorizontal();
         *      if (!prog.targetPath.Equals("replace")) {
         *              EditorGUILayout.PropertyField(targetPathProp, GUIContent.none);
         *              if (GUILayout.Button("Replace", EditorStyles.miniButton, GUILayout.ExpandWidth(false))) {
         *                      targetPathProp.stringValue = "replace";
         *              }
         *      } else {
         *              EditorGUILayout.LabelField("Replace imported Mesh");
         *              if (GUILayout.Button("Override", EditorStyles.miniButton, GUILayout.ExpandWidth(false))) {
         *                      targetPathProp.stringValue = KrablMeshUnityPreferences.defaultExtraMeshOutputPath + "/" + prog.inContainerName + "/" + prog.inMeshPath;
         *              }
         *      }
         *      EditorGUILayout.EndHorizontal();
         */

        EditorGUILayout.PropertyField(unityOptimizeMeshProp, new GUIContent("Optimize Mesh", "Improve the mesh element order after processing to render faster on the GPU"));

        EditorGUILayout.PropertyField(bypassProp, new GUIContent("Bypass Program", "Disable all processors and output the originally imported mesh"));

        GUILayout.EndVertical();

        if (bypassProp.boolValue == true)
        {
            GUI.enabled = false;
        }
        // Draw processor GUIs below for importer
        if (processorsProp != null)
        {
            int toDelete = -1, moveUp = -1, moveDown = -1;
            KrablMesh.ProcessorEditor edit;
            for (int i = 0; i < processorsProp.arraySize; ++i)
            {
                KrablMesh.Processor p = processorsProp.GetArrayElementAtIndex(i).objectReferenceValue as KrablMesh.Processor;
                edit = null;
                if (p != null && processorEditors.TryGetValue(p, out edit) == false)
                {
                    edit = (p == null) ? null : Editor.CreateEditor(p) as KrablMesh.ProcessorEditor;
                    edit.usedByMeshImporter = usedByMeshImporter;
                    processorEditors.Add(p, edit);
                }
                //fold = EditorGUILayout.InspectorTitlebar(fold, p);

                EditorGUILayout.BeginHorizontal();
                if (p == null)
                {
                    EditorGUILayout.LabelField("-- NULL PROCESSOR --");
                }
                else
                {
                    if (processorNameStyle == null)
                    {
                        processorNameStyle           = new GUIStyle(EditorStyles.toggle);
                        processorNameStyle.fontStyle = FontStyle.Bold;
                    }

                    edit.serializedObject.Update();
                    SerializedProperty enabledProp = edit.serializedObject.FindProperty("enabled");
                    if (enabledProp != null)
                    {
                        enabledProp.boolValue = GUILayout.Toggle(enabledProp.boolValue, new GUIContent(p.Name(), edit.ProcessorToolTip()), processorNameStyle, GUILayout.Width(146.0f));
                    }
                    if (edit.serializedObject.ApplyModifiedProperties())
                    {
                        modifiedDuringLastUpdate = true;
                    }
                }
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Up", EditorStyles.miniButtonLeft))
                {
                    moveUp = i;
                }
                if (GUILayout.Button("Down", EditorStyles.miniButtonRight))
                {
                    moveDown = i;
                }
                GUILayout.Space(5.0f);
                if (GUILayout.Button("DEL", EditorStyles.miniButton))
                {
                    toDelete = i;
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.Separator();

                if (p != null && edit != null)
                {
                    edit.OnInspectorGUI();
                    if (edit.modifiedDuringLastUpdate)
                    {
                        modifiedDuringLastUpdate = true;
                    }
                }
                EditorGUILayout.Separator();

                KrablMesh.UnityEditorUtils.GUILayoutAddHoriLine();
            }

            if (toDelete >= 0)
            {
                int last = processorsProp.arraySize - 1;
                processorsProp.MoveArrayElement(toDelete, last);
                processorsProp.DeleteArrayElementAtIndex(last);
                processorsProp.arraySize--;
            }
            else if (moveUp > 0)
            {
                processorsProp.MoveArrayElement(moveUp, moveUp - 1);
            }
            else if (moveDown >= 0 && moveDown < processorsProp.arraySize - 1)
            {
                processorsProp.MoveArrayElement(moveDown, moveDown + 1);
            }
        }
        EditorGUILayout.Separator();
        GUILayout.BeginHorizontal();
        GUILayout.FlexibleSpace();
        AddProcessorPopupButton("Add Processor here...", largeButtonStyle, _addProcessorCallback);
        GUILayout.FlexibleSpace();
        GUILayout.EndHorizontal();
        EditorGUILayout.Separator();

        KrablMesh.UnityEditorUtils.GUILayoutAddHoriLine();
        if (serializedObject.ApplyModifiedProperties())
        {
            modifiedDuringLastUpdate = true;
        }
    }
コード例 #13
0
    override public void OnInspectorGUI()
    {
        if (target == null || serializedObject == null)
        {
            return;
        }

        if (!KMImportSettings.DoDebug())
        {
            EditorGUILayout.HelpBox("Mesh processors programs can only be used in imported programs displayed in the mesh inspector.", MessageType.Info);
        }
        else
        {
            DrawDefaultInspector();
        }
        return;

#if false
        serializedObject.Update();

        // This will become the realtime section eventually maybe.

        modifiedDuringLastUpdate = false;
        //float dummy = 0.0f;
        // Input Section:
        //	GUIStyle headerStyle = new GUIStyle("Box");
        //	headerStyle.margin = new RectOffset(0, 0 ,0, 0);
        //EditorGUILayout.LabelField("Global Settings", EditorStyles.boldLabel);
        //EditorGUILayout.Separator();

        //	EditorGUILayout.BeginVertical(headerStyle);
        //	if (GUI.Button(r, GUIContent.none, GUIStyle.none)) {
        //		Debug.Log("BG clicked.");
        //	}
        //EditorGUILayout.BeginHorizontal();
        //EditorGUILayout.PrefixLabel("Original Mesh");
        EditorGUILayout.LabelField("Original Mesh", prog.inMeshDescription);
        //EditorGUILayout.EndHorizontal();

        /*	EditorGUILayout.LabelField("Output Mesh Path");
         *      EditorGUILayout.BeginHorizontal();
         *      if (!prog.targetPath.Equals("replace")) {
         *              EditorGUILayout.PropertyField(targetPathProp, GUIContent.none);
         *              if (GUILayout.Button("Replace", EditorStyles.miniButton, GUILayout.ExpandWidth(false))) {
         *                      targetPathProp.stringValue = "replace";
         *              }
         *      } else {
         *              EditorGUILayout.LabelField("Replace imported Mesh");
         *              if (GUILayout.Button("Override", EditorStyles.miniButton, GUILayout.ExpandWidth(false))) {
         *                      targetPathProp.stringValue = KrablMeshUnityPreferences.defaultExtraMeshOutputPath + "/" + prog.inContainerName + "/" + prog.inMeshPath;
         *              }
         *      }
         *      EditorGUILayout.EndHorizontal();
         */
        // EditorGUILayout.Separator();

        //	EditorGUILayout.EndVertical();

        KrablMesh.UnityEditorUtils.GUILayoutAddHoriLine();

        EditorGUILayout.PropertyField(unityOptimizeMeshProp, new GUIContent("Optimize Mesh", "Improve the mesh element order to render faster on the GPU"));

        if (GUILayout.Button("Calculate"))
        {
            // TODO: move this to ProcessorProgramm class
            UnityEngine.Mesh    mesh = null;
            MeshFilter          mf   = prog.GetComponent <MeshFilter>();
            SkinnedMeshRenderer smr  = null;
            if (mf)
            {
                mesh = mf.sharedMesh;
            }
            else
            {
                smr = prog.GetComponent <SkinnedMeshRenderer>();
                if (smr)
                {
                    mesh = smr.sharedMesh;
                }
            }
            if (mesh == null)
            {
                Debug.LogError("Can't process without Mesh");
            }
            else
            {
                mesh      = prog.Process(mesh);
                mesh.name = "TEMP";
                if (mf != null)
                {
                    mf.sharedMesh = mesh;
                }
                else if (smr != null)
                {
                    smr.sharedMesh = mesh;
                }
            }
        }

        if (serializedObject.ApplyModifiedProperties())
        {
            modifiedDuringLastUpdate = true;
        }
#endif
    }