mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-04-29 02:08:08 +02:00
[ui] Viewer3D: TransformGizmo - moving transform operations to Python
- Moving transform operations from QML to Python to get access to more Qt functionalities and to make a better separation of logic/display.
This commit is contained in:
parent
cb306ffc7d
commit
da765a5f98
7 changed files with 146 additions and 145 deletions
|
@ -13,7 +13,7 @@ from meshroom.core import pyCompatibility
|
|||
from meshroom.ui import components
|
||||
from meshroom.ui.components.clipboard import ClipboardHelper
|
||||
from meshroom.ui.components.filepath import FilepathHelper
|
||||
from meshroom.ui.components.scene3D import Scene3DHelper
|
||||
from meshroom.ui.components.scene3D import Scene3DHelper, Transformations3DHelper
|
||||
from meshroom.ui.palette import PaletteManager
|
||||
from meshroom.ui.reconstruction import Reconstruction
|
||||
from meshroom.ui.utils import QmlInstantEngine
|
||||
|
@ -127,6 +127,7 @@ class MeshroomApp(QApplication):
|
|||
# => expose them as context properties instead
|
||||
self.engine.rootContext().setContextProperty("Filepath", FilepathHelper(parent=self))
|
||||
self.engine.rootContext().setContextProperty("Scene3DHelper", Scene3DHelper(parent=self))
|
||||
self.engine.rootContext().setContextProperty("Transformations3DHelper", Transformations3DHelper(parent=self))
|
||||
self.engine.rootContext().setContextProperty("Clipboard", ClipboardHelper(parent=self))
|
||||
|
||||
# additional context properties
|
||||
|
|
|
@ -4,12 +4,13 @@ def registerTypes():
|
|||
from meshroom.ui.components.clipboard import ClipboardHelper
|
||||
from meshroom.ui.components.edge import EdgeMouseArea
|
||||
from meshroom.ui.components.filepath import FilepathHelper
|
||||
from meshroom.ui.components.scene3D import Scene3DHelper, TrackballController
|
||||
from meshroom.ui.components.scene3D import Scene3DHelper, TrackballController, Transformations3DHelper
|
||||
from meshroom.ui.components.csvData import CsvData
|
||||
|
||||
qmlRegisterType(EdgeMouseArea, "GraphEditor", 1, 0, "EdgeMouseArea")
|
||||
qmlRegisterType(ClipboardHelper, "Meshroom.Helpers", 1, 0, "ClipboardHelper") # TODO: uncreatable
|
||||
qmlRegisterType(FilepathHelper, "Meshroom.Helpers", 1, 0, "FilepathHelper") # TODO: uncreatable
|
||||
qmlRegisterType(Scene3DHelper, "Meshroom.Helpers", 1, 0, "Scene3DHelper") # TODO: uncreatable
|
||||
qmlRegisterType(Transformations3DHelper, "Meshroom.Helpers", 1, 0, "Transformations3DHelper") # TODO: uncreatable
|
||||
qmlRegisterType(TrackballController, "Meshroom.Helpers", 1, 0, "TrackballController")
|
||||
qmlRegisterType(CsvData, "DataObjects", 1, 0, "CsvData")
|
||||
|
|
|
@ -3,7 +3,7 @@ from math import acos, pi, sqrt
|
|||
from PySide2.QtCore import QObject, Slot, QSize, Signal, QPointF
|
||||
from PySide2.Qt3DCore import Qt3DCore
|
||||
from PySide2.Qt3DRender import Qt3DRender
|
||||
from PySide2.QtGui import QVector3D, QQuaternion, QVector2D
|
||||
from PySide2.QtGui import QVector3D, QQuaternion, QVector2D, QVector4D, QMatrix4x4
|
||||
|
||||
from meshroom.ui.utils import makeProperty
|
||||
|
||||
|
@ -103,3 +103,115 @@ class TrackballController(QObject):
|
|||
trackballSize = makeProperty(float, '_trackballSize', trackballSizeChanged)
|
||||
rotationSpeedChanged = Signal()
|
||||
rotationSpeed = makeProperty(float, '_rotationSpeed', rotationSpeedChanged)
|
||||
|
||||
|
||||
class Transformations3DHelper(QObject):
|
||||
|
||||
#---------- Exposed to QML ----------#
|
||||
|
||||
@Slot(QVector4D, Qt3DRender.QCamera, QSize, result=QVector2D)
|
||||
def pointFromWorldToScreen(self, point, camera, windowSize):
|
||||
""" Compute the Screen point corresponding to a World Point. """
|
||||
# Transform the point from World Coord to Normalized Device Coord
|
||||
viewMatrix = camera.transform().matrix().inverted()
|
||||
projectedPoint = (camera.projectionMatrix() * viewMatrix[0]).map(point)
|
||||
projectedPoint2D = QVector2D(
|
||||
projectedPoint.x()/projectedPoint.w(),
|
||||
projectedPoint.y()/projectedPoint.w()
|
||||
)
|
||||
|
||||
# Transform the point from Normalized Device Coord to Screen Coord
|
||||
screenPoint2D = QVector2D(
|
||||
int((projectedPoint2D.x() + 1) * windowSize.width() / 2),
|
||||
int((projectedPoint2D.y() - 1) * windowSize.height() / -2)
|
||||
)
|
||||
|
||||
return screenPoint2D
|
||||
|
||||
@Slot(Qt3DCore.QTransform, QMatrix4x4, QMatrix4x4, QMatrix4x4, QVector3D)
|
||||
def relativeLocalTranslate(self, transformQtInstance, initialPosMat, initialRotMat, initialScaleMat, translateVec):
|
||||
""" Translate the QTransform in its local space relatively to an initial state. """
|
||||
# Compute the translation transformation matrix
|
||||
translationMat = QMatrix4x4()
|
||||
translationMat.translate(translateVec)
|
||||
|
||||
# Compute the new model matrix (POSITION * ROTATION * TRANSLATE * SCALE) and set it to the Transform
|
||||
mat = initialPosMat * initialRotMat * translationMat * initialScaleMat
|
||||
transformQtInstance.setMatrix(mat)
|
||||
|
||||
@Slot(Qt3DCore.QTransform, QMatrix4x4, QQuaternion, QMatrix4x4, QVector3D, int)
|
||||
def relativeLocalRotate(self, transformQtInstance, initialPosMat, initialRotQuat, initialScaleMat, axis, degree):
|
||||
""" Rotate the QTransform in its local space relatively to an initial state. """
|
||||
# Compute the transformation quaternion from axis and angle in degrees
|
||||
transformQuat = QQuaternion.fromAxisAndAngle(axis, degree)
|
||||
|
||||
# Compute the new rotation quaternion and then calculate the matrix
|
||||
newRotQuat = initialRotQuat * transformQuat # Order is important
|
||||
newRotationMat = self.quaternionToRotationMatrix(newRotQuat)
|
||||
|
||||
# Compute the new model matrix (POSITION * NEW_COMPUTED_ROTATION * SCALE) and set it to the Transform
|
||||
mat = initialPosMat * newRotationMat * initialScaleMat
|
||||
transformQtInstance.setMatrix(mat)
|
||||
|
||||
@Slot(Qt3DCore.QTransform, QMatrix4x4, QMatrix4x4, QMatrix4x4, QVector3D)
|
||||
def relativeLocalScale(self, transformQtInstance, initialPosMat, initialRotMat, initialScaleMat, scaleVec):
|
||||
""" Scale the QTransform in its local space relatively to an initial state. """
|
||||
# Make a copy of the scale matrix (otherwise, it is a reference and it does not work as expected)
|
||||
scaleMat = self.copyMatrix4x4(initialScaleMat)
|
||||
|
||||
# Update the scale matrix copy (X then Y then Z) with the scaleVec values
|
||||
scaleVecTuple = scaleVec.toTuple()
|
||||
for i in range(3):
|
||||
currentRow = list(scaleMat.row(i).toTuple()) # QVector3D does not implement [] operator or easy way to access value by index so this little hack is required
|
||||
value = currentRow[i] + scaleVecTuple[i]
|
||||
value = value if value >= 0 else -value # Make sure to have only positive scale (because negative scale can make issues with matrix decomposition)
|
||||
currentRow[i] = value
|
||||
|
||||
scaleMat.setRow(i, QVector3D(currentRow[0], currentRow[1], currentRow[2])) # Apply the new row to the scale matrix
|
||||
|
||||
# Compute the new model matrix (POSITION * ROTATION * SCALE) and set it to the Transform
|
||||
mat = initialPosMat * initialRotMat * scaleMat
|
||||
transformQtInstance.setMatrix(mat)
|
||||
|
||||
@Slot(QMatrix4x4, result="QVariant")
|
||||
def modelMatrixToMatrices(self, modelMat):
|
||||
""" Decompose a model matrix into individual matrices. """
|
||||
decomposition = self.decomposeModelMatrix(modelMat)
|
||||
|
||||
posMat = QMatrix4x4()
|
||||
posMat.translate(decomposition.get("translation"))
|
||||
|
||||
rotMat = self.quaternionToRotationMatrix(decomposition.get("quaternion"))
|
||||
|
||||
scaleMat = QMatrix4x4()
|
||||
scaleMat.scale(decomposition.get("scale"))
|
||||
|
||||
return { "position": posMat, "rotation": rotMat, "scale": scaleMat, "quaternion": decomposition.get("quaternion") }
|
||||
|
||||
|
||||
#---------- "Private" Methods ----------#
|
||||
|
||||
def copyMatrix4x4(self, mat):
|
||||
""" Make a deep copy of a QMatrix4x4. """
|
||||
newMat = QMatrix4x4()
|
||||
for i in range(4):
|
||||
newMat.setRow(i, mat.row(i))
|
||||
return newMat
|
||||
|
||||
def decomposeModelMatrix(self, modelMat):
|
||||
""" Decompose a model matrix into individual component. """
|
||||
translation = modelMat.column(3).toVector3D()
|
||||
quaternion = QQuaternion.fromDirection(modelMat.column(2).toVector3D(), modelMat.column(1).toVector3D())
|
||||
scale = QVector3D(modelMat.column(0).length(), modelMat.column(1).length(), modelMat.column(2).length())
|
||||
|
||||
return { "translation": translation, "quaternion": quaternion, "scale": scale }
|
||||
|
||||
def quaternionToRotationMatrix(self, q):
|
||||
""" Return a rotation matrix from a quaternion. """
|
||||
rotMat3x3 = q.toRotationMatrix()
|
||||
return QMatrix4x4(
|
||||
rotMat3x3(0,0), rotMat3x3(0,1), rotMat3x3(0,2), 0,
|
||||
rotMat3x3(1,0), rotMat3x3(1,1), rotMat3x3(1,2), 0,
|
||||
rotMat3x3(2,0), rotMat3x3(2,1), rotMat3x3(2,2), 0,
|
||||
0, 0, 0, 1
|
||||
)
|
||||
|
|
6
meshroom/ui/qml/Utils/Transformations3DHelper.qml
Normal file
6
meshroom/ui/qml/Utils/Transformations3DHelper.qml
Normal file
|
@ -0,0 +1,6 @@
|
|||
pragma Singleton
|
||||
import Meshroom.Helpers 1.0
|
||||
|
||||
Transformations3DHelper {
|
||||
|
||||
}
|
|
@ -8,3 +8,4 @@ Format 1.0 format.js
|
|||
# singleton Clipboard 1.0 Clipboard.qml
|
||||
# singleton Filepath 1.0 Filepath.qml
|
||||
# singleton Scene3DHelper 1.0 Scene3DHelper.qml
|
||||
# singleton Transformations3DHelper 1.0 Transformations3DHelper.qml
|
||||
|
|
|
@ -5,6 +5,7 @@ import Qt3D.Extras 2.10
|
|||
import QtQuick 2.9
|
||||
import Qt3D.Logic 2.0
|
||||
import QtQuick.Controls 2.3
|
||||
import Utils 1.0
|
||||
|
||||
Entity {
|
||||
id: root
|
||||
|
@ -34,142 +35,20 @@ Entity {
|
|||
SCALE
|
||||
}
|
||||
|
||||
/***** QUATERNIONS *****/
|
||||
/***** TRANSFORMATIONS (using local vars) *****/
|
||||
|
||||
function multiplyQuaternion(q1, q2) {
|
||||
return Qt.quaternion(
|
||||
q1.scalar * q2.scalar - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z,
|
||||
q1.scalar * q2.x + q1.x * q2.scalar + q1.y * q2.z - q1.z * q2.y,
|
||||
q1.scalar * q2.y + q1.y * q2.scalar + q1.z * q2.x - q1.x * q2.z,
|
||||
q1.scalar * q2.z + q1.z * q2.scalar + q1.x * q2.y - q1.y * q2.x
|
||||
)
|
||||
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
|
||||
}
|
||||
|
||||
function dotQuaternion(q) {
|
||||
return (((q.x * q.x) + (q.y * q.y)) + (q.z * q.z)) + (q.scalar * q.scalar)
|
||||
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
|
||||
}
|
||||
|
||||
function normalizeQuaternion(q) {
|
||||
const dot = dotQuaternion(q)
|
||||
const inv = 1.0 / (Math.sqrt(dot))
|
||||
return Qt.quaternion(q.scalar * inv, q.x * inv, q.y * inv, q.z * inv)
|
||||
}
|
||||
|
||||
function quaternionFromAxisAngle(vec3, degree) {
|
||||
const rad = degree * Math.PI/180
|
||||
const factor = Math.sin(rad/2) // Used for the quaternion computation
|
||||
|
||||
// Compute the quaternion
|
||||
const x = vec3.x * factor
|
||||
const y = vec3.y * factor
|
||||
const z = vec3.z * factor
|
||||
const w = Math.cos(rad/2)
|
||||
|
||||
return normalizeQuaternion(Qt.quaternion(w, x, y, z))
|
||||
}
|
||||
|
||||
function quaternionToRotationMatrix(q) {
|
||||
const w = q.scalar
|
||||
const x = q.x
|
||||
const y = q.y
|
||||
const z = q.z
|
||||
|
||||
return Qt.matrix4x4(
|
||||
w*w + x*x - y*y - z*z, 2*(x*y - w*z), 2*(w*y + x*z), 0,
|
||||
2*(x*y + w*z), w*w - x*x + y*y - z*z, 2*(y*z - w*x), 0,
|
||||
2*(x*z - w*y), 2*(w*x + y*z), w*w - x*x - y*y + z*z, 0,
|
||||
0, 0, 0, 1
|
||||
)
|
||||
}
|
||||
|
||||
/***** GENERIC MATRIX TRANSFORMATIONS *****/
|
||||
|
||||
function pointFromWorldToScreen(point, camera, windowSize) {
|
||||
// Transform the point from World Coord to Normalized Device Coord
|
||||
const viewMatrix = camera.transform.matrix.inverted()
|
||||
const projectedPoint = camera.projectionMatrix.times(viewMatrix.times(point))
|
||||
const projectedPoint2D = Qt.vector2d(projectedPoint.x/projectedPoint.w, projectedPoint.y/projectedPoint.w)
|
||||
|
||||
// Transform the point from Normalized Device Coord to Screen Coord
|
||||
const screenPoint2D = Qt.vector2d(
|
||||
parseInt((projectedPoint2D.x + 1) * windowSize.width / 2),
|
||||
parseInt((projectedPoint2D.y - 1) * windowSize.height / -2)
|
||||
)
|
||||
|
||||
return screenPoint2D
|
||||
}
|
||||
|
||||
function decomposeModelMatrixFromTransformations(translation, rotation, scale3D) {
|
||||
const posMat = Qt.matrix4x4()
|
||||
posMat.translate(translation)
|
||||
const rotMat = quaternionToRotationMatrix(rotation)
|
||||
const scaleMat = Qt.matrix4x4()
|
||||
scaleMat.scale(scale3D)
|
||||
|
||||
const rotQuat = Qt.quaternion(rotation.scalar, rotation.x, rotation.y, rotation.z)
|
||||
|
||||
return { positionMat: posMat, rotationMat: rotMat, scaleMat: scaleMat, quaternion: rotQuat }
|
||||
}
|
||||
|
||||
function decomposeModelMatrixFromTransform(transformQtInstance) {
|
||||
return decomposeModelMatrixFromTransformations(transformQtInstance.translation, transformQtInstance.rotation, transformQtInstance.scale3D)
|
||||
}
|
||||
|
||||
function localTranslate(transformQtInstance, initialDecomposedModelMat, translateVec) {
|
||||
// Compute the translation transformation matrix
|
||||
const translationMat = Qt.matrix4x4()
|
||||
translationMat.translate(translateVec)
|
||||
|
||||
// Compute the new model matrix (POSITION * ROTATION * TRANSLATE * SCALE) and set it to the Transform
|
||||
const mat = initialDecomposedModelMat.positionMat.times(initialDecomposedModelMat.rotationMat.times(translationMat.times(initialDecomposedModelMat.scaleMat)))
|
||||
transformQtInstance.setMatrix(mat)
|
||||
}
|
||||
|
||||
function localRotate(transformQtInstance, initialDecomposedModelMat, axis, degree) {
|
||||
// Compute the transformation quaternion from axis and angle in degrees
|
||||
const transformQuat = quaternionFromAxisAngle(axis, degree)
|
||||
|
||||
// Get rotation quaternion of the current model matrix
|
||||
const initRotQuat = initialDecomposedModelMat.quaternion
|
||||
// Compute the new rotation quaternion and then calculate the matrix
|
||||
const newRotQuat = multiplyQuaternion(initRotQuat, transformQuat) // Order is important
|
||||
const newRotationMat = quaternionToRotationMatrix(newRotQuat)
|
||||
|
||||
// Compute the new model matrix (POSITION * NEW_COMPUTED_ROTATION * SCALE) and set it to the Transform
|
||||
const mat = initialDecomposedModelMat.positionMat.times(newRotationMat.times(initialDecomposedModelMat.scaleMat))
|
||||
transformQtInstance.setMatrix(mat)
|
||||
}
|
||||
|
||||
function localScale(transformQtInstance, initialDecomposedModelMat, scaleVec) {
|
||||
// Make a copy of the scale matrix (otherwise, it is a reference and it does not work as expected)
|
||||
// Unfortunately, we have to proceed like this because, in QML, Qt.matrix4x4(Qt.matrix4x4) does not work
|
||||
const scaleMat = Qt.matrix4x4()
|
||||
scaleMat.scale(Qt.vector3d(initialDecomposedModelMat.scaleMat.m11, initialDecomposedModelMat.scaleMat.m22, initialDecomposedModelMat.scaleMat.m33))
|
||||
|
||||
// Update the scale matrix copy
|
||||
scaleMat.m11 += scaleVec.x
|
||||
scaleMat.m22 += scaleVec.y
|
||||
scaleMat.m33 += scaleVec.z
|
||||
|
||||
// Compute the new model matrix (POSITION * ROTATION * SCALE) and set it to the Transform
|
||||
const mat = initialDecomposedModelMat.positionMat.times(initialDecomposedModelMat.rotationMat.times(scaleMat))
|
||||
transformQtInstance.setMatrix(mat)
|
||||
}
|
||||
|
||||
/***** SPECIFIC MATRIX TRANSFORMATIONS (using local vars) *****/
|
||||
|
||||
function doTranslation(initialDecomposedModelMat, translateVec) {
|
||||
localTranslate(gizmoDisplayTransform, initialDecomposedModelMat, translateVec) // Update gizmo matrix
|
||||
localTranslate(objectTransform, initialDecomposedModelMat, translateVec) // Update object matrix
|
||||
}
|
||||
|
||||
function doRotation(initialDecomposedModelMat, axis, degree) {
|
||||
localRotate(gizmoDisplayTransform, initialDecomposedModelMat, axis, degree) // Update gizmo matrix
|
||||
localRotate(objectTransform, initialDecomposedModelMat, axis, degree) // Update object matrix
|
||||
}
|
||||
|
||||
function doScale(initialDecomposedModelMat, scaleVec) {
|
||||
localScale(objectTransform, initialDecomposedModelMat, scaleVec) // Update object matrix
|
||||
function doRelativeScale(initialModelMatrix, scaleVec) {
|
||||
Transformations3DHelper.relativeLocalScale(objectTransform, initialModelMatrix.position, initialModelMatrix.rotation, initialModelMatrix.scale, scaleVec) // Update object matrix
|
||||
}
|
||||
|
||||
function resetTranslation() {
|
||||
|
@ -225,8 +104,8 @@ Entity {
|
|||
// 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 screenPoint2D = Transformations3DHelper.pointFromWorldToScreen(gizmoLocalPointOnAxis, camera, windowSize)
|
||||
const screenCenter2D = Transformations3DHelper.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
|
||||
|
@ -234,7 +113,7 @@ Entity {
|
|||
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
|
||||
if (offset) doRelativeTranslation(objectPicker.modelMatrix, pickedAxis.times(offset)) // Do a translation from the initial Object Model Matrix when we picked the gizmo
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -242,7 +121,7 @@ Entity {
|
|||
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)
|
||||
const screenCenter2D = Transformations3DHelper.pointFromWorldToScreen(gizmoCenterPoint, camera, root.windowSize)
|
||||
|
||||
// Get the vector screenCenter2D -> PickedPoint
|
||||
const originalVector = Qt.vector2d(objectPicker.screenPoint.x - screenCenter2D.x, -(objectPicker.screenPoint.y - screenCenter2D.y))
|
||||
|
@ -258,7 +137,7 @@ Entity {
|
|||
const gizmoToCameraVector = camera.position.toVector4d().minus(gizmoCenterPoint)
|
||||
const orientation = gizmoLocalAxisVector.dotProduct(gizmoToCameraVector) > 0 ? 1 : -1
|
||||
|
||||
if (angle !== 0) doRotation(objectPicker.decomposedObjectModelMat, pickedAxis, angle*orientation)
|
||||
if (angle !== 0) doRelativeRotation(objectPicker.modelMatrix, pickedAxis, angle*orientation)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -267,7 +146,7 @@ Entity {
|
|||
|
||||
// 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)
|
||||
const screenCenter2D = Transformations3DHelper.pointFromWorldToScreen(gizmoCenterPoint, camera, root.windowSize)
|
||||
|
||||
// Compute the scale unit
|
||||
const scaleUnit = screenCenter2D.minus(Qt.vector2d(objectPicker.screenPoint.x, objectPicker.screenPoint.y)).length()
|
||||
|
@ -277,7 +156,7 @@ 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) doScale(objectPicker.decomposedObjectModelMat, pickedAxis.times(offset))
|
||||
if (offset) doRelativeScale(objectPicker.modelMatrix, pickedAxis.times(offset))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -450,7 +329,7 @@ Entity {
|
|||
gizmoType: TransformGizmo.Type.SCALE
|
||||
|
||||
onPickedChanged: {
|
||||
this.decomposedObjectModelMat = decomposeModelMatrixFromTransformations(objectTransform.translation, objectTransform.rotation, objectTransform.scale3D) // Save the current transformations
|
||||
this.modelMatrix = Transformations3DHelper.modelMatrixToMatrices(objectTransform.matrix) // Save the current transformations
|
||||
root.pickedChanged(picker.isPressed) // Used to prevent camera transformations
|
||||
}
|
||||
}
|
||||
|
@ -509,7 +388,8 @@ Entity {
|
|||
gizmoType: TransformGizmo.Type.POSITION
|
||||
|
||||
onPickedChanged: {
|
||||
this.decomposedObjectModelMat = decomposeModelMatrixFromTransformations(objectTransform.translation, objectTransform.rotation, objectTransform.scale3D) // Save the current transformations
|
||||
// this.modelMatrix = copyMatrix(objectTransform.matrix) // Save the current transformations
|
||||
this.modelMatrix = Transformations3DHelper.modelMatrixToMatrices(objectTransform.matrix) // Save the current transformations
|
||||
root.pickedChanged(picker.isPressed) // Used to prevent camera transformations
|
||||
}
|
||||
}
|
||||
|
@ -554,7 +434,7 @@ Entity {
|
|||
gizmoType: TransformGizmo.Type.ROTATION
|
||||
|
||||
onPickedChanged: {
|
||||
this.decomposedObjectModelMat = decomposeModelMatrixFromTransformations(objectTransform.translation, objectTransform.rotation, objectTransform.scale3D) // Save the current transformations
|
||||
this.modelMatrix = Transformations3DHelper.modelMatrixToMatrices(objectTransform.matrix) // Save the current transformations
|
||||
root.pickedChanged(picker.isPressed) // Used to prevent camera transformations
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ ObjectPicker {
|
|||
property int gizmoAxis
|
||||
property int gizmoType
|
||||
property point screenPoint
|
||||
property var decomposedObjectModelMat
|
||||
property var modelMatrix
|
||||
|
||||
signal pickedChanged(var picker)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue