Skip to content

Commit dca1e3d

Browse files
authored
Add snippet for SpatialGltfModel (#889)
1 parent 2e0b186 commit dca1e3d

1 file changed

Lines changed: 117 additions & 0 deletions

File tree

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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.compose
18+
19+
import android.util.Log
20+
import androidx.compose.runtime.Composable
21+
import androidx.compose.runtime.DisposableEffect
22+
import androidx.compose.runtime.LaunchedEffect
23+
import androidx.compose.runtime.getValue
24+
import androidx.compose.runtime.mutableStateOf
25+
import androidx.compose.runtime.remember
26+
import androidx.compose.runtime.setValue
27+
import androidx.xr.compose.platform.LocalSession
28+
import androidx.xr.compose.subspace.SpatialGltfModel
29+
import androidx.xr.compose.subspace.SpatialGltfModelSource
30+
import androidx.xr.compose.subspace.layout.SubspaceModifier
31+
import androidx.xr.compose.subspace.rememberSpatialGltfModelState
32+
import androidx.xr.runtime.math.Pose
33+
import androidx.xr.runtime.math.Quaternion
34+
import androidx.xr.runtime.math.Vector4
35+
import androidx.xr.scenecore.AlphaMode
36+
import androidx.xr.scenecore.KhronosPbrMaterial
37+
import androidx.xr.scenecore.Texture
38+
import java.nio.file.Paths
39+
import kotlin.io.path.Path
40+
41+
@Composable
42+
fun SpatialGltfModelExample(){
43+
val xrSession = checkNotNull(LocalSession.current)
44+
val degrees = 1f
45+
46+
// [START androidxr_compose_SpatialGltfModelState]
47+
val modelState = rememberSpatialGltfModelState(
48+
source = SpatialGltfModelSource.fromPath(
49+
Paths.get("models/bugdroid_animated_wave.glb")
50+
)
51+
)
52+
// [END androidxr_compose_SpatialGltfModelState]
53+
54+
// [START androidxr_compose_SpatialGltfModelMaterial]
55+
// Retrieve the list of nodes (individual components/meshes) defined within the glTF model.
56+
val entityNodes = modelState.nodes
57+
58+
// Find a specific node by name to apply modifications, such as material overrides.
59+
val node = entityNodes.find { it.name == "node_name" }
60+
61+
// Maintain a reference to the custom material to avoid re-creating it on every recomposition.
62+
var pbrMaterial by remember { mutableStateOf<KhronosPbrMaterial?>(null) }
63+
64+
// Create and apply the custom material once the session is ready and the target node is available.
65+
LaunchedEffect(node) {
66+
val material = pbrMaterial ?: KhronosPbrMaterial.create(
67+
session = xrSession,
68+
alphaMode = AlphaMode.OPAQUE
69+
).also {
70+
pbrMaterial = it
71+
// Load a texture
72+
val texture = Texture.create(
73+
session = xrSession,
74+
path = Path("textures/texture_name.png")
75+
)
76+
77+
// Configure occlusion to define how the material surface handles ambient lighting.
78+
it.setOcclusionTexture(
79+
texture = texture,
80+
strength = 1.0f
81+
)
82+
83+
// Apply a base color factor (RGBA) to tint the model.
84+
it.setBaseColorFactor(
85+
Vector4(
86+
x = 0.5f,
87+
y = 0.5f,
88+
z = 1.0f,
89+
w = 1.0f
90+
)
91+
)
92+
}
93+
94+
// Apply the custom PBR material to the specific node, overriding its original glTF material.
95+
node?.setMaterialOverride(
96+
material = material
97+
)
98+
}
99+
// [END androidxr_compose_SpatialGltfModelMaterial]
100+
101+
// [START androidxr_compose_SpatialGltfModelIntrospection]
102+
val arrows = modelState.nodes.find {
103+
it.name == "Arrows"
104+
}
105+
106+
LaunchedEffect(arrows, degrees) {
107+
val rotation = Quaternion.fromEulerAngles(degrees, 0f, degrees)
108+
arrows?.localPose =
109+
Pose(arrows.localPose.translation, rotation)
110+
}
111+
// [END androidxr_compose_SpatialGltfModelIntrospection]
112+
113+
// [START androidxr_compose_SpatialGltfModelLoad]
114+
// Render the 3D model into the spatial subspace.
115+
SpatialGltfModel(state = modelState, modifier = SubspaceModifier)
116+
// [END androidxr_compose_SpatialGltfModelLoad]
117+
}

0 commit comments

Comments
 (0)