Jetpack XR SDK ให้คุณใช้ Jetpack SceneCore เพื่อสร้าง ควบคุม และจัดการอินสแตนซ์ Entity
เช่น โมเดล 3 มิติ วิดีโอสเตอริโอสโคป และ PanelEntity
โดยใช้ Jetpack SceneCore
Jetpack SceneCore ใช้รูปแบบสถาปัตยกรรมทั่วไป 2 รูปแบบเพื่อรองรับการพัฒนา 3 มิติ ได้แก่ กราฟฉากและระบบเอนทิตีคอมโพเนนต์ (ECS)
ใช้กราฟฉากเพื่อสร้างและควบคุมเอนทิตี
หากต้องการสร้างและควบคุมวัตถุในพื้นที่ 3 มิติ คุณสามารถใช้ Session API ของ Jetpack SceneCore เพื่อเข้าถึงกราฟฉาก กราฟฉากจะสอดคล้องกับโลกแห่งความเป็นจริงของผู้ใช้ และให้คุณจัดระเบียบเอนทิตี 3 มิติ เช่น แผงและโมเดล 3 มิติ ให้เป็นโครงสร้างตามลําดับชั้น และเก็บสถานะของเอนทิตีเหล่านั้น
เมื่อได้รับสิทธิ์เข้าถึงกราฟฉากแล้ว คุณจะใช้ API ใน Jetpack Compose สำหรับ XR เพื่อสร้าง UI เชิงพื้นที่ (เช่น SpatialPanel
และ Orbiter
) ภายในกราฟฉากได้ สำหรับเนื้อหา 3 มิติ เช่น โมเดล 3 มิติ คุณจะเข้าถึงเซสชันได้โดยตรง ดูข้อมูลเพิ่มเติมได้ที่เกี่ยวกับ ActivitySpace ในหน้านี้
ระบบคอมโพเนนต์เอนทิตี
ระบบเอนทิตีคอมโพเนนต์เป็นไปตามหลักการขององค์ประกอบมากกว่าการรับช่วง คุณสามารถขยายลักษณะการทํางานของเอนทิตีได้โดยแนบคอมโพเนนต์ที่กําหนดลักษณะการทํางาน ซึ่งจะช่วยให้คุณใช้ลักษณะการทํางานเดียวกันกับเอนทิตีประเภทต่างๆ ได้ ดูข้อมูลเพิ่มเติมได้ที่เพิ่มลักษณะการทำงานทั่วไปให้กับเอนทิตีในหน้านี้
เกี่ยวกับ ActivitySpace
Session
แต่ละรายการมี ActivitySpace
ที่สร้างขึ้นโดยอัตโนมัติพร้อมกับ Session
ActivitySpace
คือ Entity
ระดับบนสุดในกราฟฉาก
ActivitySpace แสดงถึงพื้นที่ 3 มิติด้วยระบบพิกัดที่ใช้มือขวา (แกน X ชี้ไปทางขวา แกน Y ชี้ขึ้น และแกน Z ชี้ไปด้านหลังโดยสัมพันธ์กับจุดเริ่มต้น) และมีเมตรเป็นหน่วยที่ตรงกับโลกแห่งความเป็นจริง ต้นทางของ ActivitySpace
นั้นค่อนข้างจะเป็นค่าที่กำหนดเอง (เนื่องจากผู้ใช้สามารถรีเซ็ตตำแหน่งของ ActivitySpace
ในโลกแห่งความเป็นจริงได้) เราจึงขอแนะนำให้จัดตำแหน่งเนื้อหาให้สัมพันธ์กันแทนที่จะสัมพันธ์กับต้นทาง
ทำงานกับเอนทิตี
เอนทิตีเป็นหัวใจสําคัญของ SceneCore เกือบทุกอย่างที่ผู้ใช้เห็นและโต้ตอบด้วยคือเอนทิตีที่แสดงแผง โมเดล 3 มิติ และอื่นๆ
เนื่องจาก ActivitySpace
เป็นโหนดระดับบนสุดของกราฟฉาก โดยค่าเริ่มต้น ระบบจะวางเอนทิตีใหม่ทั้งหมดไว้ใน ActivitySpace
โดยตรง คุณสามารถย้ายตำแหน่งของเอนทิตีตามกราฟฉากได้โดยเรียกใช้ setParent
หรือ addChild
เอนทิตีมีลักษณะการทำงานเริ่มต้นบางอย่างสำหรับสิ่งที่เป็นสากลสำหรับเอนทิตีทั้งหมด เช่น การเปลี่ยนตำแหน่ง การหมุน หรือการแสดงผล Entity
ย่อยบางคลาส เช่น GltfEntity
มีพฤติกรรมเพิ่มเติมที่รองรับคลาสย่อย
จัดการเอนทิตี
เมื่อคุณทําการเปลี่ยนแปลงในพร็อพเพอร์ตี้ Entity
ที่เป็นของคลาส Entity
พื้นฐาน การเปลี่ยนแปลงจะส่งผลต่อพร็อพเพอร์ตี้ย่อยทั้งหมด ตัวอย่างเช่น การปรับเปลี่ยน Pose
ของ Entity
หลักจะส่งผลให้รายการย่อยทั้งหมดมีการปรับเหมือนกัน การเปลี่ยนแปลงใน Entity
ย่อยจะไม่มีผลกับ Entity
หลัก
Pose
แสดงตําแหน่งและการหมุนของเอนทิตี้ภายในพื้นที่ 3 มิติ ตำแหน่งคือ Vector3
ที่ประกอบด้วยตำแหน่งตัวเลข x, y, z การหมุนจะแสดงด้วย Quaternion
ตำแหน่งของ Entity
จะสัมพันธ์กับเอนทิตีหลักเสมอ กล่าวคือ Entity
ที่มีตำแหน่ง (0,
0, 0) จะวางอยู่ที่จุดเริ่มต้นของเอนทิตีหลัก
// Place the entity forward 2 meters val newPosition = Vector3(0f, 0f, -2f) // Rotate the entity by 180 degrees on the up axis (upside-down) val newOrientation = Quaternion.fromEulerAngles(0f, 0f, 180f) // Update the position and rotation on the entity entity.setPose(Pose(newPosition, newOrientation))
หากต้องการเปลี่ยนระดับการมองเห็นของ Entity
ให้ใช้ setHidden
// Hide the entity entity.setHidden(true)
หากต้องการปรับขนาด Entity
โดยคงรูปร่างโดยรวมไว้ ให้ใช้
setScale
// Double the size of the entity entity.setScale(2f)
เพิ่มลักษณะการทำงานทั่วไปให้กับเอนทิตี
คุณใช้คอมโพเนนต์ต่อไปนี้เพื่อเพิ่มลักษณะการทำงานทั่วไปให้กับเอนทิตีได้
MovableComponent
: อนุญาตให้ผู้ใช้ย้ายเอนทิตีResizableComponent
: อนุญาตให้ผู้ใช้ปรับขนาดเอนทิตีด้วยรูปแบบ UI ที่สอดคล้องกันInteractableComponent
: ช่วยให้คุณบันทึกเหตุการณ์อินพุตสำหรับการโต้ตอบที่กําหนดเองได้
การสร้างอินสแตนซ์ของคอมโพเนนต์ต้องดำเนินการผ่านเมธอดการสร้างที่เหมาะสมในคลาส Session
เช่น หากต้องการสร้าง ResizableComponent
ให้เรียกใช้ ResizableComponent.create()
หากต้องการเพิ่มลักษณะการทํางานของคอมโพเนนต์ที่เฉพาะเจาะจงลงใน Entity
ให้ใช้เมธอด addComponent()
ใช้ MovableComponent เพื่อทำให้ผู้ใช้ย้ายเอนทิตีได้
MovableComponent
ช่วยให้ผู้ใช้ย้าย Entity
ได้ นอกจากนี้ คุณยังระบุได้ว่าเอนทิตีจะยึดกับประเภทพื้นผิวได้หรือไม่ เช่น พื้นผิวแนวนอนหรือแนวตั้ง หรือพื้นผิวเชิงความหมายที่เฉพาะเจาะจง เช่น โต๊ะ ผนัง หรือเพดาน หากต้องการระบุตัวเลือกของหมุด ให้ระบุชุด AnchorPlacement
เมื่อสร้าง MovableComponent
ต่อไปนี้คือตัวอย่างเอนทิตีที่ย้ายและยึดกับพื้นผิวแนวตั้งได้ รวมถึงพื้นผิวแนวนอนของพื้นและเพดานเท่านั้น
val anchorPlacement = AnchorPlacement.createForPlanes( planeTypeFilter = setOf(PlaneSemantic.FLOOR, PlaneSemantic.TABLE), planeSemanticFilter = setOf(PlaneType.VERTICAL) ) val movableComponent = MovableComponent.create( session = session, systemMovable = false, scaleInZ = false, anchorPlacement = setOf(anchorPlacement) ) entity.addComponent(movableComponent)
เมื่อผู้ใช้ย้ายเอนทิตี พารามิเตอร์ scaleInZ
จะปรับขนาดของเอนทิตีโดยอัตโนมัติเมื่อเอนทิตีเคลื่อนออกจากผู้ใช้ ในลักษณะที่คล้ายกับที่ระบบปรับขนาดแผงในพื้นที่ในบ้าน เนื่องจากระบบคอมโพเนนต์เอนทิตีมีลักษณะ "ตามลําดับชั้น" ขนาดของรายการหลักจึงส่งผลต่อรายการย่อยทั้งหมด
ใช้ ResizableComponent เพื่อทำให้ผู้ใช้ปรับขนาดเอนทิตีได้
ResizableComponent
ช่วยให้ผู้ใช้ปรับขนาด Entity
ได้ ResizableComponent
มีสัญญาณการโต้ตอบด้วยภาพซึ่งเชิญชวนให้ผู้ใช้ปรับขนาด Entity
เมื่อสร้าง ResizeableComponent
คุณสามารถระบุขนาดขั้นต่ำหรือสูงสุด (เป็นเมตร) นอกจากนี้ คุณยังมีตัวเลือกในการระบุสัดส่วนการแสดงผลคงที่เมื่อปรับขนาดเพื่อให้ความกว้างและความสูงปรับขนาดตามสัดส่วนกัน
เมื่อใช้ ResieableComponent
คุณต้องระบุ ResizeListener
เพื่อตอบสนองต่อเหตุการณ์การปรับขนาดที่เฉพาะเจาะจง เช่น onResizeUpdate
หรือ onResizeEnd
ต่อไปนี้คือตัวอย่างการใช้ ResizableComponent
เป็นสัดส่วนภาพแบบคงที่ใน SurfaceEntity
val resizableComponent = ResizableComponent.create(session) resizableComponent.minimumSize = Dimensions(177f, 100f, 1f) resizableComponent.fixedAspectRatio = 16f / 9f // Specify a 16:9 aspect ratio resizableComponent.addResizeListener( executor, object : ResizeListener { override fun onResizeEnd(entity: Entity, finalSize: Dimensions) { // update the size in the component resizableComponent.size = finalSize // update the Entity to reflect the new size (entity as SurfaceEntity).canvasShape = SurfaceEntity.CanvasShape.Quad(finalSize.width, finalSize.height) } }, ) entity.addComponent(resizableComponent)
ใช้ InteractableComponent เพื่อบันทึกเหตุการณ์การป้อนข้อมูลของผู้ใช้
InteractableComponent
ช่วยให้คุณบันทึกเหตุการณ์อินพุตจากผู้ใช้ได้ เช่น เมื่อผู้ใช้มีส่วนร่วมหรือวางเมาส์เหนือ Entity
เมื่อสร้าง InteractableComponent
คุณต้องระบุ InputEventListener
เพื่อรับเหตุการณ์อินพุต เมื่อผู้ใช้ดำเนินการป้อนข้อมูล ระบบจะเรียกใช้เมธอด onInputEvent
ด้วยข้อมูลการป้อนข้อมูลที่เฉพาะเจาะจงซึ่งระบุไว้ในพารามิเตอร์ InputEvent
InputEvent.action
ระบุประเภทอินพุต เช่น การวางเมาส์เหนือหรือการแตะเอนทิตีInputEvent.source
ระบุแหล่งที่มาของอินพุต เช่น อินพุตมือหรือตัวควบคุมInputEvent.pointerType
ระบุว่าอินพุตมาจากมือขวาหรือมือซ้าย
ดูรายการค่าคงที่ InputEvent
ทั้งหมดได้ที่เอกสารอ้างอิง
ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างการใช้ InteractableComponent
เพื่อเพิ่มขนาดของเอนทิตีด้วยมือขวาและลดขนาดด้วยมือซ้าย
val executor = Executors.newSingleThreadExecutor() val interactableComponent = InteractableComponent.create(session, executor) { // when the user disengages with the entity with their hands if (it.source == InputEvent.SOURCE_HANDS && it.action == InputEvent.ACTION_UP) { // increase size with right hand and decrease with left if (it.pointerType == InputEvent.POINTER_TYPE_RIGHT) { entity.setScale(1.5f) } else if (it.pointerType == InputEvent.POINTER_TYPE_LEFT) { entity.setScale(0.5f) } } } entity.addComponent(interactableComponent)