3
votes

I'm new to Qt3d and I need to handle user input on scene with multiple models. In particular i need to find with model the user has clicked. I try with mouseHandler and ObjectPicker but it seems not to work. Does someone have an example?

For example, if I have:

Entity {

 Camera { id: camera ... }

 FirstPersonCameraController {
  camera: camera
 }

 components: [
  RenderSettings{
    activeFrameGraph: ForwardRenderer {
      camera: camera
      clearColor: "transparent"
    },
    InputSettings{}    
  ]

 MouseDevice {
  id: mouse1
  sensitivity: 0.1
 }

 SphereMesh {
  id: sphereMesh
  radius: 3
 }

 PhongMaterial{
  id: material
 }

 Entity {
  id: sphere1
  components: [sphereMesh, material]
  MouseHandler {
   sourceDevice: mouse1
   onClicked: console.log("[sphere 1] clicked"
  }
 }

 Entity {
  id: sphere2
  components: [sphereMesh, material]
  MouseHandler {
    sourceDevice: mouse1
    onClicked: console.log("[sphere 2] clicked"
  }
 }
}

I need to distinguish if the user clicks on sphere1 or sphere2, but if I click on the sphere I cannot see any log!

1
Can you provide some code? What do you call a model? Maybe MouseArea can help youlolo
i edit my post!Luca Massarelli
I'm new to this too, but I THINK you need to put the ObjectPicker as a component of your entity.Matt

1 Answers

3
votes
  • You need to create an ObjectPicker and attach it as a component to each entity. You can delete the MouseHandler stuff.
Entity {
  id: sphere2
  components: [sphereMesh, material, spherePicker]      
}

ObjectPicker{
  id: spherePicker
  onPressed:{
     console.log("Sphere clicked")
  }
}
  • Note that by default, this will do bounding box raycasting, so it is very possible that you click somewhere near the mesh but not exactly on it, and it will register a click. If you want to do triangle picking, you can specify that by changing the rootEntity's pickingSettings component, which would solve this if that is a problem for you. I'm assuming this would be much slower than bounding box raycasting, but with big, 100 mb .stl files I didn't notice any visible slowdown.
 components: [
   RenderSettings{
   activeFrameGraph:ForwardRenderer {
      camera: camera
      clearColor: "transparent"
   },
   InputSettings{}
   pickingSettings.pickMethod: PickingSettings.TrianglePicking
   pickingSettings.faceOrientationPickingMode: PickingSettings.FrontAndBackFace 
   ]
  • If you want to know where in worldspace the object is pressed, most of the ObjectPicker methods have a PickEvent that you can look at.
    ObjectPicker{
       onPressed:{
         console.log("Pressed at: " + pick.worldIntersection)
         //If using triangle picking, you can also see index of the pressed triangle
         console.log("Triangle index: " + pick.triangleIndex)
       }
    }
  • Another thing to note: You'll see that for ObjectPicker, I am using onPressed rather than onClicked. For large meshes (say 90mb .stl files), onClicked was unpredictable. I'd click the mesh and sometimes it would fire, sometimes it wouldn't. But onPressed would always fire. This was my observation with Qt 5.8 and Qt 5.9.

Relevant documentation is here