Jetpack XR용 ARCore로 앵커 만들기

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

앵커는 실제 세계의 고정된 위치와 방향을 설명합니다. 객체를 앵커에 연결하면 객체가 현실 세계에 사실적으로 배치된 것처럼 표시됩니다.

세션 액세스

Jetpack XR Session용 ARCore를 통해 앵커를 만듭니다. XR용 Jetpack Compose를 사용하여 공간 UI를 개선하는 경우 XR용 Jetpack Compose에서 세션에 액세스하세요. Jetpack SceneCore 라이브러리의 공간화된 엔티티로 작업하는 경우 Jetpack XR 런타임에서 세션에 액세스합니다.

세션 구성

앵커를 만들고 로드하는 데는 세션을 구성하지 않아도 됩니다. 하지만 앵커 지속성은 XR 세션에서 기본적으로 사용 설정되지 않습니다. 로컬 스토리지에서 앵커를 유지하고 로드하려면 세션을 구성하고 AnchorPersistenceMode.LOCAL 모드를 설정합니다.

val newConfig = session.config.copy(
    anchorPersistence = Config.AnchorPersistenceMode.LOCAL,
)
when (val result = session.configure(newConfig)) {
    is SessionConfigureSuccess -> TODO(/* Success! */)
    else ->
        TODO(/* The session could not be configured. See SessionConfigureResult for possible causes. */)
}

콘텐츠를 공간의 고정된 위치에 고정

앵커는 Pose를 사용하여 생성되며, 기존 Trackable을 기준으로 해석할 수도 있고 그렇지 않을 수도 있습니다.

추적 가능 항목을 기준으로 앵커 만들기

Plane과 같은 Trackable에 상대적으로 앵커가 생성됩니다. 이렇게 하면 앵커가 공간을 이동할 때 연결된 Trackable를 따릅니다.

when (val result = trackable.createAnchor(pose)) {
    is AnchorCreateSuccess -> { /* anchor stored in `result.anchor`. */ }
    else -> { /* handle failure */ }
}

추적 가능한 항목 없이 앵커 만들기

Trackable에 연결되지 않은 앵커를 만들려면 다음을 실행하세요.

when (val result = Anchor.create(session, pose)) {
    is AnchorCreateSuccess -> { /* anchor stored in `result.anchor`. */ }
    else -> { /* handle failure */ }
}

엔티티를 앵커에 연결

이 위치에 모델을 렌더링하려면 GltfModel를 만들고 부모를 AnchorEntity로 설정합니다.

AnchorEntity.create(session, anchor).apply {
    parent = session.scene.activitySpace
    addChild(entity)
}

TrackingState 이해

Trackable에는 사용 전에 확인해야 하는 TrackingState이 있습니다. TrackingTrackableState이 있는 TrackablePose은 시스템에 의해 적극적으로 업데이트됩니다. PausedTrackable는 나중에 Tracking가 될 수 있지만 StoppedTrackableTracking가 될 수 없습니다.

세션 전체에서 앵커 유지

지속되지 않는 앵커는 세션이 소멸된 후 사라집니다. 앱은 앵커를 유지하여 비공개 앱 데이터에서 앵커의 위치를 기억합니다. 이 앵커는 후속 세션에서 검색할 수 있으며 동일한 위치에 고정됩니다.

앵커를 유지하려면 다음과 같이 Anchor.persist()를 사용합니다.

val uuid = anchor.persist()

앱은 향후 세션에서 UUID를 사용하여 앵커를 검색할 수 있습니다.

when (val result = Anchor.load(session, uuid)) {
    is AnchorCreateSuccess -> {
        // Loading was successful. The anchor is stored in result.anchor.
    }
    else -> {
        // handle failure
    }
}

더 이상 앵커가 필요하지 않으면 unpersist()을 호출합니다. 이렇게 하면 앱의 저장소에서 앵커가 삭제되고 Anchor.load() 호출에서 지정된 UUID를 가져올 수 없게 됩니다.

Anchor.unpersist(session, uuid)

앱은 앱의 저장소에 아직 있는 영구 저장된 모든 앵커 목록을 요청할 수도 있습니다.

val uuids = Anchor.getPersistedAnchorUuids(session)