glbに対応する

glTFにはファイルが複数に分かれているこれまでの形式の他に、glbというすべてが単一のバイナリファイルになっている形式もあります。
このglbに対応させてみましょう。

Gltf2Impouter.ts

まず、 URLからfetch関数で取ってきたArrayBufferに対して、DataViewを通して最初の4バイトを調べます。ASCIIコードにして'glTF'という文字列だった場合は、glbファイルとみなします。

こうした.glbのバイナリ構成は、glTF仕様書のこちら に仕様が書かれています。その仕様をもとに、バイトオフセットとチャンクサイズを調べて、Bufferデータに相当する個所のArrayBufferを抜き出します。

後の処理は基本的にこれまでと同様ですので、それ以降の処理を_loadInnerメソッドにまとめます。

image.png

_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メソッドに渡すことができる形式です。

image.png

ただし、objectURLの利用が済んだら破棄する必要があるので、loadByUrlメソッドにコールバックを追加しました。

image.png

最後に

これでglbへの対応は完了です。glbからでも正常に読み込めていますね。

image.png

ここまでの作業は、リポジトリのこちら から参照できます。