I'm trying to place a new object in the scene, how can I get list of objects already placed in the scene and their co-ordinates so that the new object I place wouldn't be placed over existing objects in the scene in AR Core?
This is an example of the simplest linear node hierarchy, where each anchor is the parent of only one node with a renderable. Every Sceneform node containing renderable, every anchor with its single child and every light source are attached to the root node of the scene. Give each node a name and create a dictionary of type <String, Vector3> to populate an empty List with a collection of dictionaries (where the key is a name of a node and a value is its coordinates).
val scene = arFragment.arSceneView.scene
anchorNode.name = "anchor" // Anchor with Model A child node
modelNode.name = "model" // Model B node without anchor
lightNode.name = "light" // Light node
scene.addChild(anchorNode)
scene.addChild(modelNode)
scene.addChild(lightNode)
var nodes = emptyList<Map<String, Vector3>>()
for (i in 0..scene.children.size-1) {
val name: String = scene.children[i].name
val coords: Vector3 = scene.children[i].worldPosition
val dictionary = mutableMapOf<String, Vector3>()
dictionary.put(name, coords)
nodes += dictionary
// down the hierarchy (anchor -> modelR)
if (scene.children[i].name == "anchor" && !scene.children[i].children.isEmpty()) {
val nameR: String = scene.children[i].children[0].name
val coordsR: Vector3 = scene.children[i].children[0].worldPosition
val dictionaryR = mutableMapOf<String, Vector3>()
dictionaryR.put(nameR, coordsR)
nodes += dictionaryR
}
}
Log.d("Nodes:", "$nodes")
As a result, you'll get a List of four dictionaries with nodes' names and their coordinates:
//* [ {anchor=[x,y,z]}, {modelR=[x,y,z]}, {model=[x,y,z]}, {light=[x,y,z]} ] *//
In some situations, you will be using models that consist of cascade of nodes, or using many nodes with renderables that are attached to the same anchor. Then you cannot live without the Sceneform .callOnHierarchy(..)
method with lambda, which saves you from the need to create an algorithm that traverses all the scene nodes down the hierarchy of each branch.
scene.callOnHierarchy { eachNode ->
val name: String = eachNode.name
val coords: Vector3 = eachNode.worldPosition
val dictionary = mutableMapOf<String, Vector3>()
dictionary.put(name, coords)
nodes += dictionary
}
Log.d("Nodes:", "$nodes")
The result is the same:
//* [ {anchor=[x,y,z]}, {modelR=[x,y,z]}, {model=[x,y,z]}, {light=[x,y,z]} ] *//