Reputation: 31
I am currently working on an AR Application for Android with Kotlin and JetPack Compose using SceneView for AR and the 3D Rendering.
At one point i have to display a 3D Model, which has certain nodes that i want to listen on for interactions. So i added an onSingleTapUp-Event onto the specific childNode. This Event gets never triggered. I made some further checks and i guess the problem is, that the GestureListener only detects the first Node the raycast hits.
Does anyone know how to solve this issue?
My Code:
val modelNode = ModelNode(
modelInstance = modelLoader.createModelInstance(assetFileLocation = mainModel),
scaleToUnits = 0.21f,
centerOrigin = Position(0f)
).apply{
setPriority(0) // set Priority to 0 for preferring hit tests on other nodes
position = Position(0.21f/2,0f,0.29f/1.5f)
rotation = Rotation(0f, -120f, 0f)
Log.d("NodeDebug", "Creating FinalModelExperienceNode with size: $size at position: $position")
}
//intially hide all nodes but the 'BikeFull'-Node
modelNode.nodes.entries.forEach { entry ->
// Always show the BikeFull node
if (entry.key.contains("BikeFull")) {
entry.value.isVisible = true
Log.d("NodeDebug", "entry: ${entry.key}, ${entry.value}")
} else {
entry.value.isVisible = false
}
}
//set visibillity and animations for reward nodes
experienceState.rewards.forEachIndexed { index, reward ->
val rewardNode = modelNode.nodes.entries.find { it.key == reward.standardNode }
val rewardNodePuls = modelNode.nodes.entries.find { it.key == reward.blinkingNode }
if (rewardNode != null && rewardNodePuls != null) {
if(reward.display == RewardDisplay.VISIBLE){
rewardNode.value.isVisible = true
rewardNodePuls.value.isVisible = false
}
if(reward.display == RewardDisplay.INVISIBLE){
rewardNode.value.isVisible = false
rewardNodePuls.value.isVisible = false
}
if(reward.display == RewardDisplay.BLINKING) {
var isBlinking = true
rewardNode.value.isVisible = true
rewardNodePuls.value.isVisible = true
rewardNodePuls.value.childNodes.forEach {
it.isVisible = true
}
rewardNode.value.onSingleTapUp = { // <-- this gets never executed, also if i try onTouch for example
Log.d("NodeDebug", "tapped RewardNode: $rewardNode")
isBlinking = false
reward.display = RewardDisplay.VISIBLE
onStateChange(experienceState.copy())
true
}
CoroutineScope(Dispatchers.Main).launch {
while (isBlinking) {
rewardNodePuls.value.isVisible = !rewardNodePuls.value.isVisible
rewardNodePuls.value.childNodes.forEach {
it.isVisible = rewardNodePuls.value.isVisible
}
delay(1000L) // 1 second delay
}
}
}
}
}
Adding GestureListener to Scene
ARScene(
...
onGestureListener = rememberOnGestureListener(
onSingleTapUp = { _, node ->
Log.d("NodeDebug", " onSingleTapUp Node: $node")
}
),
...
)
It always just registers an singleTapUp for the ModelNode and so the specific event for the childNode of ModelNode doesn't get triggered
Upvotes: 3
Views: 65