Multiple screens working, but filter down to just glasses for now
Attempt to stop input capture
This commit is contained in:
parent
021b0f4cc0
commit
f691d156b6
|
|
@ -8,30 +8,78 @@ import QtQuick
|
||||||
import QtQuick3D
|
import QtQuick3D
|
||||||
import org.kde.kwin as KWinComponents
|
import org.kde.kwin as KWinComponents
|
||||||
|
|
||||||
|
|
||||||
Node {
|
Node {
|
||||||
id: cube
|
id: cube
|
||||||
|
|
||||||
|
readonly property var supportedModels: [
|
||||||
|
"VITURE",
|
||||||
|
"nreal air",
|
||||||
|
"Air",
|
||||||
|
"Air 2",
|
||||||
|
"Air 2 Pro",
|
||||||
|
"Air 2 Ultra",
|
||||||
|
"SmartGlasses", // TCL/RayNeo
|
||||||
|
"Rokid Max",
|
||||||
|
"Rokid Air"
|
||||||
|
]
|
||||||
|
|
||||||
required property real viewportFOVHorizontal
|
required property real viewportFOVHorizontal
|
||||||
required property real viewportWidth
|
required property real viewportWidth
|
||||||
required property real viewportHeight
|
required property real viewportHeight
|
||||||
property real distance: viewportWidth / (2 * Math.tan(Math.PI * viewportFOVHorizontal / 360))
|
property real distance: viewportWidth / (2 * Math.tan(Math.PI * viewportFOVHorizontal / 360))
|
||||||
|
property var screens: KWinComponents.Workspace.screens.filter(function(screen) {
|
||||||
|
return supportedModels.includes(screen.model);
|
||||||
|
})
|
||||||
|
|
||||||
|
// x value for placing the viewport in the middle of all screens
|
||||||
|
property real screensXMid: {
|
||||||
|
let xMin = Number.MAX_VALUE;
|
||||||
|
let xMax = Number.MIN_VALUE;
|
||||||
|
|
||||||
|
for (let i = 0; i < screens.length; i++) {
|
||||||
|
const geometry = screens[i].geometry;
|
||||||
|
xMin = Math.min(xMin, geometry.x);
|
||||||
|
xMax = Math.max(xMax, geometry.x + geometry.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (xMin + xMax) / 2 - (viewportWidth / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// y value for placing the viewport in the middle of all screens
|
||||||
|
property real screensYMid: {
|
||||||
|
let yMin = Number.MAX_VALUE;
|
||||||
|
let yMax = Number.MIN_VALUE;
|
||||||
|
|
||||||
|
for (let i = 0; i < screens.length; i++) {
|
||||||
|
const geometry = screens[i].geometry;
|
||||||
|
yMin = Math.min(yMin, geometry.y);
|
||||||
|
yMax = Math.max(yMax, geometry.y + geometry.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (yMin + yMax) / 2 - (viewportHeight / 2);
|
||||||
|
}
|
||||||
|
|
||||||
Repeater3D {
|
Repeater3D {
|
||||||
id: faceRepeater
|
id: faceRepeater
|
||||||
model: KWinComponents.Workspace.screens.length
|
model: screens.length
|
||||||
delegate: CubeFace {
|
delegate: CubeFace {
|
||||||
screen: KWinComponents.Workspace.screens[index]
|
screen: screens[index]
|
||||||
|
|
||||||
property real screenRotation: {
|
property real screenRotation: {
|
||||||
const geometry = screen.geometry;
|
const geometry = screen.geometry;
|
||||||
const rot = (viewportFOVHorizontal / viewportWidth) * geometry.x
|
const rot = (viewportFOVHorizontal / viewportWidth) * (geometry.x - screensXMid);
|
||||||
console.log(`\t\t\tBreezy - screenRotation ${geometry.x} ${geometry.width} ${rot}`);
|
console.log(`\t\t\tBreezy - screenRotation ${geometry.x} ${geometry.width} ${rot}`);
|
||||||
return -rot;
|
return -rot;
|
||||||
}
|
}
|
||||||
|
|
||||||
scale: Qt.vector3d(viewportWidth / 100, viewportHeight / 100, 1)
|
property vector3d screenScale: {
|
||||||
|
const geometry = screen.geometry;
|
||||||
|
return Qt.vector3d(geometry.width / 100, geometry.height / 100, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
scale: screenScale
|
||||||
eulerRotation.y: screenRotation
|
eulerRotation.y: screenRotation
|
||||||
|
|
||||||
position: {
|
position: {
|
||||||
console.log(`\t\t\tBreezy - position ${distance} ${screenRotation}`);
|
console.log(`\t\t\tBreezy - position ${distance} ${screenRotation}`);
|
||||||
const transform = Qt.matrix4x4();
|
const transform = Qt.matrix4x4();
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,6 @@ import QtQuick3D
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property bool busy: status.useMouse
|
|
||||||
|
|
||||||
required property Camera camera
|
required property Camera camera
|
||||||
|
|
||||||
property quaternion rotation: Quaternion.fromEulerAngles(0, 0, 0)
|
property quaternion rotation: Quaternion.fromEulerAngles(0, 0, 0)
|
||||||
|
|
@ -21,67 +19,12 @@ Item {
|
||||||
property real xSpeed: 0.1
|
property real xSpeed: 0.1
|
||||||
property real ySpeed: 0.1
|
property real ySpeed: 0.1
|
||||||
|
|
||||||
property bool xInvert: false
|
|
||||||
property bool yInvert: false
|
|
||||||
|
|
||||||
implicitWidth: parent.width
|
implicitWidth: parent.width
|
||||||
implicitHeight: parent.height
|
implicitHeight: parent.height
|
||||||
|
|
||||||
onRotationChanged: root.updateCamera();
|
onRotationChanged: root.updateCamera();
|
||||||
onRadiusChanged: root.updateCamera();
|
onRadiusChanged: root.updateCamera();
|
||||||
|
|
||||||
DragHandler {
|
|
||||||
id: dragHandler
|
|
||||||
target: null
|
|
||||||
acceptedModifiers: Qt.NoModifier
|
|
||||||
onCentroidChanged: {
|
|
||||||
mouseMoved(Qt.vector2d(centroid.position.x, centroid.position.y), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
onActiveChanged: {
|
|
||||||
if (active) {
|
|
||||||
mousePressed(Qt.vector2d(centroid.position.x, centroid.position.y));
|
|
||||||
} else {
|
|
||||||
mouseReleased(Qt.vector2d(centroid.position.x, centroid.position.y));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WheelHandler {
|
|
||||||
id: wheelHandler
|
|
||||||
orientation: Qt.Vertical
|
|
||||||
target: null
|
|
||||||
onWheel: event => {
|
|
||||||
let delta = -event.angleDelta.y * 0.01;
|
|
||||||
root.radius += root.radius * 0.1 * delta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: root.forceActiveFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
function mousePressed(newPos) {
|
|
||||||
root.forceActiveFocus()
|
|
||||||
status.currentPos = newPos
|
|
||||||
status.lastPos = newPos
|
|
||||||
status.useMouse = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mouseReleased(newPos) {
|
|
||||||
status.useMouse = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mouseMoved(newPos: vector2d) {
|
|
||||||
status.currentPos = newPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
function processInputs() {
|
|
||||||
if (root.busy) {
|
|
||||||
status.processInput();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateCamera() {
|
function updateCamera() {
|
||||||
// convert NWU to EUS by passing root.rotation values: w, -y, z, -x
|
// convert NWU to EUS by passing root.rotation values: w, -y, z, -x
|
||||||
let effectiveRotation = Qt.quaternion(root.rotation.scalar, -root.rotation.y, root.rotation.z, -root.rotation.x);
|
let effectiveRotation = Qt.quaternion(root.rotation.scalar, -root.rotation.y, root.rotation.z, -root.rotation.x);
|
||||||
|
|
@ -107,50 +50,6 @@ Item {
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (useXrRotation && xrRotation.length() > 0) {
|
if (useXrRotation && xrRotation.length() > 0) {
|
||||||
root.rotation = xrRotation;
|
root.rotation = xrRotation;
|
||||||
} else if (root.busy) {
|
|
||||||
processInputs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: status
|
|
||||||
|
|
||||||
property bool useMouse: false
|
|
||||||
|
|
||||||
property real minElevation: -30
|
|
||||||
property real maxElevation: 30
|
|
||||||
|
|
||||||
property vector2d lastPos: Qt.vector2d(0, 0)
|
|
||||||
property vector2d currentPos: Qt.vector2d(0, 0)
|
|
||||||
|
|
||||||
function processInput() {
|
|
||||||
if (useMouse) {
|
|
||||||
const eulerRotation = root.rotation.toEulerAngles();
|
|
||||||
|
|
||||||
const pixelDelta = Qt.vector2d(lastPos.x - currentPos.x,
|
|
||||||
lastPos.y - currentPos.y);
|
|
||||||
lastPos = currentPos;
|
|
||||||
|
|
||||||
let azimuthDelta = pixelDelta.x * xSpeed
|
|
||||||
if (xInvert) {
|
|
||||||
azimuthDelta = -azimuthDelta;
|
|
||||||
}
|
|
||||||
let azimuth = (eulerRotation.y + azimuthDelta) % 360;
|
|
||||||
|
|
||||||
let elevationDelta = pixelDelta.y * ySpeed
|
|
||||||
if (yInvert) {
|
|
||||||
elevationDelta = -elevationDelta;
|
|
||||||
}
|
|
||||||
|
|
||||||
let elevation = eulerRotation.x + elevationDelta;
|
|
||||||
if (elevation < minElevation) {
|
|
||||||
elevation = minElevation;
|
|
||||||
} else if (elevation > maxElevation) {
|
|
||||||
elevation = maxElevation;
|
|
||||||
}
|
|
||||||
|
|
||||||
root.rotation = Quaternion.fromEulerAngles(elevation, azimuth, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import org.kde.kwin.effect.cube
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
antialiasing: true
|
||||||
focus: true
|
focus: true
|
||||||
|
|
||||||
required property QtObject effect
|
required property QtObject effect
|
||||||
|
|
@ -19,14 +20,10 @@ Item {
|
||||||
property bool animationEnabled: false
|
property bool animationEnabled: false
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
cameraController.rotateTo(KWinComponents.Workspace.currentDesktop);
|
|
||||||
root.animationEnabled = true;
|
root.animationEnabled = true;
|
||||||
cameraController.state = "distant";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function stop() {
|
function stop() {
|
||||||
cameraController.rotateTo(KWinComponents.Workspace.currentDesktop);
|
|
||||||
cameraController.state = "close";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchToSelected() {
|
function switchToSelected() {
|
||||||
|
|
@ -84,27 +81,8 @@ Item {
|
||||||
CubeCameraController {
|
CubeCameraController {
|
||||||
id: cameraController
|
id: cameraController
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
state: "close"
|
|
||||||
camera: camera
|
camera: camera
|
||||||
xInvert: effect.mouseInvertedX
|
radius: 0.5 * cube.viewportHeight / Math.tan(camera.fieldOfView * Math.PI / 360)
|
||||||
yInvert: effect.mouseInvertedY
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "close"
|
|
||||||
PropertyChanges {
|
|
||||||
target: cameraController
|
|
||||||
radius: 0.0 + 0.5 * cube.viewportHeight / Math.tan(0.5 * camera.fieldOfView * Math.PI / 180)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "distant"
|
|
||||||
PropertyChanges {
|
|
||||||
target: cameraController
|
|
||||||
radius: 0.0 * effect.distanceFactor + 0.5 * cube.viewportHeight / Math.tan(0.5 * camera.fieldOfView * Math.PI / 180)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
Behavior on rotation {
|
Behavior on rotation {
|
||||||
enabled: !cameraController.busy && root.animationEnabled
|
enabled: !cameraController.busy && root.animationEnabled
|
||||||
|
|
@ -130,15 +108,5 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: view
|
|
||||||
onClicked: root.switchToSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onEscapePressed: effect.deactivate();
|
|
||||||
Keys.onEnterPressed: root.switchToSelected();
|
|
||||||
Keys.onReturnPressed: root.switchToSelected();
|
|
||||||
Keys.onSpacePressed: root.switchToSelected();
|
|
||||||
|
|
||||||
Component.onCompleted: start();
|
Component.onCompleted: start();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue