コード例 #1
0
 private void LoadFile(int sceneIndex = -1)
 {
     _glTFData = File.ReadAllBytes(_glTFPath);
     _root     = GLTFParser.ParseJson(_glTFData);
 }
コード例 #2
0
        // 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));
        }
コード例 #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)
        {
            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;
        }
コード例 #4
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;
        }
コード例 #5
0
        // 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);
        }