รวมตำแหน่งศีรษะไว้ในแอปด้วย ARCore สำหรับ Jetpack XR

หลังจากที่ผู้ใช้ให้สิทธิ์สำหรับการติดตามการเคลื่อนไหวของศีรษะ แอปของคุณจะดึงข้อมูลท่าทางของศีรษะผ่าน ARCore สำหรับ 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
}

การใช้งานการติดตามการเคลื่อนไหวของศีรษะ

วิธีหนึ่งที่แอปของคุณสามารถใช้การติดตามศีรษะคือการคงเอนทิตีไว้ใน ฟิลด์มุมมองของผู้ใช้สำหรับแอปที่กำหนดให้ผู้ใช้ต้องมองหรือเคลื่อนที่ไปรอบๆ

หลีกเลี่ยงการใช้เอนทิตีที่ล็อกส่วนหัวในฟิลด์มุมมองของผู้ใช้ เนื่องจากอาจทำให้เกิดอาการเมารถเมาเรือได้ แต่ให้ใช้การเคลื่อนไหวของเอนทิตีที่ติดตามศีรษะของผู้ใช้ หลังจากผ่านไประยะเวลาสั้นๆ ดังนี้

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