Kết hợp vị trí đầu trong ứng dụng bằng ARCore cho Jetpack XR

Sau khi người dùng cấp quyền theo dõi cử động đầu, ứng dụng của bạn có thể truy xuất thông tin về tư thế đầu thông qua ARCore cho Jetpack XR. Thông tin về tư thế đầu có thể giúp ứng dụng của bạn tạo ra trải nghiệm trực quan hơn, chẳng hạn như một cửa sổ theo trường nhìn của người dùng.

Tạo một phiên ARCore cho Jetpack XR

Lấy thông tin về tư thế đầu thông qua phiên ARCore cho Jetpack XR. Hãy xem phần Tìm hiểu vòng đời của một phiên để lấy Session.

Định cấu hình phiên

Theo mặc định, tính năng theo dõi chuyển động đầu không được bật trong các phiên XR. Để bật tính năng theo dõi đầu, hãy định cấu hình phiên và đặt chế độ 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. */)
}

Truy xuất dữ liệu về tư thế đầu

Dữ liệu tư thế đầu được hiển thị thông qua một RenderViewpoint. RenderViewpoint mô tả tư thế và góc nhìn cho một điểm nhìn nhất định của thiết bị. Thiết bị có thể có điểm nhìn bên trái, bên phải hoặc đơn âm, tuỳ thuộc vào khả năng của thiết bị.

Cách lấy dữ liệu cho chế độ xem đơn sắc:

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

Ứng dụng theo dõi cử động đầu

Một cách mà ứng dụng của bạn có thể sử dụng tính năng theo dõi đầu là giữ các thực thể trong trường nhìn của người dùng, đối với những ứng dụng yêu cầu người dùng nhìn hoặc di chuyển xung quanh.

Tránh sử dụng các thực thể bị khoá đầu trong trường nhìn của người dùng vì điều này có thể gây ra chứng say tàu xe. Thay vào đó, hãy sử dụng chuyển động của thực thể theo đầu của người dùng sau một khoảng thời gian ngắn:

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