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)); }
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)); }
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)); }
public static void ExportGLB(GameObject root) { GLTFObject gltfObject = CreateGLTFObject(root.transform); Debug.Log(JsonConvert.SerializeObject(gltfObject, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore })); }
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); }
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); }
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); }
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; } } } }
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(); } }