Jetpack XR SDK ช่วยให้คุณใช้ Jetpack SceneCore เพื่อสร้าง ควบคุม และจัดการอินสแตนซ์
Entity
เช่น โมเดล 3 มิติ วิดีโอสเตอริโอสโคปิก และ
PanelEntity
โดยใช้ Jetpack SceneCore
Jetpack SceneCore ใช้รูปแบบสถาปัตยกรรมทั่วไป 2 รูปแบบเพื่อรองรับการพัฒนา 3 มิติ ได้แก่ Scene Graph และระบบเอนทิตี-คอมโพเนนต์ (ECS)
ใช้กราฟฉากเพื่อสร้างและควบคุมเอนทิตี
หากต้องการสร้างและควบคุมออบเจ็กต์ในพื้นที่ 3 มิติ คุณสามารถใช้ API Session ของ 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
คลาสย่อยที่เฉพาะเจาะจง เช่น GltfModelEntity
มีลักษณะการทำงานเพิ่มเติมที่
รองรับคลาสย่อย
แก้ไขเอนทิตี
เมื่อคุณเปลี่ยนแปลงพร็อพเพอร์ตี้ Entity
ที่อยู่ในคลาส Entity
ฐาน การเปลี่ยนแปลงจะส่งผลต่อพร็อพเพอร์ตี้ย่อยทั้งหมด ตัวอย่างเช่น
การปรับPose
ของEntity
หลักจะส่งผลให้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
ได้ นอกจากนี้ คุณยังระบุได้ด้วยว่าต้องการยึดเอนทิตีกับพื้นผิวประเภทใด เช่น พื้นผิวแนวนอนหรือแนวตั้ง หรือพื้นผิวเชิงความหมายที่เฉพาะเจาะจง เช่น โต๊ะ ผนัง หรือเพดาน หากต้องการระบุตัวเลือก Anchor ให้ระบุชุด 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
เมื่อสร้าง ResizableComponent
คุณจะระบุขนาดขั้นต่ำหรือสูงสุด (เป็นเมตร) ได้ นอกจากนี้ คุณยังมีตัวเลือกในการระบุสัดส่วนการแสดงผลแบบคงที่เมื่อปรับขนาด เพื่อให้ความกว้างและความสูงปรับขนาดตามสัดส่วนซึ่งกันและกัน
เมื่อใช้ ResizableComponent
คุณต้องระบุ 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)