Jetpack XR용 ARCore를 사용하여 앱에 머리 위치 통합

해당 XR 기기
이 안내는 이러한 유형의 XR 기기용 환경을 구축하는 데 도움이 됩니다.
XR 헤드셋
유선 XR 안경

사용자가 머리 추적 권한을 부여하면 앱이 Jetpack XR용 ARCore를 통해 머리 포즈 정보를 가져올 수 있습니다. 머리 포즈 정보는 앱이 사용자의 시야를 따라가는 창과 같은 더 직관적인 환경을 만드는 데 도움이 될 수 있습니다.

Jetpack XR용 ARCore 세션 만들기

앱에서 만들 수 있는 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
}

머리 추적의 적용 분야

앱에서 헤드 트래킹을 사용하는 한 가지 방법은 사용자가 둘러보거나 이동해야 하는 앱의 경우 사용자의 시야에 엔티티를 유지하는 것입니다.

사용자의 시야에서 headlocked 엔티티를 사용하면 멀미가 발생할 수 있으므로 사용하지 마세요. 대신 짧은 시간 후 사용자의 머리를 따라가는 엔티티 이동을 사용하세요.

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
        }
    }
}