mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-08-02 08:18:25 +02:00
[ui] Viewer3D: TransformGizmo - ready to be set with absolute values
- Now, we can set the transformation with a position vector, Euler angles and a scale vector.
This commit is contained in:
parent
da765a5f98
commit
d0a78d96ab
4 changed files with 70 additions and 17 deletions
|
@ -188,6 +188,29 @@ class Transformations3DHelper(QObject):
|
|||
|
||||
return { "position": posMat, "rotation": rotMat, "scale": scaleMat, "quaternion": decomposition.get("quaternion") }
|
||||
|
||||
@Slot(QVector3D, QVector3D, QVector3D, result=QMatrix4x4)
|
||||
def computeModelMatrixWithEuler(self, translation, rotation, scale):
|
||||
""" Compute a model matrix from three Vector3D.
|
||||
Args:
|
||||
translation (QVector3D): position in space (x, y, z)
|
||||
rotation (QVector3D): Euler angles in degrees (x, y, z)
|
||||
scale (QVector3D): scale of the object (x, y, z)
|
||||
Returns:
|
||||
QMatrix4x4: corresponding model matrix
|
||||
"""
|
||||
posMat = QMatrix4x4()
|
||||
posMat.translate(translation)
|
||||
|
||||
quaternion = QQuaternion.fromEulerAngles(rotation)
|
||||
rotMat = self.quaternionToRotationMatrix(quaternion)
|
||||
|
||||
scaleMat = QMatrix4x4()
|
||||
scaleMat.scale(scale)
|
||||
|
||||
modelMat = posMat * rotMat * scaleMat
|
||||
|
||||
return modelMat
|
||||
|
||||
|
||||
#---------- "Private" Methods ----------#
|
||||
|
||||
|
|
|
@ -14,8 +14,10 @@ Entity {
|
|||
readonly property Camera camera : cameraController.camera
|
||||
readonly property var windowSize: cameraController.windowSize
|
||||
readonly property alias objectTransform : transformGizmo.objectTransform // The Transform the object should use
|
||||
readonly property alias updateTransformations: transformGizmo.updateTransformations // Function to update the transformations
|
||||
|
||||
signal pickedChanged(bool pressed)
|
||||
signal gizmoChanged(var translation, var rotation, var scale)
|
||||
|
||||
onPickedChanged: {
|
||||
cameraController.loseMouseFocus = pressed // Notify the camera if the transform takes/releases the focus
|
||||
|
@ -30,5 +32,8 @@ Entity {
|
|||
onPickedChanged: {
|
||||
root.pickedChanged(pressed)
|
||||
}
|
||||
onGizmoChanged: {
|
||||
root.gizmoChanged(translation, rotation, scale)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,9 +14,29 @@ Entity {
|
|||
property var windowSize
|
||||
property var frontLayerComponent
|
||||
property var window
|
||||
readonly property Transform objectTransform : Transform {}
|
||||
|
||||
readonly property Transform objectTransform : Transform {
|
||||
translation: gizmoDisplayTransform.translation
|
||||
rotation: gizmoDisplayTransform.rotation
|
||||
scale3D: Qt.vector3d(1,1,1)
|
||||
}
|
||||
readonly property var updateTransformations: function updateTransformations(translation, rotation, scale) {
|
||||
const gizmoModelMat = Transformations3DHelper.computeModelMatrixWithEuler(translation, rotation, Qt.vector3d(1,1,1))
|
||||
gizmoDisplayTransform.setMatrix(gizmoModelMat) // Update gizmo matrix and translation/rotation of the object (with binding)
|
||||
objectTransform.scale3D = scale // Update the scale of the object
|
||||
}
|
||||
|
||||
signal pickedChanged(bool pressed)
|
||||
signal gizmoChanged(var translation, var rotation, var scale)
|
||||
|
||||
function emitGizmoChanged() {
|
||||
const translation = gizmoDisplayTransform.translation // Position in space
|
||||
const rotation = Qt.vector3d(gizmoDisplayTransform.rotationX, gizmoDisplayTransform.rotationY, gizmoDisplayTransform.rotationZ) // Euler angles
|
||||
const scale = objectTransform.scale3D // Scale of the object
|
||||
|
||||
updateTransformations(translation, rotation, scale) // Optional: just to make sure the absolute values work well
|
||||
gizmoChanged(translation, rotation, scale)
|
||||
}
|
||||
|
||||
components: [gizmoDisplayTransform, mouseHandler, frontLayerComponent]
|
||||
|
||||
|
@ -38,31 +58,27 @@ Entity {
|
|||
/***** TRANSFORMATIONS (using local vars) *****/
|
||||
|
||||
function doRelativeTranslation(initialModelMatrix, translateVec) {
|
||||
Transformations3DHelper.relativeLocalTranslate(gizmoDisplayTransform, initialModelMatrix.position, initialModelMatrix.rotation, initialModelMatrix.scale, translateVec) // Update gizmo matrix
|
||||
Transformations3DHelper.relativeLocalTranslate(objectTransform, initialModelMatrix.position, initialModelMatrix.rotation, initialModelMatrix.scale, translateVec) // Update object matrix
|
||||
Transformations3DHelper.relativeLocalTranslate(gizmoDisplayTransform, initialModelMatrix.position, initialModelMatrix.rotation, initialModelMatrix.scale, translateVec) // Update gizmo matrix and object matrix with binding
|
||||
}
|
||||
|
||||
function doRelativeRotation(initialModelMatrix, axis, degree) {
|
||||
Transformations3DHelper.relativeLocalRotate(gizmoDisplayTransform, initialModelMatrix.position, initialModelMatrix.quaternion, initialModelMatrix.scale, axis, degree) // Update gizmo matrix
|
||||
Transformations3DHelper.relativeLocalRotate(objectTransform, initialModelMatrix.position, initialModelMatrix.quaternion, initialModelMatrix.scale, axis, degree) // Update object matrix
|
||||
Transformations3DHelper.relativeLocalRotate(gizmoDisplayTransform, initialModelMatrix.position, initialModelMatrix.quaternion, initialModelMatrix.scale, axis, degree) // Update gizmo matrix and object matrix with binding
|
||||
}
|
||||
|
||||
function doRelativeScale(initialModelMatrix, scaleVec) {
|
||||
Transformations3DHelper.relativeLocalScale(objectTransform, initialModelMatrix.position, initialModelMatrix.rotation, initialModelMatrix.scale, scaleVec) // Update object matrix
|
||||
Transformations3DHelper.relativeLocalScale(objectTransform, initialModelMatrix.position, initialModelMatrix.rotation, initialModelMatrix.scale, scaleVec) // Update only object matrix
|
||||
}
|
||||
|
||||
function resetTranslation() {
|
||||
gizmoDisplayTransform.translation = Qt.vector3d(0,0,0)
|
||||
objectTransform.translation = Qt.vector3d(0,0,0)
|
||||
gizmoDisplayTransform.translation = Qt.vector3d(0,0,0) // Reset gizmo matrix and object matrix with binding
|
||||
}
|
||||
|
||||
function resetRotation() {
|
||||
gizmoDisplayTransform.rotation = Qt.quaternion(1,0,0,0)
|
||||
objectTransform.rotation = Qt.quaternion(1,0,0,0)
|
||||
gizmoDisplayTransform.rotation = Qt.quaternion(1,0,0,0) // Reset gizmo matrix and object matrix with binding
|
||||
}
|
||||
|
||||
function resetScale() {
|
||||
objectTransform.scale3D = Qt.vector3d(1,1,1)
|
||||
objectTransform.scale3D = Qt.vector3d(1,1,1) // Reset only object matrix
|
||||
}
|
||||
|
||||
function resetATransformType(transformType) {
|
||||
|
@ -71,6 +87,7 @@ Entity {
|
|||
case TransformGizmo.Type.ROTATION: resetRotation(); break
|
||||
case TransformGizmo.Type.SCALE: resetScale(); break
|
||||
}
|
||||
emitGizmoChanged()
|
||||
}
|
||||
|
||||
/***** DEVICES *****/
|
||||
|
@ -84,7 +101,7 @@ Entity {
|
|||
property bool enabled: false
|
||||
|
||||
onPositionChanged: {
|
||||
if (objectPicker) {
|
||||
if (objectPicker && objectPicker.button === Qt.LeftButton) {
|
||||
// Get the selected axis
|
||||
let pickedAxis
|
||||
switch(objectPicker.gizmoAxis) {
|
||||
|
@ -137,7 +154,8 @@ Entity {
|
|||
const gizmoToCameraVector = camera.position.toVector4d().minus(gizmoCenterPoint)
|
||||
const orientation = gizmoLocalAxisVector.dotProduct(gizmoToCameraVector) > 0 ? 1 : -1
|
||||
|
||||
if (angle !== 0) doRelativeRotation(objectPicker.modelMatrix, pickedAxis, angle*orientation)
|
||||
if (angle !== 0) doRelativeRotation(objectPicker.modelMatrix, pickedAxis, angle*orientation) // Do a rotation from the initial Object Model Matrix when we picked the gizmo
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -156,18 +174,23 @@ Entity {
|
|||
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) doRelativeScale(objectPicker.modelMatrix, pickedAxis.times(offset))
|
||||
if (offset) doRelativeScale(objectPicker.modelMatrix, pickedAxis.times(offset)) // Do a scale from the initial Object Model Matrix when we picked the gizmo
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
if(objectPicker && mouse.button === Qt.RightButton) {
|
||||
|
||||
if(objectPicker && objectPicker.button === Qt.RightButton) {
|
||||
resetMenu.updateTypeBeforePopup(objectPicker.gizmoType)
|
||||
resetMenu.popup(window)
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
if(objectPicker && mouse.button === Qt.LeftButton) {
|
||||
emitGizmoChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
|
|
|
@ -15,6 +15,7 @@ ObjectPicker {
|
|||
property int gizmoType
|
||||
property point screenPoint
|
||||
property var modelMatrix
|
||||
property int button
|
||||
|
||||
signal pickedChanged(var picker)
|
||||
|
||||
|
@ -25,6 +26,7 @@ ObjectPicker {
|
|||
mouseController.objectPicker = this
|
||||
root.isPressed = true
|
||||
screenPoint = pick.position
|
||||
button = pick.button
|
||||
pickedChanged(this)
|
||||
}
|
||||
onEntered: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue