Description/ Code
I have a Qt Quick 3D View and corresponding scene that was designed to be compiled on Qt 6.3.0
import QtQuick
import QtQml
import QtQuick3D
import QtQuick3D.Helpers
Window {
width: 800
height: 600
visible: true
property var selectedItem
property bool mousePressed: false
function multiply_vectors(vec1, vec2) {
return Qt.vector3d(vec1.x * vec2.x, vec1.y * vec2.y, vec1.z * vec2.z);
}
View3D {
renderMode: View3D.Inline
camera: camera
anchors.fill: parent
width: 800
height: 600
x: 0
y: 0
id: view
environment: SceneEnvironment {
clearColor: "black"
backgroundMode: SceneEnvironment.Color
depthTestEnabled: false
depthPrePassEnabled: true
}
Model {
id: rootEntity
pickable: true
source: "#Cube"
materials: PrincipledMaterial {
baseColor: "red"
roughness: 0.1
}
position: Qt.vector3d(25.0, 15.0, -60.0)
scale: Qt.vector3d(1.0, 1.0, 1.0)
}
PerspectiveCamera {
id: camera
position.z: 330.0
position.y: 0.75
eulerRotation.x: -12
clipNear: 0.0
clipFar: 1600.0
}
MouseArea {
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
id: mouseArea
onPressed: function (mouse) {
var result = view.pick(mouse.x, mouse.y);
if (result.objectHit) {
selectedItem = result.objectHit;
mousePressed = true;
} else {
mousePressed = false;
}
}
onMouseXChanged: function(mouse) {
if (mousePressed) {
var viewCoords = view.mapFromGlobal(mouseArea.mapToGlobal(mouse.x, mouse.y));
var sceneCoords = Qt.vector3d(viewCoords.x, viewCoords.y, 0);
var worldCoords = view.mapTo3DScene(sceneCoords);
worldCoords.z = selectedItem.z
selectedItem.position = multiply_vectors(worldCoords, Qt.vector3d(Math.abs(camera.z - selectedItem.z), Math.abs(camera.z - selectedItem.z), 1.0))
}
}
onReleased: function (mouse) {
mousePressed = false
}
}
Component.onCompleted: {
camera.lookAt(rootEntity)
}
}
}
Overview
The use case is that whenever the mouse is pressed while pointing at the cube, whenever the mouse moves it will cause the cube to move along with it to the corresponding point in the 3d Scene.
This works great when looking from a point that is on the same z-axis. However when looking at the object from a point say along the x-axis, the model will move along the x-axis instead of following the mouse position.
Question
How can I modify the business logic in onMouseXChanged: function(mouse) { to correctly transform the matrix (or equivalent transform) to consistently match the mouse position irregardless of the camera's position relative to the Model?
If I understood you correctly, you need to move the object with the mouse parallel to the camera regardless of the camera position and model scaling? I admit that I don't have a solution, but still it's better than the original code. First of all, do not set the
clipNearto 0, it would make the frustum degenerate and break the projection math.Secondly, I would suppose that the code which sets the object position should look like
The docs say that mapFrom3DScene/mapTo3DScene should interpret the
zcoordinate as the distance from the near clip plane of the frustum to the mapped position. However when I move it towards the sides of the window the object gets larger, whereas it should get smaller.Here's the complete code with a few corrections of mine: