[ui] Viewer3D: TransformGizmo - add picking and transformations

- For now, transformations do not take well in count the orientation of the mouse but gizmo is functional.
This commit is contained in:
Julien-Haudegond 2020-07-06 17:10:54 +02:00
parent 30004fe690
commit 45fae981ba
2 changed files with 144 additions and 7 deletions

View file

@ -9,8 +9,14 @@ Entity {
id: root
property real gizmoScale: 0.15
property Camera camera
readonly property Transform objectTransform : Transform {}
components: [gizmoTransform]
signal pickedChanged(bool picked)
components: [gizmoDisplayTransform, mouseHandler]
/***** ENUM *****/
enum Axis {
X,
@ -126,10 +132,43 @@ Entity {
transform.setMatrix(mat)
}
/***** SPECIFIC MATRIX TRANSFORMATIONS (using local vars) *****/
function doTranslation(translateVec) {
localTranslate(gizmoDisplayTransform, translateVec) // Update gizmo matrix
localTranslate(objectTransform, translateVec) // Update object matrix
}
function doRotation(axis, degree) {
localRotate(gizmoDisplayTransform, axis, degree) // Update gizmo matrix
localRotate(objectTransform, axis, degree) // Update object matrix
}
function doScale(scaleVec) {
localScale(objectTransform, scaleVec) // Update object matrix
}
/***** DEVICES *****/
MouseDevice { id: mouseSourceDevice }
MouseHandler {
id: mouseHandler
sourceDevice: mouseSourceDevice
property point lastPosition
property point currentPosition
onPositionChanged: {
currentPosition.x = mouse.x
currentPosition.y = mouse.y
}
}
/***** GIZMO'S BASIC COMPONENTS *****/
Transform {
id: gizmoTransform
id: gizmoDisplayTransform
scale: {
return root.gizmoScale * (camera.position.minus(gizmoTransform.translation)).length()
return root.gizmoScale * (camera.position.minus(gizmoDisplayTransform.translation)).length()
}
}
@ -223,7 +262,7 @@ Entity {
Entity {
id: axisScaleBox
components: [cubeScaleMesh, cubeScaleTransform, material]
components: [cubeScaleMesh, cubeScaleTransform, material, scalePicker]
CuboidMesh {
id: cubeScaleMesh
@ -257,12 +296,19 @@ Entity {
}
}
}
TransformGizmoPicker {
id: scalePicker
onPickedChanged: {
root.pickedChanged(picked)
}
}
}
// POSITION ENTITY
Entity {
id: positionEntity
components: [coneMesh, coneTransform, material]
components: [coneMesh, coneTransform, material, positionPicker]
ConeMesh {
id: coneMesh
@ -298,12 +344,19 @@ Entity {
return m
}
}
TransformGizmoPicker {
id: positionPicker
onPickedChanged: {
root.pickedChanged(picked)
}
}
}
// ROTATION ENTITY
Entity {
id: rotationEntity
components: [torusMesh, torusTransform, material]
components: [torusMesh, torusTransform, material, rotationPicker]
TorusMesh {
id: torusMesh
@ -325,6 +378,60 @@ Entity {
return m
}
}
TransformGizmoPicker {
id: rotationPicker
onPickedChanged: {
root.pickedChanged(picked)
}
}
}
FrameAction {
onTriggered: {
// POSITION PICKER
if (positionPicker.isPressed) {
const offsetX = mouseHandler.currentPosition.x - mouseHandler.lastPosition.x
const offsetY = mouseHandler.currentPosition.y - mouseHandler.lastPosition.y
let pickedAxis
switch(axis) {
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
}
doTranslation(pickedAxis.times(0.01*offsetX - 0.01*offsetY))
mouseHandler.lastPosition = mouseHandler.currentPosition
return
}
if (rotationPicker.isPressed) {
const offsetX = mouseHandler.currentPosition.x - mouseHandler.lastPosition.x
const offsetY = mouseHandler.currentPosition.y - mouseHandler.lastPosition.y
// const offset = 0.1*offsetX - 0.1*offsetY
const offset = 1
doRotation(axis, offset)
mouseHandler.lastPosition = mouseHandler.currentPosition
return
}
if (scalePicker.isPressed) {
const offsetX = mouseHandler.currentPosition.x - mouseHandler.lastPosition.x
const offsetY = mouseHandler.currentPosition.y - mouseHandler.lastPosition.y
// const offset = 0.1*offsetX - 0.1*offsetY
const offset = 0.05
let pickedAxis
switch(axis) {
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
}
doScale(pickedAxis.times(offset))
mouseHandler.lastPosition = mouseHandler.currentPosition
return
}
}
}
}
}

View file

@ -0,0 +1,30 @@
import Qt3D.Core 2.0
import Qt3D.Render 2.9
import Qt3D.Input 2.0
import Qt3D.Extras 2.10
import QtQuick 2.9
import Qt3D.Logic 2.0
ObjectPicker {
id: root
hoverEnabled: true
property bool isPressed : false
signal pickedChanged(bool picked)
onPressed: {
root.isPressed = true
pickedChanged(true)
mouseHandler.currentPosition = mouseHandler.lastPosition = pick.position
}
onEntered: {
material.ambient = "white"
}
onExited: {
if(!isPressed) material.ambient = baseColor
}
onReleased: {
material.ambient = baseColor
root.isPressed = false
pickedChanged(false)
}
}