AR.jsを触っていました。

ARやMRなどのXR分野に手を出してみたくて、調べていたらAR.jsを見つけました。

以前のml5.jsや、フロントエンドの技術とIOTと組合わせることで、
何か面白いものが作れそうな気がしたので、試してみます。

数年前にThree.jsを触っていたこともあったので、3Dの描画にAR.jsはとてもよさそうです。

今回の作成にあたって、いくつかのWEBサイトを参考にしています。

参考

その中でもA-Frameを使用せずに使っているサンプルは一つしか見当たらなくて、
正直丸パクリぽくて心苦しい部分があります。
ですが、webpackを絡めているものは見当たらなかったので、そのあたりで参考にしてもらえればうれしいです。
ARマーカーに立方体を表示するだけのシンプルな構成にしました。
それではソース他の解説です。

コード他

まず、ディレクトリ構成です。

ディレクトリ構成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|   package-lock.json
| package.json
| webpack.config.js
|
+---node_modules
| この下にパッケージ
|
+---public
| | camera_para.dat
| | index.html
| | pattern-A.patt
| |
| \---js
| ar.js
| three.js
|
\---src
index.js

camera_para.datはjeromeetienne/AR.js からダウンロードします。

index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,minimum-scale=1,maximum-scale=1">
<style>
body {
margin: 0px;
overflow: hidden;
}
</style>
<title>Sample</title>
</head>
<body>
<script src='js/three.js'></script>
<script src="js/ar.js"></script>
<script src="bundle.js"></script>
</body>
</html>
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// シーンの作成
var scene = new THREE.Scene();

// レンダラの作成
// canvasに透明度を使用できるようにする。AR.jsの利用ではほとんど必須とおもう。
var renderer = new THREE.WebGLRenderer({ alpha: true });
// レンダラの背景色設定
renderer.setClearColor(new THREE.Color("black"), 0);
// レンダラのサイズ指定
renderer.setSize(640, 480);
// レンダラの DOM を body に入れる
document.body.appendChild(renderer.domElement);

var camera = new THREE.Camera(); // カメラの作成
scene.add(camera); // カメラをシーンに追加

//白色の平行光源を作成
var light = new THREE.DirectionalLight(0xffffff);
//カメラ方向から照らす
light.position.set(0, 0, 2);
//シーンに光源を追加
scene.add(light);

// // Webカメラ入力にするarToolkitSourceの作成
var source = new THREEx.ArToolkitSource({ sourceType: "webcam" });

// リサイズ関数
function onResize() {
// トラッキングソースをリサイズ
source.onResizeElement();
// レンダラをトラッキングソースと同じ大きさに設定
source.copyElementSizeTo(renderer.domElement);
// それも同じサイズに
if (context.arController !== null) {
source.copyElementSizeTo(context.arController.canvas);
}
}

// ソースを初期化
source.init(function onReady() {
onResize();
});

// arToolkitContextの作成
var context = new THREEx.ArToolkitContext({
cameraParametersUrl: "camera_para.dat",
detectionMode: "mono",
canvasWidth: source.parameters.sourceWidth,
canvasHeight: source.parameters.sourceHeight
});

context.init(function onCompleted() {
// コンテクスト初期化が完了したら
camera.projectionMatrix.copy(context.getProjectionMatrix()); // 射影行列をコピー
});
// マーカをグループとして作成
var group = new THREE.Group();
// マーカを登録
var controls = new THREEx.ArMarkerControls(context, group, {
type: "pattern", // マーカのタイプ
patternUrl: "pattern-A.patt" // マーカファイル
});
// マーカーをシーンに追加
scene.add(group);

//ジオメトリ作成
var geo = new THREE.CubeGeometry(1, 1, 1);
//マテリアル作成
var mat = new THREE.MeshLambertMaterial({ color: 0xff0000 });
//メッシュ作成
var mesh1 = new THREE.Mesh(geo, mat);
//マーカーから浮かせる
mesh1.position.set(0, 0.5, 0);
//マーカーの子要素に追加
group.add(mesh1);

// レンダリングループ関数
function renderScene() {
requestAnimationFrame(renderScene);
// メディアソースの準備ができていなければ抜ける
if (source.ready === false) {
return;
}
// ARToolkitのコンテキストを更新
context.update(source.domElement);
// レンダリング
renderer.render(scene, camera);
}

//レンダリング開始
renderScene();

実行時はnpm run devでローカルサーバで立ち上がります。
カメラが付いてるPCならlocalhostの起動されたポートで起動すると立ち上がります。
Chorme Dev toolsのRemote devicesを立ち上げてUSBケーブルで繋いだAndroidに、
localhostを転送できるでスマホで動作させたときの動きを確認できます。

マーカーにスマホをかざすと

赤い立方体を表示します。

出来ました。

終わりに

ほとんど参考にさせてもらったソースのそのままなので、
もやもやしますがお作法に近い記述が多いのだなとThree.jsを使ってゲームを作っていたころを思い出しました。

インタラクションと派手な演出をすることができたら、
自分の個人名刺と2020年の年賀状にARを仕込んでみたいなと思います。

ではでは。