ทำงานร่วมกับ ARCore สำหรับ Jetpack XR

ARCore สำหรับ Jetpack XR ช่วยให้แอปทำงานกับแนวคิดพื้นฐานของเทคโนโลยีความจริงเสริม (AR) ได้โดยใช้องค์ประกอบพื้นฐานของการทําความเข้าใจฉากระดับล่างและการติดตามการเคลื่อนไหว ใช้ ARCore สำหรับ Jetpack XR เมื่อสร้างประสบการณ์ AR และคุณจำเป็นต้องใช้ข้อมูลแบบระนาบหรือกำหนดตำแหน่งเนื้อหาไปยังตำแหน่งคงที่ในพื้นที่

ทําความเข้าใจวงจรชีวิตของเซสชัน

ออบเจ็กต์ทั้งหมดที่ ARCore สำหรับ Jetpack XR ติดตามต้องเข้าถึงผ่านเซสชัน ออบเจ็กต์เซสชันยังมีวงจรที่ต้องมีการดูแลรักษาตามการใช้งานฟีเจอร์ของออบเจ็กต์เซสชันของแอปด้วย ซึ่งคล้ายกับวงจรของกิจกรรม หากแอปของคุณมีกิจกรรมที่เปิดใช้ XR รายการเดียว ให้พิจารณาจัดการวงจรของเซสชันโดยใช้คอมโพเนนต์ที่รับรู้วงจร

สร้างเซสชัน

คุณต้องสร้างเซสชันก่อนจึงจะใช้ได้ การสร้างเซสชันกำหนดให้ผู้ใช้ต้องให้สิทธิ์ android.permission.SCENE_UNDERSTANDING แก่แอปของคุณ

วิธีสร้างเซสชัน

when (val result = Session.create(owner)) {
  is SessionCreateSuccess -> {
    session = result.session
  }
  is SessionCreatePermissionsNotGranted -> {
   // Request android.permission.SCENE_UNDERSTANDING.
  }
}

ดูสาเหตุที่การสร้างเซสชันอาจไม่สําเร็จได้ที่ SessionCreateResult

ดำเนินเซสชันต่อ

คุณควรกลับมาดำเนินการต่อในเซสชันเมื่อแอปพร้อมจัดการการเปลี่ยนแปลงสถานะจาก ARCore สำหรับ Jetpack XR ในกรณีส่วนใหญ่ การดำเนินการนี้จะอยู่ใน onResume() callback ของกิจกรรม แต่แอปอาจต้องการเลื่อนเวลาการประมวลผลจนกว่าผู้ใช้จะโต้ตอบ

ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างการกลับมาทําเซสชันต่อ

when (val result = session.resume()) {
  is SessionResumeSuccess -> {
    // Session has been created successfully.
    // Attach any successful handlers here.
  }
  is SessionResumePermissionsNotGranted -> {
    // Request android.permission.SCENE_UNDERSTANDING.
}

ดูสาเหตุที่เซสชันอาจไม่สามารถกลับมาทำงานต่อได้ที่ SessionResumeResult

หยุดเซสชันชั่วคราว

เมื่อกิจกรรมทำงานอยู่เบื้องหลัง ให้หยุดเซสชันชั่วคราวโดยใช้ Session.pause() การหยุดเซสชันชั่วคราวจะหยุดการติดตามชั่วคราวจนกว่าเซสชันจะกลับมาทํางานต่อ โดยระบบจะคงสถานะของ Perception ไว้

ทำลายเซสชัน

หากต้องการทิ้งเซสชันอย่างถาวร ให้ใช้ Session.destroy() ซึ่งจะเพิ่มพื้นที่ว่างสำหรับทรัพยากรที่ใช้โดยเซสชันและทำลายสถานะเซสชันทั้งหมด

ดึงข้อมูลสถานะของเครื่องบินที่รับรู้

ARCore สำหรับ Jetpack XR จะระบุสถานะของเครื่องบินผ่าน StateFlow ที่แสดงสถานะของเครื่องบิน การติดตามเที่ยวบินในเซสชันจะแจ้งให้แอปทราบเมื่อมีการเพิ่ม อัปเดต หรือนำเที่ยวบินออก

Plane.subscribe(session).collect { planes ->
 // Planes have changed; update plane rendering
}

เครื่องบินมีพร็อพเพอร์ตี้ต่อไปนี้

  • label: คำอธิบายเชิงความหมายของPlaneที่ระบุ อาจเป็น Wall, Floor, Ceiling หรือ Table
  • centerPose: การวางตัวของจุดศูนย์กลางของเครื่องบินที่ตรวจพบ
  • extents: ขนาดของเครื่องบินที่ตรวจพบเป็นเมตร
  • vertices: รายการจุดยอดของรูปหลายเหลี่ยมที่Convexซึ่งประมาณระนาบ

ทำการทดสอบการชนกับเครื่องบิน

Hit-test เป็นวิธีการคํานวณจุดตัดของรังสีกับวัตถุที่เซสชันติดตาม การใช้งาน Hit-Test ที่พบบ่อยคือการชี้ไปที่ตารางและวางวัตถุในตำแหน่งนั้น การดำเนินการทดสอบการทํางานจะแสดงรายการออบเจ็กต์ที่พบ กล่าวคือ Hit-Test จะไม่หยุดที่วัตถุแรกที่พบ อย่างไรก็ตาม บ่อยครั้งที่คุณอาจสนใจเฉพาะออบเจ็กต์แรกที่พบของประเภทหนึ่งๆ

หากต้องการทำการทดสอบการทํางาน ให้ใช้ Interaction.hitTest() กับ Ray ดังนี้

val results = Interaction.hitTest(session, ray)
// When interested in the first Table hit:
val tableHit = results.firstOrNull {
  val trackable = it.trackable
  trackable is Plane && trackable.state.value.label == Plane.Label.Table
}

ยึดเนื้อหาไว้ที่ตำแหน่งคงที่ในพื้นที่ทำงาน

หากต้องการให้วัตถุเสมือนมีตำแหน่งในโลกแห่งความเป็นจริง ให้ใช้ Anchor ออบเจ็กต์หมุดช่วยให้แอปติดตามตำแหน่งคงที่ในพื้นที่จริงได้

ระบบจะสร้างจุดยึดโดยใช้ Pose ซึ่งสามารถตีความโดยสัมพันธ์กับ Trackable ที่มีอยู่หรือไม่ก็ได้

สร้างจุดยึดซึ่งสัมพันธ์กับรายการที่ติดตามได้

เมื่อสร้างจุดยึดตาม Trackable เช่น Plane ซึ่งทำให้จุดยึดติดตาม Trackable ที่แนบอยู่เมื่อ Trackable นั้นเคลื่อนไหวผ่านพื้นที่

val anchor = trackable.createAnchor(pose)

สร้างหมุดโดยไม่มีรายการที่ติดตามได้

วิธีสร้างหมุดที่ไม่ได้แนบอยู่กับ Trackable

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

แนบเอนทิตีกับจุดยึด

หากต้องการแสดงผลโมเดลในตำแหน่งนี้ ให้สร้าง GltfModel และตั้งค่าท่าทางของ GltfModel ให้เหมือนกับท่าทางของจุดยึด ตรวจสอบว่าโมเดลซ่อนอยู่เมื่อTrackingStateของ Anchor เป็น Stopped

// renderSession is androidx.xr.core.Session
anchor.state.collect { state ->
  if (state.trackingState == TrackingState.Tracking) {
    gltfEntity.setPose(
      renderSession.perceptionSpace.transformPoseTo(state.pose, renderSession.activitySpace)
    )
  } else if (state.trackingState == TrackingState.Stopped) {
    entity.setHidden(true)
  }
}

ทําความเข้าใจ TrackingState

Trackable แต่ละรายการมี TrackingState ที่ควรตรวจสอบก่อนใช้งาน Trackable ที่มี TrackableState เป็น Tracking จะมีการอัปเดต Pose โดยระบบอยู่อย่างต่อเนื่อง Trackable ที่ระบุว่า Paused อาจกลายเป็น Tracking ในอนาคต แต่Trackable ที่ระบุว่า Stopped จะกลายเป็น Tracking ไม่ได้

คงหมุดไว้ตลอดเซสชัน

หมุดที่ไม่คงที่จะหายไปหลังจากเซสชันถูกทำลาย การคงหมุดไว้จะทำให้แอปจดจำตําแหน่งของหมุดนั้นในข้อมูลแอปส่วนตัว ระบบจะเรียกข้อมูลจุดยึดนี้ในเซสชันถัดไปได้ และจุดยึดจะอยู่ในตำแหน่งเดียวกันในโลก

หากต้องการเก็บข้อมูลแอตทริบิวต์แองเคอร์ไว้ ให้ใช้ 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() ซึ่งจะนําหมุดออกจากพื้นที่เก็บข้อมูลของแอปและทําให้เรียกใช้ UUID ที่ระบุสําหรับการเรียกAnchor.load()ไม่ได้

Anchor.unpersist(session, uuid)

นอกจากนี้ แอปยังขอรายการหมุดทั้งหมดที่ยังคงอยู่ในพื้นที่เก็บข้อมูลของแอปได้ด้วย โดยทำดังนี้

val uuids = Anchor.getPersistedAnchorUuids(session)