private void LoadFile(int sceneIndex = -1) { _glTFData = File.ReadAllBytes(_glTFPath); _root = GLTFParser.ParseJson(_glTFData); }
// todo undo #if !WINDOWS_UWP IEnumerator Start() { var fullPath0 = Application.streamingAssetsPath + Path.DirectorySeparatorChar + asset0Path; ILoader loader0 = new FileLoader(URIHelper.GetDirectoryName(fullPath0)); var fullPath1 = Application.streamingAssetsPath + Path.DirectorySeparatorChar + asset1Path; ILoader loader1 = new FileLoader(URIHelper.GetDirectoryName(fullPath1)); yield return(loader0.LoadStream(Path.GetFileName(asset0Path))); var asset0Stream = loader0.LoadedStream; GLTFRoot asset0Root = null; GLTFParser.ParseJson(asset0Stream, ref asset0Root); yield return(loader1.LoadStream(Path.GetFileName(asset1Path))); var asset1Stream = loader1.LoadedStream; GLTFRoot asset1Root = null; GLTFParser.ParseJson(asset0Stream, ref asset1Root); string newPath = "../../" + URIHelper.GetDirectoryName(asset0Path); int previousBufferCount = asset1Root.Buffers.Count; int previousImageCount = asset1Root.Images.Count; int previousSceneCounter = asset1Root.Scenes.Count; GLTFHelpers.MergeGLTF(asset1Root, asset0Root); for (int i = previousBufferCount; i < asset1Root.Buffers.Count; ++i) { GLTF.Schema.GLTFBuffer buffer = asset1Root.Buffers[i]; if (!URIHelper.IsBase64Uri(buffer.Uri)) { buffer.Uri = newPath + buffer.Uri; } } for (int i = previousImageCount; i < asset1Root.Images.Count; ++i) { GLTFImage image = asset1Root.Images[i]; if (!URIHelper.IsBase64Uri(image.Uri)) { image.Uri = newPath + image.Uri; } } foreach (NodeId node in asset1Root.Scenes[asset0Root.Scene.Id + previousSceneCounter].Nodes) { node.Value.Translation.X += 5f; asset1Root.Scene.Value.Nodes.Add(node); } GLTFSceneImporter importer = new GLTFSceneImporter( asset1Root, loader1 ); importer.MaximumLod = MaximumLod; importer.isMultithreaded = Multithreaded; yield return(importer.LoadScene(-1)); }
/// <summary> /// Creates a scene based off loaded JSON. Includes loading in binary and image data to construct the meshes required. /// </summary> /// <param name="sceneIndex">The index of scene in gltf file to load</param> /// <param name="isMultithreaded">Whether to use a thread to do loading</param> /// <returns></returns> protected IEnumerator ImportScene(int sceneIndex = -1, bool isMultithreaded = false) { Scene scene; if (sceneIndex >= 0 && sceneIndex < _root.Scenes.Count) { scene = _root.Scenes[sceneIndex]; } else { scene = _root.GetDefaultScene(); } if (scene == null) { throw new Exception("No default scene in gltf file."); } _assetCache = new AssetCache( _root.Images != null ? _root.Images.Count : 0, _root.Textures != null ? _root.Textures.Count : 0, _root.Materials != null ? _root.Materials.Count : 0, _root.Buffers != null ? _root.Buffers.Count : 0, _root.Meshes != null ? _root.Meshes.Count : 0 ); if (_lastLoadedScene == null) { if (_root.Buffers != null) { // todo add fuzzing to verify that buffers are before uri for (int i = 0; i < _root.Buffers.Count; ++i) { GLTF.Schema.Buffer buffer = _root.Buffers[i]; if (buffer.Uri != null) { yield return(LoadBuffer(_gltfDirectoryPath, buffer, i)); } else //null buffer uri indicates GLB buffer loading { GLTFParser.SeekToBinaryChunk(_gltfStream.Stream, i, _gltfStream.StartPosition); _assetCache.BufferCache[i] = new BufferCacheData() { ChunkOffset = _gltfStream.Stream.Position, Stream = _gltfStream.Stream }; } } } if (_root.Images != null) { for (int i = 0; i < _root.Images.Count; ++i) { Image image = _root.Images[i]; yield return(LoadImage(_gltfDirectoryPath, image, i)); } } #if !WINDOWS_UWP // generate these in advance instead of as-needed if (isMultithreaded) { yield return(_asyncAction.RunOnWorkerThread(() => BuildAttributesForMeshes())); } #endif } var sceneObj = CreateScene(scene); if (_sceneParent != null) { sceneObj.transform.SetParent(_sceneParent, false); } _lastLoadedScene = sceneObj; }
/// <summary> /// Creates a scene based off loaded JSON. Includes loading in binary and image data to construct the meshes required. /// </summary> /// <param name="sceneIndex">The index of scene in gltf file to load</param> /// <param name="isMultithreaded">Whether to use a thread to do loading</param> /// <returns></returns> protected IEnumerator ImportScene(int sceneIndex = -1, bool isMultithreaded = false) { GLTF.Schema.Scene scene; if (sceneIndex >= 0 && sceneIndex < _root.Scenes.Count) { scene = _root.Scenes[sceneIndex]; } else { scene = _root.GetDefaultScene(); } if (scene == null) { throw new Exception("No default scene in gltf file."); } _assetCache = new AssetCache( _root.Images != null ? _root.Images.Count : 0, _root.Textures != null ? _root.Textures.Count : 0, _root.Materials != null ? _root.Materials.Count : 0, _root.Buffers != null ? _root.Buffers.Count : 0, _root.Meshes != null ? _root.Meshes.Count : 0 ); if (_lastLoadedScene == null) { if (_root.Buffers != null) { // todo add fuzzing to verify that buffers are before uri for (int i = 0; i < _root.Buffers.Count; ++i) { GLTF.Schema.Buffer buffer = _root.Buffers[i]; if (buffer.Uri != null) { yield return(LoadBuffer(_gltfDirectoryPath, buffer, i)); } else //null buffer uri indicates GLB buffer loading { byte[] glbBuffer; GLTFParser.ExtractBinaryChunk(_gltfData, i, out glbBuffer); _assetCache.BufferCache[i] = glbBuffer; } } } if (_root.Images != null) { for (int i = 0; i < _root.Images.Count; ++i) { GLTF.Schema.Image image = _root.Images[i]; yield return(LoadImage(_gltfDirectoryPath, image, i)); } } #if !WINDOWS_UWP // generate these in advance instead of as-needed if (isMultithreaded) { yield return(_asyncAction.RunOnWorkerThread(() => BuildAttributesForMeshes())); } #endif } var sceneObj = CreateScene(scene); if (_sceneParent != null) { sceneObj.transform.SetParent(_sceneParent, false); } // Experiment with fitting the scene into a prescribed size by accumulating // all of the scenes nodes bounding boxes and then scaling the root node // (I think this would be better as a mode to scale vertices but not for now..) var allRenderersInScene = sceneObj.GetComponentsInChildren <Renderer>(false); Bounds?box = null; foreach (var renderer in allRenderersInScene) { //CreateBox(sceneObj.transform, renderer.bounds); if (!box.HasValue) { box = new Bounds(renderer.bounds.center, renderer.bounds.size); } else { var val = box.Value; val.Encapsulate(renderer.bounds); box = val; } } //CreateBox(sceneObj.transform, box); // Now, for each individual mesh we can move the pivot to the bottom/centre // w.r.t the vertices. This way we can easily place models on a flat surface var allMeshesInScene = sceneObj.GetComponentsInChildren <MeshFilter>(false); foreach (var renderer in allMeshesInScene) { var bbox = renderer.mesh.bounds; // Calculate the distances we need to shift all of the vertices in // each direction to get them centred in x and z and have them sitting // at zero in the y-axis float adjustY = bbox.center.y; float adjustx = bbox.center.x; float adjustZ = bbox.center.z; //var verts = renderer.mesh.vertices; //for (int i = 0; i < verts.Length; i++) //{ // verts[i].x = verts[i].x - adjustx; // verts[i].y = verts[i].y - adjustY; // verts[i].z = verts[i].z - adjustZ; //} //renderer.mesh.vertices = verts; } Vector3 targetSize = Vector3.one / 4.0f; Vector3 sceneBoundsSize = box.Value.max - box.Value.min; float ratioX = targetSize.x / sceneBoundsSize.x; float ratioY = targetSize.y / sceneBoundsSize.y; float ratioZ = targetSize.z / sceneBoundsSize.z; float biggest = Math.Min(ratioZ, Math.Min(ratioX, ratioY)); //sceneObj.transform.localScale = sceneObj.transform.localScale * // (componentMax(targetSize) / componentMax(sceneBoundsSize)); //float f = componentMax(div(targetSize, sceneBoundsSize)); sceneObj.transform.localScale = sceneObj.transform.localScale * biggest; _lastLoadedScene = sceneObj; }
// todo undo #if !WINDOWS_UWP private async Task Start() { var fullPath0 = Application.streamingAssetsPath + Path.DirectorySeparatorChar + asset0Path; ILoader loader0 = new FileLoader(URIHelper.GetDirectoryName(fullPath0)); var fullPath1 = Application.streamingAssetsPath + Path.DirectorySeparatorChar + asset1Path; ILoader loader1 = new FileLoader(URIHelper.GetDirectoryName(fullPath1)); await loader0.LoadStream(Path.GetFileName(asset0Path)); var asset0Stream = loader0.LoadedStream; GLTFRoot asset0Root; GLTFParser.ParseJson(asset0Stream, out asset0Root); await loader1.LoadStream(Path.GetFileName(asset1Path)); var asset1Stream = loader1.LoadedStream; GLTFRoot asset1Root; GLTFParser.ParseJson(asset1Stream, out asset1Root); string newPath = "../../" + URIHelper.GetDirectoryName(asset0Path); int previousBufferCount = asset1Root.Buffers.Count; int previousImageCount = asset1Root.Images.Count; int previousSceneCounter = asset1Root.Scenes.Count; GLTFHelpers.MergeGLTF(asset1Root, asset0Root); for (int i = previousBufferCount; i < asset1Root.Buffers.Count; ++i) { GLTF.Schema.GLTFBuffer buffer = asset1Root.Buffers[i]; if (!URIHelper.IsBase64Uri(buffer.Uri)) { buffer.Uri = newPath + buffer.Uri; } } for (int i = previousImageCount; i < asset1Root.Images.Count; ++i) { GLTFImage image = asset1Root.Images[i]; if (!URIHelper.IsBase64Uri(image.Uri)) { image.Uri = newPath + image.Uri; } } foreach (NodeId node in asset1Root.Scenes[asset0Root.Scene.Id + previousSceneCounter].Nodes) { node.Value.Translation.X += 5f; asset1Root.Scene.Value.Nodes.Add(node); } GLTFSceneImporter importer = new GLTFSceneImporter( asset1Root, null, new ImportOptions { ExternalDataLoader = loader1, AsyncCoroutineHelper = gameObject.AddComponent <AsyncCoroutineHelper>() }); importer.MaximumLod = MaximumLod; importer.IsMultithreaded = Multithreaded; await importer.LoadSceneAsync(-1); }