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 modelPosition = 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
ให้เรียกใช้ session.createResizableComponent()
หากต้องการเพิ่มลักษณะการทํางานของคอมโพเนนต์ที่เฉพาะเจาะจงลงใน Entity
ให้ใช้เมธอด addComponent()
ใช้ MovableComponent เพื่อทำให้เอนทิตีเคลื่อนย้ายได้โดยผู้ใช้
MovableComponent
ช่วยให้ผู้ใช้ย้าย Entity
ได้ นอกจากนี้ คุณยังระบุได้ว่าเอนทิตีจะยึดกับประเภทพื้นผิวได้หรือไม่ เช่น พื้นผิวแนวนอนหรือแนวตั้ง หรือพื้นผิวเชิงความหมายที่เฉพาะเจาะจง เช่น โต๊ะ ผนัง หรือเพดาน หากต้องการระบุตัวเลือกของหมุด ให้ระบุชุด AnchorPlacement
เมื่อสร้าง MovableComponent
ต่อไปนี้คือตัวอย่างของเอนทิตีที่ย้ายและยึดกับพื้นผิวแนวตั้งได้ รวมถึงพื้นผิวแนวนอนของพื้นและเพดานเท่านั้น
val anchorPlacement = AnchorPlacement.createForPlanes(
planeTypeFilter = setOf(PlaneSemantic.FLOOR, PlaneSemantic.TABLE),
planeSemanticFilter = setOf(PlaneType.VERTICAL))
val movableComponent = xrSession.createMovableComponent(
systemMovable = false,
scaleInZ = false,
anchorPlacement = setOf(anchorPlacement)
)
entity.addComponent(movableComponent)
ใช้ ResizableComponent เพื่อทำให้ผู้ใช้ปรับขนาดเอนทิตีได้
ResizableComponent
ช่วยให้ผู้ใช้ปรับขนาด Entity
ได้ ResizableComponent
มีสัญญาณการโต้ตอบด้วยภาพซึ่งเชิญชวนให้ผู้ใช้ปรับขนาด Entity
เมื่อสร้าง ResizeableComponent
คุณสามารถระบุขนาดขั้นต่ำหรือสูงสุด (เป็นเมตร) นอกจากนี้ คุณยังมีตัวเลือกในการระบุสัดส่วนการแสดงผลคงที่เมื่อปรับขนาดเพื่อให้ความกว้างและความสูงปรับขนาดตามสัดส่วนกัน
ต่อไปนี้คือตัวอย่างการใช้ ResizableComponent
ที่มีสัดส่วนภาพแบบคงที่
val resizableComponent = xrSession.createResizableComponent()
resizableComponent.minimumSize = Dimensions(177f, 100f, 1f )
resizableComponent.fixedAspectRatio = 16f / 9f //Specify a 16:9 aspect ratio
entity.addComponent(resizableComponent)
ใช้ InteractableComponent เพื่อบันทึกเหตุการณ์การป้อนข้อมูลของผู้ใช้
InteractableComponent
ช่วยให้คุณบันทึกเหตุการณ์อินพุตจากผู้ใช้ได้ เช่น เมื่อผู้ใช้มีส่วนร่วมหรือวางเมาส์เหนือ Entity
เมื่อสร้าง InteractableComponent
คุณต้องระบุ InputEventListener
เพื่อรับเหตุการณ์อินพุต เมื่อผู้ใช้ดำเนินการป้อนข้อมูล ระบบจะเรียกใช้เมธอด onInputEvent
ด้วยข้อมูลการป้อนข้อมูลที่เฉพาะเจาะจงซึ่งระบุไว้ในพารามิเตอร์ InputEvent
InputEvent.action
ระบุประเภทอินพุต เช่น การวางเมาส์เหนือหรือการแตะเอนทิตีInputEvent.source
ระบุแหล่งที่มาของอินพุต เช่น อินพุตมือหรือตัวควบคุมInputEvent.pointerType
ระบุว่าอินพุตมาจากมือขวาหรือมือซ้าย
ดูรายการค่าคงที่ InputEvent
ทั้งหมดได้ที่เอกสารอ้างอิง
ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างการใช้ InteractableComponent
เพื่อเพิ่มขนาดของเอนทิตีด้วยมือขวาและลดขนาดด้วยมือซ้าย
private val executor by lazy { Executors.newSingleThreadExecutor() }
val interactableComponent = xrSession.createInteractableComponent(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)