Exemple #1
0
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            VoxModel model = target as VoxModel;

            if (targetModel == null || model != targetModel)
            {
                filePath    = model.modelSource;
                targetModel = model;
            }
            GUILayout.BeginHorizontal();
            GUILayout.Label("File:", GUILayout.ExpandWidth(false));
            GUILayout.TextArea(filePath.Replace(Application.dataPath, ""));
            if (GUILayout.Button("Open file", GUILayout.ExpandWidth(false)))
            {
                filePath = EditorUtility.OpenFilePanel("Open model", EditorPrefs.GetString("LastVoxPath", Application.dataPath), "vox");
                if (File.Exists(filePath))
                {
                    EditorPrefs.SetString("LastVoxPath", filePath);
                }
            }
            GUILayout.EndHorizontal();
            if (filePath != string.Empty)
            {
                if (GUILayout.Button("Generate Model", GUILayout.ExpandWidth(false)))
                {
                    MagicaVoxelParser parser = new MagicaVoxelParser();
                    model.modelSource = filePath;
                    parser.LoadModel(filePath, model);
                    EditorUtility.SetDirty(model);
                    string   path      = AssetDatabase.GetAssetPath(model);
                    string   name      = Path.GetFileNameWithoutExtension(path);
                    Object[] subAssets = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(model));
                    //load asset meshes
                    List <Mesh> assetMeshes = new List <Mesh>();
                    for (int i = 0; i < subAssets.Length; i++)
                    {
                        if (subAssets[i] is Mesh)
                        {
                            assetMeshes.Add(subAssets[i] as Mesh);
                        }
                    }
                    int  max = model.meshes.Count;
                    bool update = false;
                    Mesh m, temp;
                    for (int i = 0; i < max; i++)
                    {
                        //get mesh
                        if (i < assetMeshes.Count)
                        {
                            update = false;
                            m      = assetMeshes[i];
                            if (m == null)
                            {
                                update = true;
                                m      = new Mesh();
                            }
                        }
                        else
                        {
                            m      = new Mesh();
                            update = true;
                        }
                        //turn temp meshes into assets
                        if (i < model.meshes.Count)
                        {
                            m.name = name + "_frame_" + i;
                            temp   = model.meshes[i];
                            m.Clear();
                            m.vertices  = temp.vertices;
                            m.colors    = temp.colors;
                            m.normals   = temp.normals;
                            m.triangles = temp.triangles;
                            m.uv        = Unwrapping.GeneratePerTriangleUV(m);
                            Unwrapping.GenerateSecondaryUVSet(m);
                            //new mesh
                            if (update)
                            {
                                AssetDatabase.AddObjectToAsset(m, targetModel);
                            }
                            model.meshes[i] = m;
                        }
                    }
                    //destroy un needed meshes
                    for (int i = 0; i < subAssets.Length; i++)
                    {
                        m = subAssets[i] as Mesh;
                        if (m != null)
                        {
                            if (model.meshes.Contains(m) == false)
                            {
                                DestroyImmediate(m, true);
                            }
                        }
                    }
                    EditorUtility.SetDirty(targetModel);
                    AssetDatabase.SaveAssets();
                    AssetDatabase.Refresh();
                }
            }
        }
Exemple #2
0
        GameObject GenerateModel(VoxModel model, AssetImportContext ctx)
        {
            var parser = new MagicaVoxelParser();

            parser.LoadModel(ctx.assetPath, model,
                             s => EditorUtility.DisplayProgressBar("vox", s, 0));

            var subAssets = new List <Object>();

            ctx.GetObjects(subAssets);
            var assetMeshes = subAssets
                              .Select(s => s as Mesh)
                              .Where(s => s != null)
                              .ToArray();
            var updateOpaque      = false;
            var updateTransparent = false;

            var uv3 = new List <Vector4>();

            var assetIndex = 0;

            for (int i = 0; i < model.meshes.Count; i++)
            {
                for (int l = 0; l < model.meshes[i].LODs.Count; l++)
                {
                    MeshSet m;
                    //get mesh
                    m.opaque      = assetIndex < assetMeshes.Length ? assetMeshes[assetIndex++] : null;
                    m.transparent = assetIndex < assetMeshes.Length ? assetMeshes[assetIndex++] : null;
                    updateOpaque  = m.opaque == null;
                    if (updateOpaque)
                    {
                        m.opaque = new Mesh();
                    }
                    updateTransparent = m.transparent == null;
                    if (updateTransparent)
                    {
                        m.transparent = new Mesh();
                    }

                    //turn temp meshes into assets

                    EditorUtility.DisplayProgressBar("vox",
                                                     $"asset: frame={i}/{model.meshes.Count}, lod={l}/{model.meshes[i].LODs.Count}",
                                                     .5f + (.5f * i) / model.voxelFrames.Count);
                    var frame = model.meshes[i].LODs[l];
                    BuildMesh(m.opaque, frame.opaque,
                              $"{name}.{i}.{l}.opaque", uv3, model.Settings.OmitsUVUnwrapping);
                    BuildMesh(m.transparent, frame.transparent,
                              $"{name}.{i}.{l}.transparent", uv3, model.Settings.OmitsUVUnwrapping);
                    //new mesh
                    if (updateOpaque)
                    {
                        ctx.AddObjectToAsset(m.opaque.name, m.opaque);
                    }
                    if (updateTransparent)
                    {
                        ctx.AddObjectToAsset(m.transparent.name, m.transparent);
                    }
                    model.meshes[i].LODs[l] = m;
                }
            }

            var baseGO = ctx.mainObject as GameObject;

            if (baseGO == null)
            {
                baseGO = new GameObject();
                ctx.AddObjectToAsset("main", baseGO);
                ctx.SetMainObject(baseGO);
            }
            var gos = Enumerable.Range(0, baseGO.transform.childCount)
                      .Select(i => baseGO.transform.GetChild(i))
                      .Select(t => t.gameObject)
                      .ToList();
            var gosCount = gos.Count;

            for (int i = gosCount; i < model.meshes.Count; i++)
            {
                var target = new GameObject();
                target.transform.SetParent(baseGO.transform);
                gos.Add(target.gameObject);
            }
            BuildLODGroups(model, gos);
            if (model.Settings.asSceneGraph)
            {
                var root = BuildSceneGraph(model, gos);
                DestroyImmediate(baseGO);
                baseGO = root;
                ctx.AddObjectToAsset("main", root);
                ctx.SetMainObject(root);
            }
            //destroy unneeded meshes
            var meshSetContained = model.meshes.SelectMany(x => x.LODs).ToArray();

            foreach (var go in subAssets
                     .Where(s => (s as Mesh) != null)
                     .Where(s => !meshSetContained.Any(x => x.Contains(s as Mesh))))
            {
                DestroyImmediate(go, true);
            }

            //DestroyImmediate(baseGO);
            return(baseGO);
        }
        void GenerateModel(string filePath, VoxModel model, VoxModel targetModel)
        {
            var parser = new MagicaVoxelParser();

            //model.modelSource = filePath;
            parser.LoadModel(filePath, model,
                             s => EditorUtility.DisplayProgressBar("vox", s, 0));

            EditorUtility.SetDirty(model);
            var path      = AssetDatabase.GetAssetPath(model);
            var name      = Path.GetFileNameWithoutExtension(path);
            var subAssets = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(model));
            //load asset meshes
            var assetMeshes = subAssets
                              .Select(s => s as Mesh)
                              .Where(s => s != null)
                              .ToArray();
            var updateOpaque      = false;
            var updateTransparent = false;

            var uv3 = new List <Vector4>();

            var assetIndex = 0;

            for (int i = 0; i < model.meshes.Count; i++)
            {
                for (int l = 0; l < model.meshes[i].LODs.Count; l++)
                {
                    MeshSet m;
                    //get mesh
                    m.opaque      = assetIndex < assetMeshes.Length ? assetMeshes[assetIndex++] : null;
                    m.transparent = assetIndex < assetMeshes.Length ? assetMeshes[assetIndex++] : null;
                    updateOpaque  = m.opaque == null;
                    if (updateOpaque)
                    {
                        m.opaque = new Mesh();
                    }
                    updateTransparent = m.transparent == null;
                    if (updateTransparent)
                    {
                        m.transparent = new Mesh();
                    }

                    //turn temp meshes into assets

                    EditorUtility.DisplayProgressBar("vox",
                                                     $"asset: frame={i}/{model.meshes.Count}, lod={l}/{model.meshes[i].LODs.Count}",
                                                     .5f + (.5f * i) / model.voxelFrames.Count);
                    var frame = model.meshes[i].LODs[l];
                    BuildMesh(m.opaque, frame.opaque,
                              $"{name}.{i}.{l}.opaque", uv3, model.Settings.OmitsUVUnwrapping);
                    BuildMesh(m.transparent, frame.transparent,
                              $"{name}.{i}.{l}.transparent", uv3, model.Settings.OmitsUVUnwrapping);
                    //new mesh
                    if (updateOpaque)
                    {
                        AssetDatabase.AddObjectToAsset(m.opaque, targetModel);
                    }
                    if (updateTransparent)
                    {
                        AssetDatabase.AddObjectToAsset(m.transparent, targetModel);
                    }
                    model.meshes[i].LODs[l] = m;
                }
            }

            var baseGO = new GameObject();
            var gos    = Enumerable.Range(0, baseGO.transform.childCount)
                         .Select(i => baseGO.transform.GetChild(i))
                         .Select(t => t.gameObject)
                         .ToList();
            var gosCount = gos.Count;

            for (int i = gosCount; i < model.meshes.Count; i++)
            {
                var target = new GameObject();
                target.transform.SetParent(baseGO.transform);
                gos.Add(target.gameObject);
            }
            BuildLODGroups(model, gos);
            if (model.Settings.asSceneGraph)
            {
                var root = BuildSceneGraph(model, gos);
                DestroyImmediate(baseGO);
                baseGO = root;
            }
            //destroy unneeded meshes
            foreach (var go in subAssets
                     .Where(s => (s as Mesh) != null)
                     .Where(s => !model.meshes.SelectMany(x => x.LODs).Any(x => x.Contains(s as Mesh))))
            {
                DestroyImmediate(go, true);
            }

            if (targetModel.prefab == null)
            {
                targetModel.prefab = PrefabUtility.CreatePrefab(path + ".prefab", new GameObject());
            }
            PrefabUtility.ReplacePrefab(baseGO, targetModel.prefab, ReplacePrefabOptions.ReplaceNameBased);
            DestroyImmediate(baseGO);
            EditorUtility.SetDirty(targetModel);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }