Skip to content

Commit 088823c

Browse files
authored
Migrate last batch of XR snippets (#507)
* Migrate "Add 3D models to your app" to snippets * Migrate "Check for spatial capabilities" to snippets * Migrate "Transition from Home Space to Full Space" to snippets
1 parent 015df95 commit 088823c

File tree

4 files changed

+169
-0
lines changed

4 files changed

+169
-0
lines changed

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

+28
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@
1717
package com.example.xr.compose
1818

1919
import androidx.compose.runtime.Composable
20+
import androidx.compose.ui.unit.dp
2021
import androidx.xr.compose.platform.LocalSpatialCapabilities
22+
import androidx.xr.compose.spatial.Subspace
23+
import androidx.xr.compose.subspace.SpatialPanel
24+
import androidx.xr.compose.subspace.layout.SubspaceModifier
25+
import androidx.xr.compose.subspace.layout.fillMaxHeight
26+
import androidx.xr.compose.subspace.layout.width
2127

2228
@Composable
2329
private fun SupportingInfoPanel() {}
@@ -38,3 +44,25 @@ private fun SpatialCapabilitiesCheck() {
3844
val spatialAudioEnabled = LocalSpatialCapabilities.current.isSpatialAudioEnabled
3945
// [END androidxr_compose_checkSpatialCapabilities]
4046
}
47+
48+
@Composable
49+
private fun checkSpatialUiEnabled() {
50+
// [START androidxr_compose_checkSpatialUiEnabled]
51+
if (LocalSpatialCapabilities.current.isSpatialUiEnabled) {
52+
Subspace {
53+
SpatialPanel(
54+
modifier = SubspaceModifier
55+
.width(1488.dp)
56+
.fillMaxHeight()
57+
) {
58+
AppContent()
59+
}
60+
}
61+
} else {
62+
AppContent()
63+
}
64+
// [END androidxr_compose_checkSpatialUiEnabled]
65+
}
66+
67+
@Composable
68+
private fun AppContent() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.xr.misc
18+
19+
import androidx.compose.runtime.Composable
20+
import androidx.xr.compose.platform.LocalSpatialConfiguration
21+
import androidx.xr.scenecore.Session
22+
23+
@Composable
24+
fun modeTransitionCompose() {
25+
// [START androidxr_misc_modeTransitionCompose]
26+
LocalSpatialConfiguration.current.requestHomeSpaceMode()
27+
// or
28+
LocalSpatialConfiguration.current.requestFullSpaceMode()
29+
// [END androidxr_misc_modeTransitionCompose]
30+
}
31+
32+
fun modeTransitionScenecore(xrSession: Session) {
33+
// [START androidxr_misc_modeTransitionScenecore]
34+
xrSession.spatialEnvironment.requestHomeSpaceMode()
35+
// [END androidxr_misc_modeTransitionScenecore]
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.xr.scenecore
18+
19+
import android.content.Intent
20+
import android.net.Uri
21+
import androidx.activity.ComponentActivity
22+
import androidx.xr.scenecore.GltfModel
23+
import androidx.xr.scenecore.GltfModelEntity
24+
import androidx.xr.scenecore.Session
25+
import androidx.xr.scenecore.SpatialCapabilities
26+
import androidx.xr.scenecore.getSpatialCapabilities
27+
import kotlinx.coroutines.guava.await
28+
29+
private suspend fun loadGltfFile(session: Session) {
30+
// [START androidxr_scenecore_gltfmodel_create]
31+
val gltfModel = GltfModel.create(session, "models/saturn_rings.glb").await()
32+
// [END androidxr_scenecore_gltfmodel_create]
33+
}
34+
35+
private fun createModelEntity(session: Session, gltfModel: GltfModel) {
36+
// [START androidxr_scenecore_gltfmodelentity_create]
37+
if (session.getSpatialCapabilities()
38+
.hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_3D_CONTENT)
39+
) {
40+
val gltfEntity = GltfModelEntity.create(session, gltfModel)
41+
}
42+
// [END androidxr_scenecore_gltfmodelentity_create]
43+
}
44+
45+
private fun animateEntity(gltfEntity: GltfModelEntity) {
46+
// [START androidxr_scenecore_gltfmodelentity_animation]
47+
gltfEntity.startAnimation(loop = true, animationName = "Walk")
48+
// [END androidxr_scenecore_gltfmodelentity_animation]
49+
}
50+
51+
private fun ComponentActivity.startSceneViewer() {
52+
// [START androidxr_scenecore_sceneviewer]
53+
val url =
54+
"https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/FlightHelmet/glTF/FlightHelmet.gltf"
55+
val sceneViewerIntent = Intent(Intent.ACTION_VIEW)
56+
val intentUri =
57+
Uri.parse("https://arvr.google.com/scene-viewer/1.2")
58+
.buildUpon()
59+
.appendQueryParameter("file", url)
60+
.build()
61+
sceneViewerIntent.setDataAndType(intentUri, "model/gltf-binary")
62+
startActivity(sceneViewerIntent)
63+
// [END androidxr_scenecore_sceneviewer]
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.xr.scenecore
18+
19+
import androidx.xr.scenecore.Session
20+
import androidx.xr.scenecore.SpatialCapabilities
21+
import androidx.xr.scenecore.getSpatialCapabilities
22+
23+
fun checkMultipleCapabilities(xrSession: Session) {
24+
// [START androidxr_compose_checkMultipleCapabilities]
25+
// Example 1: check if enabling passthrough mode is allowed
26+
if (xrSession.getSpatialCapabilities().hasCapability(
27+
SpatialCapabilities.SPATIAL_CAPABILITY_PASSTHROUGH_CONTROL
28+
)
29+
) {
30+
xrSession.spatialEnvironment.setPassthroughOpacityPreference(0f)
31+
}
32+
// Example 2: multiple capability flags can be checked simultaneously:
33+
if (xrSession.getSpatialCapabilities().hasCapability(
34+
SpatialCapabilities.SPATIAL_CAPABILITY_PASSTHROUGH_CONTROL and
35+
SpatialCapabilities.SPATIAL_CAPABILITY_3D_CONTENT
36+
)
37+
) {
38+
// ...
39+
}
40+
// [END androidxr_compose_checkMultipleCapabilities]
41+
}

0 commit comments

Comments
 (0)