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.shape = SurfaceEntity.Shape.Quad(FloatSize2d(event.newSize.width, event.newSize.height)) } } resizableComponent.minimumEntitySize = FloatSize3d(177f, 100f, 1f) resizableComponent.isFixedAspectRatioEnabled = true // Maintain a fixed aspect ratio when resizing 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)