mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-06-07 05:12:00 +02:00
[ui] Viewer3D: TransformGizmo - removing FrameAction
- Moving the mouse's dependent events inside the MouseHandler and removing the FrameAction. - MouseHandler is only enabled when the gizmo is selected. There is no infinite loop waiting for an event.
This commit is contained in:
parent
f9d57cadff
commit
b234a766a9
2 changed files with 86 additions and 101 deletions
|
@ -200,16 +200,91 @@ Entity {
|
||||||
|
|
||||||
MouseHandler {
|
MouseHandler {
|
||||||
id: mouseHandler
|
id: mouseHandler
|
||||||
sourceDevice: mouseSourceDevice
|
sourceDevice: enabled ? mouseSourceDevice : null
|
||||||
property point currentPosition
|
|
||||||
property var objectPicker: null
|
property var objectPicker: null
|
||||||
|
property bool enabled: false
|
||||||
|
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
currentPosition.x = mouse.x
|
if (objectPicker) {
|
||||||
currentPosition.y = mouse.y
|
// Get the selected axis
|
||||||
|
let pickedAxis
|
||||||
|
switch(objectPicker.gizmoAxis) {
|
||||||
|
case TransformGizmo.Axis.X: pickedAxis = Qt.vector3d(1,0,0); break
|
||||||
|
case TransformGizmo.Axis.Y: pickedAxis = Qt.vector3d(0,1,0); break
|
||||||
|
case TransformGizmo.Axis.Z: pickedAxis = Qt.vector3d(0,0,1); break
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(objectPicker.gizmoType) {
|
||||||
|
case TransformGizmo.Type.POSITION: {
|
||||||
|
const sensibility = 0.02
|
||||||
|
|
||||||
|
// Compute the current vector PickedPoint -> CurrentMousePoint
|
||||||
|
const pickedPosition = objectPicker.screenPoint
|
||||||
|
const mouseVector = Qt.vector2d(mouse.x - pickedPosition.x, -(mouse.y - pickedPosition.y))
|
||||||
|
|
||||||
|
// Transform the positive picked axis vector from World Coord to Screen Coord
|
||||||
|
const gizmoLocalPointOnAxis = gizmoDisplayTransform.matrix.times(Qt.vector4d(pickedAxis.x, pickedAxis.y, pickedAxis.z, 1))
|
||||||
|
const gizmoCenterPoint = gizmoDisplayTransform.matrix.times(Qt.vector4d(0, 0, 0, 1))
|
||||||
|
const screenPoint2D = pointFromWorldToScreen(gizmoLocalPointOnAxis, camera, windowSize)
|
||||||
|
const screenCenter2D = pointFromWorldToScreen(gizmoCenterPoint, camera, windowSize)
|
||||||
|
const screenAxisVector = Qt.vector2d(screenPoint2D.x - screenCenter2D.x, -(screenPoint2D.y - screenCenter2D.y))
|
||||||
|
|
||||||
|
// Get the cosinus of the angle from the screenAxisVector to the mouseVector
|
||||||
|
const cosAngle = screenAxisVector.dotProduct(mouseVector) / (screenAxisVector.length() * mouseVector.length())
|
||||||
|
const offset = cosAngle * mouseVector.length() * sensibility
|
||||||
|
|
||||||
|
// If the mouse is not at the same spot as the pickedPoint, we do translation
|
||||||
|
if (offset) doTranslation(objectPicker.decomposedObjectModelMat, pickedAxis.times(offset)) // Do a translation from the initial Object Model Matrix when we picked the gizmo
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case TransformGizmo.Type.ROTATION: {
|
||||||
|
// Get Screen Coordinates of the gizmo center
|
||||||
|
const gizmoCenterPoint = gizmoDisplayTransform.matrix.times(Qt.vector4d(0, 0, 0, 1))
|
||||||
|
const screenCenter2D = pointFromWorldToScreen(gizmoCenterPoint, camera, root.windowSize)
|
||||||
|
|
||||||
|
// Get the vector screenCenter2D -> PickedPoint
|
||||||
|
const originalVector = Qt.vector2d(objectPicker.screenPoint.x - screenCenter2D.x, -(objectPicker.screenPoint.y - screenCenter2D.y))
|
||||||
|
|
||||||
|
// Compute the current vector screenCenter2D -> CurrentMousePoint
|
||||||
|
const mouseVector = Qt.vector2d(mouse.x - screenCenter2D.x, -(mouse.y - screenCenter2D.y))
|
||||||
|
|
||||||
|
// Get the angle from the originalVector to the mouseVector
|
||||||
|
const angle = Math.atan2(-originalVector.y*mouseVector.x + originalVector.x*mouseVector.y, originalVector.x*mouseVector.x + originalVector.y*mouseVector.y) * 180 / Math.PI
|
||||||
|
|
||||||
|
// Get the orientation of the gizmo in function of the camera
|
||||||
|
const gizmoLocalAxisVector = gizmoDisplayTransform.matrix.times(Qt.vector4d(pickedAxis.x, pickedAxis.y, pickedAxis.z, 0))
|
||||||
|
const gizmoToCameraVector = camera.position.toVector4d().minus(gizmoCenterPoint)
|
||||||
|
const orientation = gizmoLocalAxisVector.dotProduct(gizmoToCameraVector) > 0 ? 1 : -1
|
||||||
|
|
||||||
|
if (angle !== 0) doRotation(objectPicker.decomposedObjectModelMat, pickedAxis, angle*orientation)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case TransformGizmo.Type.SCALE: {
|
||||||
|
const sensibility = 0.05
|
||||||
|
|
||||||
|
// Get Screen Coordinates of the gizmo center
|
||||||
|
const gizmoCenterPoint = gizmoDisplayTransform.matrix.times(Qt.vector4d(0, 0, 0, 1))
|
||||||
|
const screenCenter2D = pointFromWorldToScreen(gizmoCenterPoint, camera, root.windowSize)
|
||||||
|
|
||||||
|
// Compute the scale unit
|
||||||
|
const scaleUnit = screenCenter2D.minus(Qt.vector2d(objectPicker.screenPoint.x, objectPicker.screenPoint.y)).length()
|
||||||
|
|
||||||
|
// Compute the current vector screenCenter2D -> CurrentMousePoint
|
||||||
|
const mouseVector = Qt.vector2d(mouse.x - screenCenter2D.x, -(mouse.y - screenCenter2D.y))
|
||||||
|
let offset = (mouseVector.length() - scaleUnit) * sensibility
|
||||||
|
offset = (offset < 0) ? offset * 3 : offset // Used to make it more sensible when we want to reduce the scale (because the action field is shorter)
|
||||||
|
|
||||||
|
if (offset) doScale(objectPicker.decomposedObjectModelMat, pickedAxis.times(offset))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onReleased: {
|
onReleased: {
|
||||||
if(objectPicker && mouse.button == Qt.RightButton) {
|
if(objectPicker && mouse.button === Qt.RightButton) {
|
||||||
resetMenu.updateTypeBeforePopup(objectPicker.gizmoType)
|
resetMenu.updateTypeBeforePopup(objectPicker.gizmoType)
|
||||||
resetMenu.popup(window)
|
resetMenu.popup(window)
|
||||||
}
|
}
|
||||||
|
@ -240,9 +315,7 @@ Entity {
|
||||||
|
|
||||||
Transform {
|
Transform {
|
||||||
id: gizmoDisplayTransform
|
id: gizmoDisplayTransform
|
||||||
scale: {
|
scale: root.gizmoScale * (camera.position.minus(gizmoDisplayTransform.translation)).length()
|
||||||
return root.gizmoScale * (camera.position.minus(gizmoDisplayTransform.translation)).length()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity {
|
Entity {
|
||||||
|
@ -379,8 +452,6 @@ Entity {
|
||||||
onPickedChanged: {
|
onPickedChanged: {
|
||||||
this.decomposedObjectModelMat = decomposeModelMatrixFromTransformations(objectTransform.translation, objectTransform.rotation, objectTransform.scale3D) // Save the current transformations
|
this.decomposedObjectModelMat = decomposeModelMatrixFromTransformations(objectTransform.translation, objectTransform.rotation, objectTransform.scale3D) // Save the current transformations
|
||||||
root.pickedChanged(picker.isPressed) // Used to prevent camera transformations
|
root.pickedChanged(picker.isPressed) // Used to prevent camera transformations
|
||||||
mouseHandler.objectPicker = picker.isPressed ? picker : null // Set the objectPicker of the mouseHandler
|
|
||||||
transformHandler.objectPicker = picker.isPressed ? picker : null // Pass the picker to the global FrameAction
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -440,8 +511,6 @@ Entity {
|
||||||
onPickedChanged: {
|
onPickedChanged: {
|
||||||
this.decomposedObjectModelMat = decomposeModelMatrixFromTransformations(objectTransform.translation, objectTransform.rotation, objectTransform.scale3D) // Save the current transformations
|
this.decomposedObjectModelMat = decomposeModelMatrixFromTransformations(objectTransform.translation, objectTransform.rotation, objectTransform.scale3D) // Save the current transformations
|
||||||
root.pickedChanged(picker.isPressed) // Used to prevent camera transformations
|
root.pickedChanged(picker.isPressed) // Used to prevent camera transformations
|
||||||
mouseHandler.objectPicker = picker.isPressed ? picker : null // Set the objectPicker of the mouseHandler
|
|
||||||
transformHandler.objectPicker = picker.isPressed ? picker : null // Pass the picker to the global FrameAction
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -487,93 +556,6 @@ Entity {
|
||||||
onPickedChanged: {
|
onPickedChanged: {
|
||||||
this.decomposedObjectModelMat = decomposeModelMatrixFromTransformations(objectTransform.translation, objectTransform.rotation, objectTransform.scale3D) // Save the current transformations
|
this.decomposedObjectModelMat = decomposeModelMatrixFromTransformations(objectTransform.translation, objectTransform.rotation, objectTransform.scale3D) // Save the current transformations
|
||||||
root.pickedChanged(picker.isPressed) // Used to prevent camera transformations
|
root.pickedChanged(picker.isPressed) // Used to prevent camera transformations
|
||||||
mouseHandler.objectPicker = picker.isPressed ? picker : null // Set the objectPicker of the mouseHandler
|
|
||||||
transformHandler.objectPicker = picker.isPressed ? picker : null // Pass the picker to the global FrameAction
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameAction {
|
|
||||||
id: transformHandler
|
|
||||||
property var objectPicker: null
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
if (objectPicker) {
|
|
||||||
|
|
||||||
let pickedAxis
|
|
||||||
switch(objectPicker.gizmoAxis) {
|
|
||||||
case TransformGizmo.Axis.X: pickedAxis = Qt.vector3d(1,0,0); break
|
|
||||||
case TransformGizmo.Axis.Y: pickedAxis = Qt.vector3d(0,1,0); break
|
|
||||||
case TransformGizmo.Axis.Z: pickedAxis = Qt.vector3d(0,0,1); break
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(objectPicker.gizmoType) {
|
|
||||||
case TransformGizmo.Type.POSITION: {
|
|
||||||
const sensibility = 0.02
|
|
||||||
|
|
||||||
// Compute the current vector PickedPoint -> CurrentMousePoint
|
|
||||||
const pickedPosition = objectPicker.screenPoint
|
|
||||||
const mouseVector = Qt.vector2d(mouseHandler.currentPosition.x - pickedPosition.x, -(mouseHandler.currentPosition.y - pickedPosition.y))
|
|
||||||
|
|
||||||
// Transform the positive picked axis vector from World Coord to Screen Coord
|
|
||||||
const gizmoLocalPointOnAxis = gizmoDisplayTransform.matrix.times(Qt.vector4d(pickedAxis.x, pickedAxis.y, pickedAxis.z, 1))
|
|
||||||
const gizmoCenterPoint = gizmoDisplayTransform.matrix.times(Qt.vector4d(0, 0, 0, 1))
|
|
||||||
const screenPoint2D = pointFromWorldToScreen(gizmoLocalPointOnAxis, camera, windowSize)
|
|
||||||
const screenCenter2D = pointFromWorldToScreen(gizmoCenterPoint, camera, windowSize)
|
|
||||||
const screenAxisVector = Qt.vector2d(screenPoint2D.x - screenCenter2D.x, -(screenPoint2D.y - screenCenter2D.y))
|
|
||||||
|
|
||||||
// Get the cosinus of the angle from the screenAxisVector to the mouseVector
|
|
||||||
const cosAngle = screenAxisVector.dotProduct(mouseVector) / (screenAxisVector.length() * mouseVector.length())
|
|
||||||
const offset = cosAngle * mouseVector.length() * sensibility
|
|
||||||
|
|
||||||
// If the mouse is not at the same spot as the pickedPoint, we do translation
|
|
||||||
if (offset) doTranslation(objectPicker.decomposedObjectModelMat, pickedAxis.times(offset)) // Do a translation from the initial Object Model Matrix when we picked the gizmo
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
case TransformGizmo.Type.ROTATION: {
|
|
||||||
// Get Screen Coordinates of the gizmo center
|
|
||||||
const gizmoCenterPoint = gizmoDisplayTransform.matrix.times(Qt.vector4d(0, 0, 0, 1))
|
|
||||||
const screenCenter2D = pointFromWorldToScreen(gizmoCenterPoint, camera, root.windowSize)
|
|
||||||
|
|
||||||
// Get the vector screenCenter2D -> PickedPoint
|
|
||||||
const originalVector = Qt.vector2d(objectPicker.screenPoint.x - screenCenter2D.x, -(objectPicker.screenPoint.y - screenCenter2D.y))
|
|
||||||
|
|
||||||
// Compute the current vector screenCenter2D -> CurrentMousePoint
|
|
||||||
const mouseVector = Qt.vector2d(mouseHandler.currentPosition.x - screenCenter2D.x, -(mouseHandler.currentPosition.y - screenCenter2D.y))
|
|
||||||
|
|
||||||
// Get the angle from the originalVector to the mouseVector
|
|
||||||
const angle = Math.atan2(-originalVector.y*mouseVector.x + originalVector.x*mouseVector.y, originalVector.x*mouseVector.x + originalVector.y*mouseVector.y) * 180 / Math.PI
|
|
||||||
|
|
||||||
// Get the orientation of the gizmo in function of the camera
|
|
||||||
const gizmoLocalAxisVector = gizmoDisplayTransform.matrix.times(Qt.vector4d(pickedAxis.x, pickedAxis.y, pickedAxis.z, 0))
|
|
||||||
const gizmoToCameraVector = camera.position.toVector4d().minus(gizmoCenterPoint)
|
|
||||||
const orientation = gizmoLocalAxisVector.dotProduct(gizmoToCameraVector) > 0 ? 1 : -1
|
|
||||||
|
|
||||||
if (angle !== 0) doRotation(objectPicker.decomposedObjectModelMat, pickedAxis, angle*orientation)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
case TransformGizmo.Type.SCALE: {
|
|
||||||
const sensibility = 0.05
|
|
||||||
|
|
||||||
// Get Screen Coordinates of the gizmo center
|
|
||||||
const gizmoCenterPoint = gizmoDisplayTransform.matrix.times(Qt.vector4d(0, 0, 0, 1))
|
|
||||||
const screenCenter2D = pointFromWorldToScreen(gizmoCenterPoint, camera, root.windowSize)
|
|
||||||
|
|
||||||
// Compute the scale unit
|
|
||||||
const scaleUnit = screenCenter2D.minus(Qt.vector2d(objectPicker.screenPoint.x, objectPicker.screenPoint.y)).length()
|
|
||||||
|
|
||||||
// Compute the current vector screenCenter2D -> CurrentMousePoint
|
|
||||||
const mouseVector = Qt.vector2d(mouseHandler.currentPosition.x - screenCenter2D.x, -(mouseHandler.currentPosition.y - screenCenter2D.y))
|
|
||||||
let offset = (mouseVector.length() - scaleUnit) * sensibility
|
|
||||||
offset = (offset < 0) ? offset * 3 : offset // Used to make it more sensible when we want to reduce the scale (because the action field is shorter)
|
|
||||||
|
|
||||||
if (offset) doScale(objectPicker.decomposedObjectModelMat, pickedAxis.times(offset))
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,11 @@ ObjectPicker {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
onPressed: {
|
onPressed: {
|
||||||
|
mouseController.enabled = true
|
||||||
|
mouseController.objectPicker = this
|
||||||
root.isPressed = true
|
root.isPressed = true
|
||||||
pickedChanged(this)
|
|
||||||
screenPoint = pick.position
|
screenPoint = pick.position
|
||||||
mouseController.currentPosition = pick.position
|
pickedChanged(this)
|
||||||
}
|
}
|
||||||
onEntered: {
|
onEntered: {
|
||||||
gizmoMaterial.ambient = "white"
|
gizmoMaterial.ambient = "white"
|
||||||
|
@ -35,6 +36,8 @@ ObjectPicker {
|
||||||
onReleased: {
|
onReleased: {
|
||||||
gizmoMaterial.ambient = gizmoBaseColor
|
gizmoMaterial.ambient = gizmoBaseColor
|
||||||
root.isPressed = false
|
root.isPressed = false
|
||||||
|
mouseController.objectPicker = null
|
||||||
|
mouseController.enabled = false
|
||||||
pickedChanged(this)
|
pickedChanged(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue