Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added app/src/main/assets/white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,20 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.xr.compose.platform.LocalSession
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.spatial.PlanarEmbeddedSubspace
import androidx.xr.compose.subspace.SceneCoreEntity
import androidx.xr.compose.subspace.SceneCoreEntitySizeAdapter
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.scale
import androidx.xr.compose.unit.Meter
import androidx.xr.runtime.math.Vector4
import androidx.xr.scenecore.AlphaMode
import androidx.xr.scenecore.GltfModelEntity
import androidx.xr.scenecore.KhronosPbrMaterial
import androidx.xr.scenecore.KhronosPbrMaterialSpec
import androidx.xr.scenecore.Texture
import com.example.helloandroidxr.bugdroid.BugdroidController
import com.example.helloandroidxr.viewmodel.ModelTransform
import kotlin.io.path.Path

// Bugdroid glb height in meters
private const val bugdroidHeight = 2.08f
Expand All @@ -67,41 +69,52 @@ fun BugdroidModel(
}
val gltfModel = bugdroidController.gltfModel
gltfModel?.let { model ->
Subspace {
PlanarEmbeddedSubspace {
val density = LocalDensity.current
var scaleFromLayout by remember { mutableFloatStateOf(1f) }
var pbrMaterial by remember { mutableStateOf<KhronosPbrMaterial?>(null) }
LaunchedEffect(xrSession) {
try {
val spec =
KhronosPbrMaterialSpec.create(
lightingModel = KhronosPbrMaterialSpec.LightingModel.LIT,
blendMode = KhronosPbrMaterialSpec.BlendMode.OPAQUE,
doubleSidedMode = KhronosPbrMaterialSpec.DoubleSidedMode.SINGLE_SIDED,
pbrMaterial = KhronosPbrMaterial.create(
session = xrSession,
alphaMode = AlphaMode.OPAQUE
)
val texture = Texture.create(
session = xrSession,
path = Path("white.png") // Used as a base texture for material properties.
)
pbrMaterial?.setOcclusionTexture(
texture = texture,
strength = modelTransform.materialProperties.ambientOcclusion
)
pbrMaterial?.setBaseColorFactor(
Vector4(
x = modelTransform.materialColor.x,
y = modelTransform.materialColor.y,
z = modelTransform.materialColor.z,
w = modelTransform.materialColor.w
)
pbrMaterial = KhronosPbrMaterial.create(xrSession, spec)
)
} catch (e: Exception) {
Log.e(TAG, "Error creating material", e)
}
}
LaunchedEffect(
pbrMaterial,
modelTransform.materialColor.x,
modelTransform.materialColor.y,
modelTransform.materialColor.z,
modelTransform.materialColor.w,
modelTransform.materialProperties.ambientOcclusion,
modelTransform.materialProperties.metallic,
modelTransform.materialProperties.roughness,
) {
pbrMaterial?.setBaseColorFactors(
pbrMaterial?.setBaseColorFactor(
Vector4(
x = modelTransform.materialColor.x,
y = modelTransform.materialColor.y,
z = modelTransform.materialColor.z,
w = modelTransform.materialColor.w
)
)
pbrMaterial?.setAmbientOcclusionFactor(modelTransform.materialProperties.ambientOcclusion)
pbrMaterial?.setMetallicFactor(modelTransform.materialProperties.metallic)
pbrMaterial?.setRoughnessFactor(modelTransform.materialProperties.roughness)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,21 +313,6 @@ fun MaterialPropertySliders(
Text(text = stringResource(R.string.change_material_factors))
Spacer(modifier = Modifier.padding(10.dp))

Text(text = stringResource(R.string.ambient))
Slider(
value = materialProperties.ambientOcclusion,
onValueChange = { newAmbientOcclusion ->
onMaterialPropertiesChange(
materialProperties.copy(
ambientOcclusion = newAmbientOcclusion
)
)
},
valueRange = MIN_MATERIAL_PROP_VALUE..MAX_MATERIAL_PROP_VALUE,
modifier = Modifier.padding()
)
Text(text = "%.2f".format(materialProperties.ambientOcclusion))

Text(text = stringResource(R.string.metallic))
Slider(
value = materialProperties.metallic,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.Icon
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
Expand All @@ -42,6 +40,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview
Expand Down Expand Up @@ -85,7 +84,14 @@ fun SearchTextBox(
stringResource(R.string.search_product_name),
)
},
leadingIcon = { Icon(Icons.Filled.Search, null) },
leadingIcon = {
// This icon is decorative. The TextField's placeholder text is sufficient for screen
// readers.
Icon(
painter = painterResource(R.drawable.search_24px),
contentDescription = null,
)
},
colors = TextFieldDefaults.colors(
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ private const val DEFAULT_X_MATERIAL_COLOR = 0.0f
private const val DEFAULT_Y_MATERIAL_COLOR = 1.0f
private const val DEFAULT_Z_MATERIAL_COLOR = 0.0f
private const val DEFAULT_W_MATERIAL_COLOR = 0.0f
private const val DEFAULT_AMBIENT_OCCLUSION = 0.5f
private const val DEFAULT_AMBIENT_OCCLUSION = 1.0f
private const val DEFAULT_METALLIC = 0.0f
private const val DEFAULT_ROUGHNESS = 0.0f
const val MIN_SCALE_VALUE = 0.1f
Expand Down Expand Up @@ -176,10 +176,22 @@ class BugdroidViewModel : ViewModel() {
currentState.copy(
modelTransform = currentState.modelTransform.copy(
materialColor = currentState.modelTransform.materialColor.copy(
x = newMaterialColor.x.coerceIn(MIN_MATERIAL_COLOR_VALUE, MAX_MATERIAL_COLOR_VALUE),
y = newMaterialColor.y.coerceIn(MIN_MATERIAL_COLOR_VALUE, MAX_MATERIAL_COLOR_VALUE),
z = newMaterialColor.z.coerceIn(MIN_MATERIAL_COLOR_VALUE, MAX_MATERIAL_COLOR_VALUE),
w = newMaterialColor.w.coerceIn(MIN_MATERIAL_COLOR_VALUE, MAX_MATERIAL_COLOR_VALUE),
x = newMaterialColor.x.coerceIn(
MIN_MATERIAL_COLOR_VALUE,
MAX_MATERIAL_COLOR_VALUE
),
y = newMaterialColor.y.coerceIn(
MIN_MATERIAL_COLOR_VALUE,
MAX_MATERIAL_COLOR_VALUE
),
z = newMaterialColor.z.coerceIn(
MIN_MATERIAL_COLOR_VALUE,
MAX_MATERIAL_COLOR_VALUE
),
w = newMaterialColor.w.coerceIn(
MIN_MATERIAL_COLOR_VALUE,
MAX_MATERIAL_COLOR_VALUE
),
)
)
)
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/search_24px.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:pathData="M784,840L532,588Q502,612 463,626Q424,640 380,640Q271,640 195.5,564.5Q120,489 120,380Q120,271 195.5,195.5Q271,120 380,120Q489,120 564.5,195.5Q640,271 640,380Q640,424 626,463Q612,502 588,532L840,784L784,840ZM380,560Q455,560 507.5,507.5Q560,455 560,380Q560,305 507.5,252.5Q455,200 380,200Q305,200 252.5,252.5Q200,305 200,380Q200,455 252.5,507.5Q305,560 380,560Z" />
</vector>
22 changes: 11 additions & 11 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
[versions]
androidx-runtime = "1.9.2"
agp = "8.13.0"
arcore = "1.0.0-alpha06"
compose = "1.0.0-alpha07"
androidx-runtime = "1.10.0"
agp = "8.13.1"
arcore = "1.0.0-alpha09"
compose = "1.0.0-alpha09"
extensionsXr = "1.1.0"
scenecore = "1.0.0-alpha07"
scenecore = "1.0.0-alpha10"
kotlinxCoroutinesGuava = "1.10.2"
kotlin = "2.2.0"
kotlin = "2.2.21"
concurrentFuturesKtx = "1.3.0"
activityCompose = "1.10.1"
composeBom = "2025.08.00"
material = "1.12.0"
adaptiveAndroid = "1.1.0"
kotlinAndroid = "2.2.0"
activityCompose = "1.12.1"
composeBom = "2025.12.00"
material = "1.13.0"
adaptiveAndroid = "1.2.0"
kotlinAndroid = "2.2.21"

[libraries]
androidx-arcore = { module = "androidx.xr.arcore:arcore", version.ref = "arcore" }
Expand Down