summaryrefslogtreecommitdiffstats
path: root/tradeshow/enterprise-kinectdatavis/src/quickfreenect
diff options
context:
space:
mode:
Diffstat (limited to 'tradeshow/enterprise-kinectdatavis/src/quickfreenect')
-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
9 files changed, 875 insertions, 0 deletions
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