glbに対応する
glTFにはファイルが複数に分かれているこれまでの形式の他に、glbというすべてが単一のバイナリファイルになっている形式もあります。
このglbに対応させてみましょう。
Gltf2Impouter.ts
まず、 URLからfetch関数で取ってきたArrayBufferに対して、DataViewを通して最初の4バイトを調べます。ASCIIコードにして'glTF'という文字列だった場合は、glbファイルとみなします。
こうした.glbのバイナリ構成は、glTF仕様書のこちら に仕様が書かれています。その仕様をもとに、バイトオフセットとチャンクサイズを調べて、Bufferデータに相当する個所のArrayBufferを抜き出します。
後の処理は基本的にこれまでと同様ですので、それ以降の処理を_loadInner
メソッドにまとめます。
_loadInner
メソッドがこちらです。
private static _loadInner(json: Gltf2, basePath: string, arrayBuffer: ArrayBuffer) { const textures = this._loadTexture(json, basePath, arrayBuffer); const meshes = this._loadMesh(arrayBuffer, json, textures); const entities = this._loadNode(json, meshes); return entities; }
また、_loadTexture
メソッドですが、glbの場合はImageJsonに.urlプロパティがなく、BufferView番号を使ってBufferデータから適切なバイト列を抜き出します。それを元にバイトの塊であるBlob、さらにobjectURLを作成します。これはTexture2DクラスのloadByUrlメソッドに渡すことができる形式です。
ただし、objectURLの利用が済んだら破棄する必要があるので、loadByUrlメソッドにコールバックを追加しました。
最後に
これでglbへの対応は完了です。glbからでも正常に読み込めていますね。
ここまでの作業は、リポジトリのこちら から参照できます。