예제 #1
0
        private static GameObject ImportGLTF(string filepath, ImportSettings importSettings, out AnimationClip[] animations)
        {
            string json = File.ReadAllText(filepath);

            // Parse json
            GLTFObject gltfObject = JsonConvert.DeserializeObject <GLTFObject>(json);

            return(gltfObject.LoadInternal(filepath, null, 0, importSettings, out animations));
        }
예제 #2
0
        private static GameObject ImportGLB(string filepath, ImportSettings importSettings, out AnimationClip[] animations)
        {
            FileStream stream = File.OpenRead(filepath);
            long       binChunkStart;
            string     json       = GetGLBJson(stream, out binChunkStart);
            GLTFObject gltfObject = JsonConvert.DeserializeObject <GLTFObject>(json);

            return(gltfObject.LoadInternal(filepath, null, binChunkStart, importSettings, out animations));
        }
예제 #3
0
        private static GameObject ImportGLB(byte[] bytes, ImportSettings importSettings, out AnimationClip[] animations)
        {
            Stream     stream = new MemoryStream(bytes);
            long       binChunkStart;
            string     json       = GetGLBJson(stream, out binChunkStart);
            GLTFObject gltfObject = JsonConvert.DeserializeObject <GLTFObject>(json);

            return(gltfObject.LoadInternal(null, bytes, binChunkStart, importSettings, out animations));
        }
예제 #4
0
        public static void ExportGLB(GameObject root)
        {
            GLTFObject gltfObject = CreateGLTFObject(root.transform);

            Debug.Log(JsonConvert.SerializeObject(gltfObject, new JsonSerializerSettings()
            {
                NullValueHandling = NullValueHandling.Ignore
            }));
        }
예제 #5
0
        private static void ProcessExtrasInternal(GameObject gameObject, GLTFObject gltfObject, ImportSettings importSettings, AnimationClip[] animations)
        {
            if (gltfObject.extras == null)
            {
                gltfObject.extras = new JObject();
            }

            if (gltfObject.materials != null)
            {
                JArray materialExtras       = new JArray();
                bool   hasMaterialExtraData = false;
                foreach (GLTFMaterial material in gltfObject.materials)
                {
                    if (material.extras != null)
                    {
                        materialExtras.Add(material.extras);
                        hasMaterialExtraData = true;
                    }
                    else
                    {
                        materialExtras.Add(new JObject());
                    }
                }
                if (hasMaterialExtraData)
                {
                    gltfObject.extras.Add("material", materialExtras);
                }
            }

            if (gltfObject.animations != null)
            {
                JArray animationExtras       = new JArray();
                bool   hasAnimationExtraData = false;
                foreach (GLTFAnimation animation in gltfObject.animations)
                {
                    if (animation.extras != null)
                    {
                        hasAnimationExtraData = true;
                        animationExtras.Add(animation.extras);
                    }
                    else
                    {
                        animationExtras.Add(new JObject());
                    }
                }
                if (hasAnimationExtraData)
                {
                    gltfObject.extras.Add("animation", animationExtras);
                }
            }

            importSettings.extrasProcessor.ProcessExtras(gameObject, animations, gltfObject.extras);
        }
예제 #6
0
        private static GameObject LoadInternal(this GLTFObject gltfObject, string filepath, byte[] bytefile, long binChunkStart, ImportSettings importSettings, out AnimationClip[] animations)
        {
            CheckExtensions(gltfObject);

            // directory root is sometimes used for loading buffers from containing file, or local images
            string directoryRoot = filepath != null?Directory.GetParent(filepath).ToString() + "/" : null;

            importSettings.shaderOverrides.CacheDefaultShaders();

            // Import tasks synchronously
            GLTFBuffer.ImportTask bufferTask = new GLTFBuffer.ImportTask(gltfObject.buffers, filepath, bytefile, binChunkStart);
            bufferTask.RunSynchronously();
            GLTFBufferView.ImportTask bufferViewTask = new GLTFBufferView.ImportTask(gltfObject.bufferViews, bufferTask);
            bufferViewTask.RunSynchronously();
            GLTFAccessor.ImportTask accessorTask = new GLTFAccessor.ImportTask(gltfObject.accessors, bufferViewTask);
            accessorTask.RunSynchronously();
            GLTFImage.ImportTask imageTask = new GLTFImage.ImportTask(gltfObject.images, directoryRoot, bufferViewTask);
            imageTask.RunSynchronously();
            GLTFTexture.ImportTask textureTask = new GLTFTexture.ImportTask(gltfObject.textures, imageTask);
            textureTask.RunSynchronously();
            GLTFMaterial.ImportTask materialTask = new GLTFMaterial.ImportTask(gltfObject.materials, textureTask, importSettings);
            materialTask.RunSynchronously();
            GLTFMesh.ImportTask meshTask = new GLTFMesh.ImportTask(gltfObject.meshes, accessorTask, bufferViewTask, materialTask, importSettings);
            meshTask.RunSynchronously();
            GLTFSkin.ImportTask skinTask = new GLTFSkin.ImportTask(gltfObject.skins, accessorTask);
            skinTask.RunSynchronously();
            GLTFNode.ImportTask nodeTask = new GLTFNode.ImportTask(gltfObject.nodes, meshTask, skinTask, gltfObject.cameras);
            nodeTask.RunSynchronously();
            GLTFAnimation.ImportResult[] animationResult = gltfObject.animations.Import(accessorTask.Result, nodeTask.Result, importSettings);
            if (animationResult != null)
            {
                animations = animationResult.Select(x => x.clip).ToArray();
            }
            else
            {
                animations = new AnimationClip[0];
            }

            foreach (var item in bufferTask.Result)
            {
                item.Dispose();
            }

            GameObject gameObject = nodeTask.Result.GetRoot();

            if (importSettings.extrasProcessor != null)
            {
                ProcessExtrasInternal(gameObject, gltfObject, importSettings, animations);
            }
            return(gameObject);
        }
예제 #7
0
        public static GLTFObject CreateGLTFObject(Transform root)
        {
            GLTFObject gltfObject = new GLTFObject();
            GLTFAsset  asset      = new GLTFAsset()
            {
                generator = "GLTFUtility by Bitmoji https: //github.com/Bitmoji/GLTFUtility",
                version   = "2.0"
            };
            //List<GLTFAccessor.ExportResult> accessors
            List <GLTFNode.ExportResult> nodes  = GLTFNode.Export(root);
            List <GLTFMesh.ExportResult> meshes = GLTFMesh.Export(nodes);

            gltfObject.scene  = 0;
            gltfObject.asset  = asset;
            gltfObject.nodes  = nodes.Cast <GLTFNode>().ToList();
            gltfObject.meshes = meshes.Cast <GLTFMesh>().ToList();
            return(gltfObject);
        }
예제 #8
0
        private static void CheckExtensions(GLTFObject gLTFObject)
        {
            if (gLTFObject.extensionsRequired != null)
            {
                for (int i = 0; i < gLTFObject.extensionsRequired.Count; i++)
                {
                    switch (gLTFObject.extensionsRequired[i])
                    {
                    case "KHR_materials_pbrSpecularGlossiness":
                        break;

                    case "KHR_draco_mesh_compression":
                        break;

                    default:
                        Debug.LogWarning($"GLTFUtility: Required extension '{gLTFObject.extensionsRequired[i]}' not supported. Import process will proceed but results may vary.");
                        break;
                    }
                }
            }
        }
예제 #9
0
        private static IEnumerator LoadAsync(string json, string filepath, byte[] bytefile, long binChunkStart, ImportSettings importSettings, Action <GameObject, AnimationClip[]> onFinished, Action <float> onProgress = null)
        {
            // Threaded deserialization
            Task <GLTFObject> deserializeTask = new Task <GLTFObject>(() => JsonConvert.DeserializeObject <GLTFObject>(json));

            deserializeTask.Start();
            while (!deserializeTask.IsCompleted)
            {
                yield return(null);
            }
            GLTFObject gltfObject = deserializeTask.Result;

            CheckExtensions(gltfObject);

            // directory root is sometimes used for loading buffers from containing file, or local images
            string directoryRoot = filepath != null?Directory.GetParent(filepath).ToString() + "/" : null;

            importSettings.shaderOverrides.CacheDefaultShaders();

            // Setup import tasks
            List <ImportTask> importTasks = new List <ImportTask>();

            GLTFBuffer.ImportTask bufferTask = new GLTFBuffer.ImportTask(gltfObject.buffers, filepath, bytefile, binChunkStart);
            importTasks.Add(bufferTask);
            GLTFBufferView.ImportTask bufferViewTask = new GLTFBufferView.ImportTask(gltfObject.bufferViews, bufferTask);
            importTasks.Add(bufferViewTask);
            GLTFAccessor.ImportTask accessorTask = new GLTFAccessor.ImportTask(gltfObject.accessors, bufferViewTask);
            importTasks.Add(accessorTask);
            GLTFImage.ImportTask imageTask = new GLTFImage.ImportTask(gltfObject.images, directoryRoot, bufferViewTask);
            importTasks.Add(imageTask);
            GLTFTexture.ImportTask textureTask = new GLTFTexture.ImportTask(gltfObject.textures, imageTask);
            importTasks.Add(textureTask);
            GLTFMaterial.ImportTask materialTask = new GLTFMaterial.ImportTask(gltfObject.materials, textureTask, importSettings);
            importTasks.Add(materialTask);
            GLTFMesh.ImportTask meshTask = new GLTFMesh.ImportTask(gltfObject.meshes, accessorTask, bufferViewTask, materialTask, importSettings);
            importTasks.Add(meshTask);
            GLTFSkin.ImportTask skinTask = new GLTFSkin.ImportTask(gltfObject.skins, accessorTask);
            importTasks.Add(skinTask);
            GLTFNode.ImportTask nodeTask = new GLTFNode.ImportTask(gltfObject.nodes, meshTask, skinTask, gltfObject.cameras);
            importTasks.Add(nodeTask);

            // Ignite
            for (int i = 0; i < importTasks.Count; i++)
            {
                TaskSupervisor(importTasks[i], onProgress).RunCoroutine();
            }

            // Wait for all tasks to finish
            while (!importTasks.All(x => x.IsCompleted))
            {
                yield return(null);
            }

            // Fire onFinished when all tasks have completed
            GameObject root = nodeTask.Result.GetRoot();

            GLTFAnimation.ImportResult[] animationResult = gltfObject.animations.Import(accessorTask.Result, nodeTask.Result, importSettings);
            AnimationClip[] animations = new AnimationClip[0];
            if (animationResult != null)
            {
                animations = animationResult.Select(x => x.clip).ToArray();
            }
            if (importSettings.extrasProcessor != null)
            {
                ProcessExtrasInternal(root, gltfObject, importSettings, animations);
            }
            if (onFinished != null)
            {
                onFinished(nodeTask.Result.GetRoot(), animations);
            }

            // Close file streams
            foreach (var item in bufferTask.Result)
            {
                item.Dispose();
            }
        }