mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-08-02 00:08:29 +02:00
[ui] Viewer3D: new Trackball camera manipulator
This commit is contained in:
parent
6836f7fd93
commit
87d5a62846
6 changed files with 148 additions and 24 deletions
|
@ -15,6 +15,9 @@ Entity {
|
|||
property bool moving: pressed || (actionAlt.active && keyboardHandler._pressed)
|
||||
property alias focus: keyboardHandler.focus
|
||||
readonly property bool pickingActive: actionControl.active && keyboardHandler._pressed
|
||||
property real rotationSpeed: 2.0
|
||||
property size windowSize
|
||||
property real trackballSize: 1.0
|
||||
|
||||
readonly property alias pressed: mouseHandler._pressed
|
||||
signal mousePressed(var mouse)
|
||||
|
@ -29,10 +32,20 @@ Entity {
|
|||
MouseHandler {
|
||||
id: mouseHandler
|
||||
property bool _pressed
|
||||
property point lastPosition
|
||||
property point currentPosition
|
||||
sourceDevice: mouseSourceDevice
|
||||
onPressed: { _pressed = true; mousePressed(mouse) }
|
||||
onReleased: { _pressed = false; mouseReleased(mouse) }
|
||||
onPressed: {
|
||||
_pressed = true;
|
||||
currentPosition = lastPosition = Qt.point(mouse.x, mouse.y);
|
||||
mousePressed(mouse);
|
||||
}
|
||||
onReleased: {
|
||||
_pressed = false;
|
||||
mouseReleased(mouse);
|
||||
}
|
||||
onClicked: mouseClicked(mouse)
|
||||
onPositionChanged: { currentPosition = Qt.point(mouse.x, mouse.y) }
|
||||
onDoubleClicked: mouseDoubleClicked(mouse)
|
||||
onWheel: {
|
||||
var d = (root.camera.viewCenter.minus(root.camera.position)).length() * 0.2;
|
||||
|
@ -135,6 +148,36 @@ Entity {
|
|||
]
|
||||
}
|
||||
|
||||
// Based on the C++ version from https://github.com/cjmdaixi/Qt3DTrackball
|
||||
function projectToTrackball(screenCoords)
|
||||
{
|
||||
var sx = screenCoords.x, sy = windowSize.height - screenCoords.y;
|
||||
var p2d = Qt.vector2d(sx / windowSize.width - 0.5, sy / windowSize.height - 0.5);
|
||||
var z = 0.0;
|
||||
var r2 = trackballSize * trackballSize;
|
||||
var lengthSquared = p2d.length() * p2d.length();
|
||||
if(lengthSquared <= r2 * 0.5)
|
||||
z = Math.sqrt(r2 - lengthSquared);
|
||||
else
|
||||
z = r2 * 0.5 / p2d.length();
|
||||
return Qt.vector3d(p2d.x, p2d.y, z);
|
||||
}
|
||||
|
||||
function clamp(x)
|
||||
{
|
||||
return Math.max(-1, Math.min(x, 1));
|
||||
}
|
||||
|
||||
function createRotation(firstPoint, nextPoint)
|
||||
{
|
||||
var lastPos3D = projectToTrackball(firstPoint).normalized();
|
||||
var currentPos3D = projectToTrackball(nextPoint).normalized();
|
||||
var obj = {};
|
||||
obj.angle = Math.acos(clamp(currentPos3D.dotProduct(lastPos3D)));
|
||||
obj.dir = currentPos3D.crossProduct(lastPos3D);
|
||||
return obj;
|
||||
}
|
||||
|
||||
components: [
|
||||
FrameAction {
|
||||
onTriggered: {
|
||||
|
@ -145,11 +188,14 @@ Entity {
|
|||
root.camera.translate(Qt.vector3d(-tx, -ty, 0).times(dt))
|
||||
return;
|
||||
}
|
||||
if(actionLMB.active) { // rotate
|
||||
var rx = -axisMX.value;
|
||||
var ry = -axisMY.value;
|
||||
root.camera.panAboutViewCenter(root.panSpeed * rx * dt, Qt.vector3d(0,1,0))
|
||||
root.camera.tiltAboutViewCenter(root.tiltSpeed * ry * dt)
|
||||
if(actionLMB.active){ // trackball rotation
|
||||
var res = createRotation(mouseHandler.lastPosition, mouseHandler.currentPosition);
|
||||
var transform = root.camera.components[1]; // transform is camera first component
|
||||
var currentRotation = transform.rotation;
|
||||
var rotatedAxis = Scene3DHelper.rotatedVector(transform.rotation, res.dir);
|
||||
res.angle *= rotationSpeed * dt;
|
||||
root.camera.rotateAboutViewCenter(transform.fromAxisAndAngle(rotatedAxis, res.angle * Math.PI * 180));
|
||||
mouseHandler.lastPosition = mouseHandler.currentPosition;
|
||||
return;
|
||||
}
|
||||
if(actionAlt.active && actionRMB.active) { // zoom with alt + RMD
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue