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;
        }
Exemple #3
0
        /// <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;
        }