建立、控制及管理實體

使用 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 (例如 SpatialPanelOrbiter)。對於 3D 模型等 3D 內容,您可以直接存取工作階段。詳情請參閱本頁的「活動空間簡介」。

實體元件系統

實體元件系統遵循組合優先於繼承的原則。您可以透過附加行為定義元件來擴充實體的行為,這樣一來,您就能將相同的行為套用至不同類型的實體。詳情請參閱本頁的「為實體新增常用行為」。

關於 ActivitySpace

每個 Session 都有一個 ActivitySpace,系統會自動使用 Session 建立這個 ActivitySpaceActivitySpace 是場景圖中的頂層 Entity

ActivitySpace 代表 3D 空間,採用右手定則的座標系統 (x 軸指向右邊、y 軸指向上方,z 軸則相對於原點向後),並以公尺為單位,以便與現實世界相符。ActivitySpace 的來源是隨機的 (因為使用者可以在現實世界中重設 ActivitySpace 的位置),因此建議您將內容彼此相對定位,而非相對於來源定位。

使用實體

實體是 SceneCore 的核心元素。使用者看到並互動的大部分內容,都是代表面板、3D 模型等實體。

由於 ActivitySpace 是場景圖的頂層節點,因此根據預設,所有新的實體都會直接放入 ActivitySpace。您可以呼叫 setParentaddChild,沿著場景圖表重新定位實體。

實體具有一些預設行為,適用於所有實體的通用行為,例如變更位置、旋轉或可見度。特定 Entity 子類別 (例如 GltfEntity) 具有支援子類別的其他行為。

操控實體

當您變更屬於基本 Entity 類別的 Entity 屬性時,變更會依序套用至所有子項。舉例來說,調整父項 EntityPose,會導致所有子項都進行相同的調整。在子項 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)

為實體新增常見行為

您可以使用下列元件,為實體新增常見行為:

您必須透過 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 常數的完整清單,請參閱參考文件

下列程式碼片段示範如何使用 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)