private IEnumerator LoadBuffers() { if (_root.Buffers != null) { // todo add fuzzing to verify that buffers are before uri setProgress(IMPORT_STEP.BUFFER, 0, _root.Buffers.Count); for (int i = 0; i < _root.Buffers.Count; ++i) { GLTF.Schema.Buffer buffer = _root.Buffers[i]; if (buffer.Uri != null) { LoadBuffer(_gltfDirectoryPath, buffer, i); } else //null buffer uri indicates GLB buffer loading { byte[] glbBuffer; GLTFParser.ExtractBinaryChunk(_glTFData, i, out glbBuffer); _assetCache.BufferCache[i] = glbBuffer; } setProgress(IMPORT_STEP.BUFFER, (i + 1), _root.Buffers.Count); yield return(null); } } }
/// <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 { 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) { 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; }