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

מכשירי XR רלוונטיים
ההנחיות האלה יעזרו לכם ליצור חוויות למכשירי XR מהסוגים האלה.
משקפי XR
משקפי AR חוטיים

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

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

אפשר לקבל מידע על תנוחת הראש באמצעות סביבת זמן ריצה של 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
        }
    }
}