diff --git a/kwin/src/breezydesktopeffect.cpp b/kwin/src/breezydesktopeffect.cpp index 32bc474..c74783c 100644 --- a/kwin/src/breezydesktopeffect.cpp +++ b/kwin/src/breezydesktopeffect.cpp @@ -202,6 +202,10 @@ QColor BreezyDesktopEffect::backgroundColor() const { return QColor(Qt::black); } +bool BreezyDesktopEffect::imuResetState() const { + return m_imuResetState; +} + QList BreezyDesktopEffect::imuRotations() const { return m_imuRotations; } @@ -310,14 +314,7 @@ void BreezyDesktopEffect::updateImuRotation() { float imuData[4 * DataView::IMU_QUAT_ENTRIES]; // 4 quaternion-sized rows memcpy(imuData, data + DataView::IMU_QUAT_DATA[DataView::OFFSET_INDEX], sizeof(imuData)); - const bool imuResetState = (imuData[0] == 0.0f && imuData[1] == 0.0f && imuData[2] == 0.0f && imuData[3] == 1.0f); - if (imuResetState) { - if (isRunning()) { - qCCritical(KWIN_XR) << "\t\t\tBreezy - deactivate due to reset state"; - deactivate(); - } - return; - } + m_imuResetState = (imuData[0] == 0.0f && imuData[1] == 0.0f && imuData[2] == 0.0f && imuData[3] == 1.0f); // convert NWU to EUS by passing root.rotation values: -y, z, -x QQuaternion quatT0(imuData[3], -imuData[1], imuData[2], -imuData[0]); @@ -326,7 +323,9 @@ void BreezyDesktopEffect::updateImuRotation() { QQuaternion quatT1(imuData[imuDataOffset + 3], -imuData[imuDataOffset + 1], imuData[imuDataOffset + 2], -imuData[imuDataOffset + 0]); imuDataOffset += DataView::IMU_QUAT_ENTRIES; + // skip the 3rd quaternion + imuDataOffset += DataView::IMU_QUAT_ENTRIES; // set imuRotations to the last two rotations, leave out the elapsed time m_imuRotations.clear(); @@ -335,7 +334,6 @@ void BreezyDesktopEffect::updateImuRotation() { // 4th row isn't actually a quaternion, it contains the timestamps for each of the 3 quaternions // elapsed time between T0 and T1 is: imuData[0] - imuData[1] - imuDataOffset += DataView::IMU_QUAT_ENTRIES; m_imuTimeElapsedMs = static_cast(imuData[imuDataOffset + 0] - imuData[imuDataOffset + 1]); m_imuTimestamp = imuDateMs; diff --git a/kwin/src/breezydesktopeffect.h b/kwin/src/breezydesktopeffect.h index 338cf5e..1867413 100644 --- a/kwin/src/breezydesktopeffect.h +++ b/kwin/src/breezydesktopeffect.h @@ -18,6 +18,7 @@ namespace KWin Q_PROPERTY(qreal distanceFactor READ distanceFactor NOTIFY distanceFactorChanged) Q_PROPERTY(BackgroundMode backgroundMode READ backgroundMode NOTIFY backgroundModeChanged) Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY backgroundColorChanged) + Q_PROPERTY(bool imuResetState READ imuResetState NOTIFY imuRotationsChanged) Q_PROPERTY(QList imuRotations READ imuRotations NOTIFY imuRotationsChanged) Q_PROPERTY(quint32 imuTimeElapsedMs READ imuTimeElapsedMs NOTIFY imuRotationsChanged) Q_PROPERTY(quint64 imuTimestamp READ imuTimestamp NOTIFY imuRotationsChanged) @@ -52,6 +53,7 @@ namespace KWin QString cursorImageSource() const; QPointF cursorPos() const; + bool imuResetState() const; QList lookAheadConfig() const; QList displayResolution() const; qreal diagonalFOV() const; @@ -99,6 +101,7 @@ namespace KWin QList m_touchBorderActivate; QString m_cursorImageSource; + bool m_imuResetState; QList m_imuRotations; quint32 m_imuTimeElapsedMs; quint64 m_imuTimestamp; diff --git a/kwin/src/qml/BreezyDesktop.qml b/kwin/src/qml/BreezyDesktop.qml index 2387eef..71f1ebc 100644 --- a/kwin/src/qml/BreezyDesktop.qml +++ b/kwin/src/qml/BreezyDesktop.qml @@ -16,10 +16,15 @@ Node { "Rokid Air" ] - required property real viewportFOVHorizontal - required property real viewportWidth - required property real viewportHeight - property real distance: viewportWidth / (2 * Math.tan(Math.PI * viewportFOVHorizontal / 360)) + property real viewportDiagonalFOV: effect.diagonalFOV + property var viewportResolution: effect.displayResolution + property real viewportHorizontalFOV: { + const aspectRatio = viewportResolution[0] / viewportResolution[1]; + return viewportDiagonalFOV * aspectRatio / Math.sqrt(aspectRatio * aspectRatio + 1); + } + property real viewportCenterRadius: { + return viewportResolution[0] / (2 * Math.tan(Math.PI * viewportHorizontalFOV / 360)) + } property var screens: KWinComponents.Workspace.screens // .filter(function(screen) { // return supportedModels.includes(screen.model); @@ -36,7 +41,7 @@ Node { xMax = Math.max(xMax, geometry.x + geometry.width); } - return (xMin + xMax) / 2 - (viewportWidth / 2); + return (xMin + xMax) / 2 - (viewportResolution[0] / 2); } // y value for placing the viewport in the middle of all screens @@ -50,7 +55,7 @@ Node { yMax = Math.max(yMax, geometry.y + geometry.height); } - return (yMin + yMax) / 2 - (viewportHeight / 2); + return (yMin + yMax) / 2 - (viewportResolution[1] / 2); } Repeater3D { @@ -60,24 +65,26 @@ Node { property real screenRotation: { const geometry = screen.geometry; - const rot = (viewportFOVHorizontal / viewportWidth) * (geometry.x - screensXMid); - console.log(`\t\t\tBreezy - screenRotation ${geometry.x} ${geometry.width} ${rot}`); + const rot = (viewportHorizontalFOV / viewportResolution[0]) * (geometry.x - screensXMid); return -rot; } property vector3d screenScale: { const geometry = screen.geometry; + + // apparently the default model unit size is 100x100, so we scale it up to the screen size return Qt.vector3d(geometry.width / 100, geometry.height / 100, 1); } scale: screenScale eulerRotation.y: screenRotation - position: { - console.log(`\t\t\tBreezy - position ${distance} ${screenRotation}`); + position: { + // rotate about the Y (up) axis, to create a horizontal movement const transform = Qt.matrix4x4(); transform.rotate(screenRotation, Qt.vector3d(0, 1, 0)); - const position = Qt.vector3d(0, 0, -distance); - return transform.times(position).minus(position); + + // camera looks along the negative Z axis + return transform.times(Qt.vector3d(0, 0, -viewportCenterRadius)); } } } diff --git a/kwin/src/qml/CameraController.qml b/kwin/src/qml/CameraController.qml index b29f5ce..a2329ad 100644 --- a/kwin/src/qml/CameraController.qml +++ b/kwin/src/qml/CameraController.qml @@ -6,7 +6,6 @@ Item { required property Camera camera - property real radius: 2000 property var imuRotations: effect.imuRotations property int imuTimeElapsedMs: effect.imuTimeElapsedMs property double imuTimestamp: effect.imuTimestamp @@ -22,12 +21,6 @@ Item { implicitHeight: parent.height function updateCamera(rotation) { - const theta = 90 * Math.PI / 180; - const phi = 0.0; - - camera.position = Qt.vector3d(radius * Math.sin(phi) * Math.sin(theta), - radius * Math.cos(theta), - radius * Math.cos(phi) * Math.sin(theta)); camera.eulerRotation = rotation; } @@ -62,10 +55,8 @@ Item { function updateFOV() { const aspectRatio = displayResolution[0] / displayResolution[1]; camera.fieldOfView = 2 * Math.atan(Math.tan(diagonalFOV * Math.PI / 360) / Math.sqrt(1 + aspectRatio * aspectRatio)) * 180 / Math.PI; - radius = 0.5 * displayResolution[1] / Math.tan(camera.fieldOfView * Math.PI / 360); } - onRadiusChanged: updateCamera(camera.eulerRotation); onDisplayResolutionChanged: updateFOV(); onDiagonalFOVChanged: updateFOV(); diff --git a/kwin/src/qml/main.qml b/kwin/src/qml/main.qml index 9648c78..4c60e3d 100644 --- a/kwin/src/qml/main.qml +++ b/kwin/src/qml/main.qml @@ -23,39 +23,23 @@ Item { View3D { id: view anchors.fill: parent + environment: SceneEnvironment { + antialiasingMode: SceneEnvironment.MSAA + } PerspectiveCamera { id: camera - fieldOfView: 22.55 + frustumCullingEnabled: false } BreezyDesktop { id: breezyDesktop - viewportFOVHorizontal: 40.09 - viewportWidth: 1920 - viewportHeight: 1080 } CameraController { id: cameraController anchors.fill: parent camera: camera - radius: 0.5 * breezyDesktop.viewportHeight / Math.tan(camera.fieldOfView * Math.PI / 360) - - Behavior on rotation { - enabled: !cameraController.busy && root.animationEnabled - QuaternionAnimation { - id: rotationAnimation - duration: effect.animationDuration - easing.type: Easing.OutCubic - } - } - Behavior on radius { - NumberAnimation { - duration: effect.animationDuration - easing.type: Easing.OutCubic - } - } } }