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