summaryrefslogtreecommitdiffstats
path: root/tradeshow/enterprise-kinectdatavis/src
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2015-01-21 15:22:37 +0100
committerJocelyn Turcotte <jocelyn.turcotte@theqtcompany.com>2015-01-26 15:34:35 +0200
commita48d66e54876335a3e5c02fa0eb269ccb237b332 (patch)
tree14f2552c2acd37223958525712221571ed70c334 /tradeshow/enterprise-kinectdatavis/src
parentfb74273be089955cc9f9c8f08efaad52c18e4fa4 (diff)
Add enterprise-kinectdatavis in tradeshow demos
This is a small demo I did with feedback from the sales guys in Berlin. It's similar to the Kinect demo we had for 3D charts, except that it doesn't require complicated packages like OpenNI; only libfreenect to get the depth image. I only tested the demo on the imx6. The mesh processing of incoming frames is quite heavy so it might not work well on slower devices. The resolution can be tweaked with QQuickFreenectDepthDataProxy's width and height variables to change the resolution of the graph. It isn't in basicsuits since it require a Kinect to be of any value. Change-Id: I4b4619599842119e7d3e8ee130ece7244c0c645c Reviewed-by: Michal Klocek <michal.klocek@digia.com>
Diffstat (limited to 'tradeshow/enterprise-kinectdatavis/src')
m---------tradeshow/enterprise-kinectdatavis/src/libfreenect0
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/libfreenect.pro31
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/quickfreenect/plugin.cpp64
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectbackend.cpp232
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectbackend.h103
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectdepthdataproxy.cpp79
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectdepthdataproxy.h79
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectstate.h98
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectvideooutput.cpp115
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectvideooutput.h82
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/quickfreenect/quickfreenect.pro23
-rw-r--r--tradeshow/enterprise-kinectdatavis/src/src.pro9
12 files changed, 915 insertions, 0 deletions
diff --git a/tradeshow/enterprise-kinectdatavis/src/libfreenect b/tradeshow/enterprise-kinectdatavis/src/libfreenect
new file mode 160000
+Subproject 846b6bf1a3790a69f565238f905b270eaf2fda4
diff --git a/tradeshow/enterprise-kinectdatavis/src/libfreenect.pro b/tradeshow/enterprise-kinectdatavis/src/libfreenect.pro
new file mode 100644
index 0000000..4930236
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/libfreenect.pro
@@ -0,0 +1,31 @@
+cmake_args = -DBUILD_EXAMPLES=OFF -DBUILD_CPP=OFF -DBUILD_FAKENECT=OFF -DBUILD_C_SYNC=OFF
+cross_compile {
+ cmake_args += -DCMAKE_SYSTEM_NAME=Linux
+ cmake_args += -DCMAKE_SYSTEM_PROCESSOR=arm
+ cmake_args += -DCMAKE_CXX_COMPILER=$$QMAKE_CXX
+ cmake_args += -DCMAKE_C_COMPILER=$$QMAKE_CC
+ cmake_args += -DCMAKE_FIND_ROOT_PATH=$$[QT_SYSROOT]
+ cmake_args += -DCMAKE_CXX_FLAGS="--sysroot=$$[QT_SYSROOT]"
+ cmake_args += -DCMAKE_C_FLAGS="--sysroot=$$[QT_SYSROOT]"
+}
+
+!exists("$$PWD/libfreenect/CMakeLists.txt"): {
+ warning("You forgot to update the git submodule, I'll do that for you...")
+ system("git submodule update --init")
+ system("cd libfreenect && git apply ../../patches/0*")
+}
+
+system("cd libfreenect && cmake . $$cmake_args")
+
+build_pass|!debug_and_release {
+ make.target = invoke_make
+ # Build only the static lib to avoid linking to the shared one later on.
+ make.commands = make -C libfreenect freenectstatic
+ QMAKE_EXTRA_TARGETS += make
+
+ build_pass:build_all: default_target.target = all
+ else: default_target.target = first
+ default_target.depends = make
+
+ QMAKE_EXTRA_TARGETS += default_target
+}
diff --git a/tradeshow/enterprise-kinectdatavis/src/quickfreenect/plugin.cpp b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/plugin.cpp
new file mode 100644
index 0000000..926e94f
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/plugin.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: For any questions to Digia, please use the contact form at
+** http://www.qt.io
+**
+** This file is part of the examples of the Qt Enterprise Embedded.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtQml/QQmlExtensionPlugin>
+#include <QtQml/qqml.h>
+
+#include "qquickfreenectstate.h"
+#include "qquickfreenectbackend.h"
+#include "qquickfreenectdepthdataproxy.h"
+#include "qquickfreenectvideooutput.h"
+
+class QExampleQmlPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ void registerTypes(const char *uri)
+ {
+ qmlRegisterType<QQuickFreenectDepthDataProxy>(uri, 1, 0, "FreenectDepthDataProxy");
+ qmlRegisterType<QQuickFreenectState>(uri, 1, 0, "FreenectState");
+ qmlRegisterType<QQuickFreenectVideoOutput>(uri, 1, 0, "FreenectVideoOutput");
+ }
+};
+
+
+#include "plugin.moc"
diff --git a/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectbackend.cpp b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectbackend.cpp
new file mode 100644
index 0000000..e32c20a
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectbackend.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: For any questions to Digia, please use the contact form at
+** http://www.qt.io
+**
+** This file is part of the examples of the Qt Enterprise Embedded.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qquickfreenectbackend.h"
+
+#include <QElapsedTimer>
+#include <QVector3D>
+#include "libfreenect.h"
+
+static std::weak_ptr<QQuickFreenectBackend> s_instance;
+
+std::shared_ptr<QQuickFreenectBackend> QQuickFreenectBackend::instance()
+{
+ std::shared_ptr<QQuickFreenectBackend> ret = s_instance.lock();
+ if (!ret)
+ s_instance = ret = std::shared_ptr<QQuickFreenectBackend>(new QQuickFreenectBackend);
+ return ret;
+}
+
+QQuickFreenectBackend::QQuickFreenectBackend()
+{
+ start();
+}
+
+QQuickFreenectBackend::~QQuickFreenectBackend()
+{
+ m_exitRequested = true;
+ wait();
+ s_instance.reset();
+}
+
+uint8_t *QQuickFreenectBackend::pickVideoFrontBuffer()
+{
+ QMutexLocker lock(&m_mutex);
+ if (m_gotVideoFrame) {
+ std::swap(m_videoMid, m_videoFront);
+ m_gotVideoFrame = false;
+ return m_videoFront;
+ }
+ return 0;
+}
+
+void QQuickFreenectBackend::run()
+{
+ freenect_context *f_ctx;
+ freenect_device *f_dev = 0;
+ QVector3D accelVectorAccum;
+ QVector3D emittedAccelVector;
+ QElapsedTimer accelVectorTimer;
+
+ accelVectorTimer.start();
+
+ if (freenect_init(&f_ctx, NULL) < 0) {
+ emit errorStringValue(QStringLiteral("Initialization of libfreenect failed, please restart."));
+ qWarning("freenect_init() failed");
+ return;
+ }
+
+#ifndef QT_NO_DEBUG
+ freenect_set_log_level(f_ctx, FREENECT_LOG_DEBUG);
+#endif
+ freenect_select_subdevices(f_ctx, (freenect_device_flags)(FREENECT_DEVICE_MOTOR | FREENECT_DEVICE_CAMERA));
+
+ int numDevices = freenect_num_devices(f_ctx);
+ if (!numDevices) {
+ emit errorStringValue(QStringLiteral("WARNING!\nNo Kinect detected, waiting for device..."));
+ qWarning("WARNING: No Kinect detected, make sure that udev permissions are set properly. See <src/libfreenect/platform/linux/udev/README>.");
+ }
+
+ int status = 0;
+ while (!m_exitRequested && status >= 0) {
+ // Set up the device
+ if (!f_dev) {
+ if (!(numDevices = freenect_num_devices(f_ctx))) {
+ timeval timeout{1, 0};
+ status = freenect_process_events_timeout(f_ctx, &timeout);
+ continue;
+ }
+
+ if (numDevices > 1)
+ qWarning("WARNING: More than one Kinect detected, using the first available.");
+ if (freenect_open_device(f_ctx, &f_dev, 0) < 0) {
+ emit errorStringValue(QStringLiteral("ERROR!\nCould open device. Please restart."));
+ freenect_shutdown(f_ctx);
+ return;
+ }
+
+ freenect_set_user(f_dev, this);
+ freenect_set_led(f_dev,LED_RED);
+ freenect_set_depth_callback(f_dev, depth_cb);
+ freenect_set_video_callback(f_dev, video_cb);
+ // Success.
+ emit errorStringValue(QString());
+ }
+
+ // Set up the depth stream
+ if (m_currentDepthStreamEnabled != m_requestedDepthStreamEnabled) {
+ if (m_requestedDepthStreamEnabled) {
+ freenect_set_depth_mode(f_dev, freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_DEPTH_11BIT));
+ m_depthBuffer = (uint16_t*)malloc(freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_DEPTH_11BIT).bytes);
+ freenect_set_depth_buffer(f_dev, m_depthBuffer);
+ freenect_start_depth(f_dev);
+ } else {
+ freenect_stop_depth(f_dev);
+ free(m_depthBuffer);
+ }
+ m_currentDepthStreamEnabled = m_requestedDepthStreamEnabled;
+ }
+
+ // Set up the video stream
+ if (m_currentVideoStream != m_requestedVideoStream) {
+ freenect_stop_video(f_dev);
+ // FIXME: Use YUV or BAYER instead.
+ freenect_video_format videoFormat = m_requestedVideoStream == QQuickFreenectVideoOutput::VideoRGB ? FREENECT_VIDEO_RGB : FREENECT_VIDEO_IR_8BIT;
+ free(m_videoBack);
+ free(m_videoMid);
+ free(m_videoFront);
+ m_videoBack = (uint8_t*)malloc(freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, videoFormat).bytes);
+ m_videoMid = (uint8_t*)malloc(freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, videoFormat).bytes);
+ m_videoFront = (uint8_t*)malloc(freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, videoFormat).bytes);
+ freenect_set_video_mode(f_dev, freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, videoFormat));
+ freenect_set_video_buffer(f_dev, m_videoBack);
+ freenect_start_video(f_dev);
+ m_currentVideoStream = m_requestedVideoStream;
+ }
+
+ if (m_requestedTiltDegrees != m_currentTiltDegrees) {
+ freenect_set_tilt_degs(f_dev, m_requestedTiltDegrees);
+ m_currentTiltDegrees = m_requestedTiltDegrees;
+ }
+
+ double dx, dy, dz;
+ freenect_update_tilt_state(f_dev);
+ freenect_get_mks_accel(freenect_get_tilt_state(f_dev), &dx, &dy, &dz);
+ // Weighted average of value updates over the last 100ms to flatten the noise.
+ float newVecRatio = std::min(100, (int)accelVectorTimer.elapsed()) / 100.;
+ accelVectorAccum = accelVectorAccum * (1. - newVecRatio) + QVector3D(dx, dy, dz) * newVecRatio;
+ accelVectorTimer.restart();
+ if (accelVectorAccum != emittedAccelVector) {
+ emit accelVectorValue(accelVectorAccum);
+ emittedAccelVector = accelVectorAccum;
+ }
+
+ // New accelerometer values seem to be available every ~5ms, make sure we come back to pick them.
+ timeval timeout{0, 5000};
+ status = freenect_process_events_timeout(f_ctx, &timeout);
+ }
+
+ if (status < 0) {
+ emit errorStringValue(QStringLiteral("ERROR!\nCould not read from device."));
+ freenect_shutdown(f_ctx);
+ return;
+ }
+
+ if (f_dev) {
+ freenect_stop_depth(f_dev);
+ freenect_stop_video(f_dev);
+ freenect_set_led(f_dev, LED_BLINK_GREEN);
+
+ freenect_close_device(f_dev);
+ }
+ freenect_shutdown(f_ctx);
+ free(m_videoBack);
+ free(m_videoMid);
+ free(m_videoFront);
+ free(m_depthBuffer);
+}
+
+void QQuickFreenectBackend::depth_cb(freenect_device *dev, void *buffer, uint32_t timestamp)
+{
+ Q_UNUSED(buffer)
+ Q_UNUSED(timestamp)
+ QQuickFreenectBackend *that = static_cast<QQuickFreenectBackend *>(freenect_get_user(dev));
+ ++that->m_depthFrameId;
+ emit that->depthFrameReady();
+}
+
+void QQuickFreenectBackend::video_cb(freenect_device *dev, void *buffer, uint32_t timestamp)
+{
+ Q_UNUSED(buffer)
+ Q_UNUSED(timestamp)
+ QQuickFreenectBackend *that = static_cast<QQuickFreenectBackend *>(freenect_get_user(dev));
+ {
+ QMutexLocker lock(&that->m_mutex);
+ Q_ASSERT(that->m_videoBack == buffer);
+ freenect_set_video_buffer(dev, that->m_videoMid);
+ std::swap(that->m_videoBack, that->m_videoMid);
+
+ // Don't notify if a stream change was requested
+ if (that->m_currentVideoStream == that->m_requestedVideoStream) {
+ that->m_gotVideoFrame = true;
+ emit that->videoFrameReady();
+ }
+ }
+}
diff --git a/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectbackend.h b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectbackend.h
new file mode 100644
index 0000000..07fbaa5
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectbackend.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: For any questions to Digia, please use the contact form at
+** http://www.qt.io
+**
+** This file is part of the examples of the Qt Enterprise Embedded.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQUICKFREENECTBACKEND_H
+#define QQUICKFREENECTBACKEND_H
+
+#include "qquickfreenectvideooutput.h"
+
+#include <QMutex>
+#include <QSize>
+#include <QThread>
+#include <memory>
+
+class QVector3D;
+struct _freenect_context;
+typedef struct _freenect_context freenect_context;
+struct _freenect_device;
+typedef struct _freenect_device freenect_device;
+
+class QQuickFreenectBackend : public QThread {
+ Q_OBJECT
+public:
+ static std::shared_ptr<QQuickFreenectBackend> instance();
+ ~QQuickFreenectBackend();
+
+ void requestTiltDegrees(double degrees) { m_requestedTiltDegrees = degrees; }
+ void requestDepthStreamEnabled() { m_requestedDepthStreamEnabled = true; }
+ void requestVideoStreamType(QQuickFreenectVideoOutput::StreamType type) { m_requestedVideoStream = type; }
+ unsigned depthFrameId() const { return m_depthFrameId; }
+ QQuickFreenectVideoOutput::StreamType requestedVideoStreamType() const { return m_requestedVideoStream; }
+
+ QSize depthBufferSize() const { return {640, 480}; }
+ uint16_t *depthBuffer() { return m_depthBuffer; }
+ QQuickFreenectVideoOutput::StreamType videoFrontBufferStreamType() const { return m_currentVideoStream; }
+ uint8_t *pickVideoFrontBuffer();
+
+ void run() override;
+
+signals:
+ void videoFrameReady();
+ void depthFrameReady();
+ void accelVectorValue(const QVector3D&);
+ void errorStringValue(const QString&);
+
+private:
+ QQuickFreenectBackend();
+ static void depth_cb(freenect_device *dev, void *buffer, uint32_t timestamp);
+ static void video_cb(freenect_device *dev, void *buffer, uint32_t timestamp);
+
+ uint8_t *m_videoBack = 0;
+ uint8_t *m_videoMid = 0;
+ uint8_t *m_videoFront = 0;
+ uint16_t *m_depthBuffer = 0;
+ double m_requestedTiltDegrees = 0;
+ double m_currentTiltDegrees = 0;
+ bool m_requestedDepthStreamEnabled = false;
+ bool m_currentDepthStreamEnabled = false;
+ QQuickFreenectVideoOutput::StreamType m_requestedVideoStream = QQuickFreenectVideoOutput::VideoOff;
+ QQuickFreenectVideoOutput::StreamType m_currentVideoStream = QQuickFreenectVideoOutput::VideoOff;
+ bool m_gotVideoFrame = false;
+ bool m_exitRequested = false;
+ unsigned m_depthFrameId = 0;
+ QMutex m_mutex;
+};
+
+#endif
diff --git a/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectdepthdataproxy.cpp b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectdepthdataproxy.cpp
new file mode 100644
index 0000000..0a36b04
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectdepthdataproxy.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: For any questions to Digia, please use the contact form at
+** http://www.qt.io
+**
+** This file is part of the examples of the Qt Enterprise Embedded.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qquickfreenectdepthdataproxy.h"
+
+#include "libfreenect.h"
+
+QQuickFreenectDepthDataProxy::QQuickFreenectDepthDataProxy()
+ : m_backend(QQuickFreenectBackend::instance())
+{
+ connect(m_backend.get(), SIGNAL(depthFrameReady()), SLOT(updateData()));
+ connect(this, SIGNAL(highClipChanged()), SLOT(updateData()));
+
+ m_dataArray = new QtDataVisualization::QSurfaceDataArray;
+ m_dataArray->reserve(height);
+ for (int y = 0; y < height; ++y)
+ m_dataArray->append(new QtDataVisualization::QSurfaceDataRow(width));
+ resetArray(m_dataArray);
+ m_backend->requestDepthStreamEnabled();
+}
+
+void QQuickFreenectDepthDataProxy::updateData()
+{
+ unsigned frameId = m_backend->depthFrameId();
+ if (m_lastUpdateFrameId == frameId)
+ return;
+
+ uint16_t *buffer = m_backend->depthBuffer();
+ QSize bufferSize = m_backend->depthBufferSize();
+ int widthRatio = bufferSize.width() / width;
+ int heightRatio = bufferSize.height() / height;
+ for (int y = 0; y < height; ++y) {
+ auto proxyRow = (*m_dataArray)[y];
+ for (int x = 0; x < width; ++x) {
+ uint16_t data = buffer[(height - 1 - y)*widthRatio * bufferSize.width() + x*heightRatio];
+ data = std::min(m_highClip, data != FREENECT_DEPTH_RAW_NO_VALUE ? FREENECT_DEPTH_RAW_MAX_VALUE - data : 0);
+ (*proxyRow)[x].setPosition(QVector3D(x, data, y));
+ }
+ }
+ resetArray(m_dataArray);
+ m_lastUpdateFrameId = frameId;
+}
diff --git a/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectdepthdataproxy.h b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectdepthdataproxy.h
new file mode 100644
index 0000000..dad2376
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectdepthdataproxy.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: For any questions to Digia, please use the contact form at
+** http://www.qt.io
+**
+** This file is part of the examples of the Qt Enterprise Embedded.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQUICLFREENECTDEPTHDATAPROXY_H
+#define QQUICLFREENECTDEPTHDATAPROXY_H
+
+#include "qquickfreenectbackend.h"
+
+#include <QSurfaceDataItem>
+#include <QSurfaceDataProxy>
+#include <QVector>
+
+class QQuickFreenectDepthDataProxy : public QtDataVisualization::QSurfaceDataProxy {
+ Q_OBJECT
+ Q_PROPERTY(int highClip READ highClip WRITE setHighClip NOTIFY highClipChanged)
+public:
+ QQuickFreenectDepthDataProxy();
+ int highClip() const { return m_highClip; }
+ void setHighClip(int highClip) {
+ if (highClip == m_highClip)
+ return;
+ m_highClip = highClip;
+ m_lastUpdateFrameId = 0;
+ emit highClipChanged();
+ }
+
+signals:
+ void highClipChanged();
+
+private slots:
+ void updateData();
+
+private:
+ std::shared_ptr<QQuickFreenectBackend> m_backend;
+ const int width = 160;
+ const int height = 120;
+ QtDataVisualization::QSurfaceDataArray *m_dataArray;
+ bool m_lastUpdateFrameId = 0;
+ int m_highClip = 2048;
+};
+
+#endif
diff --git a/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectstate.h b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectstate.h
new file mode 100644
index 0000000..fcedc5b
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectstate.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: For any questions to Digia, please use the contact form at
+** http://www.qt.io
+**
+** This file is part of the examples of the Qt Enterprise Embedded.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQUICKFREENECTSTATE_H
+#define QQUICKFREENECTSTATE_H
+
+#include "qquickfreenectbackend.h"
+
+#include <QObject>
+#include <QVector3D>
+
+class QQuickFreenectState : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QVector3D accelVector READ accelVector NOTIFY accelVectorChanged)
+ Q_PROPERTY(double motorTilt READ motorTilt WRITE setMotorTilt NOTIFY motorTiltChanged)
+ Q_PROPERTY(qreal minMotorTilt READ minMotorTilt CONSTANT)
+ Q_PROPERTY(qreal maxMotorTilt READ maxMotorTilt CONSTANT)
+ Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged)
+
+public:
+ QQuickFreenectState()
+ : m_backend(QQuickFreenectBackend::instance()) {
+ connect(m_backend.get(), SIGNAL(accelVectorValue(const QVector3D&)), SLOT(updateAccelVector(const QVector3D&)));
+ connect(m_backend.get(), SIGNAL(errorStringValue(const QString&)), SLOT(updateErrorString(const QString&)));
+ }
+
+ QVector3D accelVector() const { return m_accelVector; }
+
+ void setMotorTilt(double motorTilt) {
+ QQuickFreenectBackend::instance()->requestTiltDegrees(motorTilt);
+ m_motorTilt = motorTilt;
+ emit motorTiltChanged();
+ }
+ bool motorTilt() const { return m_motorTilt; }
+ QString errorString() const { return m_errorString; }
+ qreal minMotorTilt() const { return -30; }
+ qreal maxMotorTilt() const { return 30; }
+
+signals:
+ void accelVectorChanged();
+ void motorTiltChanged();
+ void errorStringChanged();
+
+private slots:
+ void updateAccelVector(const QVector3D &accelVector) {
+ m_accelVector = accelVector;
+ emit accelVectorChanged();
+ }
+ void updateErrorString(const QString &errorString) {
+ m_errorString = errorString;
+ emit errorStringChanged();
+ }
+
+private:
+ std::shared_ptr<QQuickFreenectBackend> m_backend;
+ QVector3D m_accelVector{0, 1, 0};
+ double m_motorTilt;
+ QString m_errorString;
+};
+
+#endif
diff --git a/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectvideooutput.cpp b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectvideooutput.cpp
new file mode 100644
index 0000000..408b0f4
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectvideooutput.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: For any questions to Digia, please use the contact form at
+** http://www.qt.io
+**
+** This file is part of the examples of the Qt Enterprise Embedded.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qquickfreenectvideooutput.h"
+
+#include "qquickfreenectbackend.h"
+
+#include <QQuickWindow>
+#include <QSGSimpleTextureNode>
+#include <memory>
+
+class TextureOwningNode : public QSGSimpleTextureNode {
+ std::unique_ptr<QSGTexture> m_texture;
+public:
+ TextureOwningNode() {
+ }
+ void setTexture(QSGTexture *texture) {
+ QSGSimpleTextureNode::setTexture(texture);
+ m_texture.reset(texture);
+ }
+};
+
+QQuickFreenectVideoOutput::QQuickFreenectVideoOutput()
+ : m_backend(QQuickFreenectBackend::instance())
+{
+ setFlag(ItemHasContents);
+ connect(m_backend.get(), SIGNAL(videoFrameReady()), SLOT(onReceivedFrame()));
+ m_backend->requestVideoStreamType(VideoRGB);
+}
+
+QQuickFreenectVideoOutput::StreamType QQuickFreenectVideoOutput::streamType() const
+{
+ return m_backend->requestedVideoStreamType();
+}
+
+void QQuickFreenectVideoOutput::setStreamType(StreamType type)
+{
+ m_backend->requestVideoStreamType(type);
+ emit streamTypeChanged();
+ m_isStreaming = false;
+ emit isStreamingChanged();
+}
+
+QSGNode *QQuickFreenectVideoOutput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ StreamType bufferType = m_backend->videoFrontBufferStreamType();
+ const QSize textureSize(640, bufferType == VideoRGB ? 480 : 488);
+ auto textureNode = static_cast<TextureOwningNode *>(oldNode);
+ if (!textureNode) {
+ GLuint texId;
+ glGenTextures(1, &texId);
+ QSGTexture *texture = window()->createTextureFromId(texId, textureSize, QQuickWindow::TextureOwnsGLTexture);
+
+ textureNode = new TextureOwningNode;
+ textureNode->setTexture(texture);
+ }
+
+ qreal widthRatio = width() / textureSize.width();
+ qreal heightRatio = height() / textureSize.height();
+ QSizeF nodeSize = QSizeF(textureSize) * std::min(widthRatio, heightRatio);
+ textureNode->setRect(QRectF(QPointF((width() - nodeSize.width()) / 2, (height() - nodeSize.height()) / 2), nodeSize));
+
+ if (uint8_t *buffer = m_backend->pickVideoFrontBuffer()) {
+ GLint bufferFormat = bufferType == VideoRGB ? GL_RGB : GL_LUMINANCE;
+ glBindTexture(GL_TEXTURE_2D, textureNode->texture()->textureId());
+ glTexImage2D(GL_TEXTURE_2D, 0, bufferFormat, textureSize.width(), textureSize.height(), 0, bufferFormat, GL_UNSIGNED_BYTE, buffer);
+ textureNode->markDirty(QSGNode::DirtyMaterial);
+ }
+
+ return textureNode;
+}
+
+void QQuickFreenectVideoOutput::onReceivedFrame()
+{
+ m_isStreaming = true;
+ emit isStreamingChanged();
+ update();
+}
diff --git a/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectvideooutput.h b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectvideooutput.h
new file mode 100644
index 0000000..4632117
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/qquickfreenectvideooutput.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: For any questions to Digia, please use the contact form at
+** http://www.qt.io
+**
+** This file is part of the examples of the Qt Enterprise Embedded.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QQUICKFREENECTVIDEOOUTPUT_H
+#define QQUICKFREENECTVIDEOOUTPUT_H
+
+#include <QQuickItem>
+#include <memory>
+
+class QQuickFreenectBackend;
+
+class QQuickFreenectVideoOutput : public QQuickItem {
+ Q_OBJECT
+ Q_PROPERTY(StreamType streamType READ streamType WRITE setStreamType NOTIFY streamTypeChanged)
+ Q_PROPERTY(bool streaming READ isStreaming NOTIFY isStreamingChanged)
+ Q_ENUMS(StreamType)
+
+public:
+ enum StreamType {
+ VideoOff,
+ VideoRGB,
+ VideoIR
+ };
+ QQuickFreenectVideoOutput();
+
+ StreamType streamType() const;
+ void setStreamType(StreamType type);
+
+ bool isStreaming() const { return m_isStreaming; }
+
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
+
+private slots:
+ void onReceivedFrame();
+
+signals:
+ void streamTypeChanged();
+ void isStreamingChanged();
+
+private:
+ std::shared_ptr<QQuickFreenectBackend> m_backend;
+ bool m_isStreaming = false;
+};
+
+#endif
diff --git a/tradeshow/enterprise-kinectdatavis/src/quickfreenect/quickfreenect.pro b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/quickfreenect.pro
new file mode 100644
index 0000000..15cf004
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/quickfreenect/quickfreenect.pro
@@ -0,0 +1,23 @@
+TEMPLATE = lib
+
+# Make it easier to run the UI with qmlscene
+DESTDIR = ../../Freenect
+
+QT += quick datavisualization
+CONFIG += c++11 link_pkgconfig plugin
+PKGCONFIG = libusb-1.0
+
+INCLUDEPATH += ../libfreenect/include
+LIBS += -L ../libfreenect/lib -lfreenect
+
+SOURCES += \
+ plugin.cpp \
+ qquickfreenectbackend.cpp \
+ qquickfreenectdepthdataproxy.cpp \
+ qquickfreenectvideooutput.cpp
+
+HEADERS += \
+ qquickfreenectbackend.h \
+ qquickfreenectdepthdataproxy.h \
+ qquickfreenectstate.h \
+ qquickfreenectvideooutput.h
diff --git a/tradeshow/enterprise-kinectdatavis/src/src.pro b/tradeshow/enterprise-kinectdatavis/src/src.pro
new file mode 100644
index 0000000..25bebc1
--- /dev/null
+++ b/tradeshow/enterprise-kinectdatavis/src/src.pro
@@ -0,0 +1,9 @@
+TEMPLATE = subdirs
+
+libfreenect.file = libfreenect.pro
+
+quickfreenect.file = quickfreenect/quickfreenect.pro
+quickfreenect.depends = libfreenect
+
+SUBDIRS += libfreenect \
+ quickfreenect