שילוב של מיקום הראש באפליקציה באמצעות ARCore for Jetpack XR

אחרי שהמשתמש מעניק הרשאה למעקב תנועות הראש, האפליקציה יכולה לאחזר מידע על תנוחת הראש באמצעות ARCore for Jetpack XR. המידע על תנוחת הראש יכול לעזור לאפליקציה ליצור חוויות אינטואיטיביות יותר, כמו חלון שעוקב אחרי שדה הראייה של המשתמש.

יצירת פעילות לסשן של ARCore for Jetpack XR

קבלת מידע על תנוחת הראש באמצעות פעילות לסשן של ARCore for Jetpack XR. כדי לקבל Session, אפשר לעיין במאמר הסבר על מחזור החיים של סשן.

הגדרת הסשן

התכונה 'מעקב אחר תנועת הראש' לא מופעלת כברירת מחדל בסשנים של XR. כדי להפעיל את מעקב הראש, צריך להגדיר את הסשן ולבחור את המצב של HeadTrackingMode.LAST_KNOWN:

val newConfig = session.config.copy(
    headTracking = Config.HeadTrackingMode.LAST_KNOWN,
)
when (val result = session.configure(newConfig)) {
    is SessionConfigureSuccess -> TODO(/* Success! */)
    is SessionConfigureConfigurationNotSupported ->
        TODO(/* Some combinations of configurations are not valid. Handle this failure case. */)

    else ->
        TODO(/* The session could not be configured. See SessionConfigureResult for possible causes. */)
}

אחזור נתונים של תנוחת הראש

נתוני תנוחת הראש נחשפים באמצעות RenderViewpoint. ‫RenderViewpoint מתאר את התנוחה ואת שדה הראייה של נקודת מבט מסוימת של מכשיר. למכשיר יכולות להיות נקודות מבט שמאלית, ימנית או מונו, בהתאם ליכולות המכשיר.

כדי לקבל נתונים לגבי נקודת המבט מונו:

val mono = RenderViewpoint.mono(session) ?: return
mono.state.collect { state ->
    val fov = state.fieldOfView
    val viewpointPose = state.pose
}

שימושים במעקב אחרי תנועות הראש

אחת הדרכים שבהן האפליקציה יכולה להשתמש במעקב אחרי תנועות הראש היא לשמור על ישויות בשדה הראייה של המשתמש, באפליקציות שדורשות מהמשתמשים להסתכל או לנוע.

אל תשתמשו בישויות שמוצמדות לראש בשדה הראייה של המשתמש, כי זה עלול לגרום לבחילה. במקום זאת, כדאי להשתמש בתנועת ישות שעוקבת אחרי הראש של המשתמש אחרי פרק זמן קצר:

val viewpointPose = RenderViewpoint.left(session)!!.state
lifecycleScope.launch {
    while (true) {
        delay(2000)
        val start = panel.getPose()
        val startTime = session.state.value.timeMark

        val pose = session.scene.perceptionSpace.transformPoseTo(
            viewpointPose.value.pose,
            session.scene.activitySpace
        )
        val target = Pose(pose.translation + pose.forward * 1f, pose.rotation)
        while (true) {
            val ratio =
                (session.state.value.timeMark - startTime).inWholeMilliseconds / 500f
            panel.setPose(Pose.lerp(start, target, ratio))
            if (ratio > 1f) break
        }
    }
}