使用 Jetpack XR SDK,您可以使用 Jetpack SceneCore 建立、控制及管理 Entity
執行個體,例如使用 Jetpack SceneCore 的3D 模型、立體影片和 PanelEntity
。
Jetpack SceneCore 採用兩種常見的架構模式來支援 3D 開發:場景圖和實體元件系統 (ECS)。
使用場景圖表建立及控制實體
如要在 3D 空間中建立及控制物件,您必須使用 Jetpack SceneCore 的 Session API 來存取場景圖表。場景圖會與使用者的實際世界保持一致,讓您將面板和 3D 模型等 3D 實體整理成階層式結構,並保留這些實體的狀態。
取得場景群組存取權後,您就可以使用 Jetpack Compose for XR 中的 API,在場景群組中建立空間 UI (例如 SpatialPanel
和 Orbiter
)。對於 3D 模型等 3D 內容,您可以直接存取工作階段。詳情請參閱本頁的「活動空間簡介」。
實體元件系統
實體元件系統遵循組合優先於繼承的原則。您可以透過附加行為定義元件來擴充實體的行為,這樣一來,您就能將相同的行為套用至不同類型的實體。詳情請參閱本頁的「為實體新增常用行為」。
關於 ActivitySpace
每個 Session
都有一個 ActivitySpace
,系統會使用 Session
自動建立這個 ActivitySpace
。ActivitySpace
是場景圖中的頂層 Entity
。
ActivitySpace 代表 3D 空間,採用右手定則的座標系統 (x 軸指向右邊、y 軸指向上方,z 軸則相對於原點向後),並以公尺為單位,以便與現實世界相符。ActivitySpace
的來源是隨機的 (因為使用者可以在現實世界中重設 ActivitySpace
的位置),因此建議您將內容彼此相對定位,而非相對於來源定位。
使用實體
實體是 SceneCore 的核心元素。使用者看到並互動的大部分內容,都是代表面板、3D 模型等實體。
由於 ActivitySpace
是場景圖的頂層節點,因此根據預設,所有新的實體都會直接放入 ActivitySpace
。您可以呼叫 setParent
或 addChild
,沿著場景圖表重新定位實體。
實體具有一些預設行為,適用於所有實體的通用行為,例如變更位置、旋轉或可見度。特定 Entity
子類別 (例如 GltfEntity
) 具有支援子類別的其他行為。
操控實體
當您變更屬於基本 Entity
類別的 Entity
屬性時,變更會依序套用至所有子項。舉例來說,調整父項 Entity
的 Pose
,會導致所有子項都進行相同的調整。在子項 Entity
中進行變更不會影響父項。
Pose
代表實體在 3D 空間中的位置和旋轉角度。位置是 Vector3
,包含 x、y、z 數值位置。旋轉會以 Quaternion
表示。Entity
的位置一律相對於其父項實體。換句話說,位置為 (0, 0, 0) 的 Entity
會放置在其父項實體的原點。
//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
。您也可以指定實體是否可以錨定至水平或垂直表面等表面類型,或是桌子、牆壁或天花板等特定語意表面。如要指定錨點選項,請在建立 MovableComponent
時指定一組 AnchorPlacement
。
以下是實體的範例,可移動並固定在任何垂直表面,以及地板和天花板的水平表面。
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
互動或將滑鼠游標懸停在 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)