diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-11-13 16:14:18 +0100 |
---|---|---|
committer | Andy Nichols <andy.nichols@theqtcompany.com> | 2015-11-20 13:29:18 +0000 |
commit | e878523084f8a08c1f85571556cd410b50f4d381 (patch) | |
tree | 516afdd66eb6c90e92a932cffafc7809db5631c3 | |
parent | 14ec90c0284058dae0876ec89f9f7b91da3eb3d7 (diff) |
TriangleBoundingVolume added
Change-Id: I82ed00b73595330df9a6b7b870433e5c919a99a0
Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
-rw-r--r-- | src/render/backend/render-backend.pri | 6 | ||||
-rw-r--r-- | src/render/backend/triangleboundingvolume.cpp | 171 | ||||
-rw-r--r-- | src/render/backend/triangleboundingvolume_p.h | 110 |
3 files changed, 285 insertions, 2 deletions
diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri index 96444f861..a9ba02d64 100644 --- a/src/render/backend/render-backend.pri +++ b/src/render/backend/render-backend.pri @@ -23,7 +23,8 @@ HEADERS += \ $$PWD/nodefunctor_p.h \ $$PWD/transform_p.h \ $$PWD/boundingvolumedebug_p.h \ - $$PWD/nodemanagers_p.h + $$PWD/nodemanagers_p.h \ + $$PWD/triangleboundingvolume_p.h SOURCES += \ $$PWD/renderthread.cpp \ @@ -43,4 +44,5 @@ SOURCES += \ $$PWD/layer.cpp \ $$PWD/transform.cpp \ $$PWD/boundingvolumedebug.cpp \ - $$PWD/nodemanagers.cpp + $$PWD/nodemanagers.cpp \ + $$PWD/triangleboundingvolume.cpp diff --git a/src/render/backend/triangleboundingvolume.cpp b/src/render/backend/triangleboundingvolume.cpp new file mode 100644 index 000000000..75b87dc75 --- /dev/null +++ b/src/render/backend/triangleboundingvolume.cpp @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "triangleboundingvolume_p.h" +#include <Qt3DCore/qray3d.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +// Note: a, b, c in clockwise order +// RealTime Collision Detection page 192 +bool intersectsSegmentTriangle(const Qt3DCore::QRay3D &ray, + const QVector3D &a, + const QVector3D &b, + const QVector3D &c, + QVector3D &uvw, + float &t) +{ + const QVector3D ab = b - a; + const QVector3D ac = c - a; + const QVector3D qp = (ray.origin() - ray.point(ray.distance())); + + const QVector3D n = QVector3D::crossProduct(ab, ac); + const float d = QVector3D::dotProduct(qp, n); + + if (d <= 0.0f) + return false; + + const QVector3D ap = ray.origin() - a; + t = QVector3D::dotProduct(ap, n); + + if (t < 0.0f || t > d) + return false; + + const QVector3D e = QVector3D::crossProduct(qp, ap); + uvw.setY(QVector3D::dotProduct(ac, e)); + + if (uvw.y() < 0.0f || uvw.y() > d) + return false; + + uvw.setZ(-QVector3D::dotProduct(ab, e)); + + if (uvw.z() < 0.0f || uvw.y() + uvw.z() > d) + return false; + + const float ood = 1.0f / d; + t *= ood; + uvw.setY(uvw.y() * ood); + uvw.setZ(uvw.z() * ood); + uvw.setX(1.0f - uvw.y() - uvw.z()); + + return true; +} + +TriangleBoundingVolume::TriangleBoundingVolume() + : Qt3DCore::QBoundingVolume() +{ +} + +/*! + The vertices a, b, c are assumed to be in counter clockwise order. + */ +TriangleBoundingVolume::TriangleBoundingVolume(const Qt3DCore::QNodeId &id, const QVector3D &a, const QVector3D &b, const QVector3D &c) + : Qt3DCore::QBoundingVolume() + , m_id(id) + , m_a(a) + , m_b(b) + , m_c(c) +{} + +Qt3DCore::QNodeId TriangleBoundingVolume::id() const +{ + return m_id; +} + +bool TriangleBoundingVolume::intersects(const Qt3DCore::QRay3D &ray, QVector3D *q) const +{ + float t = 0.0f; + QVector3D uvw; + const float intersected = intersectsSegmentTriangle(ray, m_c, m_b, m_a, uvw, t); + + if (intersected && q != Q_NULLPTR) + *q = ray.origin() + t * ray.direction(); + + return intersected; +} + +Qt3DCore::QBoundingVolume::Type TriangleBoundingVolume::type() const +{ + return Qt3DCore::QBoundingVolume::Triangle; +} + +QVector3D TriangleBoundingVolume::a() const +{ + return m_a; +} + +QVector3D TriangleBoundingVolume::b() const +{ + return m_b; +} + +QVector3D TriangleBoundingVolume::c() const +{ + return m_c; +} + +void TriangleBoundingVolume::setA(const QVector3D &a) +{ + m_a = a; +} + +void TriangleBoundingVolume::setB(const QVector3D &b) +{ + m_b = b; +} + +void TriangleBoundingVolume::setC(const QVector3D &c) +{ + m_c = c; +} + +TriangleBoundingVolume TriangleBoundingVolume::transformed(const QMatrix4x4 &mat) const +{ + const QVector3D tA = mat * m_a; + const QVector3D tB = mat * m_b; + const QVector3D tC = mat * m_c; + return TriangleBoundingVolume(id(), tA, tB, tC); +} + +} // namespace Render + +} // namespace Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/backend/triangleboundingvolume_p.h b/src/render/backend/triangleboundingvolume_p.h new file mode 100644 index 000000000..5cdbbd9f2 --- /dev/null +++ b/src/render/backend/triangleboundingvolume_p.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DRENDER_RENDER_TRIANGLEBOUNDINGVOLUME_P_H +#define QT3DRENDER_RENDER_TRIANGLEBOUNDINGVOLUME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/qboundingvolume.h> +#include <Qt3DCore/qnodeid.h> +#include <QVector3D> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +Q_AUTOTEST_EXPORT bool intersectsSegmentTriangle(const Qt3DCore::QRay3D &ray, + const QVector3D &a, + const QVector3D &b, + const QVector3D &c, + QVector3D &uvw, + float &t); + +class Q_AUTOTEST_EXPORT TriangleBoundingVolume : public Qt3DCore::QBoundingVolume +{ +public: + TriangleBoundingVolume(); + explicit TriangleBoundingVolume(const Qt3DCore::QNodeId &id, + const QVector3D &a, + const QVector3D &b, + const QVector3D &c); + + Qt3DCore::QNodeId id() const Q_DECL_FINAL; + bool intersects(const Qt3DCore::QRay3D &ray, QVector3D *q) const Q_DECL_FINAL; + Type type() const Q_DECL_FINAL; + + QVector3D a() const; + QVector3D b() const; + QVector3D c() const; + + void setA(const QVector3D &a); + void setB(const QVector3D &b); + void setC(const QVector3D &c); + + TriangleBoundingVolume transformed(const QMatrix4x4 &mat) const; + + inline TriangleBoundingVolume &transform(const QMatrix4x4 &mat) + { + *this = transformed(mat); + return *this; + } + +private: + Qt3DCore::QNodeId m_id; + QVector3D m_a, m_b, m_c; +}; + +} // namespace Render + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(Qt3DRender::Render::TriangleBoundingVolume*) + +#endif // QT3DRENDER_RENDER_TRIANGLEBOUNDINGVOLUME_P_H |