はじめに
Three.jsにはMMDモデルを読み込んでくれるMMDLoaderというツールがあり、これでMMDモデルを確認できるビューアーアプリを作りたいと思ったのですが、MMDモデルをサーバーにアップロードする形だと著作権的にグレーな気がしました。
そのとき、「ローカルで見るだけならわざわざサーバーに送る必要ないのでは?」ということに気づき、サーバーに送らなくて済むタイプのMMDモデルビューアを作ってみることにしました。
そのために一時的にブラウザからアクセス可能なローカルの領域を用意する必要があるのですが、今回はそれにIndexedDBを使いました。
(Githubのissueを調べたところ、IndexedDBについては何かしら議論したあとがあったのですが、この感じだとまだサポートは無いんだと思います)
作ったもの
デモ
こちらのデモをご覧ください。
MMDモデル(pmd/pmx)のファイルを選択すると、そのMMDモデルが表示されるはずです。
※MMDモデルはてきとうに「MMDモデル 配布」とかでググって見つけてください。
※申し訳ありませんがまだテクスチャは貼れません...
プログラム
-
app/MMDSaver.js
というのがIndexedDBのあれこれを操作してるjsです。 -
app/js/loaders/MMDLoader.js
はarraybufferを直接読み込めるように改造してあります。
仕組み
MMDLoaderに限らず、Three.jsの3Dモデルローダーは第一引数に静的ファイルのパスを渡す仕様になっていると思います。MMDLoader内ではこのパスに基づいて xhrリクエストをサーバーに送信し、レスポンスとしてArrayBuffer形式のモデルファイルを受け取っています。 このことから、ローダーにパスではなく直接ArrayBufferを渡せばいいと思いました。
流れ
- フォームからバイナリ形式のファイルを取得
- ファイルを
readAsArrayBuffer
でArrayBufferに変換 - IndexedDBに保存
- IndexedDBから取り出し
- 一度blobに変換しローダーに渡す ※なぜかArrayBufferのままではローダーに渡せなかったため
- ローダー内でblobに対し
readAsArrayBuffer
をかけArrayBufferに戻す - 本来xhr処理するはずだった場所でこのArrayBufferを受け取る
さいごに
初心者なので間違ったことを書いてしまっているかもしれません。もし何かあればコメントください!!