インターネットをご覧の皆さん こんばんは。
先日公開された MML (Metaverse Markup Language) を触ってみたのでメモがてら記事を書いてみます。
試した時点の環境は
- mml v0.1.1
です。
MML (Metaverse Markup Language) とは?
Improbable社 (https://improbable.io) が主導する、M² (https://www.msquared.io/) というメタバース エコシステムで使用されている技術です。
メタバースは大きく分けると、空間/オブジェクト/人で構成されていますが、
M² は異なるメタバース間でそれらを相互に運用できるようにすることを目標に開発されているようです。
MML (Metaverse Markup Language) は、そのうちのオブジェクトを記述するオープンソースの技術で、
3Dモデル(メッシュ)やアニメーションだけでなく、メタバース内で動作する際に必要な、意味付けや振る舞いの記述ができるようです。
MML の構成要素
MML ドキュメント
MML では HTML と JavaScript を使用してオブジェクトを記述できます。
いくつかのサンプルが公開されていますが、例えば、クリックすると転がるサイコロの場合、下記のような MML ドキュメントとして記述できるようです。
https://mml.io/examples?example=Dice
<m-model
id="dice"
src="https://public.mml.io/dice.glb"
sx="1" sy="1" sz="1"
y="1"
rx="0" ry="0" rz="0"
onclick="rollDice()"
></m-model>
<script>
function lerp(start, end, t) { return start * (1 - t) + end * t; }
function radToDeg(radians) { return radians * (180 / Math.PI); }
let rollResult = 1;
function rollDice() {
const rollMap = {
1: {
rx: radToDeg(2 * Math.PI),
ry: 0,
rz: radToDeg(2 * Math.PI),
},
2: {
rx: radToDeg(2 * Math.PI),
ry: 0,
rz: radToDeg(2 * Math.PI - Math.PI / 2),
},
3: {
rx: radToDeg(2 * Math.PI - Math.PI / 2),
ry: 0,
rz: radToDeg(2 * Math.PI),
},
4: {
rx: radToDeg(2 * Math.PI + Math.PI / 2),
ry: 0,
rz: radToDeg(2 * Math.PI),
},
5: {
rx: radToDeg(2 * Math.PI),
ry: 0,
rz: radToDeg(2 * Math.PI + Math.PI / 2),
},
6: {
rx: radToDeg(2 * Math.PI + Math.PI),
ry: 0,
rz: radToDeg(2 * Math.PI),
},
};
const diceElement = document.getElementById("dice");
let newRoll = Math.floor(Math.random() * 6) + 1;
while (newRoll === rollResult) {
newRoll = Math.floor(Math.random() * 6) + 1;
}
rollResult = newRoll;
const targetRotation = rollMap[rollResult];
const startRotation = {
rx: parseFloat(diceElement.getAttribute("rx")),
ry: parseFloat(diceElement.getAttribute("ry")),
rz: parseFloat(diceElement.getAttribute("rz")),
};
const animationTime = 400;
const interval = 40;
let currentTime = 0;
let intervalId = setInterval(() => {
currentTime += interval;
if (currentTime < animationTime) {
let t = currentTime / animationTime;
let currentRotation = {
rx: lerp(startRotation.rx, targetRotation.rx, t),
ry: lerp(startRotation.ry, targetRotation.ry, t),
rz: lerp(startRotation.rz, targetRotation.rz, t),
};
diceElement.setAttribute("rx", currentRotation.rx.toString());
diceElement.setAttribute("ry", currentRotation.ry.toString());
diceElement.setAttribute("rz", currentRotation.rz.toString());
diceElement.setAttribute("y", Math.cos(t * 2.0 - 0.5) * 3.5);
} else {
diceElement.setAttribute("rx", targetRotation.rx.toString());
diceElement.setAttribute("ry", targetRotation.ry.toString());
diceElement.setAttribute("rz", targetRotation.rz.toString());
clearInterval(intervalId);
}
}, interval);
}
</script>
ネットワークDOM
メタバース空間上ではオブジェクトの状態を全ユーザで共有する必要があります。
MML では、ネットワークDOMという仕組みでオブジェクトの状態を同期しているようです。
MML ドキュメントから構築されたネットワークDOMは、メタバース空間とは独立したサーバーで実行され、ネットワークDOMクライアントと WebSocket で通信することで、ネットワークDOMの要素を操作することができるようです。
MML Playground
MML を試す環境として、mml-playground というリポジトリが公開されています。
こちらを利用すると、自身で作成した MML ドキュメントを手軽に試してみることができます。
MML Playground を CodeSandbox で実行してみる
MML Playground は CodeSandbox.io で実行することができるようになっています。
サンドボックスで MML Playground を起動する
- まず、CodeSandbox ( https://codesandbox.io/ ) にサインインします。
- MML Playground ( https://github.com/mml-io/mml-playground ) に記載されているリンクから、サンドボックスを開きます。
- 「Please click the 'Fork' button to create your sandbox.」という表示が出る場合は、CodeSandbox 右上の Fork ボタンでサンドボックス環境を作成します。
- サンドボックス環境が作成されると MML Playground が起動します。
MML Playground 上に MML ドキュメントを表示してみる
- MML Playground が起動すると、キャラクターが表示されます。キャラクターはキーボードの WASDキーで移動できます。
- フィールド上のスロット(緑色の領域)をマウスクリックすると、MMLドキュメントのURLを入力するダイアログが表示されます。
- MML Playground にはサンプルの MML ドキュメントが含まれており、packages/server/examples/以下に配置されています。
MML ドキュメントの WebSocket URL はwss://ホスト/examples/ファイル
となっています。 - 試しに duck.html を表示する場合は
wss://サンドボックス環境の識別子.csb.app/examples/duck.html
のような URL を入力すると、スロット上に duck が表示されます。 - 独自の MML ドキュメントを作成する場合は、packages/server/examples/以下にファイルを配置すれば同様の方法で表示することができます。
<m-cube id="test-cube" y="0.5" color="red" collide="true"></m-cube>
<script>
const clickableCube = document.getElementById("test-cube");
clickableCube.addEventListener("click", () => {
clickableCube.setAttribute("color", `#${Math.floor(Math.random() * 16777215).toString(16)}`);
});
</script>
wss://サンドボックス環境の識別子.csb.app/examples/cube.html
おわりに
各種サンプルやサンドボックス環境が用意されていたので、手軽に MML を体験することができました。
HTML と javascript で記述できるため敷居も低い印象です。
まだ公開されたばかりなので、これからできることも増えていくのではないかと思います。
ちなみに、M²(or Morpheus?)はメタバースの空間(場所)を作成するための World Builder も公開準備しているようで、こちらも面白そうだなと思いました。
以上 おつきあいいただきありがとうございました。