More Related Content Similar to AR-Frame x AR.js入門 (20) More from Takashi Yoshinaga (18) AR-Frame x AR.js入門17. 必要なもの
Webブラウザ → コンテンツの体験や動作確認
テキストエディタ → HTMLやjavascriptの記述
Webサーバー → コンテンツの公開
サーバーに関して今回は・・・
Glitchを利用 https://glitch.com/
FacebookかGitHubのアカウントがあればOK
サーバーとエディタの両方を無料で提供
この資料ではGlitch使用を前提に説明します
24. ソースの確認
<html>
<head>
<title>Hello, WebVR! - A-Frame</title>
<meta name="description" content="Hello, WebVR! - A-Frame">
<script src="https://aframe.io/releases/1.2.0/aframe.min.js">
</script>
</head>
<body>
<a-scene background="color: #ECECEC">
表示するオブジェクトや背景の設定をここに記述
</a-scene>
</body>
</html>
ヘッダー部でA-Frameの機能を提供するライブラリを取り込む
<a-scene>と</a-scene>の間に描画に関する記述をする
25. ソースの確認
<a-scene background="color: #ECECEC">
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9">
</a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E">
</a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5"
color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0"
width="4" height="4" color="#7BC8A4"></a-plane>
</a-scene>
基本図形はa-xxxタグで提供されている
https://aframe.io/docs/1.2.0/primi
tives/a-box.html (例:a-boxの詳細)
位置 回転 色
32. [編集例]
<a-scene background="color: #0000FF">
<a-box position="-1 0.5 -3" rotation="0 45 45" color="#4CC3D9">
</a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E">
</a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="0.2"
color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0"
width="4" height="4" color="#7BC8A4"></a-plane>
<a-text position="0 1.5 -2" align="center" color="#000000”
value="AR Fukuoka"></a-text>
</a-scene>
HTML編集に慣れよう
角度
高さ
色
40. <a-scene background="color: #ECECEC">
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9">
</a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E">
</a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5"
color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0"
width="4" height="4" color="#7BC8A4"></a-plane>
</a-scene>
不要なオブジェクトの削除
HTMLの記述の中からタグを削るだけ
この後の演習のため、a-sphereのみを
残して削除してみましょう
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9">
</a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E">
</a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5"
color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0"
width="4" height="4" color="#7BC8A4"></a-plane>
lesson01
48. ソースの書き換え
<head>
<title>Hello, WebVR! - A-Frame</title>
<meta name="description" content="Hello, WebVR! - A-Frame">
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
</head>
<body>
<a-scene background="color: #ECECEC">
<a-sphere position="0 1.25 -5" radius="1.25" src="コピーしたURL"
shadow> </a-sphere>
</a-scene>
</body>
a-sphereの色をcolor(色)ではなくsrc(画像へのリンク)に変更
srcの右辺に前の操作でコピーした“画像のURL”を貼り付ける
colorをsrcに変更
Lesson02
49. アニメーションの追加
<a-sphere position="0 1.25 -5" radius="1.25"
src="テクスチャのURL" shadow
animation = "
property :rotation; ←アニメーションの種類
dur : 10000; ←アニメーションにかける時間(ミリ秒)
from : 0␣0␣0; ←開始時の角度(0,0,0)
to: 0␣360␣0; ←終了時の角度(0,360,0)
loop : 0; ←繰り返し回数
"
>
</a-sphere>
animationを用いてアニメーションに関する設定を行う
Z
X
Y
"を忘れずに!
50. アニメーションを繰り返す
<a-sphere position="0 1.25 -5" radius="1.25"
src="テクスチャのURL" shadow
animation = "
property :rotation; ←アニメーションの種類
dur : 10000; ←アニメーションにかける時間(ミリ秒)
from : 0␣0␣0; ←開始時の角度(0,0,0)
to: 0␣360␣0; ←終了時の角度(0,360,0)
loop : -1; ←繰り返し回数
"
>
</a-sphere>
repeatを"-1"にするといつまでも繰り返し続ける
51. 同じ速度で回転させる
animation = "
property : rotation; ←アニメーションの種類
dur : 10000; ←アニメーションにかける時間(ミリ秒)
from : 0␣0␣0; ←開始時の角度(0,0,0)
to : 0␣360␣0; ←終了時の角度(0,360,0)
loop : -1; ←繰り返し回数
easing : linear; ←速度の変化
"
easingを追加し、"linear"にすると同じ速度で動くようになる。
ほかには最初がゆっくりなease-inや後半がゆっくりなease-outも。
→ https://easings.net
lesson03
58. タグの追加
<head>
<title>Hello, WebVR! - A-Frame</title>
<meta name="description" content="Hello, WebVR! - A-Frame">
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
</head>
<body>
<a-scene background="color: #FAFAFA">
<a-sphere position="0 1.25 -5" radius="1.25" src="URL" shadow
animation = "長いので割愛"
>
</a-sphere>
<a-sky src="さっきコピーした画像のURL"></a-sky>
</a-scene>
</body>
a-skyタグを利用し、背景情報として画像のURLを指定すればOK
a-skyを追加 lesson04
61. ほか、A-Frameで利用できるデータの例
• 文字列 <a-text>
• 音 <a-sound>
• ビデオ <a-video>
• 3Dファイル
obj <a-obj-model>
glTF <a-gltf-model>
• VRコントローラによる入力
HTC Vive
<a-entity vive-controls="hand: left">
OculusQuest など
<a-entity laser-controls="hand: left">
66. AR.jsをインポート & カメラ画像の表示
<head>
<title>Hello, WebVR! - A-Frame</title>
<meta name="description" content="Hello, WebVR! - A-Frame">
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/
build/aframe-ar.js"></script>
</head>
<body>
<a-scene background="color: #FAFAFA">
<a-sphere position="0 1.25 -5" radius="1.25" src="URL" shadow
animation = "中略"
>
</a-sphere>
<a-sky src="画像URL"></a-sky>
</a-scene>
</body>
AR.jsの読み込みをしたあと、a-sceneタグにembeddedを追加
追加
<a-scene embedded>
背景色を削除してembeded
a-sky削除 lesson05
67. マーカーを認識してその上にCGを表示
<body>
<a-scene embedded arjs>
<a-marker preset="hiro">
<a-sphere position="0 1.25 -5" radius="1.25" src="URL" shadow
animation = "中略"
>
</a-sphere>
</a-marker>
</a-scene>
</body>
AR表示をするにはマーカーとCGとの関連付けが必要
A-Frameの場合<a-marker></a-marker>でCGを挟む
presetでマーカー名を指定 (付属マーカーのHiro使用)
正方形内のマーカーを独自に作ることも可能 (参考)
マーカーの上にこれを表示したい
追加
lesson06
73. 現状の問題点と解決策
<body>
<a-scene embedded arjs>
<a-marker preset="hiro">
<a-sphere position="0 1.25 0" radius="1.25" src="URL" shadow
animation = "中略"
>
</a-sphere>
</a-marker>
</a-scene>
</body>
問題点
表示するCGがa-markerの子要素なのでマーカーが消えるとCGも消える
解決策
a-markerの子要素としてではなく自前のjavascriptでCGの位置・姿勢を制御
74. CG管理用のオブジェクト作成
<body>
<a-scene embedded arjs>
<a-marker preset="hiro">
<a-sphere position="0 1.25 0" radius="1.25" src="URL" shadow
animation = "中略"
>
</a-sphere>
</a-marker>
<a-entity id="ar-objects">
</a-entity>
</a-scene>
</body>
ここで表示するCGに関する記述
a-entityという空オブジェクトを作成。javascriptで利用するためidもつけておく
id名は任意でOK
75. CG管理用のオブジェクト作成
<body>
<a-scene embedded arjs>
<a-marker preset="hiro">
<a-sphere position="0 1.25 0" radius="1.25" src="URL" shadow
animation = "中略"
>
</a-sphere>
</a-marker>
<a-entity id="ar-objects">
</a-entity>
</a-scene>
</body>
ここで表示するCGに関する記述
a-sphereを<a-entity id="ar-objects">と</a-entity>の間に移動
CG管理用オブジェクトに移動
76. CG管理用のオブジェクト作成
<body>
<a-scene embedded arjs>
<a-marker preset="hiro">
</a-marker>
<a-entity id="ar-objects">
<a-sphere position="0 1.25 0" radius="1.25" src="URL" shadow
animation = "中略"
>
</a-sphere>
</a-entity>
</a-scene>
</body>
親オブジェクト(id:ar-objects)を作ることで複数CGのAR表示も可能
こっちは空っぽでOK
lesson08
80. マーカー検出/ロストのタイミングを取得
<head>
<meta charset="utf-8">
<title>Hello, WebVR! • A-Frame</title>
<meta name="description" content="Hello, WebVR! • A-Frame">
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://raw.githack.com/AR-js-
org/AR.js/master/aframe/build/aframe-ar.js"></script>
<script>
</script>
</head>
<body>
<a-scene embedded arjs>
スペースの都合上中略
</a-scene>
</body>
ここにスクリプトを記述(次のページ)
84. マーカー検出/ロストのタイミングを取得
init: function () {
//マーカー検出/ロストの状態を管理する変数を定義しfalseで初期化
this.isTracking=false;
//markerFoundはマーカー検出時に呼ばれる
this.el.sceneEl.addEventListener('markerFound', () => {
this.isTracking=true;
console.log("tracking:"+ this. isTracking);
});
//markerLostはマーカーロスト時に呼ばれる
this.el.sceneEl.addEventListener('markerLost', () => {
this.isTracking=false;
console.log("tracking:"+ this. isTracking);
});
} lesson11
85. 自作機能(コンポーネント)を利用する
<head>
<meta charset="utf-8">
<title>Hello, WebVR! • A-Frame</title>
<meta name="description" content="Hello, WebVR! • A-Frame">
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://raw.githack.com/AR-js-
org/AR.js/master/aframe/build/aframe-ar.js"></script>
<script>
</script>
</head>
<body>
<a-marker preset="hiro"> </a-marker>
<a-scene embedded arjs>
スペースの都合上中略
</a-scene>
</body>
先ほど記述したコンポーネント(markerhandler)
ここを編集。(次のページ)
86. 自作機能(コンポーネント)を利用する
<head>
<meta charset="utf-8">
<title>Hello, WebVR! • A-Frame</title>
<meta name="description" content="Hello, WebVR! • A-Frame">
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://raw.githack.com/AR-js-
org/AR.js/master/aframe/build/aframe-ar.js"></script>
<script>
</script>
</head>
<body>
<a-marker markerhandler preset="hiro"> </a-marker>
<a-scene embedded arjs>
スペースの都合上中略
</a-scene>
</body>
自作コンポーネント(markerhandler)
lesson12
90. CGをマーカーに追従させる
tick: function (time, timeDelta) {
//もしマーカー追跡中ならば
if(this.isTracking){
//このスクリプトが適用されているオブジェクト(=マーカー)を取得
var marker=this.el.object3D;
//マーカーの位置を取得
var p = new THREE.Vector3();
marker.getWorldPosition(p);
//マーカーの姿勢(向き)を取得
var q = new THREE.Quaternion();
marker.getWorldQuaternion(q);
//AR表示に用いるオブジェクトの位置・姿勢に反映
var obj =this.data.arobject.object3D;
obj.position.set(p.x, p.y, p.z);
obj.quaternion.set ( q.x, q.y, q.z, q.w);
}
}
lesson13
92. CGをマーカーに追従させる
<head>
<meta charset="utf-8">
<title>Hello, WebVR! • A-Frame</title>
<meta name="description" content="Hello, WebVR! • A-Frame">
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://raw.githack.com/AR-js-
org/AR.js/master/aframe/build/aframe-ar.js"></script>
<script>
<!-- 自作コンポーネントのmarkerhandler (スペースの都合時により省略) -->
</script>
</head>
<body>
<a-marker markerhandler preset="hiro"> </a-marker>
<a-scene embedded arjs>
スペースの都合により省略
</a-scene>
</body>
ここを編集(次のページ)
93. CGをマーカーに追従させる
<body>
<a-scene embedded arjs>
<a-marker markerhandler ="arobject:#ar-objects" preset="hiro">
</a-marker>
<a-entity id="ar-objects">
<a-sphere position="0 1.25 0" radius="1.25" src="画像のURL" shadow
animation="
property:rotation;
dur:10000;
from:0 0 0;
to:0 360 0;
loop:-1;
easing:linear;
">
</a-sphere>
</a-entity>
<a-entity camera></a-entity>
</a-scene>
</body> lesson14
96. マーカーを見失ったらCGを画面中央に置く
init: function () {
//マーカー検出/ロストの状態を管理する変数を定義しfalseで初期化
this.isTracking=false;
//markerFoundはマーカー検出時に呼ばれる
this.el.sceneEl.addEventListener('markerFound', () => {
this.isTracking=true;
console.log("tracking:"+ this. isTracking);
});
//markerLostはマーカーロスト時に呼ばれる
this.el.sceneEl.addEventListener('markerLost', () => {
this.isTracking=false;
console.log("tracking:"+ this. isTracking);
});
}
ここにコードを追加 (次のページ)
97. マーカーを見失ったらCGを画面中央に置く
this.el.sceneEl.addEventListener('markerLost', () => {
this.isTracking=false;
console.log("tracking:"+ this. isTracking);
var obj =this.data.arobject.object3D; //ARオブジェクトを取得
obj.position.set(0,0,-6); //z=-6 (画面置く方向に配置)
obj.quaternion.set ( 0,0,0,1); //姿勢を初期状態に戻す
obj.rotateX ( 3.14/2 ) ; //90度回転させて調整
});
ロスト
位置(0,0,-6)
傾いたまま
初期姿勢
初期姿勢
90度回転
向きの調整
lesson15
101. 地球のCGをjavascriptで制御する準備
<body>
<a-scene embedded arjs>
<a-marker markerhandler="arobject:#ar-objects" preset="hiro">
</a-marker>
<a-entity id="ar-objects">
<a-sphere position="0 1.25 0" radius="1.25" src=”URL" shadow
animation="省略"
>
</a-sphere>
</a-entity>
<a-entity camera></a-entity>
</a-scene>
</body>
画面操作以外の要因で値が変わる部分はこれ以上、操作しない方が分かり易い
アニメーションで勝手に値が変わる
マーカーロスト時の位置・姿勢を微調整されてる
102. 地球のCGをjavascriptで制御する準備
<body>
<a-scene embedded arjs>
<a-marker markerhandler="arobject:#ar-objects" preset="hiro">
</a-marker>
<a-entity id="ar-objects">
<a-entity id="earth">
<a-sphere position="0 1.25 0" radius="1.25" src=”URL" shadow
animation="省略"
>
</a-sphere>
</a-entity>
</a-entity>
<a-entity camera></a-entity>
</a-scene>
</body>
解決案:画面操作用の要素を一つ作りa-sphereの親にする
終了を忘れずに
Earthという名前の空オブジェクト
lesson16
103. 画面操作用スクリプトの追加
<head>
<meta name="description" content="Hello, WebVR! • A-Frame">
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://raw.githack.com/AR-js-
org/AR.js/master/aframe/build/aframe-ar.js"></script>
<script>
</script>
</head>
<body>
<a-marker markerhandler preset="hiro"> </a-marker>
<a-scene embedded arjs>
スペースの都合上中略
</a-scene>
</body>
自作コンポーネント(markerhandler)
画面操作用スクリプトを追加(次のページ)
104. 画面操作用スクリプトの追加
<script>
window.onload = function() {
//マウス操作に対応
window.addEventListener('mousedown', touchDownHandler);
window.addEventListener('mousemove', touchMoveHandler);
window.addEventListener('mouseup', touchEndHandler);
//スマホ画面操作に対応
window.addEventListener('touchstart', touchDownHandler);
window.addEventListener('touchmove', touchMoveHandler);
window.addEventListener('touchend', touchEndHandler);
};
AFRAME.registerComponent('markerhandler', {
schema: { /*省略*/ },
init: function () {{ /*省略*/ },
tick: function (time, timeDelta) {{ /*省略*/ }
});
</script> lesson17
105. 画面操作用スクリプトの追加
window.onload = function() {
//マウス操作に対応
window.addEventListener('mousedown', touchDownHandler);
window.addEventListener('mousemove', touchMoveHandler);
window.addEventListener('mouseup', touchEndHandler);
//スマホ画面操作に対応
window.addEventListener('touchstart', touchDownHandler);
window.addEventListener('touchmove', touchMoveHandler);
window.addEventListener('touchend', touchEndHandler);
};
var touchDownHandler= function(e) {
};
var touchEndHandler= function(e) {
};
var touchMoveHandler = function(e) {
}; lesson18
106. 画面操作用スクリプトの追加
var startX; //画面タッチorクリック開始位置
var pressed=false; //現在画面を触っているか否か
var touchDownHandler= function(e) {
pressed=true; //画面操作開始
if (e.touches && e.touches[0]) {//スマホ画面をタッチしたなら
startX = e.touches[0].clientX;
}
else if (e.clientX) {//PC画面をクリックしたなら
startX = e.clientX;
}
};
var touchEndHandler= function(e) {
pressed=false; //画面操作終了
};
var touchMoveHandler = function(e) {
//指移動時に回転させる(次のページで解説)
};
lesson19
107. 画面操作用スクリプトの追加
var startX; //画面タッチorクリック開始位置
var pressed=false; //現在画面を触っているか否か
var touchDownHandler= function(e) { /*中略*/ };
var touchEndHandler= function(e) { /*中略*/ };
var touchMoveHandler = function(e) {
if(pressed){ //画面操作中なら
var x = 0;
if (e.touches && e.touches[0]) {
x = e.touches[0].clientX;
}
else if (e.clientX) {
x = e.clientX;
}
var obj =document.getElementById("earth").object3D;
obj.rotateZ((x-startX)*0.001); //Z軸回転
}
};
lesson20