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
โดยตรง คุณย้ายตำแหน่ง
เอนทิตีตามกราฟฉากได้โดยการตั้งค่า parent
หรือใช้
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
ให้ใช้ setEnabled()
ซึ่งจะทำให้มองไม่เห็นและ
หยุดการประมวลผลทั้งหมดที่ดำเนินการกับไฟล์
// Disable the entity. entity.setEnabled(false)
หากต้องการปรับขนาด Entity
โดยยังคงรูปร่างโดยรวมไว้ ให้ใช้ setScale()
// Double the size of the entity entity.setScale(2f)
เพิ่มลักษณะการทำงานทั่วไปให้กับเอนทิตี
คุณใช้คอมโพเนนต์ต่อไปนี้เพื่อเพิ่มลักษณะการทำงานทั่วไปให้กับเอนทิตีได้
MovableComponent
: อนุญาตให้ผู้ใช้ย้ายเอนทิตีResizableComponent
: อนุญาตให้ผู้ใช้ปรับขนาดเอนทิตีด้วย รูปแบบ UI ที่สอดคล้องกันInteractableComponent
: ให้คุณบันทึกเหตุการณ์อินพุตสำหรับการโต้ตอบที่กำหนดเอง
การสร้างอินสแตนซ์ของคอมโพเนนต์ต้องทำผ่านวิธีการสร้างที่เหมาะสมในคลาส Session
เช่น หากต้องการสร้าง ResizableComponent
ให้เรียกใช้
ResizableComponent.create()
หากต้องการเพิ่มลักษณะการทำงานของคอมโพเนนต์ที่เฉพาะเจาะจงลงใน Entity
ให้ใช้เมธอด
addComponent()
ใช้ MovableComponent
เพื่อให้ผู้ใช้ย้ายเอนทิตีได้
MovableComponent
อนุญาตให้ผู้ใช้ย้าย Entity
ได้
ระบบจะส่งเหตุการณ์การเคลื่อนไหวไปยังคอมโพเนนต์เมื่อมีการโต้ตอบกับองค์ประกอบตกแต่ง
ลักษณะการทำงานเริ่มต้นของระบบที่สร้างด้วย
MovableComponent.createSystemMovable()
จะย้าย Entity
เมื่อมีการลาก
การตกแต่ง
val movableComponent = MovableComponent.createSystemMovable(session) entity.addComponent(movableComponent)
พารามิเตอร์ scaleInZ
ที่ไม่บังคับ (ตั้งค่าเป็น true
โดยค่าเริ่มต้น) จะทําให้เอนทิตี
ปรับขนาดโดยอัตโนมัติเมื่อย้ายออกจากผู้ใช้
ในลักษณะเดียวกับที่ระบบปรับขนาดแผงในพื้นที่บ้าน
เนื่องจากลักษณะ "เรียงซ้อน" ของระบบคอมโพเนนต์เอนทิตี สเกลของออบเจ็กต์หลัก
จะมีผลกับออบเจ็กต์ย่อยทั้งหมด
นอกจากนี้ คุณยังระบุได้ด้วยว่าเอนทิตีสามารถยึดกับประเภทพื้นผิว เช่น พื้นผิวแนวนอนหรือแนวตั้ง หรือพื้นผิวเชิงความหมายที่เฉพาะเจาะจง เช่น โต๊ะ ผนัง หรือเพดาน ได้หรือไม่ หากต้องการระบุตัวเลือก Anchor ให้ระบุชุด AnchorPlacement
เมื่อสร้าง MovableComponent
ในตัวอย่างนี้ เอนทิตีที่สามารถ
ย้ายและยึดกับพื้นหรือพื้นผิวแนวนอนของโต๊ะได้มีดังนี้
val anchorPlacement = AnchorPlacement.createForPlanes( anchorablePlaneOrientations = setOf(PlaneOrientation.VERTICAL), anchorablePlaneSemanticTypes = setOf(PlaneSemanticType.FLOOR, PlaneSemanticType.TABLE) ) val movableComponent = MovableComponent.createAnchorable( session = session, anchorPlacement = setOf(anchorPlacement) ) entity.addComponent(movableComponent)
ใช้ ResizableComponent
เพื่อให้ผู้ใช้ปรับขนาดเอนทิตีได้
ResizableComponent
ช่วยให้ผู้ใช้ปรับขนาด Entity
ได้
ResizableComponent
มีคิวการโต้ตอบด้วยภาพที่กระตุ้นให้ผู้ใช้
ปรับขนาด Entity
เมื่อสร้าง ResizableComponent
คุณจะระบุขนาดขั้นต่ำหรือสูงสุด (เป็นเมตร) ได้ นอกจากนี้ คุณยังมีตัวเลือกในการระบุสัดส่วนการแสดงผลแบบคงที่เมื่อปรับขนาด เพื่อให้ความกว้างและความสูงปรับขนาดตามสัดส่วนซึ่งกันและกัน
เมื่อสร้าง ResizableComponent
ให้ระบุ resizeEventListener
ที่
จัดการเหตุการณ์การอัปเดต คุณตอบกลับResizeState
กิจกรรมต่างๆ เช่น RESIZE_STATE_ONGOING
หรือ RESIZE_STATE_END
ได้
ตัวอย่างการใช้ ResizableComponent
ที่มีสัดส่วนภาพคงที่ใน SurfaceEntity
val resizableComponent = ResizableComponent.create(session) { event -> if (event.resizeState == ResizeEvent.ResizeState.RESIZE_STATE_END) { // update the Entity to reflect the new size surfaceEntity.canvasShape = SurfaceEntity.CanvasShape.Quad(event.newSize.width, event.newSize.height) } } resizableComponent.minimumEntitySize = FloatSize3d(177f, 100f, 1f) resizableComponent.fixedAspectRatio = 16f / 9f // Specify a 16:9 aspect ratio surfaceEntity.addComponent(resizableComponent)
ใช้ InteractableComponent
เพื่อบันทึกเหตุการณ์อินพุตของผู้ใช้
InteractableComponent
ช่วยให้คุณบันทึกเหตุการณ์อินพุตจากผู้ใช้ได้
เช่น เมื่อผู้ใช้มีส่วนร่วมหรือวางเมาส์เหนือ Entity
เมื่อสร้าง
InteractableComponent
ให้ระบุ Listener ที่รับเหตุการณ์อินพุต
เมื่อผู้ใช้ดำเนินการป้อนข้อมูล ระบบจะเรียก Listener พร้อมกับ
ข้อมูลอินพุตที่ระบุในพารามิเตอร์ 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.SOURCE_HANDS && it.action == InputEvent.Action.ACTION_UP) { // increase size with right hand and decrease with left if (it.pointerType == InputEvent.Pointer.POINTER_TYPE_RIGHT) { entity.setScale(1.5f) } else if (it.pointerType == InputEvent.Pointer.POINTER_TYPE_LEFT) { entity.setScale(0.5f) } } } entity.addComponent(interactableComponent)