diff options
Diffstat (limited to 'tests/manual/qardboard')
18 files changed, 885 insertions, 0 deletions
diff --git a/tests/manual/qardboard/CMakeLists.txt b/tests/manual/qardboard/CMakeLists.txt new file mode 100644 index 000000000..c03fb413f --- /dev/null +++ b/tests/manual/qardboard/CMakeLists.txt @@ -0,0 +1,90 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(qardboard LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}") + +find_package(Qt6 REQUIRED COMPONENTS 3DCore 3DExtras 3DInput 3DQuick 3DQuickExtras 3DRender Core Gui Qml Quick) + +qt_add_executable(qardboard + abstractdeviceorientation.cpp abstractdeviceorientation.h + dummydeviceorientation.cpp dummydeviceorientation.h + main.cpp +) + +set_target_properties(qardboard PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(qardboard PUBLIC + Qt::3DCore + Qt::3DExtras + Qt::3DInput + Qt::3DQuick + Qt::3DQuickExtras + Qt::3DRender + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +# Resources: +set(resources_resource_files + "PlacedEntity.qml" + "QardboardCamera.qml" + "QardboardFrameGraph.qml" + "QardboardRootEntity.qml" + "QardboardScene3D.qml" + "main.qml" +) + +qt6_add_resources(qardboard "resources" + PREFIX + "/" + FILES + ${resources_resource_files} +) + +set(obj_resource_files + "../exampleresources/assets/obj/ball.obj" + "../exampleresources/assets/obj/material-sphere.obj" + "../exampleresources/assets/obj/plane-10x10.obj" + "../exampleresources/assets/obj/toyplane.obj" + "../exampleresources/assets/obj/trefoil.obj" +) + +qt6_add_resources(qardboard "obj" + PREFIX + "/" + BASE + "../exampleresources" + FILES + ${obj_resource_files} +) + +if(IOS) + target_sources(qardboard PUBLIC + iosdeviceorientation.h iosdeviceorientation.mm iosdeviceorientation_p.h iosdeviceorientation_p.mm + ) + + target_link_libraries(qardboard PUBLIC + Qt::Sensors + Qt::SensorsPrivate + ) +endif() + +install(TARGETS qardboard + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/tests/manual/qardboard/Info.plist b/tests/manual/qardboard/Info.plist new file mode 100644 index 000000000..26c5fe5e2 --- /dev/null +++ b/tests/manual/qardboard/Info.plist @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleIconFile</key> + <string></string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleGetInfoString</key> + <string>Created by Qt/QMake</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleExecutable</key> + <string>qardboard</string> + <key>CFBundleIdentifier</key> + <string>com.kdab.${PRODUCT_NAME:rfc1034identifier}</string> + <key>CFBundleDisplayName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleVersion</key> + <string>1.0</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> +</dict> +</plist> diff --git a/tests/manual/qardboard/PlacedEntity.qml b/tests/manual/qardboard/PlacedEntity.qml new file mode 100644 index 000000000..075bfd48d --- /dev/null +++ b/tests/manual/qardboard/PlacedEntity.qml @@ -0,0 +1,35 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Extras 2.0 + +Entity { + id: root + property double angle: 0 + property double radius: 10 + property var mesh + property alias color: material.diffuse + property vector3d center: Qt.vector3d(0, 0, 0) + + components: [ + Transform { + id: tr + matrix: { + var ra = 0// (root.angle) * Math.PI / 180 + var m = Qt.matrix4x4() + m.rotate(root.angle, Qt.vector3d(0, 1, 0)) + m.translate(Qt.vector3d(root.center.x + root.radius * Math.sin(ra), root.center.y, root.center.z - root.radius * Math.cos(ra))) + return m + } + } + ] + + Entity { + PhongMaterial { + id: material + } + components: [ material, mesh ] + } +} diff --git a/tests/manual/qardboard/QardboardCamera.qml b/tests/manual/qardboard/QardboardCamera.qml new file mode 100644 index 000000000..f20a18078 --- /dev/null +++ b/tests/manual/qardboard/QardboardCamera.qml @@ -0,0 +1,89 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qardboard 1.0 + +Entity { + id: root + property real convergence: 2000.0 + property real eyeSeparation: 35.0 + property real aspectRatio: _window.width / _window.height + property real fieldOfView: 60.0 + property real nearPlane: 1. + property real farPlane: 1000.0 + + property vector3d position: Qt.vector3d(0.0, 0.0, 0.0) + property vector3d viewDirection: Qt.vector3d(0.0, 0.0, 1.0) + property vector3d viewUp: Qt.vector3d(0.0, 1.0, 0.0) + property alias viewMatrix: eyeTransform.matrix + + readonly property real _fov2: Math.tan(fieldOfView * Math.PI / 180 * 0.5) + readonly property real top: nearPlane * _fov2 + readonly property real a: aspectRatio * _fov2 * convergence + + DeviceOrientation { + id: orientation + enabled: true + } + + CameraLens { + id: leftEyeLens + projectionType: CameraLens.FrustumProjection + nearPlane : root.nearPlane + farPlane : root.farPlane + left: -(a - eyeSeparation * 0.5) * nearPlane / convergence + right: (a + eyeSeparation * 0.5) * nearPlane / convergence + top: root.top + bottom: -root.top + } + + CameraLens { + id: rightEyeLens + projectionType: CameraLens.FrustumProjection + nearPlane : root.nearPlane + farPlane : root.farPlane + left: -(a + eyeSeparation * 0.5) * nearPlane / convergence + right: (a - eyeSeparation * 0.5) * nearPlane / convergence + top: root.top + bottom: -root.top + } + + Transform { + id: eyeTransform + + function computeMatrix(roll, pitch, yaw) { + var n = Qt.matrix4x4() + n.rotate(-roll, Qt.vector3d(1, 0, 0)) + n.rotate(yaw, Qt.vector3d(0, 1, 0)) + var vd = n.times(stereoCamera.viewDirection) + var vu = n.times(stereoCamera.viewUp) + var vc = stereoCamera.position.minus(vd) + + var m = Qt.matrix4x4(); + m.translate(stereoCamera.position) + var zAxis = stereoCamera.position.minus(vc).normalized() + var xAxis = vu.crossProduct(zAxis).normalized(); + var yAxis = zAxis.crossProduct(xAxis); + var r = Qt.matrix4x4(xAxis.x, yAxis.x, zAxis.x, 0, + xAxis.y, yAxis.y, zAxis.y, 0, + xAxis.z, yAxis.z, zAxis.z, 0, + 0, 0, 0, 1) + return m.times(r); + } + + matrix: computeMatrix(orientation.roll, orientation.pitch, orientation.yaw) + } + + components: [ eyeTransform ] + + property Entity leftCamera: Entity { + components: [ leftEyeLens ] + } + + property Entity rightCamera: Entity { + id: rightCameraEntity + components: [ rightEyeLens ] + } +} diff --git a/tests/manual/qardboard/QardboardFrameGraph.qml b/tests/manual/qardboard/QardboardFrameGraph.qml new file mode 100644 index 000000000..9379b949a --- /dev/null +++ b/tests/manual/qardboard/QardboardFrameGraph.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 + +Viewport { + property alias leftCamera: leftCameraSelector.camera + property alias rightCamera: rightCameraSelector.camera + property alias window: surfaceSelector.surface + + RenderSurfaceSelector { + id: surfaceSelector + + // ColorMask is reset by default + // By default reset to the default if not specified + ClearBuffers { + clearColor: "white" + buffers: ClearBuffers.ColorDepthBuffer + NoDraw {} // We just want to clear the buffers + } + + // Draw with left eye + Viewport { + id: leftViewport + normalizedRect: Qt.rect(0, 0, .5, 1) + + CameraSelector { + id: leftCameraSelector + } + } + + // Draw with right eye + Viewport { + id: rightViewport + normalizedRect: Qt.rect(.5, 0, .5, 1) + + CameraSelector { + id: rightCameraSelector + } + } + } +} diff --git a/tests/manual/qardboard/QardboardRootEntity.qml b/tests/manual/qardboard/QardboardRootEntity.qml new file mode 100644 index 000000000..641341073 --- /dev/null +++ b/tests/manual/qardboard/QardboardRootEntity.qml @@ -0,0 +1,33 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Input 2.0 + +Entity { + id: root + property alias fieldOfView: stereoCamera.fieldOfView + property alias cameraPosition: stereoCamera.position + property alias cameraDirection: stereoCamera.viewDirection + property alias headlightDirection: headLight.worldDirection + + components: [ + RenderSettings { + activeFrameGraph: QardboardFrameGraph { + id: stereoFrameGraph + leftCamera: stereoCamera.leftCamera + rightCamera: stereoCamera.rightCamera + } + }, + InputSettings { }, + DirectionalLight { + id: headLight + worldDirection: stereoCamera.viewDirection.times(-1) + } + ] + + QardboardCamera { + id: stereoCamera + } +} diff --git a/tests/manual/qardboard/QardboardScene3D.qml b/tests/manual/qardboard/QardboardScene3D.qml new file mode 100644 index 000000000..827eb4f88 --- /dev/null +++ b/tests/manual/qardboard/QardboardScene3D.qml @@ -0,0 +1,21 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick 2.0 +import QtQuick.Scene3D 2.0 + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.0 + +Scene3D { + id: scene3d + focus: true + aspects: ["input", "logic"] + cameraAspectRatioMode: Scene3D.UserAspectRatio + multisample: true + + QardboardRootEntity { + } +} diff --git a/tests/manual/qardboard/abstractdeviceorientation.cpp b/tests/manual/qardboard/abstractdeviceorientation.cpp new file mode 100644 index 000000000..eefeecddb --- /dev/null +++ b/tests/manual/qardboard/abstractdeviceorientation.cpp @@ -0,0 +1,65 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "abstractdeviceorientation.h" + +#include <QDateTime> +#include <QDebug> +#include <QtMath> +#include <QScreen> + + +AbstractDeviceOrientation::AbstractDeviceOrientation(QObject *parent) + : QObject(parent) + , m_roll(0) + , m_pitch(0) + , m_yaw(0) + , m_enabled(false) +{ +} + +bool AbstractDeviceOrientation::enabled() const +{ + return m_enabled; +} + +void AbstractDeviceOrientation::stop() +{ + if (m_enabled) { + m_enabled = false; + emit enabledChanged(m_enabled); + } +} + +void AbstractDeviceOrientation::setRoll(qreal v) +{ + if (v != m_roll) { + m_roll = v; + emit rollChanged(v); + } +} + +void AbstractDeviceOrientation::setPitch(qreal v) +{ + if (v != m_pitch) { + m_pitch = v; + emit pitchChanged(v); + } +} + +void AbstractDeviceOrientation::setYaw(qreal v) +{ + if (v != m_yaw) { + m_yaw = v; + emit yawChanged(v); + } +} + +void AbstractDeviceOrientation::setEnabled(bool v) +{ + if (v && !m_enabled) { + start(); + } else if (!v && m_enabled) { + stop(); + } +} diff --git a/tests/manual/qardboard/abstractdeviceorientation.h b/tests/manual/qardboard/abstractdeviceorientation.h new file mode 100644 index 000000000..0d1e34063 --- /dev/null +++ b/tests/manual/qardboard/abstractdeviceorientation.h @@ -0,0 +1,49 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef ABSTRACT_DEVICEORIENTATION_H +#define ABSTRACT_DEVICEORIENTATION_H + +#include <QObject> + +class AbstractDeviceOrientation : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal roll READ roll WRITE setRoll NOTIFY rollChanged) + Q_PROPERTY(qreal pitch READ pitch WRITE setPitch NOTIFY pitchChanged) + Q_PROPERTY(qreal yaw READ yaw WRITE setYaw NOTIFY yawChanged) + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + +public: + AbstractDeviceOrientation(QObject* parent = 0); + + qreal roll() const { return m_roll; } + qreal pitch() const { return m_pitch; } + qreal yaw() const { return m_yaw; } + + bool enabled() const; + +signals: + void rollChanged(qreal roll); + void pitchChanged(qreal pitch); + void yawChanged(qreal yaw); + void enabledChanged(bool); + +public slots: + virtual void setRoll(qreal v); + virtual void setPitch(qreal v); + virtual void setYaw(qreal v); + virtual void setEnabled(bool v); + + virtual bool start() = 0; //!< Called to start the sensor services. + virtual void stop(); //!< Called to stop updates from the #CompassClino. + +protected: + qreal m_roll; + qreal m_pitch; + qreal m_yaw; + bool m_enabled; +}; + + +#endif // ABSTRACT_DEVICEORIENTATION_H diff --git a/tests/manual/qardboard/dummydeviceorientation.cpp b/tests/manual/qardboard/dummydeviceorientation.cpp new file mode 100644 index 000000000..313522f46 --- /dev/null +++ b/tests/manual/qardboard/dummydeviceorientation.cpp @@ -0,0 +1,26 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "dummydeviceorientation.h" + +DummyDeviceOrientation::DummyDeviceOrientation(QObject *parent) + : AbstractDeviceOrientation(parent) +{ +} + +bool DummyDeviceOrientation::start() +{ + if (!m_enabled) { + m_enabled = true; + emit enabledChanged(m_enabled); + } + return true; +} + +void DummyDeviceOrientation::stop() +{ + if (m_enabled) { + m_enabled = false; + emit enabledChanged(m_enabled); + } +} diff --git a/tests/manual/qardboard/dummydeviceorientation.h b/tests/manual/qardboard/dummydeviceorientation.h new file mode 100644 index 000000000..5b8c2bdef --- /dev/null +++ b/tests/manual/qardboard/dummydeviceorientation.h @@ -0,0 +1,21 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef DUMMY_DEVICEORIENTATION_H +#define DUMMY_DEVICEORIENTATION_H + +#include "abstractdeviceorientation.h" + +class DummyDeviceOrientation : public AbstractDeviceOrientation +{ + Q_OBJECT +public: + DummyDeviceOrientation(QObject* parent = 0); + +public slots: + bool start() override; + void stop() override; +}; + + +#endif // DUMMY_DEVICEORIENTATION_H diff --git a/tests/manual/qardboard/iosdeviceorientation.h b/tests/manual/qardboard/iosdeviceorientation.h new file mode 100644 index 000000000..756dfd9e1 --- /dev/null +++ b/tests/manual/qardboard/iosdeviceorientation.h @@ -0,0 +1,21 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef IOS_DEVICEORIENTATION_H +#define IOS_DEVICEORIENTATION_H + +#include <abstractdeviceorientation.h> + +class iOSDeviceOrientation : public AbstractDeviceOrientation +{ + Q_OBJECT +public: + iOSDeviceOrientation(QObject* parent = 0); + +public slots: + bool start() override; + void stop() override; +}; + + +#endif // IOS_DEVICEORIENTATION_H diff --git a/tests/manual/qardboard/iosdeviceorientation.mm b/tests/manual/qardboard/iosdeviceorientation.mm new file mode 100644 index 000000000..0ac4e2489 --- /dev/null +++ b/tests/manual/qardboard/iosdeviceorientation.mm @@ -0,0 +1,30 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "iosdeviceorientation.h" +#include "iosdeviceorientation_p.h" + +iOSDeviceOrientation::iOSDeviceOrientation(QObject *parent) + : AbstractDeviceOrientation(parent) +{ + [[iOSDeviceOrientationP instance] setHandler:this]; +} + +bool iOSDeviceOrientation::start() +{ + if (!m_enabled) { + [[iOSDeviceOrientationP instance] start]; + m_enabled = true; + emit enabledChanged(m_enabled); + } + return true; +} + +void iOSDeviceOrientation::stop() +{ + if (m_enabled) { + [[iOSDeviceOrientationP instance] stop]; + m_enabled = false; + emit enabledChanged(m_enabled); + } +} diff --git a/tests/manual/qardboard/iosdeviceorientation_p.h b/tests/manual/qardboard/iosdeviceorientation_p.h new file mode 100644 index 000000000..44c0b99a6 --- /dev/null +++ b/tests/manual/qardboard/iosdeviceorientation_p.h @@ -0,0 +1,16 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#import <Foundation/Foundation.h> +#import <CoreLocation/CoreLocation.h> +#import <CoreMotion/CoreMotion.h> + + +@interface iOSDeviceOrientationP : NSObject <CLLocationManagerDelegate> +@property (readonly) BOOL isActive; + ++ (iOSDeviceOrientationP*)instance; +- (void)setHandler:(iOSDeviceOrientation*) handler; +- (void)start; +- (void)stop; +@end diff --git a/tests/manual/qardboard/iosdeviceorientation_p.mm b/tests/manual/qardboard/iosdeviceorientation_p.mm new file mode 100644 index 000000000..5034db4a6 --- /dev/null +++ b/tests/manual/qardboard/iosdeviceorientation_p.mm @@ -0,0 +1,105 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> + +#include "iosdeviceorientation.h" +#import "iosdeviceorientation_p.h" +#include <QtCore/qmath.h> + +@interface QIOSMotionManager : NSObject { +} + ++ (CMMotionManager *)sharedManager; +@end + +@interface iOSDeviceOrientationP() +{ + BOOL active; + iOSDeviceOrientation* handler; +} + +@property (strong) CMMotionManager *motionManager; +@end + + + +@implementation iOSDeviceOrientationP + +#define kUpdateFrequency 20.0 + + ++ (iOSDeviceOrientationP*)instance +{ + static iOSDeviceOrientationP* _myInstance = 0; + if (0 == _myInstance) + _myInstance = [[iOSDeviceOrientationP alloc] init]; + return _myInstance; +} + +- (id)init +{ + self = [super init]; + if (self) { + self.motionManager = [QIOSMotionManager sharedManager]; // [[CMMotionManager alloc] init]; + self.motionManager.deviceMotionUpdateInterval = 1. / kUpdateFrequency; + + active = FALSE; + } + return self; +} + +- (void)setHandler:(iOSDeviceOrientation*)h +{ + handler = h; +} + +- (BOOL)isActive +{ + return active; +} + +- (void)start +{ + // Motion updates + [self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryCorrectedZVertical + toQueue:[NSOperationQueue currentQueue] + withHandler: ^(CMDeviceMotion *motion, NSError *error) { + //CMAttitude *attitude = motion.attitude; + //NSLog(@"rotation rate = [%f, %f, %f]", attitude.pitch, attitude.roll, attitude.yaw); + if (error) + NSLog(@"%@", [error description]); + else + [self performSelectorOnMainThread:@selector(handleDeviceMotion:) withObject:motion waitUntilDone:YES]; + }]; + active = TRUE; +} + +- (void)stop +{ + [_motionManager stopDeviceMotionUpdates]; + active = FALSE; +} + +- (void)handleDeviceMotion:(CMDeviceMotion*)motion +{ + if (!active) + return; + + if (motion.magneticField.accuracy == CMMagneticFieldCalibrationAccuracyUncalibrated) + return; + + // X: A pitch is a rotation around a lateral axis that passes through the device from side to side. + // Y: A roll is a rotation around a longitudinal axis that passes through the device from its top to bottom. + // Z: A yaw is a rotation around an axis that runs vertically through the device. It is perpendicular to the + // body of the device, with its origin at the center of gravity and directed toward the bottom of the device. + + CMAttitude *attitude = motion.attitude; + handler->setRoll(90 - qRadiansToDegrees(attitude.roll)); + handler->setPitch(qRadiansToDegrees(attitude.pitch)); + handler->setYaw(qRadiansToDegrees(attitude.yaw)); +} + +@end diff --git a/tests/manual/qardboard/main.cpp b/tests/manual/qardboard/main.cpp new file mode 100644 index 000000000..7d5ac86c2 --- /dev/null +++ b/tests/manual/qardboard/main.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <Qt3DQuickExtras/qt3dquickwindow.h> +#include <Qt3DQuick/QQmlAspectEngine> +#include <QGuiApplication> +#include <QQmlEngine> +#include <QQmlContext> + +#ifdef Q_OS_IOS +#include "iosdeviceorientation.h" +#else +#include "dummydeviceorientation.h" +#endif + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + + Qt3DExtras::Quick::Qt3DQuickWindow view; + +#ifdef Q_OS_IOS + qmlRegisterType<iOSDeviceOrientation>("Qardboard", 1, 0, "DeviceOrientation"); +#else + qmlRegisterType<DummyDeviceOrientation>("Qardboard", 1, 0, "DeviceOrientation"); +#endif + + view.engine()->qmlEngine()->rootContext()->setContextProperty(QStringLiteral("_window"), &view); + view.setSource(QUrl("qrc:/main.qml")); +#ifdef Q_OS_IOS + view.showFullScreen(); +#else + view.resize(800, 400); + view.show(); +#endif + + return app.exec(); +} diff --git a/tests/manual/qardboard/main.qml b/tests/manual/qardboard/main.qml new file mode 100644 index 000000000..63d2582b1 --- /dev/null +++ b/tests/manual/qardboard/main.qml @@ -0,0 +1,158 @@ +// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Extras 2.0 +import QtQuick 2.4 as QQ2 + +QardboardRootEntity { + id: root + cameraPosition: cameraController.position + + Entity { + id: cameraController + + function posAtAngle(a) { + return Qt.vector3d(cameraRadius * Math.cos(a), 0.0, cameraRadius * Math.sin(a)) + } + function rotAtAngle(a) { + return a * 180 / Math.PI + 90 + } + + property real circleRotation: 0 + readonly property real cameraRadius: obstaclesRepeater.radius + readonly property vector3d circlePosition: cameraController.posAtAngle(cameraController.circleRotation) + property vector3d position: planeTransform.translation.plus(Qt.vector3d(0, 0, 35)) + + QQ2.NumberAnimation { + target: cameraController + property: "circleRotation" + from: 0; to: Math.PI * 2 + duration: 10000 + loops: QQ2.Animation.Infinite + running: true + } + } + + // AirPlane + Entity { + components: [ + Mesh { + source: "assets/obj/toyplane.obj" + }, + Transform { + id: planeTransform + property real rollAngle: 0.0 + translation: cameraController.posAtAngle(cameraController.circleRotation) + rotation: fromAxesAndAngles(Qt.vector3d(1.0, 0.0, 0.0), planeTransform.rollAngle, + Qt.vector3d(0.0, -1.0, 0.0), cameraController.rotAtAngle(cameraController.circleRotation)) + }, + PhongMaterial { + shininess: 20.0 + diffuse: "#ba1a02" // Inferno Orange + } + ] + + QQ2.SequentialAnimation { + running: true + loops: QQ2.Animation.Infinite + + QQ2.NumberAnimation { + target: planeTransform + property: "rollAngle" + from: -30; to: 45 + duration: 1500 + } + QQ2.NumberAnimation { + target: planeTransform + property: "rollAngle" + from: 45; to: -30 + duration: 3500 + } + } + } + + // Cylinder + Entity { + property GeometryRenderer cylinder: CylinderMesh { + radius: 1 + length: 3 + rings: 100 + slices: 20 + } + property Transform transform: Transform { + id: cylinderTransform + property real theta: 0.0 + property real phi: 0.0 + rotation: fromEulerAngles(theta, phi, 0) + } + property Material phong: PhongMaterial {} + + QQ2.ParallelAnimation { + loops: QQ2.Animation.Infinite + running: true + QQ2.SequentialAnimation { + QQ2.NumberAnimation { + target: cylinderTransform + property: "scale" + from: 5; to: 45 + duration: 2000 + easing.type: QQ2.Easing.OutInQuad + } + QQ2.NumberAnimation { + target: cylinderTransform + property: "scale" + from: 45; to: 5 + duration: 2000 + easing.type: QQ2.Easing.InOutQuart + } + } + QQ2.NumberAnimation { + target: cylinderTransform + property: "phi" + from: 0; to: 360 + duration: 4000 + } + QQ2.NumberAnimation { + target: cylinderTransform + property: "theta" + from: 0; to: 720 + duration: 4000 + } + } + + components: [cylinder, transform, phong] + } + + // Torus obsctacles + NodeInstantiator { + id: obstaclesRepeater + model: 4 + readonly property real radius: 130.0; + readonly property real det: 1.0 / model + delegate: Entity { + components: [ + TorusMesh { + radius: 35 + minorRadius: 5 + rings: 100 + slices: 20 + }, + Transform { + id: transform + readonly property real angle: Math.PI * 2.0 * index * obstaclesRepeater.det + translation: Qt.vector3d(obstaclesRepeater.radius * Math.cos(transform.angle), + 0.0, + obstaclesRepeater.radius * Math.sin(transform.angle)) + rotation: fromAxisAndAngle(Qt.vector3d(0.0, 1.0, 0.0), transform.angle * 180 / Math.PI) + }, + PhongMaterial { + diffuse: Qt.rgba(Math.abs(Math.cos(transform.angle)), 204 / 255, 75 / 255, 1) + specular: "white" + shininess: 20.0 + } + ] + } + } +} diff --git a/tests/manual/qardboard/resources.qrc b/tests/manual/qardboard/resources.qrc new file mode 100644 index 000000000..fae6dc122 --- /dev/null +++ b/tests/manual/qardboard/resources.qrc @@ -0,0 +1,10 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>QardboardCamera.qml</file> + <file>QardboardFrameGraph.qml</file> + <file>QardboardRootEntity.qml</file> + <file>QardboardScene3D.qml</file> + <file>PlacedEntity.qml</file> + </qresource> +</RCC> |