Poly APIをARKitで使ってみる


ARKit Advent Calendar 2017の11日目です。
Timers Inc.でiOSエンジニアをしていますかっくん a.k.a. fromKKと申します。
今年のWWDCでAppleがARKitを発表した時に現場に居たのですが、凄く盛り上がったのを未だに覚えています。
業務でもARKitは少しずつ活用し始めているのですが、2017年10月末にGoogleがリリースしたPolyと組み合わせた機能もちょうど本日リリースしました🎉

その機能の開発中の2017年11月末にPoly APIもリリースされました。
流石に業務で入れるのは間に合わなかったのですが、この度2017年 AKIBA.swift忘年回にて登壇する事になり、それに合わせて少し触ってみた事をまとめておきます。

Poly

Polyは2017年10月末にGoogleリリースした3Dモデルが自由にダウンロード出来るサイトです。
様々なクリエイターが作った3Dデータが無料でダウンロード出来るので独自に3Dモデルを作る時間が無い場合は、Polyからモデルをダウンロードして利用する事も検討して良いと思います。
但し、利用する際にはライセンスに注意が必要です。
大半の3DデータはCC-BYというライセンスになっており、製作者を画面に表示する必要がありますので、実際に利用する際にはご注意下さい。

Poly API

Poly APIは2017年11月末にGoogleが発表したPolyのデータをダウンロードしてアプリ等で利用出来る様にしたプラットフォームです。
まだ、出来る事は少なくて、assetの検索、詳細の取得、ユーザー毎の投稿の取得、ユーザーが高評価にしたものリストの取得しか出来ません。
assetの検索、詳細の取得はAPIキーさえあれば利用可能ですが、ユーザー毎の投稿の取得、ユーザーが高評価にしたものリストの取得はOAuthでの認証が必要です。
Google製のSampleもありますので参考にして頂ければと思います。

APIの利用方法

先にGoogle APIのConsole画面でPoly APIを有効にしておく必要があります。

その後Poly APIのDocumentからAPIキーを取得する事が出来ます。

API概要

ドメインはhttps://poly.googleapis.comで共通しています。

v1.assets

Methods Path
get GET /v1/{name=assets/*}
list GET /v1/assets

検索や詳細の取得が出来ます。URLの後ろにAPIキーを付与するだけの簡易認証で利用出来ます。
(例: https://poly.googleapis.com/v1/assets?key=YOUR_API_KEY )

v1.users.assets

Methods Path
list GET /v1/{name=users/*}/assets

ユーザーが投稿したasset一覧です。OAuth認証が必要なので今回は試せていません。

v1.users.likedassets

Methods Path
list GET /v1/{name=users/*}/likedassets

ユーザーが高評価にしたもののasset一覧です。OAuth認証が必要なので同じく今回は試せていません。

PolyのデータをARKit/SceneKitで利用する

Assetの中にformatsというオブジェクトがあります。
Polyでは3Dデータの登録時に.objファイルと.mtlファイルをアップロードするのですが、他のデータ形式にも変換されるのか様々なデータ形式が格納されている事がありますのでformatsの中からformatTypeOBJの物を検索して利用する必要があります。
formatにはrootというオブジェクトとresourcesという配列があるのですが、それぞれ.objファイルのURLと.mtlファイルのURLを格納しています。データによっては.jpg.png等のテクスチャファイルを格納している事がある様です。
これらのURLのファイルを全てダウンロードしてローカルの同じフォルダに格納します。
全てのファイルをダウンロードした後は下記の様に.objファイルのURLを使用すればSCNNodeとして利用出来ます。

import SceneKit
import SceneKit.ModelIO
import ModelIO

// MDLAssetインスタンスを生成
let mdlAsset = MDLAsset(url: objURL)
// テクスチャを読み込む
mdlAsset.loadTextures()
// SCNNodeを生成
let node = SCNNode(mdlObject: mdlAsset.object(at: 0))

PolyKit

今回触ってみて、Googleが定義している構造をマッピングしたり、Assetから複数のファイルをダウンロードする処理を書くのが少し面倒だったのでライブラリ化しました。

https://github.com/fromkk/PolyKit

Carthageに対応したのでインストールは下記の様にCartfileに書いてTerminal.appcarthage update --platform iosを実行してプロジェクトにインポートするだけで利用出来ます。

#Cartfile
github "fromkk/PolyKit"

使い方

検索

検索は先にクエリーを作成してAPIのインスタンスに渡すとassetの検索が可能です。

import PolyKit

let query = PolyAssetsQuery(keywords: "Cat", format: Poly3DFormat.obj)
let polyApi = PolyAPI(apiKey: "Poly API Key is HERE!!!")
polyApi.assets(with: query) { (result) in
    switch result {
    case .success(let assets):
        self.dataSource.assets = assets.assets ?? []
    case .failure(_):
        self.showFetchFailedAlert()
    }
}

.obj.mtlのダウンロード

assetのダウンロードはdownloadObj関数を実行すれば必要なファイルをダウンロードした後で.objのローカルURLを取得する事が出来ます。

import PolyKit

let asset: PolyAsset = ...
// Download obj and mtl files from Poly
asset.downloadObj { (result) in
    switch result {
    case .success(let localUrl):
        let mdlAsset = MDLAsset(url: localUrl)
        mdlAsset.loadTextures()
        let node = SCNNode(mdlObject: mdlAsset.object(at: 0))
        // do something with node
    case .failure(let error):
        debugPrint(#function, "error", error)
    }
}

まとめ

APIをラップしただけのライブラリですが利用が随分と簡単になったかと思います。
特にこれまでは3Dデータを動的に利用する様なアプリを作るのは大変でしたが、Polyのお陰でARKitSceneKitのアプリ開発も幅が広がっているなと感じます。
既にPolyには沢山の3Dデータがあり、今も続々とファイルが増えているので、今後のアプリやゲーム制作でもどんどん活用していきましょう⤴️
PolyKitを使ってみて良いなと思った人は良かったら⭐️下さい❗️

P.S.

今はAPIキーを利用しただけの機能しか利用出来ないのですが、GoogleのOAuthの利用の仕方ご存知の方いましたら、ご教授、Pull Requestお待ちしています🙇🏻‍♂️

English ver is here