3Dモデルの拡張
このサンプルは、ターゲットを3DモデルによってAR化する方法を示します。このセクションでは、ターゲットに3Dモデルを拡張する方法、アニメーションとイベントの追加、3Dモデルを固定表示する方法、3Dアニメーションの再生方法ついて示します。また、最後に、ロケーションベース型ARとして3Dモデルを特定のロケーションに配置する方法を示します。
画像認識型ARの作成方法をまだ理解していない場合は、前のクライアント認識のサンプルを見てください。
Wikitude SDKでは、独自の形式である、Wikitude 3Dフォーマットファイル(.wt3)にエンコードされた3Dモデルのみ拡張オブジェクトとして使用できます。これは3Dモデルを拡張するために圧縮されたバイナリ形式のファイルで、モバイルデバイスで3Dモデルを高速に読み込み、処理できるように最適化されています。3Dモデルの作成には好みの3Dモデリングツール(AutodeskR MayaRやBlenderなど)を使用できますが、作成した3Dモデルをwt3ファイル形式にエンコードする必要があります。3DモデルのエンコードにはWikitude 3D Encoderデスクトップアプリケーション(WindowsおよびMac)を使用します。Wikitude 3D Encoderでは、AutodeskR FBXRファイル(.fbx)形式を.wt3
にエンコードできます。
3Dモデルのエンコード方法の詳細については、「Wikitude 3D Encoder」のセクションを参照してください。このサンプルでは、.wt3ファイルはすでに用意されており、assets/car.wt3に保存されています。
次の架空の印刷広告をターゲットに、3Dモデルを拡張し自動車広告をAR化します。
3Dモデルの拡張
対応するサンプルタイトル名「3D Model on Target」
まずはじめに、AR.Model
を作成し、3Dモデルをエンコードした.wt3ファイルを示すURLを渡します。さらに、オプションパラメーターを使用して、ARchitect Worldでのモデルのスケーリング、回転、および配置を指定します。
this.modelCar = new AR.Model("assets/car.wt3", {
onLoaded: this.loadingStep,
scale: {
x: 0.045,
y: 0.045,
z: 0.045
},
translate: {
x: 0.0,
y: 0.05,
z: 0.0
},
rotate: {
z: -25
}
});
このサンプルでは、onLoaded
トリガーに関数をアタッチして、3Dモデルのレンダリングが完了したときに通知を受けます。モデルのサイズと保存場所(ローカルかリモートか)によってはロードが完了するまでに時間がかかる場合があるので、ロード時間をユーザーに知らせることを推奨します。
2D拡張オブジェクトと同様に、3DモデルをAR.ImageTrackable
のdrawables.cam
プロパティに追加します。
var trackable = new AR.ImageTrackable(this.tracker, "*", {
drawables: {
cam: [this.modelCar]
}
});
3Dモデルをターゲットに拡張するために必要なことはこれですべてです。3Dモデルのスケーリングと配置を調整するには、AR.Model
にオプションとしてscaleプロパティとtranslateプロパティを渡します。
サンプルの確認には、このページにある画像を使用できます。
アニメーションの追加
対応するサンプルタイトル名「Appearing Animation」
次のステップとして、アニメーションを追加します。このサンプルではターゲットが認識され3Dモデルが表示されるタイミングでアニメーションを追加しています。AR.PropertyAnimation
を使用して、オブジェクトの単一プロパティに対するアニメーションを作成します。X、Y、Zのすべての方向に自動車モデルを拡大するため、3つのアニメーションが必要です。AR.AnimationGroup
を使用してこれらのアニメーションをグループ化し、すべてのアニメーションが並行して再生されるようにします。
var sx = new AR.PropertyAnimation(model, "scale.x", 0, scale, 1500, {
type: AR.CONST.EASING_CURVE_TYPE.EASE_OUT_QUAD
});
var sy = new AR.PropertyAnimation(model, "scale.y", 0, scale, 1500, {
type: AR.CONST.EASING_CURVE_TYPE.EASE_OUT_QUAD
});
var sz = new AR.PropertyAnimation(model, "scale.z", 0, scale, 1500, {
type: AR.CONST.EASING_CURVE_TYPE.EASE_OUT_QUAD
});
return new AR.AnimationGroup(AR.CONST.ANIMATION_GROUP_TYPE.PARALLEL, [sx, sy, sz]);
それぞれのAR.PropertyAnimation
はX、Y、Z方向のいずれかを対象とし、0からscale
変数で渡された値までモデルを拡大します。よりダイナミックなアニメーション効果を生み出すため、EASE_OUT_QUAD
イージングカーブを使用しています。
ターゲットが認識されたときに通知を受けるため、AR.ImageTrackable
のonEnterFieldOfVision
トリガーを使用します。このサンプルでは、appear()
関数をアタッチしています。
appear: function appearFn() {
World.trackableVisible = true;
if (World.loaded) {
World.appearingAnimation.start();
}
},
appear
関数内で、上で作成したAR.AnimationGroup
のstart()
関数を呼び出してアニメーショングループを開始し、アニメーションを1回再生します。
3D拡張オブジェクトへのイベント追加
対応するサンプルタイトル名「Interactivity」
さらに機能を追加するため、回転アニメーションを3Dモデルに追加します。回転の開始と停止はボタンまたは3Dモデルのクリックによって制御します。
3Dモデルを回転させるボタンとなる拡張オブジェクトをターゲットに追加します。そのため、AR.ImageResource
をロードしてそこからAR.ImageDrawable
を作成します。
var imgRotate = new AR.ImageResource("assets/rotateButton.png");
var buttonRotate = new AR.ImageDrawable(imgRotate, 0.2, {
translate: {
x: 0.35,
y: 0.45
},
onClick: this.toggleAnimateModel
});
作成したAR.ImageDrawable
を3Dモデルとともにターゲットに追加するため、両方の拡張オブジェクトをAR.ImageTrackable
に渡します。
var trackable = new AR.ImageTrackable(this.tracker, "*", {
drawables: {
cam: [this.modelCar, buttonRotate]
},
onEnterFieldOfVision: this.appear
});
rotate.z
プロパティに対するAR.PropertyAnimation
を定義して、3Dモデルの回転アニメーションを作成します。
// Rotation Animation
this.rotationAnimation = new AR.PropertyAnimation(this.modelCar, "rotate.z", -25, 335, 10000);
これらの拡張オブジェクトは、onClick
トリガーを設定することでクリック可能になります。onClick
トリガーは、拡張オブジェクトの作成時にオプションで設定できます。そのため、3DモデルのonClick: this.toggleAnimateModel
をオプションで設定してAR.Model
コンストラクターに渡します。ボタンのonClick: this.toggleAnimateModel
トリガーも同様に、AR.ImageDrawable
コンストラクターでオプションとして設定します。これにより、3DモデルまたはボタンをクリックしたときにtoggleAnimateModel()
が呼び出されます。
toggleAnimateModel()
関数では、アニメーションが現在実行中かどうかをチェックして、アニメーションの開始、再開、停止のいずれかを実行します。
toggleAnimateModel: function toggleAnimateModelFn() {
if (!World.rotationAnimation.isRunning()) {
if (!World.rotating) {
World.rotationAnimation.start(-1);
World.rotating = true;
} else {
World.rotationAnimation.resume();
}
} else {
World.rotationAnimation.pause();
}
return false;
}
アニメーションを.start(-1)
で開始すると、アニメーションが無限に繰り返されます。
3D拡張オブジェクトの固定表示
対応するサンプルタイトル名「Snap To Screen」
次に、3Dモデルをよりじっくりと確認できるように、3D拡張オブジェクトの固定表示機能を追加します。固定表示機能は、AR.ImageTrackable
にアタッチされた拡張オブジェクトをARchitect Worldから切り離してカメラビューに固定表示します。一度固定表示した拡張オブジェクトは、ARchitect Worldに戻るよう指示されるまでカメラビューにとどまります。したがって、ユーザーはターゲットをカメラビュー内に入れていなくてもコンテンツを確認することができます。
カメラビュー上の固定表示位置はdiv
要素によって定義します。AR.ImageTrackable
の作成時に、div
を追加オプションとして渡します。このサンプルでは、idがsnapContainer
であるdiv
を使用しています。
this.trackable = new AR.ImageTrackable(this.tracker, "*", {
drawables: {
...
},
snapToScreen: {
snapContainer: document.getElementById('snapContainer')
},
...
});
次に、ボタンを追加することによって固定表示を有効にします。このボタンは、回転ボタンと同じように作成します。唯一の違いはonClick
トリガーであり、新しく作成したボタンでは異なる関数を指定します。
toggleSnapping: function toggleSnappingFn() {
if (World.appearingAnimation.isRunning()) {
World.appearingAnimation.stop();
}
World.snapped = !World.snapped;
World.trackable.snapToScreen.enabled = World.snapped;
if (World.snapped) {
World.applyLayout(World.layout.snapped);
} else {
World.applyLayout(World.layout.normal);
}
}
固定表示の有効/無効を切り替えるには、AR.ImageTrackable
のsnapToScreen.enabled
プロパティをtrue
またはfalse
に設定します。現在のスナップ状態に基づいて、拡張オブジェクトの配置とスケーリングが異なります。
このサンプルでは、一度スクリーンにスナップされると、ジェスチャーイベントによって3Dモデルを回転させたり、拡大/縮小といったスケーリングをすることができます。新しい回転、位置およびスケール値を適用するには、onScale
、onDrag
およびonRotation
のジェスチャコールバックが使用されます。
3Dアニメーションの再生
対応するサンプルタイトル名「Animated Model Parts」
3Dモデルは三角形メッシュの集合であり、これはさらにメッシュパーツに分割できます。各メッシュまたはメッシュパーツは、その外観や空間位置を決定するマテリアルプロパティと変形値を保持しています。このサンプルで使用している赤いランボルギーニモデルの場合は、ホイール、ドア、屋根、ボンネットなどがメッシュを表します。たとえば自動車のドアは、ドアのフレーム、サイドミラー、ドアハンドルを表すメッシュパーツに細分化されます。メッシュパーツをグループ化することで、3Dモデルのパーツを個別にアニメーション表示できます。ランボルギーニのサンプルでは、ドアとそのすべてのパーツを開くことができます(下の図を参照)。
メッシュおよびメッシュパーツに異なる識別子を設定し、それをAR.Model
のonClick
トリガーにmodelPart
パラメーターとして渡すことで、ユーザーが3Dモデルの特定のパーツをクリック/タッチしたときに異なるアクションを適用できます。以下のコードでは、switch構文でmodelPart
パラメーターを使用しています。渡されたmodelPart
が自動車の左ドアを表すパーツの場合、3Dモデルのアニメーションが作成されて開始されます。それ以外の場合は、メッシュまたはメッシュパーツの識別子(modelPart
パラメーター)がalert関数によってポップアップウィンドウに表示されます。
this.model = new AR.Model("assets/car_animated.wt3", {
...
});
this.animationDoorL = new AR.ModelAnimation(this.model, "DoorOpenL_animation");
this.model.onClick = function( drawable, model_part ) {
switch(model_part)
{
case 'WindFL':
case 'DoorL[0]':
case 'DoorL[1]':
case 'DoorL[2]':
case 'DoorL[3]':
World.animationDoorL.start();
break;
...
}
メッシュパーツの識別子は3Dモデルによって提供されます。この識別子は、3Dモデルを作成したモデリングツール(3d Studio Max、Maya、Blenderなど)で指定します。3Dモデルのメッシュおよびメッシュパーツの一覧はWikitude 3D Encoderから取得できます(下の図を参照)。メッシュが単一のパーツで構成されている場合、その識別子はメッシュの名前になります(例: 'WindFL')。メッシュが複数のパーツで構成されている場合、その識別子はメッシュの名前にパーツのインデックスを含む角カッコが付加されたものになります(例: DoorL[0]
)。
特定ロケーションへの3Dモデル拡張
対応するサンプルタイトル名「3d Model At Geo Location」
Wikitude SDKでは、3Dモデルを画像認識型ARだけでなく、ロケーションベース型ARでも拡張することができます。下のサンプルでは、3Dモデルを特定の相対位置に配置する方法を示します。3Dモデルは、ユーザーの現在の位置から北に5m離れた地点の上方2mに配置されます。ここでは簡単に試せるように相対位置を使用していますが、実際のロケーションを使用することもできます。(詳細については、AR.GeoLocation
およびAR.RelativeLocation
を参照)。
var location = new AR.RelativeLocation(null, 5, 0, 2);
var modelEarth = new AR.Model("assets/earth.wt3", {
onLoaded: this.worldLoaded,
scale: {
x: 1,
y: 1,
z: 1
}
});
var obj = new AR.GeoObject(location, {
drawables: {
cam: [modelEarth]
}
});
サンプルを実行すると、カメラをやや東側のやや上方に向ける必要がありますが、そうすると地球の3Dモデルが拡張されていることを確認できます。