日々是好日~every day is a good day~

日常の中の非日常の備忘録

【Android Studio】スマホをタップしてコダックを召喚

非日常生活に入る前に 下書きをしていた記事があったことを思い出しました
ARにハマっていて勉強中だったのに…すっかりリセットされてしまいました
また日常に戻ったら1からやり直しかな(悲)
その時のために まとめたものをアップしておきます


以前アップしたUnityのスマホをタップしてコダックを召喚
everydayisagoodday.hatenadiary.com
これのAndroid Studio版です

Android StudioでもARアプリができるはずなのでいろいろ調べながら挑戦してみました
が うまくいかず保留にしようかと思い始めた頃この記事に遭遇
qiita.com
解説通りにやってみたらうまくいったので 忘れないうちにメモ!メモ!!

1.New ProjectのEmpty Views Activityを選択し次へ

2.名前をつけて完了

3.Gradle Scripts/build.gradle.kts(:app)を開き minSdkを24以上にする

4.下の方へスクロールして

implementation("com.gorisse.thomas.sceneform:sceneform:1.20.3")

 を追加 Sync Nowをクリック

5.app/manifests/AndroidManifest.xmlを開き

<uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />

を追加

6.下の方へスクロールして

<meta-data android:name="com.google.ar.core" android:value="optional" />

を追加

7.activity_main.xmlにArFragmentを配置

8.MainActivity.ktでArFragmentを呼び出す

9.ここで一度実行
スマホを持った手の形のインジケーターが表示されればここまで成功!

10.appを右クリックし新規 /Folder/Assets Folderを選択

11.完了をクリック

12.作成したapp/assetsを右クリックし新規/ディレクトリを選択

13.modelsというディレクトリを作成

14.app/assets/modelsにAR表示したいglbファイルを設定

15.MainActivity.ktを編集

import android.net.Uri
import android.os.Bundle
import android.view.MotionEvent
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.example.artest.R.layout
import com.google.ar.core.HitResult
import com.google.ar.core.Plane
import com.google.ar.sceneform.AnchorNode
import com.google.ar.sceneform.SceneView
import com.google.ar.sceneform.rendering.ModelRenderable
import com.google.ar.sceneform.rendering.Renderable
import com.google.ar.sceneform.ux.ArFragment
import com.google.ar.sceneform.ux.TransformableNode
import com.gorisse.thomas.sceneform.scene.await

private var model: Renderable? = null
private lateinit var arFragment: ArFragment
private val arSceneView
    get() = arFragment.arSceneView
private val arScene
    get() = arSceneView.scene

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(layout.activity_main)

        //arFragment = (supportFragmentManager.findFragmentById(R.id.arFragment) as ArFragment)
        arFragment = (supportFragmentManager.findFragmentById(R.id.arFragment) as ArFragment).apply {
            setOnSessionConfigurationListener { session, config ->
            }
            setOnViewCreatedListener { arSceneView ->
                arSceneView.setFrameRateFactor(SceneView.FrameRate.FULL)
            }
            setOnTapArPlaneListener(::onPlaneTapped)
        }
        lifecycleScope.launchWhenCreated {
            fetchModels()
        }
    }

    private suspend fun fetchModels() {
        //ARモデルのローディング
        model = ModelRenderable.builder()
            .setSource(this, Uri.parse("models/koDuck.glb"))
            .setIsFilamentGltf(true)
            .await()
    }

    /*
     * Scene空間がタップされた時に呼び出されるメソッド
     * @param hitResult: ユーザーがタップした空間の点に関連する情報を持ったオブジェクト
     * @param plane: ARモデルをSceneに配置する平面
     * @param motionEvent: ユーザーのジェスチャー(Pinch、Rotate、Dragなど)を処理するイベントクラス
     */
    private fun onPlaneTapped(hitResult: HitResult?, plane: Plane?, motionEvent: MotionEvent?) {
        if (model == null) {
            Toast.makeText(this, "Loading AR Model...", Toast.LENGTH_SHORT).show()
            return
        }
        initScene(hitResult)
    }

    private fun initScene(hitResult: HitResult?) {
        if (hitResult != null) {
            arScene.addChild(AnchorNode(hitResult.createAnchor()).apply {
                addChild(TransformableNode(arFragment.transformationSystem).apply {
                    renderable = model
                    renderableInstance.animate(true).start()
                })
            })
        }
    }
}

長くなりましたが これでAndroidスマホをつないで実行すると

難しいー(汗)ここから展開できる気がしない(笑)