예제 #1
0
        public static ImporterContext Parse(string path, Byte[] bytes)
        {
            var ext     = Path.GetExtension(path).ToLower();
            var context = new ImporterContext(UnityPath.FromFullpath(path));

            switch (ext)
            {
            case ".gltf":
                context.ParseJson(Encoding.UTF8.GetString(bytes), new FileSystemStorage(Path.GetDirectoryName(path)));
                break;

            case ".zip":
            {
                var zipArchive = Zip.ZipArchiveStorage.Parse(bytes);
                var gltf       = zipArchive.Entries.FirstOrDefault(x => x.FileName.ToLower().EndsWith(".gltf"));
                if (gltf == null)
                {
                    throw new Exception("no gltf in archive");
                }
                var jsonBytes = zipArchive.Extract(gltf);
                var json      = Encoding.UTF8.GetString(jsonBytes);
                context.ParseJson(json, zipArchive);
            }
            break;

            case ".glb":
                context.ParseGlb(bytes);
                break;

            default:
                throw new NotImplementedException();
            }
            return(context);
        }
예제 #2
0
        public void UniGLTFSimpleSceneTest()
        {
            var go      = CreateSimpelScene();
            var context = new ImporterContext();

            try
            {
                // export
                var gltf = new glTF();
                using (var exporter = new gltfExporter(gltf))
                {
                    exporter.Prepare(go);
                    exporter.Export();

                    // import
                    context.ParseJson(gltf.ToJson(), new SimpleStorage(new ArraySegment <byte>()));
                    //Debug.LogFormat("{0}", context.Json);
                    gltfImporter.Load(context);

                    AssertAreEqual(go.transform, context.Root.transform);
                }
            }
            finally
            {
                //Debug.LogFormat("Destory, {0}", go.name);
                GameObject.DestroyImmediate(go);
                context.Destroy(true);
            }
        }
예제 #3
0
        GameObject Load(string path)
        {
            var bytes = File.ReadAllBytes(path);

            Debug.LogFormat("[OnClick] {0}", path);
            var context = new ImporterContext();

            var ext = Path.GetExtension(path).ToLower();

            switch (ext)
            {
            case ".gltf":
                context.ParseJson(Encoding.UTF8.GetString(bytes), new FileSystemStorage(Path.GetDirectoryName(path)));
                break;

            case ".zip":
            {
                var zipArchive = Zip.ZipArchiveStorage.Parse(bytes);
                var gltf       = zipArchive.Entries.FirstOrDefault(x => x.FileName.ToLower().EndsWith(".gltf"));
                if (gltf == null)
                {
                    throw new Exception("no gltf in archive");
                }
                var jsonBytes = zipArchive.Extract(gltf);
                var json      = Encoding.UTF8.GetString(jsonBytes);
                context.ParseJson(json, zipArchive);
            }
            break;

            case ".glb":
                context.ParseGlb(bytes);
                break;

            default:
                throw new NotImplementedException();
            }

            context.Load();
            context.Root.name = Path.GetFileNameWithoutExtension(path);
            context.ShowMeshes();

            return(context.Root);
        }
예제 #4
0
        public static void Import(UnityPath gltfPath)
        {
            if (!gltfPath.IsUnderAssetsFolder)
            {
                throw new Exception();
            }

            ImporterContext context = new ImporterContext(gltfPath);
            var             ext     = gltfPath.Extension.ToLower();

            try
            {
                var prefabPath = gltfPath.Parent.Child(gltfPath.FileNameWithoutExtension + ".prefab");
                if (ext == ".gltf")
                {
                    context.ParseJson(File.ReadAllText(gltfPath.FullPath, System.Text.Encoding.UTF8),
                                      new FileSystemStorage(gltfPath.Parent.FullPath));
                    gltfImporter.Load(context);
                    context.SaveAsAsset(prefabPath);
                    context.Destroy(false);
                }
                else if (ext == ".glb")
                {
                    context.ParseGlb(File.ReadAllBytes(gltfPath.FullPath));
                    context.SaveTexturesAsPng(prefabPath);
                    EditorApplication.delayCall += () =>
                    {
                        // delay and can import png texture
                        gltfImporter.Load(context);
                        context.SaveAsAsset(prefabPath);
                        context.Destroy(false);
                    };
                }
                else
                {
                    return;
                }
            }
            catch (UniGLTFNotSupportedException ex)
            {
                Debug.LogWarningFormat("{0}: {1}",
                                       gltfPath,
                                       ex.Message
                                       );
            }
            catch (Exception ex)
            {
                Debug.LogErrorFormat("import error: {0}", gltfPath);
                Debug.LogErrorFormat("{0}", ex);
                if (context != null)
                {
                    context.Destroy(true);
                }
            }
        }
예제 #5
0
        IEnumerator Start()
        {
            Debug.LogFormat("get {0}", m_url);
            var www = new WWW(m_url);

            yield return(www);

            var bytes = www.bytes;

            if (!string.IsNullOrEmpty(www.error))
            {
                Debug.LogWarningFormat("fail to download: {0}", www.error);
                yield break;
            }
            Debug.LogFormat("downloaded {0} bytes", bytes.Length);

            var task = CoroutineUtil.RunOnThread(() => Zip.ZipArchiveStorage.Parse(bytes));

            yield return(task);

            if (task.Error != null)
            {
                throw task.Error;
            }
            var zipArchive = task.Result;

            Debug.LogFormat("done {0}", zipArchive);

            var gltf = zipArchive.Entries.FirstOrDefault(x => x.FileName.ToLower().EndsWith(".gltf"));

            if (gltf == null)
            {
                Debug.LogWarning("no gltf in archive");
                yield break;
            }

#if false
            var json = zipArchive.ExtractToString(gltf, Encoding.UTF8);
#else
            var jsonBytes = zipArchive.Extract(gltf);
            var json      = Encoding.UTF8.GetString(jsonBytes);
#endif
            Debug.LogFormat("gltf json: {0}", json);

            var context = new ImporterContext();
            context.ParseJson(json, zipArchive);
            context.Load();
            context.ShowMeshes();
        }
예제 #6
0
        public static void ImportMenu()
        {
            var path = UnityEditor.EditorUtility.OpenFilePanel("open gltf", "", "gltf,glb");

            if (!string.IsNullOrEmpty(path))
            {
                Debug.Log(path);
                var context = new ImporterContext
                {
                    Path = path,
                };
                var bytes = File.ReadAllBytes(path);
                var ext   = Path.GetExtension(path).ToLower();
                switch (ext)
                {
                case ".gltf":
                {
                    context.ParseJson <glTF>(Encoding.UTF8.GetString(bytes), new FileSystemStorage(Path.GetDirectoryName(path)));
                    gltfImporter.Import <glTF>(context);
                    context.Root.name = Path.GetFileNameWithoutExtension(path);
                    context.ShowMeshes();
                    Selection.activeGameObject = context.Root;
                }
                break;

                case ".glb":
                {
                    context.ParseGlb <glTF>(bytes);
                    gltfImporter.Import <glTF>(context);
                    context.Root.name = Path.GetFileNameWithoutExtension(path);
                    context.ShowMeshes();
                    Selection.activeGameObject = context.Root;
                }
                break;

                default:
                    Debug.LogWarningFormat("unknown ext: {0}", path);
                    break;
                }
            }
        }
        public void ImportExportTest()
        {
            var path       = Path.GetFullPath(Application.dataPath + "/../glTF-Sample-Models/2.0/Box/glTF/Box.gltf");
            var context    = new ImporterContext();
            var bytes      = File.ReadAllBytes(path);
            var importJson = Encoding.UTF8.GetString(bytes);

            context.ParseJson(importJson, new FileSystemStorage(Path.GetDirectoryName(path)));
            context.Load();

            var gltf       = gltfExporter.Export(context.Root);
            var exportJson = gltf.ToJson();

            var l = UniJSON.JsonParser.Parse(importJson);
            var r = UniJSON.JsonParser.Parse(exportJson);

            foreach (var diff in l.Diff(r))
            {
                Debug.Log(diff);
            }

            //Assert.AreEqual();
        }
예제 #8
0
        public void UniGLTFSimpleSceneTest()
        {
            var go      = CreateSimpleScene();
            var context = new ImporterContext();

            try
            {
                // export
                var gltf = new glTF();

                string json = null;
                using (var exporter = new gltfExporter(gltf))
                {
                    exporter.Prepare(go);
                    exporter.Export();

                    // remove empty buffer
                    gltf.buffers.Clear();

                    json = gltf.ToJson();
                }

                // import
                context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>()));
                //Debug.LogFormat("{0}", context.Json);
                context.Load();

                AssertAreEqual(go.transform, context.Root.transform);
            }
            finally
            {
                //Debug.LogFormat("Destory, {0}", go.name);
                GameObject.DestroyImmediate(go);
                context.EditorDestroyRootAndAssets();
            }
        }
예제 #9
0
        public void SameMeshButDifferentMaterialExport()
        {
            var go = new GameObject("same_mesh");

            try
            {
                var shader = Shader.Find("Unlit/Color");

                var cubeA = GameObject.CreatePrimitive(PrimitiveType.Cube);
                {
                    cubeA.transform.SetParent(go.transform);
                    var material = new Material(shader);
                    material.name  = "red";
                    material.color = Color.red;
                    cubeA.GetComponent <Renderer>().sharedMaterial = material;
                }

                {
                    var cubeB = GameObject.Instantiate(cubeA);
                    cubeB.transform.SetParent(go.transform);
                    var material = new Material(shader);
                    material.color = Color.blue;
                    material.name  = "blue";
                    cubeB.GetComponent <Renderer>().sharedMaterial = material;

                    Assert.AreEqual(cubeB.GetComponent <MeshFilter>().sharedMesh, cubeA.GetComponent <MeshFilter>().sharedMesh);
                }

                // export
                var gltf = new glTF();
                var json = default(string);
                using (var exporter = new gltfExporter(gltf))
                {
                    exporter.Prepare(go);
                    exporter.Export();

                    json = gltf.ToJson();
                }

                Assert.AreEqual(2, gltf.meshes.Count);

                var red = gltf.materials[gltf.meshes[0].primitives[0].material];
                Assert.AreEqual(new float[] { 1, 0, 0, 1 }, red.pbrMetallicRoughness.baseColorFactor);

                var blue = gltf.materials[gltf.meshes[1].primitives[0].material];
                Assert.AreEqual(new float[] { 0, 0, 1, 1 }, blue.pbrMetallicRoughness.baseColorFactor);

                Assert.AreEqual(2, gltf.nodes.Count);

                Assert.AreNotEqual(gltf.nodes[0].mesh, gltf.nodes[1].mesh);

                // import
                {
                    var context = new ImporterContext();
                    context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024])));
                    //Debug.LogFormat("{0}", context.Json);
                    context.Load();

                    var importedRed         = context.Root.transform.GetChild(0);
                    var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("red", importedRedMaterial.name);
                    Assert.AreEqual(Color.red, importedRedMaterial.color);

                    var importedBlue         = context.Root.transform.GetChild(1);
                    var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("blue", importedBlueMaterial.name);
                    Assert.AreEqual(Color.blue, importedBlueMaterial.color);
                }

                // import new version
                {
                    var context = new ImporterContext
                    {
                        UseUniJSONParser = true
                    };
                    context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024])));
                    //Debug.LogFormat("{0}", context.Json);
                    context.Load();

                    var importedRed         = context.Root.transform.GetChild(0);
                    var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("red", importedRedMaterial.name);
                    Assert.AreEqual(Color.red, importedRedMaterial.color);

                    var importedBlue         = context.Root.transform.GetChild(1);
                    var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("blue", importedBlueMaterial.name);
                    Assert.AreEqual(Color.blue, importedBlueMaterial.color);
                }
            }
            finally
            {
                GameObject.DestroyImmediate(go);
            }
        }
        static void OnPostprocessAllAssets(string[] importedAssets,
                                           string[] deletedAssets,
                                           string[] movedAssets,
                                           string[] movedFromAssetPaths)
        {
            foreach (string path in importedAssets)
            {
                ImporterContext context = new ImporterContext
                {
                    Path = path,
                };
                var ext = Path.GetExtension(path).ToLower();
                try
                {
                    if (ext == ".gltf")
                    {
                        context.ParseJson <glTF>(File.ReadAllText(context.Path, System.Text.Encoding.UTF8),
                                                 new FileSystemStorage(Path.GetDirectoryName(path)));
                        gltfImporter.Import <glTF>(context);
                        context.SaveAsAsset();
                        context.Destroy(false);
                    }
                    else if (ext == ".glb")
                    {
                        context.ParseGlb <glTF>(File.ReadAllBytes(context.Path));

                        //
                        // https://answers.unity.com/questions/647615/how-to-update-import-settings-for-newly-created-as.html
                        //
                        for (int i = 0; i < context.GLTF.textures.Count; ++i)
                        {
                            var x     = context.GLTF.textures[i];
                            var image = context.GLTF.images[x.source];
                            if (string.IsNullOrEmpty(image.uri))
                            {
                                // glb buffer
                                var folder = context.GetAssetFolder(".Textures").AssetPathToFullPath();
                                if (!Directory.Exists(folder))
                                {
                                    UnityEditor.AssetDatabase.CreateFolder(context.GLTF.baseDir, Path.GetFileNameWithoutExtension(context.Path) + ".Textures");
                                    //Directory.CreateDirectory(folder);
                                }

                                // name & bytes
                                var textureName = !string.IsNullOrEmpty(image.name) ? image.name : string.Format("{0:00}#GLB", i);
                                var byteSegment = context.GLTF.GetViewBytes(image.bufferView);

                                // path
                                var png = Path.Combine(folder, textureName + ".png");
                                File.WriteAllBytes(png, byteSegment.ToArray());

                                var assetPath = png.ToUnityRelativePath();
                                //Debug.LogFormat("import asset {0}", assetPath);
                                UnityEditor.AssetDatabase.ImportAsset(assetPath);
                                image.uri = assetPath.Substring(context.GLTF.baseDir.Length + 1);
                            }
                        }
                        UnityEditor.AssetDatabase.Refresh();

                        EditorApplication.delayCall += () =>
                        {
                            // delay and can import png texture
                            gltfImporter.Import <glTF>(context);
                            context.SaveAsAsset();
                            context.Destroy(false);
                        };
                    }
                    else
                    {
                        continue;
                    }
                }
                catch (UniGLTFNotSupportedException ex)
                {
                    Debug.LogWarningFormat("{0}: {1}",
                                           path,
                                           ex.Message
                                           );
                }
                catch (Exception ex)
                {
                    Debug.LogErrorFormat("import error: {0}", path);
                    Debug.LogErrorFormat("{0}", ex);
                    if (context != null)
                    {
                        context.Destroy(true);
                    }
                }
            }
        }