Kuesa Object Picking
Kuesa 3D allows designers and developers to work together on a complex 3D scene, while keeping control of their disciplines throughout the workflow. This blog post explores object picking from the perspective of a developer in an existing 3D scene.
Object Picking
In a 3D scene, you may want to allow the user to select entities within the scene and then the scene to react depending on what has been selected. For example, if a certain object within a scene is selected, a popup could be shown displaying extra information or a visual hint could point towards the selected object.
The first step to object picking is to add an ObjectPicker to the View3D‘s, or your scene’s, components as shown in the example code below. This allows you to listen for a clicked event and receive a PickedEvent when an entity is selected in the scene. From this event, you can inspect the Entity that was picked.
KuesaUtils.View3D {
id: scene3D
...
components: [
ObjectPicker {
onClicked: console.log("Picked:", pick.entity)
}
]
...
}
Finding a transform for a picked entity
If you want to transform the picked entity, you may need to use Asset to retrieve the QTransform for the Entity, which allows you to transform the mesh. We use Asset by passing the objectName of the picked entity and selecting the transforms collection.
Kuesa.Asset {
id: pickedAsset
collection: scene3D.scene.transforms
name: pickedEntity.objectName
}
When an asset is successfully found, we can then use pickedAsset.node to access properties from the QTransform, such as scale and rotation.
Grouping
If you have many nested entities, you may want picking of multiple entities to result in the selection of the same group.
This could be done by using the objectName of Entity’s and climbing their tree. As in the following example, we climb the parent of the pickedEntity until we find an objectName that is defined in our groups or until we reach the root Entity.
readonly property var groups: ["groupA"]
readonly property string groupName: {
for (let entity = pickedEntity; entity !== null; entity = entity.parent) {
if (entity.objectName !== "") {
if (groups.indexOf(entity.objectName) !== -1) {
return entity.objectName;
}
}
}
return "";
}
Example
The gif below demos the example code from the Kuesa 3D repository in action. It shows that each cube has a different name when picked, and that the red and blue cube are part of the same group. The example code can be found at: https://github.com/KDAB/kuesa/tree/master/blog/picking.