JavaScript
OpenCV
Matter.js

絵文字😄で物理演算がしたい👌

皆さんは絵文字😄で物理演算💨がしたくなったことはありますか?
私はあります。😉
ということで作ってみました。

emoji.gif

デモページ

Github

解説

絵文字で物理演算するためには大きく分けて二つのポイントがあります。
一つ目は 絵文字の当たり判定 、二つ目は 物理演算のエンジンについてです。

絵文字の当たり判定

物理演算には当たり判定が必ず必要です。
四角にしてしまってもいいのですが、せっかく絵文字を使うのだからちゃんといい感じの当たり判定にする必要があります。
今回は当たり判定を作成するために OpenCV を使用することにしました。
OpenCV には findContours という画像から輪郭を抽出する関数が存在しているのでそれを利用します。
(OpenCVはEmscriptenを使用することでブラウザ上でも使用できます。ただし、ビルド済みのものが配布されていないので頑張って自分でビルドしましょう。)

当たり判定作成の流れは以下の通りです。

  1. 絵文字をcanvasに描画する
  2. canvasに描画した画像を使って輪郭を抽出する

それほど難しくないですね。

物理演算のエンジン

物理演算をする以上それようのエンジンが必要です。
自分で書いてもいいですがあまりにも面倒なので既存のものを使います。
今回のデモではMatter.jsを使用しました。
これを選んだ理由は特になく、ググったら出てきたものを使用しています。

Matter.jsには頂点座標(二次元座標)からオブジェクト(Matter.jsではBody)を作成する関数が存在します。
この関数にOpenCVで作成した輪郭を入れてやれば終わりです。
と言いたいところですがMatter.js特有の注意事項があります。
それは凸状(Convex)でないとうまく扱えないということ、作成したオブジェクトにテクスチャを張ることです。
一応凸状でななくても、poly-decomp.jsを入れれば扱えないこともないのですが挙動が微妙だったので諦めました。
凸状に変換する方法はいくつかあるのですが、今回はなんとなくOpenCVのconvexHullを使って凸状に変換しました。
テクスチャについてはMatter.jsのソースを見ながら調整しました。

当たり判定、物理演算のエンジンがそろえばあとは普通に追加するだけで完成です。

最後に

やってること自体は単純ですが、OpenCVやMatter.jsの使い方が分かるまでに苦労しました。
もっと何か面白そうなことができそうな気もしますがめんどくさくなってきたのでこれ以上はやりません。
OpenCVを使って輪郭を抽出するというものは以下のツイートで行われているものを参考にさせていただきました。

(二番煎じですがブラウザ上で動かすこと、絵文字を使うということやってみたかったのです。)