protected override void Init() { base.Init(); this._root = new GLTFRoot { Accessors = new List <Accessor>(), Asset = new Asset { Version = "2.0", Generator = "paper", }, Buffers = new List <GLTF.Schema.Buffer>(), BufferViews = new List <BufferView>(), Animations = new List <GLTF.Schema.Animation>(), }; _buffer = new GLTF.Schema.Buffer(); _bufferId = new BufferId { Id = _root.Buffers.Count, Root = _root }; _root.Buffers.Add(_buffer); }
/// <summary> /// Create a GLTFExporter that exports out a transform /// </summary> /// <param name="rootTransforms">Root transform of object to export</param> public GLTFSceneExporter(Transform[] rootTransforms) { _rootTransforms = rootTransforms; _root = new GLTFRoot { Accessors = new List <Accessor>(), Asset = new Asset { Version = "2.0" }, Buffers = new List <GLTF.Schema.Buffer>(), BufferViews = new List <BufferView>(), Images = new List <Image>(), Materials = new List <GLTF.Schema.Material>(), Meshes = new List <GLTF.Schema.Mesh>(), Nodes = new List <Node>(), Samplers = new List <Sampler>(), Scenes = new List <Scene>(), Textures = new List <GLTF.Schema.Texture>(), }; _images = new List <Texture2D>(); _materials = new List <UnityEngine.Material>(); _textures = new List <UnityEngine.Texture>(); _buffer = new GLTF.Schema.Buffer(); _bufferId = new BufferId { Id = _root.Buffers.Count, Root = _root }; _root.Buffers.Add(_buffer); }
/// <summary> /// Load the remote URI data into a byte array. /// </summary> protected virtual IEnumerator LoadBuffer(string sourceUri, GLTF.Schema.Buffer buffer, int bufferIndex) { if (buffer.Uri != null) { Stream bufferStream = null; var uri = buffer.Uri; Regex regex = new Regex(Base64StringInitializer); Match match = regex.Match(uri); if (match.Success) { string base64String = uri.Substring(match.Length); byte[] base64ByteData = Convert.FromBase64String(base64String); bufferStream = new MemoryStream(base64ByteData, 0, base64ByteData.Length, false, true); } else if (_loadType == LoadType.Uri) { var www = UnityWebRequest.Get(Path.Combine(sourceUri, uri)); yield return(www.Send()); bufferStream = new MemoryStream(www.downloadHandler.data, 0, www.downloadHandler.data.Length, false, true); } else if (_loadType == LoadType.Stream) { var pathToLoad = Path.Combine(sourceUri, uri); bufferStream = File.OpenRead(pathToLoad); } _assetCache.BufferCache[bufferIndex] = new BufferCacheData() { Stream = bufferStream }; } }
protected override void Init() { base.Init(); this._root = new GLTFRoot { Accessors = new List <Accessor>(), Asset = new Asset { Version = "2.0", Generator = "paper", Extensions = new Dictionary <string, IExtension>(), }, Buffers = new List <GLTF.Schema.Buffer>(), BufferViews = new List <BufferView>(), Meshes = new List <GLTF.Schema.Mesh>() }; _root.Asset.Extensions.Add(CoordinateSystemExtensionFactory.EXTENSION_NAME, new CoordinateSystemExtension(CoordinateSystem.leftHand.ToString(), 1.0f)); _buffer = new GLTF.Schema.Buffer(); _bufferId = new BufferId { Id = _root.Buffers.Count, Root = _root }; _root.Buffers.Add(_buffer); }
// 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; var asset0Root = GLTFParser.ParseJson(asset0Stream); yield return(loader1.LoadStream(Path.GetFileName(asset1Path))); var asset1Stream = loader1.LoadedStream; var asset1Root = GLTFParser.ParseJson(asset1Stream); 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.Buffer buffer = asset1Root.Buffers[i]; if (!URIHelper.IsBase64Uri(buffer.Uri)) { buffer.Uri = newPath + buffer.Uri; } } for (int i = previousImageCount; i < asset1Root.Images.Count; ++i) { Image 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; yield return(importer.LoadScene(-1, Multithreaded)); }
protected virtual void LoadBuffer(string sourceUri, GLTF.Schema.Buffer buffer, int bufferIndex) { if (buffer.Uri != null) { byte[] bufferData = null; var uri = buffer.Uri; var bufferPath = Path.Combine(sourceUri, uri); bufferData = File.ReadAllBytes(bufferPath); _assetCache.BufferCache[bufferIndex] = bufferData; } }
public void Finish() { var prefixStr = Config.GeneratorName; for (var i = Config.GeneratorName.Length; i < 24; i += 1) { prefixStr += " "; } var prefix = Encoding.ASCII.GetBytes(prefixStr); var uri = name + ".bin"; var fp = Path.Combine(ExporterSettings.Export.folder, uri); var bufferId = new BufferId { Id = 0, Root = root }; var outputFile = new FileStream(fp, FileMode.Create); int offset = prefix.Length; using (var binWriter = new BinaryWriter(outputFile)) { binWriter.Write(prefix); foreach (var bufferView in _bufferViews) { int length = 0; if (bufferView.byteBuffer != null) { length = bufferView.byteBuffer.Length; binWriter.Write(bufferView.byteBuffer); } else if (bufferView.streamBuffer != null) { length = (int)bufferView.streamBuffer.Length; binWriter.Write(bufferView.streamBuffer.ToArray()); } bufferView.view.ByteLength = length; bufferView.view.ByteOffset = offset; bufferView.view.Buffer = bufferId; offset += length; } binWriter.Flush(); } var buffer = new GLTF.Schema.Buffer(); buffer.ByteLength = offset; buffer.Uri = uri; root.Buffers = new List<GLTF.Schema.Buffer> { buffer }; using (var writer = File.CreateText(path)) { root.Serialize(writer); } }
protected override void Init() { base.Init(); _root = new GLTFRoot { Accessors = new List <Accessor>(), Asset = new Asset { Version = "2.0", Generator = "paper", }, Buffers = new List <GLTF.Schema.Buffer>(), BufferViews = new List <BufferView>() { new BufferView { Buffer = new BufferId() { Id = 0, Root = _root, }, ByteOffset = 0, ByteLength = 0, } }, Nodes = new List <Node>(), Scenes = new List <Scene>() { new Scene() { Nodes = new List <NodeId>(), } }, Animations = new List <GLTF.Schema.Animation>(), }; _buffer = new GLTF.Schema.Buffer(); _bufferId = new BufferId { Id = _root.Buffers.Count, Root = _root }; _root.Buffers.Add(_buffer); }
/// <summary> /// Load the remote URI data into a byte array. /// </summary> protected virtual IEnumerator LoadBuffer(string sourceUri, GLTF.Schema.Buffer buffer, int bufferIndex) { if (buffer.Uri != null) { byte[] bufferData = null; var uri = buffer.Uri; Regex regex = new Regex(Base64StringInitializer); Match match = regex.Match(uri); if (match.Success) { var base64Data = uri.Substring(match.Length); bufferData = Convert.FromBase64String(base64Data); } else if (_loadType == LoadType.Uri) { var www = UnityWebRequest.Get(Path.Combine(sourceUri, uri)); #if UNITY_2017_2_OR_NEWER yield return(www.SendWebRequest()); #else yield return(www.Send()); #endif bufferData = www.downloadHandler.data; } else if (_loadType == LoadType.Stream) { var pathToLoad = Path.Combine(sourceUri, uri); var file = File.OpenRead(pathToLoad); bufferData = new byte[buffer.ByteLength]; file.Read(bufferData, 0, buffer.ByteLength); #if !WINDOWS_UWP file.Close(); #else file.Dispose(); #endif } _assetCache.BufferCache[bufferIndex] = bufferData; } }
/// <summary> /// Create a GLTFExporter that exports out a transform /// </summary> /// <param name="rootTransforms">Root transform of object to export</param> public GLTFSceneExporter(Transform[] rootTransforms, RetrieveTexturePathDelegate retrieveTexturePathDelegate) { _retrieveTexturePathDelegate = retrieveTexturePathDelegate; var metalGlossChannelSwapShader = Resources.Load("MetalGlossChannelSwap", typeof(UnityEngine.Shader)) as UnityEngine.Shader; _metalGlossChannelSwapMaterial = new UnityEngine.Material(metalGlossChannelSwapShader); var normalChannelShader = Resources.Load("NormalChannel", typeof(UnityEngine.Shader)) as UnityEngine.Shader; _normalChannelMaterial = new UnityEngine.Material(normalChannelShader); _rootTransforms = rootTransforms; _root = new GLTFRoot { Accessors = new List <Accessor>(), Asset = new Asset { Version = "2.0" }, Buffers = new List <GLTF.Schema.Buffer>(), BufferViews = new List <BufferView>(), Images = new List <Image>(), Materials = new List <GLTF.Schema.Material>(), Meshes = new List <GLTF.Schema.Mesh>(), Nodes = new List <Node>(), Samplers = new List <Sampler>(), Scenes = new List <Scene>(), Textures = new List <GLTF.Schema.Texture>(), }; _imageInfos = new List <ImageInfo> (); _materials = new List <UnityEngine.Material> (); _textures = new List <UnityEngine.Texture> (); _buffer = new GLTF.Schema.Buffer(); _bufferId = new BufferId { Id = _root.Buffers.Count, Root = _root }; _root.Buffers.Add(_buffer); }
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; }
public static GLTFRoot Deserialize(TextReader textReader) { var jsonReader = new JsonTextReader(textReader); var root = new GLTFRoot(); if (jsonReader.Read() && jsonReader.TokenType != JsonToken.StartObject) { throw new Exception("gltf json must be an object"); } while (jsonReader.Read() && jsonReader.TokenType == JsonToken.PropertyName) { var curProp = jsonReader.Value.ToString(); switch (curProp) { case "extensionsUsed": root.ExtensionsUsed = jsonReader.ReadStringList(); break; case "extensionsRequired": root.ExtensionsRequired = jsonReader.ReadStringList(); break; case "accessors": root.Accessors = jsonReader.ReadList(() => Accessor.Deserialize(root, jsonReader)); break; case "animations": root.Animations = jsonReader.ReadList(() => Animation.Deserialize(root, jsonReader)); break; case "asset": root.Asset = Asset.Deserialize(root, jsonReader); break; case "buffers": root.Buffers = jsonReader.ReadList(() => Buffer.Deserialize(root, jsonReader)); break; case "bufferViews": root.BufferViews = jsonReader.ReadList(() => BufferView.Deserialize(root, jsonReader)); break; case "cameras": root.Cameras = jsonReader.ReadList(() => Camera.Deserialize(root, jsonReader)); break; case "images": root.Images = jsonReader.ReadList(() => Image.Deserialize(root, jsonReader)); break; case "materials": root.Materials = jsonReader.ReadList(() => Material.Deserialize(root, jsonReader)); break; case "meshes": root.Meshes = jsonReader.ReadList(() => Mesh.Deserialize(root, jsonReader)); break; case "nodes": root.Nodes = jsonReader.ReadList(() => Node.Deserialize(root, jsonReader)); break; case "samplers": root.Samplers = jsonReader.ReadList(() => Sampler.Deserialize(root, jsonReader)); break; case "scene": root.Scene = SceneId.Deserialize(root, jsonReader); break; case "scenes": root.Scenes = jsonReader.ReadList(() => GLTF.Schema.Scene.Deserialize(root, jsonReader)); break; case "skins": root.Skins = jsonReader.ReadList(() => Skin.Deserialize(root, jsonReader)); break; case "textures": root.Textures = jsonReader.ReadList(() => Texture.Deserialize(root, jsonReader)); break; default: root.DefaultPropertyDeserializer(root, jsonReader); break; } } return(root); }
/// <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; }