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に保存されています。

Wikitude 3D Encoderでの自動車モデルのレンダリング

次の架空の印刷広告をターゲットに、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
    }
});
ソースコードをGitHubで見る

このサンプルでは、onLoadedトリガーに関数をアタッチして、3Dモデルのレンダリングが完了したときに通知を受けます。モデルのサイズと保存場所(ローカルかリモートか)によってはロードが完了するまでに時間がかかる場合があるので、ロード時間をユーザーに知らせることを推奨します。

2D拡張オブジェクトと同様に、3DモデルをAR.ImageTrackabledrawables.camプロパティに追加します。

var trackable = new AR.ImageTrackable(this.tracker, "*", {
    drawables: {
        cam: [this.modelCar]
    }
});
ソースコードをGitHubで見る

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]);
ソースコードをGitHubで見る

それぞれのAR.PropertyAnimationはX、Y、Z方向のいずれかを対象とし、0からscale変数で渡された値までモデルを拡大します。よりダイナミックなアニメーション効果を生み出すため、EASE_OUT_QUADイージングカーブを使用しています。

ターゲットが認識されたときに通知を受けるため、AR.ImageTrackableonEnterFieldOfVisionトリガーを使用します。このサンプルでは、appear()関数をアタッチしています。

appear: function appearFn() {
    World.trackableVisible = true;
    if (World.loaded) {
        World.appearingAnimation.start();
    }
},
ソースコードをGitHubで見る

appear関数内で、上で作成したAR.AnimationGroupstart()関数を呼び出してアニメーショングループを開始し、アニメーションを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
});
    
ソースコードをGitHubで見る

作成したAR.ImageDrawableを3Dモデルとともにターゲットに追加するため、両方の拡張オブジェクトをAR.ImageTrackableに渡します。

var trackable = new AR.ImageTrackable(this.tracker, "*", {
    drawables: {
        cam: [this.modelCar, buttonRotate]
    },
    onEnterFieldOfVision: this.appear
});
ソースコードをGitHubで見る

rotate.zプロパティに対するAR.PropertyAnimationを定義して、3Dモデルの回転アニメーションを作成します。

// Rotation Animation
this.rotationAnimation = new AR.PropertyAnimation(this.modelCar, "rotate.z", -25, 335, 10000);
ソースコードをGitHubで見る

これらの拡張オブジェクトは、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;
}
ソースコードをGitHubで見る

アニメーションを.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')
    },
    ...
});
ソースコードをGitHubで見る

次に、ボタンを追加することによって固定表示を有効にします。このボタンは、回転ボタンと同じように作成します。唯一の違いは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);
    }
}
ソースコードをGitHubで見る

固定表示の有効/無効を切り替えるには、AR.ImageTrackablesnapToScreen.enabledプロパティをtrueまたはfalseに設定します。現在のスナップ状態に基づいて、拡張オブジェクトの配置とスケーリングが異なります。

このサンプルでは、​​一度スクリーンにスナップされると、ジェスチャーイベントによって3Dモデルを回転させたり、拡大/縮小といったスケーリングをすることができます。新しい回転、位置およびスケール値を適用するには、onScaleonDragおよびonRotationのジェスチャコールバックが使用されます。

3Dアニメーションの再生

対応するサンプルタイトル名「Animated Model Parts」

3Dモデルは三角形メッシュの集合であり、これはさらにメッシュパーツに分割できます。各メッシュまたはメッシュパーツは、その外観や空間位置を決定するマテリアルプロパティと変形値を保持しています。このサンプルで使用している赤いランボルギーニモデルの場合は、ホイール、ドア、屋根、ボンネットなどがメッシュを表します。たとえば自動車のドアは、ドアのフレーム、サイドミラー、ドアハンドルを表すメッシュパーツに細分化されます。メッシュパーツをグループ化することで、3Dモデルのパーツを個別にアニメーション表示できます。ランボルギーニのサンプルでは、ドアとそのすべてのパーツを開くことができます(下の図を参照)。

3D Encoderでのモデルパーツのアニメーション

メッシュおよびメッシュパーツに異なる識別子を設定し、それをAR.ModelonClickトリガーに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;
    ...
}
ソースコードをGitHubで見る

メッシュパーツの識別子は3Dモデルによって提供されます。この識別子は、3Dモデルを作成したモデリングツール(3d Studio Max、Maya、Blenderなど)で指定します。3Dモデルのメッシュおよびメッシュパーツの一覧はWikitude 3D Encoderから取得できます(下の図を参照)。メッシュが単一のパーツで構成されている場合、その識別子はメッシュの名前になります(例: 'WindFL')。メッシュが複数のパーツで構成されている場合、その識別子はメッシュの名前にパーツのインデックスを含む角カッコが付加されたものになります(例: DoorL[0])。

3D Encoderでのモデルパーツの識別子のコピー

特定ロケーションへの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]
    }
});
ソースコードをGitHubで見る

サンプルを実行すると、カメラをやや東側のやや上方に向ける必要がありますが、そうすると地球の3Dモデルが拡張されていることを確認できます。