Skip to content

Commit 2f246fb

Browse files
authored
Update XR snippets to be compatible with the September release versions (#622)
1 parent 1da1d9d commit 2f246fb

File tree

9 files changed

+63
-72
lines changed

9 files changed

+63
-72
lines changed

gradle/libs.versions.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ androidx-test-junit = "1.3.0"
2828
androidx-window = "1.5.0-beta02"
2929
androidx-window-core = "1.5.0-beta02"
3030
androidx-window-java = "1.5.0-beta02"
31-
androidx-xr-arcore = "1.0.0-alpha05"
32-
androidx-xr-compose = "1.0.0-alpha06"
33-
androidx-xr-scenecore = "1.0.0-alpha06"
31+
androidx-xr-arcore = "1.0.0-alpha06"
32+
androidx-xr-compose = "1.0.0-alpha07"
33+
androidx-xr-scenecore = "1.0.0-alpha07"
3434
androidxHiltNavigationCompose = "1.2.0"
3535
appcompat = "1.7.1"
3636
coil = "2.7.0"

xr/src/main/java/com/example/xr/arcore/Anchors.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import androidx.xr.arcore.AnchorCreateSuccess
2121
import androidx.xr.arcore.Trackable
2222
import androidx.xr.runtime.Config
2323
import androidx.xr.runtime.Session
24-
import androidx.xr.runtime.SessionConfigureConfigurationNotSupported
2524
import androidx.xr.runtime.SessionConfigureSuccess
2625
import androidx.xr.runtime.math.Pose
2726
import androidx.xr.scenecore.AnchorEntity
@@ -34,11 +33,9 @@ fun configureAnchoring(session: Session) {
3433
anchorPersistence = Config.AnchorPersistenceMode.LOCAL,
3534
)
3635
when (val result = session.configure(newConfig)) {
37-
is SessionConfigureConfigurationNotSupported ->
38-
TODO(/* Some combinations of configurations are not valid. Handle this failure case. */)
3936
is SessionConfigureSuccess -> TODO(/* Success! */)
4037
else ->
41-
TODO(/* A different unhandled exception was thrown. */)
38+
TODO(/* The session could not be configured. See SessionConfigureResult for possible causes. */)
4239
}
4340
// [END androidxr_arcore_anchoring_configure]
4441
}

xr/src/main/java/com/example/xr/arcore/Hands.kt

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@ import android.app.Activity
2020
import androidx.activity.ComponentActivity
2121
import androidx.lifecycle.lifecycleScope
2222
import androidx.xr.arcore.Hand
23+
import androidx.xr.arcore.HandJointType
2324
import androidx.xr.runtime.Config
24-
import androidx.xr.runtime.HandJointType
2525
import androidx.xr.runtime.Session
26-
import androidx.xr.runtime.SessionConfigureConfigurationNotSupported
2726
import androidx.xr.runtime.SessionConfigureSuccess
2827
import androidx.xr.runtime.math.Pose
2928
import androidx.xr.runtime.math.Quaternion
@@ -40,11 +39,9 @@ fun ComponentActivity.configureSession(session: Session) {
4039
handTracking = Config.HandTrackingMode.BOTH
4140
)
4241
when (val result = session.configure(newConfig)) {
43-
is SessionConfigureConfigurationNotSupported ->
44-
TODO(/* Some combinations of configurations are not valid. Handle this failure case. */)
4542
is SessionConfigureSuccess -> TODO(/* Success! */)
4643
else ->
47-
TODO(/* A different unhandled exception was thrown. */)
44+
TODO(/* The session could not be configured. See SessionConfigureResult for possible causes. */)
4845
}
4946
// [END androidxr_arcore_hand_configure]
5047
}
@@ -80,7 +77,7 @@ fun ComponentActivity.renderPlanetAtHandPalm(leftHandState: Hand.State) {
8077
val session: Session = null!!
8178
val palmEntity: GltfModelEntity = null!!
8279
// [START androidxr_arcore_hand_entityAtHandPalm]
83-
val palmPose = leftHandState.handJoints[HandJointType.PALM] ?: return
80+
val palmPose = leftHandState.handJoints[HandJointType.HAND_JOINT_TYPE_PALM] ?: return
8481

8582
// the down direction points in the same direction as the palm
8683
val angle = Vector3.angleBetween(palmPose.rotation * Vector3.Down, Vector3.Up)
@@ -101,7 +98,7 @@ fun ComponentActivity.renderPlanetAtFingerTip(rightHandState: Hand.State) {
10198
val indexFingerEntity: GltfModelEntity = null!!
10299

103100
// [START androidxr_arcore_hand_entityAtIndexFingerTip]
104-
val tipPose = rightHandState.handJoints[HandJointType.INDEX_TIP] ?: return
101+
val tipPose = rightHandState.handJoints[HandJointType.HAND_JOINT_TYPE_INDEX_TIP] ?: return
105102

106103
// the forward direction points towards the finger tip.
107104
val angle = Vector3.angleBetween(tipPose.rotation * Vector3.Forward, Vector3.Up)
@@ -120,9 +117,9 @@ fun ComponentActivity.renderPlanetAtFingerTip(rightHandState: Hand.State) {
120117

121118
private fun detectPinch(session: Session, handState: Hand.State): Boolean {
122119
// [START androidxr_arcore_hand_pinch_gesture]
123-
val thumbTip = handState.handJoints[HandJointType.THUMB_TIP] ?: return false
120+
val thumbTip = handState.handJoints[HandJointType.HAND_JOINT_TYPE_THUMB_TIP] ?: return false
124121
val thumbTipPose = session.scene.perceptionSpace.transformPoseTo(thumbTip, session.scene.activitySpace)
125-
val indexTip = handState.handJoints[HandJointType.INDEX_TIP] ?: return false
122+
val indexTip = handState.handJoints[HandJointType.HAND_JOINT_TYPE_INDEX_TIP] ?: return false
126123
val indexTipPose = session.scene.perceptionSpace.transformPoseTo(indexTip, session.scene.activitySpace)
127124
return Vector3.distance(thumbTipPose.translation, indexTipPose.translation) < 0.05
128125
// [END androidxr_arcore_hand_pinch_gesture]
@@ -136,8 +133,8 @@ private fun detectStop(session: Session, handState: Hand.State): Boolean {
136133
val forward2 = handState.handJoints[joint2]?.forward ?: return false
137134
return Vector3.angleBetween(forward1, forward2) < threshold
138135
}
139-
return pointingInSameDirection(HandJointType.INDEX_PROXIMAL, HandJointType.INDEX_TIP) &&
140-
pointingInSameDirection(HandJointType.MIDDLE_PROXIMAL, HandJointType.MIDDLE_TIP) &&
141-
pointingInSameDirection(HandJointType.RING_PROXIMAL, HandJointType.RING_TIP)
136+
return pointingInSameDirection(HandJointType.HAND_JOINT_TYPE_INDEX_PROXIMAL, HandJointType.HAND_JOINT_TYPE_INDEX_TIP) &&
137+
pointingInSameDirection(HandJointType.HAND_JOINT_TYPE_MIDDLE_PROXIMAL, HandJointType.HAND_JOINT_TYPE_MIDDLE_TIP) &&
138+
pointingInSameDirection(HandJointType.HAND_JOINT_TYPE_RING_PROXIMAL, HandJointType.HAND_JOINT_TYPE_RING_TIP)
142139
// [END androidxr_arcore_hand_stop_gesture]
143140
}

xr/src/main/java/com/example/xr/arcore/Planes.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package com.example.xr.arcore
1919
import androidx.xr.arcore.Plane
2020
import androidx.xr.runtime.Config
2121
import androidx.xr.runtime.Session
22-
import androidx.xr.runtime.SessionConfigureConfigurationNotSupported
2322
import androidx.xr.runtime.SessionConfigureSuccess
2423
import androidx.xr.runtime.math.Pose
2524
import androidx.xr.runtime.math.Ray
@@ -31,11 +30,9 @@ fun configurePlaneTracking(session: Session) {
3130
planeTracking = Config.PlaneTrackingMode.HORIZONTAL_AND_VERTICAL,
3231
)
3332
when (val result = session.configure(newConfig)) {
34-
is SessionConfigureConfigurationNotSupported ->
35-
TODO(/* Some combinations of configurations are not valid. Handle this failure case. */)
3633
is SessionConfigureSuccess -> TODO(/* Success! */)
3734
else ->
38-
TODO(/* A different unhandled exception was thrown. */)
35+
TODO(/* The session could not be configured. See SessionConfigureResult for possible causes. */)
3936
}
4037
// [END androidxr_arcore_planetracking_configure]
4138
}

xr/src/main/java/com/example/xr/compose/Orbiter.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ import androidx.xr.compose.spatial.ContentEdge
4040
import androidx.xr.compose.spatial.Orbiter
4141
import androidx.xr.compose.spatial.OrbiterOffsetType
4242
import androidx.xr.compose.spatial.Subspace
43+
import androidx.xr.compose.subspace.MovePolicy
44+
import androidx.xr.compose.subspace.ResizePolicy
4345
import androidx.xr.compose.subspace.SpatialPanel
4446
import androidx.xr.compose.subspace.SpatialRow
4547
import androidx.xr.compose.subspace.layout.SpatialRoundedCornerShape
4648
import androidx.xr.compose.subspace.layout.SubspaceModifier
4749
import androidx.xr.compose.subspace.layout.height
48-
import androidx.xr.compose.subspace.layout.movable
49-
import androidx.xr.compose.subspace.layout.resizable
5050
import androidx.xr.compose.subspace.layout.width
5151
import com.example.xr.R
5252

@@ -57,9 +57,9 @@ private fun OrbiterExampleSubspace() {
5757
SpatialPanel(
5858
SubspaceModifier
5959
.height(824.dp)
60-
.width(1400.dp)
61-
.movable()
62-
.resizable()
60+
.width(1400.dp),
61+
dragPolicy = MovePolicy(),
62+
resizePolicy = ResizePolicy(),
6363
) {
6464
SpatialPanelContent()
6565
OrbiterExample()

xr/src/main/java/com/example/xr/compose/SpatialPanel.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ import androidx.compose.ui.unit.dp
2929
import androidx.compose.ui.unit.sp
3030
import androidx.xr.compose.platform.LocalSpatialCapabilities
3131
import androidx.xr.compose.spatial.Subspace
32+
import androidx.xr.compose.subspace.MovePolicy
33+
import androidx.xr.compose.subspace.ResizePolicy
3234
import androidx.xr.compose.subspace.SpatialPanel
3335
import androidx.xr.compose.subspace.layout.SubspaceModifier
3436
import androidx.xr.compose.subspace.layout.height
35-
import androidx.xr.compose.subspace.layout.movable
36-
import androidx.xr.compose.subspace.layout.resizable
3737
import androidx.xr.compose.subspace.layout.width
3838

3939
@Composable
@@ -43,9 +43,9 @@ private fun SpatialPanelExample() {
4343
SpatialPanel(
4444
SubspaceModifier
4545
.height(824.dp)
46-
.width(1400.dp)
47-
.movable()
48-
.resizable()
46+
.width(1400.dp),
47+
dragPolicy = MovePolicy(),
48+
resizePolicy = ResizePolicy(),
4949
) {
5050
SpatialPanelContent()
5151
}
@@ -81,9 +81,8 @@ private fun ContentInSpatialPanel() {
8181
if (LocalSpatialCapabilities.current.isSpatialUiEnabled) {
8282
Subspace {
8383
SpatialPanel(
84-
SubspaceModifier
85-
.resizable(true)
86-
.movable(true)
84+
dragPolicy = MovePolicy(),
85+
resizePolicy = ResizePolicy(),
8786
) {
8887
AppContent()
8988
}

xr/src/main/java/com/example/xr/compose/Volume.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ import androidx.compose.ui.unit.sp
2828
import androidx.xr.compose.platform.LocalSession
2929
import androidx.xr.compose.spatial.Subspace
3030
import androidx.xr.compose.subspace.ExperimentalSubspaceVolumeApi
31+
import androidx.xr.compose.subspace.MovePolicy
32+
import androidx.xr.compose.subspace.ResizePolicy
3133
import androidx.xr.compose.subspace.SpatialPanel
3234
import androidx.xr.compose.subspace.Volume
3335
import androidx.xr.compose.subspace.layout.SubspaceModifier
3436
import androidx.xr.compose.subspace.layout.height
35-
import androidx.xr.compose.subspace.layout.movable
3637
import androidx.xr.compose.subspace.layout.offset
37-
import androidx.xr.compose.subspace.layout.resizable
3838
import androidx.xr.compose.subspace.layout.scale
3939
import androidx.xr.compose.subspace.layout.width
4040
import kotlinx.coroutines.launch
@@ -44,8 +44,9 @@ private fun VolumeExample() {
4444
// [START androidxr_compose_Volume]
4545
Subspace {
4646
SpatialPanel(
47-
SubspaceModifier.height(1500.dp).width(1500.dp)
48-
.resizable().movable()
47+
SubspaceModifier.height(1500.dp).width(1500.dp),
48+
dragPolicy = MovePolicy(),
49+
resizePolicy = ResizePolicy(),
4950
) {
5051
ObjectInAVolume(true)
5152
Box(

xr/src/main/java/com/example/xr/scenecore/ResizableComponent.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.example.xr.scenecore
1818

1919
import androidx.xr.runtime.Session
20+
import androidx.xr.runtime.math.FloatSize2d
2021
import androidx.xr.runtime.math.FloatSize3d
2122
import androidx.xr.scenecore.ResizableComponent
2223
import androidx.xr.scenecore.ResizeEvent
@@ -32,11 +33,11 @@ private fun resizableComponentExample(
3233
val resizableComponent = ResizableComponent.create(session) { event ->
3334
if (event.resizeState == ResizeEvent.ResizeState.RESIZE_STATE_END) {
3435
// update the Entity to reflect the new size
35-
surfaceEntity.canvasShape = SurfaceEntity.CanvasShape.Quad(event.newSize.width, event.newSize.height)
36+
surfaceEntity.shape = SurfaceEntity.Shape.Quad(FloatSize2d(event.newSize.width, event.newSize.height))
3637
}
3738
}
3839
resizableComponent.minimumEntitySize = FloatSize3d(177f, 100f, 1f)
39-
resizableComponent.fixedAspectRatio = 16f / 9f // Specify a 16:9 aspect ratio
40+
resizableComponent.isFixedAspectRatioEnabled = true // Maintain a fixed aspect ratio when resizing
4041

4142
surfaceEntity.addComponent(resizableComponent)
4243
// [END androidxr_scenecore_resizableComponentExample]

xr/src/main/java/com/example/xr/scenecore/SpatialVideo.kt

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,22 @@ import androidx.media3.common.C
2424
import androidx.media3.common.MediaItem
2525
import androidx.media3.exoplayer.ExoPlayer
2626
import androidx.xr.runtime.Session
27+
import androidx.xr.runtime.math.FloatSize2d
2728
import androidx.xr.runtime.math.Pose
2829
import androidx.xr.runtime.math.Vector3
2930
import androidx.xr.scenecore.SurfaceEntity
3031
import androidx.xr.scenecore.Texture
31-
import androidx.xr.scenecore.TextureSampler
3232
import androidx.xr.scenecore.scene
3333
import java.nio.file.Paths
3434
import kotlinx.coroutines.launch
3535

3636
private fun ComponentActivity.surfaceEntityCreate(xrSession: Session) {
3737
// [START androidxr_scenecore_surfaceEntityCreate]
3838
val stereoSurfaceEntity = SurfaceEntity.create(
39-
xrSession,
40-
SurfaceEntity.StereoMode.SIDE_BY_SIDE,
41-
Pose(Vector3(0.0f, 0.0f, -1.5f)),
42-
SurfaceEntity.CanvasShape.Quad(1.0f, 1.0f)
39+
session = xrSession,
40+
stereoMode = SurfaceEntity.StereoMode.STEREO_MODE_SIDE_BY_SIDE,
41+
pose = Pose(Vector3(0.0f, 0.0f, -1.5f)),
42+
shape = SurfaceEntity.Shape.Quad(FloatSize2d(1.0f, 1.0f))
4343
)
4444
val videoUri = Uri.Builder()
4545
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
@@ -60,13 +60,13 @@ private fun ComponentActivity.surfaceEntityCreateSbs(xrSession: Session) {
6060
// Set up the surface for playing a 180° video on a hemisphere.
6161
val hemisphereStereoSurfaceEntity =
6262
SurfaceEntity.create(
63-
xrSession,
64-
SurfaceEntity.StereoMode.SIDE_BY_SIDE,
65-
xrSession.scene.spatialUser.head?.transformPoseTo(
63+
session = xrSession,
64+
stereoMode = SurfaceEntity.StereoMode.STEREO_MODE_SIDE_BY_SIDE,
65+
pose = xrSession.scene.spatialUser.head?.transformPoseTo(
6666
Pose.Identity,
6767
xrSession.scene.activitySpace
6868
)!!,
69-
SurfaceEntity.CanvasShape.Vr180Hemisphere(1.0f),
69+
shape = SurfaceEntity.Shape.Hemisphere(1.0f),
7070
)
7171
// ... and use the surface for playing the media.
7272
// [END androidxr_scenecore_surfaceEntityCreateSbs]
@@ -77,13 +77,13 @@ private fun ComponentActivity.surfaceEntityCreateTb(xrSession: Session) {
7777
// Set up the surface for playing a 360° video on a sphere.
7878
val sphereStereoSurfaceEntity =
7979
SurfaceEntity.create(
80-
xrSession,
81-
SurfaceEntity.StereoMode.TOP_BOTTOM,
82-
xrSession.scene.spatialUser.head?.transformPoseTo(
80+
session = xrSession,
81+
stereoMode = SurfaceEntity.StereoMode.STEREO_MODE_TOP_BOTTOM,
82+
pose = xrSession.scene.spatialUser.head?.transformPoseTo(
8383
Pose.Identity,
8484
xrSession.scene.activitySpace
8585
)!!,
86-
SurfaceEntity.CanvasShape.Vr360Sphere(1.0f),
86+
shape = SurfaceEntity.Shape.Sphere(1.0f),
8787
)
8888
// ... and use the surface for playing the media.
8989
// [END androidxr_scenecore_surfaceEntityCreateTb]
@@ -93,10 +93,10 @@ private fun ComponentActivity.surfaceEntityCreateMVHEVC(xrSession: Session) {
9393
// [START androidxr_scenecore_surfaceEntityCreateMVHEVC]
9494
// Create the SurfaceEntity with the StereoMode corresponding to the MV-HEVC content
9595
val stereoSurfaceEntity = SurfaceEntity.create(
96-
xrSession,
97-
SurfaceEntity.StereoMode.MULTIVIEW_LEFT_PRIMARY,
98-
Pose(Vector3(0.0f, 0.0f, -1.5f)),
99-
SurfaceEntity.CanvasShape.Quad(1.0f, 1.0f)
96+
session = xrSession,
97+
stereoMode = SurfaceEntity.StereoMode.STEREO_MODE_MULTIVIEW_LEFT_PRIMARY,
98+
pose = Pose(Vector3(0.0f, 0.0f, -1.5f)),
99+
shape = SurfaceEntity.Shape.Quad(FloatSize2d(1.0f, 1.0f))
100100
)
101101
val videoUri = Uri.Builder()
102102
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
@@ -123,10 +123,10 @@ private fun ComponentActivity.surfaceEntityCreateDRM(xrSession: Session) {
123123
// Create the SurfaceEntity with the PROTECTED content security level.
124124
val protectedSurfaceEntity = SurfaceEntity.create(
125125
session = xrSession,
126-
stereoMode = SurfaceEntity.StereoMode.SIDE_BY_SIDE,
126+
stereoMode = SurfaceEntity.StereoMode.STEREO_MODE_SIDE_BY_SIDE,
127127
pose = Pose(Vector3(0.0f, 0.0f, -1.5f)),
128-
canvasShape = SurfaceEntity.CanvasShape.Quad(1.0f, 1.0f),
129-
contentSecurityLevel = SurfaceEntity.ContentSecurityLevel.PROTECTED
128+
shape = SurfaceEntity.Shape.Quad(FloatSize2d(1.0f, 1.0f)),
129+
surfaceProtection = SurfaceEntity.SurfaceProtection.SURFACE_PROTECTION_PROTECTED
130130
)
131131

132132
// Build a MediaItem with the necessary DRM configuration.
@@ -156,20 +156,20 @@ private fun ComponentActivity.surfaceEntityHDR(xrSession: Session) {
156156
// Define the color properties for your HDR video. These values should be specific
157157
// to your content.
158158
val hdrMetadata = SurfaceEntity.ContentColorMetadata(
159-
colorSpace = SurfaceEntity.ContentColorMetadata.ColorSpace.BT2020,
160-
colorTransfer = SurfaceEntity.ContentColorMetadata.ColorTransfer.ST2084, // PQ
161-
colorRange = SurfaceEntity.ContentColorMetadata.ColorRange.LIMITED,
162-
maxCLL = 1000 // Example: 1000 nits
159+
colorSpace = SurfaceEntity.ContentColorMetadata.ColorSpace.COLOR_SPACE_BT2020,
160+
colorTransfer = SurfaceEntity.ContentColorMetadata.ColorTransfer.COLOR_TRANSFER_ST2084, // PQ
161+
colorRange = SurfaceEntity.ContentColorMetadata.ColorRange.COLOR_RANGE_LIMITED,
162+
maxContentLightLevel = 1000 // Example: 1000 nits
163163
)
164164

165165
// Create a SurfaceEntity, passing the HDR metadata at creation time.
166166
val hdrSurfaceEntity = SurfaceEntity.create(
167167
session = xrSession,
168-
stereoMode = SurfaceEntity.StereoMode.MONO,
168+
stereoMode = SurfaceEntity.StereoMode.STEREO_MODE_MONO,
169169
pose = Pose(Vector3(0.0f, 0.0f, -1.5f)),
170-
canvasShape = SurfaceEntity.CanvasShape.Quad(1.0f, 1.0f),
171-
contentColorMetadata = hdrMetadata
170+
shape = SurfaceEntity.Shape.Quad(FloatSize2d(1.0f, 1.0f)),
172171
)
172+
hdrSurfaceEntity.contentColorMetadata = hdrMetadata
173173

174174
// Initialize ExoPlayer and set the surface.
175175
val exoPlayer = ExoPlayer.Builder(this).build()
@@ -195,8 +195,8 @@ private fun surfaceEntityEdgeFeathering(xrSession: Session) {
195195
)
196196

197197
// Feather the edges of the surface.
198-
surfaceEntity.edgeFeather =
199-
SurfaceEntity.EdgeFeatheringParams.SmoothFeather(0.1f, 0.1f)
198+
surfaceEntity.edgeFeatheringParams =
199+
SurfaceEntity.EdgeFeatheringParams.RectangleFeather(0.1f, 0.1f)
200200
// [END androidxr_scenecore_surfaceEntityEdgeFeathering]
201201
}
202202

@@ -214,7 +214,6 @@ private fun surfaceEntityAlphaMasking(xrSession: Session, activity: ComponentAct
214214
Texture.create(
215215
xrSession,
216216
Paths.get("textures", "alpha_mask.png"),
217-
TextureSampler.create()
218217
)
219218

220219
// Apply the alpha mask.

0 commit comments

Comments
 (0)