diff options
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/geometry/geometry.pri | 5 | ||||
-rw-r--r-- | src/render/geometry/qconegeometry.cpp | 590 | ||||
-rw-r--r-- | src/render/geometry/qconegeometry.h | 114 | ||||
-rw-r--r-- | src/render/geometry/qconegeometry_p.h | 90 | ||||
-rw-r--r-- | src/render/geometry/qconemesh.cpp | 145 | ||||
-rw-r--r-- | src/render/geometry/qconemesh.h | 106 |
6 files changed, 1050 insertions, 0 deletions
diff --git a/src/render/geometry/geometry.pri b/src/render/geometry/geometry.pri index acc53474f..35e559fc2 100644 --- a/src/render/geometry/geometry.pri +++ b/src/render/geometry/geometry.pri @@ -16,6 +16,9 @@ HEADERS += \ $$PWD/qbuffer.h \ $$PWD/qbuffer_p.h \ $$PWD/qbufferfunctor.h \ + $$PWD/qconegeometry.h \ + $$PWD/qconegeometry_p.h \ + $$PWD/qconemesh.h \ $$PWD/qcuboidmesh.h \ $$PWD/qcylindergeometry.h \ $$PWD/qcylindergeometry_p.h \ @@ -51,6 +54,8 @@ SOURCES += \ $$PWD/qabstractbuffer.cpp \ $$PWD/qattribute.cpp \ $$PWD/qbuffer.cpp \ + $$PWD/qconegeometry.cpp \ + $$PWD/qconemesh.cpp \ $$PWD/qcuboidmesh.cpp \ $$PWD/qcylindergeometry.cpp \ $$PWD/qcylindermesh.cpp \ diff --git a/src/render/geometry/qconegeometry.cpp b/src/render/geometry/qconegeometry.cpp new file mode 100644 index 000000000..12780e355 --- /dev/null +++ b/src/render/geometry/qconegeometry.cpp @@ -0,0 +1,590 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 _USE_MATH_DEFINES +# define _USE_MATH_DEFINES // For MSVC +#endif + +#include "qconegeometry.h" +#include "qconegeometry_p.h" +#include <Qt3DRender/qbuffer.h> +#include <Qt3DRender/qbufferfunctor.h> +#include <Qt3DRender/qattribute.h> +#include <QVector3D> +#include <cmath> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace { + +void createSidesVertices(float *&verticesPtr, + int rings, + int slices, + double topRadius, + double bottomRadius, + double length) +{ + const float dY = length / static_cast<float>(rings - 1); + const float dTheta = (M_PI * 2) / static_cast<float>(slices); + + for (int ring = 0; ring < rings; ++ring) { + const float y = -length / 2.0f + static_cast<float>(ring) * dY; + + const float t = (y + length / 2) / length; + const float radius = (bottomRadius * (1 - t)) + (t * topRadius); + + for (int slice = 0; slice <= slices; ++slice) { + const float theta = static_cast<float>(slice) * dTheta; + const float ta = std::tan((M_PI/2) - std::atan(length / (bottomRadius - topRadius))); + const float ct = std::cos(theta); + const float st = std::sin(theta); + + *verticesPtr++ = radius * ct; + *verticesPtr++ = y; + *verticesPtr++ = radius * st; + + *verticesPtr++ = (y + length / 2.0) / length; + *verticesPtr++ = theta / (M_PI * 2); + + QVector3D n(ct, ta, st); + n.normalize(); + *verticesPtr++ = n.x(); + *verticesPtr++ = n.y(); + *verticesPtr++ = n.z(); + + if (slice == slices) + continue; + } + } +} + +void createSidesIndices(quint16 *&indicesPtr, int rings, int slices) +{ + for (int ring = 0; ring < rings-1; ++ring) { + const int ringIndexStart = ring * (slices + 1); + const int nextRingIndexStart = (ring + 1) * (slices + 1); + + for (int slice = 0; slice <= slices; ++slice) { + if (slice == slices) + continue; + + const int nextSlice = slice + 1; + + *indicesPtr++ = (ringIndexStart + slice); + *indicesPtr++ = (nextRingIndexStart + slice); + *indicesPtr++ = (ringIndexStart + nextSlice); + *indicesPtr++ = (ringIndexStart + nextSlice); + *indicesPtr++ = (nextRingIndexStart + slice); + *indicesPtr++ = (nextRingIndexStart + nextSlice); + } + } +} + +void createDiscVertices(float *&verticesPtr, + int slices, + double topRadius, + double bottomRadius, + double length, + double yPosition) +{ + const float dTheta = (M_PI * 2) / static_cast<float>(slices); + const double yNormal = (yPosition < 0.0f) ? -1.0f : 1.0f; + + *verticesPtr++ = 0.0f; + *verticesPtr++ = yPosition; + *verticesPtr++ = 0.0f; + + *verticesPtr++ = 1.0f; + *verticesPtr++ = 0.0f; + + *verticesPtr++ = 0.0f; + *verticesPtr++ = yNormal; + *verticesPtr++ = 0.0f; + + + for (int slice = 0; slice <= slices; ++slice) + { + const float theta = static_cast<float>(slice) * dTheta; + const float ct = std::cos(theta); + const float st = std::sin(theta); + + const float t = (yPosition + length / 2) / length; + const float radius = (bottomRadius * (1 - t)) + (t * topRadius); + + *verticesPtr++ = radius * ct; + *verticesPtr++ = yPosition; + *verticesPtr++ = radius * st; + + *verticesPtr++ = 1.0f; + *verticesPtr++ = theta / (M_PI * 2); + + *verticesPtr++ = 0.0f; + *verticesPtr++ = yNormal; + *verticesPtr++ = 0.0f; + + if (slice == slices) + continue; + } +} + +void createDiscIndices(quint16 *&indicesPtr, + int discCenterIndex, + int slices, + bool isTopCap) +{ + if ( !isTopCap ) { + for ( int i = slices - 1 ; i >= 0 ; --i ) + { + if ( i != 0 ) { + *indicesPtr++ = discCenterIndex; + *indicesPtr++ = discCenterIndex + i + 1; + *indicesPtr++ = discCenterIndex + i; + } else { + *indicesPtr++ = discCenterIndex; + *indicesPtr++ = discCenterIndex + i + 1; + *indicesPtr++ = discCenterIndex + slices; + } + } + } else { + for ( int i = 0 ; i < slices; ++i ) + { + if ( i != slices - 1 ) { + *indicesPtr++ = discCenterIndex; + *indicesPtr++ = discCenterIndex + i + 1; + *indicesPtr++ = discCenterIndex + i + 2; + } else { + *indicesPtr++ = discCenterIndex; + *indicesPtr++ = discCenterIndex + i + 1; + *indicesPtr++ = discCenterIndex + 1; + } + } + } +} + +} // anonymous + + +class ConeVertexDataFunctor : public QBufferFunctor +{ +public: + ConeVertexDataFunctor(bool hasTopEndcap, bool hasBottomEndcap, int rings, int slices, + float topRadius, float bottomRadius, float length) + : m_hasTopEndcap(hasTopEndcap) + , m_hasBottomEndcap(hasBottomEndcap) + , m_rings(rings) + , m_slices(slices) + , m_topRadius(topRadius) + , m_bottomRadius(bottomRadius) + , m_length(length) + {} + + QByteArray operator ()() Q_DECL_OVERRIDE + { + int verticesCount = 0; + + verticesCount = ( m_slices + 1 ) * m_rings // Sides + + (m_hasTopEndcap + m_hasBottomEndcap) * (m_slices + 1) + 2; // endcaps + + // vec3 pos, vec2 texCoord, vec3 normal + const quint32 vertexSize = (3 + 2 + 3) * sizeof(float); + + QByteArray verticesData; + verticesData.resize(vertexSize * verticesCount); + float *verticesPtr = reinterpret_cast<float*>(verticesData.data()); + + createSidesVertices(verticesPtr, m_rings, m_slices, m_topRadius, m_bottomRadius, m_length); + if ( m_hasTopEndcap ) + createDiscVertices(verticesPtr, m_slices, m_topRadius, m_bottomRadius, m_length, m_length * 0.5f); + if ( m_hasBottomEndcap ) + createDiscVertices(verticesPtr, m_slices, m_topRadius, m_bottomRadius, m_length, -m_length * 0.5f); + + return verticesData; + } + + bool operator ==(const QBufferFunctor &other) const Q_DECL_OVERRIDE + { + const ConeVertexDataFunctor *otherFunctor = functor_cast<ConeVertexDataFunctor>(&other); + if (otherFunctor != Q_NULLPTR) + return (otherFunctor->m_hasTopEndcap == m_hasTopEndcap && + otherFunctor->m_hasBottomEndcap == m_hasBottomEndcap && + otherFunctor->m_rings == m_rings && + otherFunctor->m_slices == m_slices && + otherFunctor->m_topRadius == m_topRadius && + otherFunctor->m_bottomRadius == m_bottomRadius && + otherFunctor->m_length == m_length); + return false; + } + + QT3D_FUNCTOR(ConeVertexDataFunctor) + +private: + bool m_hasTopEndcap; + bool m_hasBottomEndcap; + int m_rings; + int m_slices; + float m_topRadius; + float m_bottomRadius; + float m_length; +}; + +class ConeIndexDataFunctor : public QBufferFunctor +{ +public: + ConeIndexDataFunctor(bool hasTopEndcap, bool hasBottomEndcap, int rings, int slices, + float length) + : m_hasTopEndcap(hasTopEndcap) + , m_hasBottomEndcap(hasBottomEndcap) + , m_rings(rings) + , m_slices(slices) + , m_length(length) + { + } + + QByteArray operator ()() Q_DECL_OVERRIDE + { + int facesCount = 0; + + facesCount = (m_slices * 2) * m_rings // 2 x tris per side, for all rings + + m_slices * (m_hasTopEndcap + m_hasBottomEndcap); // endcaps + + const int indicesCount = facesCount * 3; + const int indexSize = sizeof(quint16); + Q_ASSERT(indicesCount < 65536); + + QByteArray indicesBytes; + indicesBytes.resize(indicesCount * indexSize); + quint16 *indicesPtr = reinterpret_cast<quint16*>(indicesBytes.data()); + + createSidesIndices(indicesPtr, m_rings, m_slices); + if ( m_hasTopEndcap ) + createDiscIndices(indicesPtr, m_rings * (m_slices + 1) + m_slices + 2, m_slices, true); + if ( m_hasBottomEndcap ) + createDiscIndices(indicesPtr, m_rings * (m_slices + 1), m_slices, false); + + return indicesBytes; + } + + bool operator ==(const QBufferFunctor &other) const Q_DECL_OVERRIDE + { + const ConeIndexDataFunctor *otherFunctor = functor_cast<ConeIndexDataFunctor>(&other); + if (otherFunctor != Q_NULLPTR) + return (otherFunctor->m_hasTopEndcap == m_hasTopEndcap && + otherFunctor->m_hasBottomEndcap == m_hasBottomEndcap && + otherFunctor->m_rings == m_rings && + otherFunctor->m_slices == m_slices && + otherFunctor->m_length == m_length); + return false; + } + + QT3D_FUNCTOR(ConeIndexDataFunctor) + +private: + bool m_hasTopEndcap; + bool m_hasBottomEndcap; + int m_rings; + int m_slices; + float m_length; +}; + + +QConeGeometryPrivate::QConeGeometryPrivate() + : QGeometryPrivate() + , m_hasTopEndcap(true) + , m_hasBottomEndcap(true) + , m_rings(16) + , m_slices(16) + , m_topRadius(0.0f) + , m_bottomRadius(1.0f) + , m_length(1.0f) + , m_positionAttribute(Q_NULLPTR) + , m_normalAttribute(Q_NULLPTR) + , m_texCoordAttribute(Q_NULLPTR) + , m_indexAttribute(Q_NULLPTR) + , m_vertexBuffer(Q_NULLPTR) + , m_indexBuffer(Q_NULLPTR) +{ +} + +void QConeGeometryPrivate::init() +{ + Q_Q(QConeGeometry); + m_positionAttribute = new QAttribute(q); + m_normalAttribute = new QAttribute(q); + m_texCoordAttribute = new QAttribute(q); + m_indexAttribute = new QAttribute(q); + m_vertexBuffer = new QBuffer(QBuffer::VertexBuffer, q); + m_indexBuffer = new QBuffer(QBuffer::IndexBuffer, q); + + // vec3 pos, vec2 tex, vec3 normal + const quint32 elementSize = 3 + 2 + 3; + const quint32 stride = elementSize * sizeof(float); + const int faces = (m_slices + 1) * (m_rings + 1); + int nVerts = 0; + + nVerts = (m_slices * 2) * m_rings // Sides + + m_slices * (m_hasTopEndcap + m_hasBottomEndcap); // endcaps + + m_positionAttribute->setName(QAttribute::defaultPositionAttributeName()); + m_positionAttribute->setDataType(QAttribute::Float); + m_positionAttribute->setDataSize(3); + m_positionAttribute->setAttributeType(QAttribute::VertexAttribute); + m_positionAttribute->setBuffer(m_vertexBuffer); + m_positionAttribute->setByteStride(stride); + m_positionAttribute->setCount(nVerts); + + m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName()); + m_texCoordAttribute->setDataType(QAttribute::Float); + m_texCoordAttribute->setDataSize(2); + m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute); + m_texCoordAttribute->setBuffer(m_vertexBuffer); + m_texCoordAttribute->setByteStride(stride); + m_texCoordAttribute->setByteOffset(3 * sizeof(float)); + m_texCoordAttribute->setCount(nVerts); + + m_normalAttribute->setName(QAttribute::defaultNormalAttributeName()); + m_normalAttribute->setDataType(QAttribute::Float); + m_normalAttribute->setDataSize(3); + m_normalAttribute->setAttributeType(QAttribute::VertexAttribute); + m_normalAttribute->setBuffer(m_vertexBuffer); + m_normalAttribute->setByteStride(stride); + m_normalAttribute->setByteOffset(5 * sizeof(float)); + m_normalAttribute->setCount(nVerts); + + m_indexAttribute->setAttributeType(QAttribute::IndexAttribute); + m_indexAttribute->setDataType(QAttribute::UnsignedShort); + m_indexAttribute->setBuffer(m_indexBuffer); + + m_indexAttribute->setCount(faces * 3); + + m_vertexBuffer->setBufferFunctor(QBufferFunctorPtr(new ConeVertexDataFunctor(m_hasTopEndcap, m_hasBottomEndcap, m_rings, m_slices, + m_topRadius, m_bottomRadius, m_length))); + m_indexBuffer->setBufferFunctor(QBufferFunctorPtr(new ConeIndexDataFunctor(m_hasTopEndcap, m_hasBottomEndcap, m_rings, m_slices, + m_length))); + + q->addAttribute(m_positionAttribute); + q->addAttribute(m_texCoordAttribute); + q->addAttribute(m_normalAttribute); + q->addAttribute(m_indexAttribute); +} + +QConeGeometry::QConeGeometry(QNode *parent) + : QGeometry(*new QConeGeometryPrivate, parent) +{ + Q_D(QConeGeometry); + d->init(); +} + +QConeGeometry::QConeGeometry(QConeGeometryPrivate &dd, QNode *parent) + :QGeometry(dd, parent) +{ + Q_D(QConeGeometry); + d->init(); +} + +QConeGeometry::~QConeGeometry() +{ + QGeometry::cleanup(); +} + +void QConeGeometry::updateVertices() +{ + Q_D(QConeGeometry); + const int nVerts = (d->m_slices + 1) * (d->m_rings + 1); + d->m_positionAttribute->setCount(nVerts); + d->m_texCoordAttribute->setCount(nVerts); + d->m_normalAttribute->setCount(nVerts); + d->m_vertexBuffer->setBufferFunctor(QBufferFunctorPtr(new ConeVertexDataFunctor(d->m_hasTopEndcap, d->m_hasBottomEndcap, d->m_rings, d->m_slices, + d->m_topRadius, d->m_bottomRadius, d->m_length))); +} + +void QConeGeometry::updateIndices() +{ + Q_D(QConeGeometry); + int faces = 0; + + faces = (d->m_slices * 2) * d->m_rings // 2 x tris per side, for all rings + + d->m_slices * (d->m_hasTopEndcap + d->m_hasBottomEndcap); // 2 x endcaps + + d->m_indexAttribute->setCount(faces * 3); + d->m_indexBuffer->setBufferFunctor(QBufferFunctorPtr(new ConeIndexDataFunctor(d->m_hasTopEndcap, d->m_hasBottomEndcap, d->m_rings, d->m_slices, + d->m_length))); +} + +void QConeGeometry::setHasTopEndcap(bool hasTopEndcap) +{ + Q_D(QConeGeometry); + if (hasTopEndcap != d->m_hasTopEndcap) { + d->m_hasTopEndcap = hasTopEndcap; + updateVertices(); + emit hasTopEndcapChanged(hasTopEndcap); + } +} + + +void QConeGeometry::setHasBottomEndcap(bool hasBottomEndcap) +{ + Q_D(QConeGeometry); + if (hasBottomEndcap != d->m_hasBottomEndcap) { + d->m_hasBottomEndcap = hasBottomEndcap; + updateVertices(); + emit hasBottomEndcapChanged(hasBottomEndcap); + } +} + +void QConeGeometry::setRings(int rings) +{ + Q_D(QConeGeometry); + if (rings != d->m_rings) { + d->m_rings = rings; + updateVertices(); + updateIndices(); + emit ringsChanged(rings); + } +} + +void QConeGeometry::setSlices(int slices) +{ + Q_D(QConeGeometry); + if (slices != d->m_slices) { + d->m_slices = slices; + updateVertices(); + updateIndices(); + emit slicesChanged(slices); + } +} + +void QConeGeometry::setTopRadius(float topRadius) +{ + Q_D(QConeGeometry); + if (topRadius != d->m_topRadius) { + d->m_topRadius = topRadius; + updateVertices(); + emit topRadiusChanged(topRadius); + } +} + +void QConeGeometry::setBottomRadius(float bottomRadius) +{ + Q_D(QConeGeometry); + if (bottomRadius != d->m_bottomRadius) { + d->m_bottomRadius = bottomRadius; + updateVertices(); + emit bottomRadiusChanged(bottomRadius); + } +} + +void QConeGeometry::setLength(float length) +{ + Q_D(QConeGeometry); + if (length != d->m_length) { + d->m_length = length; + updateVertices(); + updateIndices(); + emit lengthChanged(length); + } +} + +bool QConeGeometry::hasTopEndcap() const +{ + Q_D(const QConeGeometry); + return d->m_hasTopEndcap; +} + +bool QConeGeometry::hasBottomEndcap() const +{ + Q_D(const QConeGeometry); + return d->m_hasBottomEndcap; +} + +float QConeGeometry::topRadius() const +{ + Q_D(const QConeGeometry); + return d->m_topRadius; +} + +float QConeGeometry::bottomRadius() const +{ + Q_D(const QConeGeometry); + return d->m_bottomRadius; +} + +int QConeGeometry::rings() const +{ + Q_D(const QConeGeometry); + return d->m_rings; +} + +int QConeGeometry::slices() const +{ + Q_D(const QConeGeometry); + return d->m_slices; +} + +float QConeGeometry::length() const +{ + Q_D(const QConeGeometry); + return d->m_length; +} + +QAttribute *QConeGeometry::positionAttribute() const +{ + Q_D(const QConeGeometry); + return d->m_positionAttribute; +} + +QAttribute *QConeGeometry::normalAttribute() const +{ + Q_D(const QConeGeometry); + return d->m_normalAttribute; +} + +QAttribute *QConeGeometry::texCoordAttribute() const +{ + Q_D(const QConeGeometry); + return d->m_texCoordAttribute; +} + +QAttribute *QConeGeometry::indexAttribute() const +{ + Q_D(const QConeGeometry); + return d->m_indexAttribute; +} + +} // namespace Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/geometry/qconegeometry.h b/src/render/geometry/qconegeometry.h new file mode 100644 index 000000000..7b5182552 --- /dev/null +++ b/src/render/geometry/qconegeometry.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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_QCONEGEOMETRY_H +#define QT3DRENDER_QCONEGEOMETRY_H + +#include <Qt3DRender/qt3drender_global.h> +#include <Qt3DRender/qgeometry.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QConeGeometryPrivate; +class QAttribute; + +class QT3DRENDERSHARED_EXPORT QConeGeometry : public QGeometry +{ + Q_OBJECT + Q_PROPERTY( bool hasTopEndcap READ hasTopEndcap WRITE setHasTopEndcap NOTIFY hasTopEndcapChanged ) + Q_PROPERTY( bool hasBottomEndcap READ hasBottomEndcap WRITE setHasBottomEndcap NOTIFY hasBottomEndcapChanged ) + Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged) + Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged) + Q_PROPERTY( float topRadius READ topRadius WRITE setTopRadius NOTIFY topRadiusChanged ) + Q_PROPERTY( float bottomRadius READ bottomRadius WRITE setBottomRadius NOTIFY bottomRadiusChanged ) + Q_PROPERTY(float length READ length WRITE setLength NOTIFY lengthChanged) + Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT) + Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT) + Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT) + Q_PROPERTY(Qt3DRender::QAttribute *indexAttribute READ indexAttribute CONSTANT) + +public: + explicit QConeGeometry(QNode *parent = 0); + ~QConeGeometry(); + + void updateVertices(); + void updateIndices(); + + bool hasTopEndcap() const; + bool hasBottomEndcap() const; + float topRadius() const; + float bottomRadius() const; + int rings() const; + int slices() const; + float length() const; + + QAttribute *positionAttribute() const; + QAttribute *normalAttribute() const; + QAttribute *texCoordAttribute() const; + QAttribute *indexAttribute() const; + +public Q_SLOTS: + void setHasTopEndcap( bool hasTopEndcap ); + void setHasBottomEndcap( bool hasBottomEndcap ); + void setTopRadius( float topRadius ); + void setBottomRadius( float bottomRadius ); + void setRings( int rings ); + void setSlices( int slices ); + void setLength( float length ); + +Q_SIGNALS: + void hasTopEndcapChanged( bool hasTopEndcap ); + void hasBottomEndcapChanged( bool hasBottomEndcap ); + void topRadiusChanged( float topRadius ); + void bottomRadiusChanged( float bottomRadius ); + void ringsChanged( int rings ); + void slicesChanged( int slices ); + void lengthChanged( float length ); + +protected: + QConeGeometry(QConeGeometryPrivate &dd, QNode *parent = 0); + +private: + Q_DECLARE_PRIVATE(QConeGeometry) +}; + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QCONEGEOMETRY_H diff --git a/src/render/geometry/qconegeometry_p.h b/src/render/geometry/qconegeometry_p.h new file mode 100644 index 000000000..a878a71d4 --- /dev/null +++ b/src/render/geometry/qconegeometry_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** 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_QCONEGEOMETRY_P_H +#define QT3DRENDER_QCONEGEOMETRY_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 <Qt3DRender/private/qgeometry_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QAttribute; +class QBuffer; + +class QConeGeometryPrivate : public QGeometryPrivate +{ +public: + QConeGeometryPrivate(); + + void init(); + + Q_DECLARE_PUBLIC(QConeGeometry) + + bool m_hasTopEndcap; + bool m_hasBottomEndcap; + int m_rings; + int m_slices; + float m_topRadius; + float m_bottomRadius; + float m_length; + QAttribute *m_positionAttribute; + QAttribute *m_normalAttribute; + QAttribute *m_texCoordAttribute; + QAttribute *m_indexAttribute; + QBuffer *m_positionBuffer; + QBuffer *m_vertexBuffer; + QBuffer *m_indexBuffer; +}; + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QCONEGEOMETRY_P_H + diff --git a/src/render/geometry/qconemesh.cpp b/src/render/geometry/qconemesh.cpp new file mode 100644 index 000000000..17fed349d --- /dev/null +++ b/src/render/geometry/qconemesh.cpp @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 _USE_MATH_DEFINES +# define _USE_MATH_DEFINES // For MSVC +#endif + +#include "qconemesh.h" +#include "qconegeometry.h" +#include <Qt3DRender/qbuffer.h> +#include <Qt3DRender/qbufferfunctor.h> +#include <Qt3DRender/qattribute.h> +#include <qmath.h> +#include <QVector3D> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +QConeMesh::QConeMesh(QNode *parent) + : QGeometryRenderer(parent) +{ + QConeGeometry *geometry = new QConeGeometry(this); + QObject::connect(geometry, &QConeGeometry::hasTopEndcapChanged, this, &QConeMesh::hasTopEndcapChanged); + QObject::connect(geometry, &QConeGeometry::hasBottomEndcapChanged, this, &QConeMesh::hasBottomEndcapChanged); + QObject::connect(geometry, &QConeGeometry::topRadiusChanged, this, &QConeMesh::topRadiusChanged); + QObject::connect(geometry, &QConeGeometry::bottomRadiusChanged, this, &QConeMesh::bottomRadiusChanged); + QObject::connect(geometry, &QConeGeometry::ringsChanged, this, &QConeMesh::ringsChanged); + QObject::connect(geometry, &QConeGeometry::slicesChanged, this, &QConeMesh::slicesChanged); + QObject::connect(geometry, &QConeGeometry::lengthChanged, this, &QConeMesh::lengthChanged); + + QGeometryRenderer::setGeometry(geometry); +} + +QConeMesh::~QConeMesh() +{ + QNode::cleanup(); +} + +void QConeMesh::setHasTopEndcap(bool hasTopEndcap) +{ + static_cast<QConeGeometry *>(geometry())->setHasTopEndcap(hasTopEndcap); +} + +void QConeMesh::setHasBottomEndcap(bool hasBottomEndcap) +{ + static_cast<QConeGeometry *>(geometry())->setHasBottomEndcap(hasBottomEndcap); +} + +void QConeMesh::setTopRadius(float topRadius) +{ + static_cast<QConeGeometry *>(geometry())->setTopRadius(topRadius); +} + +void QConeMesh::setBottomRadius(float bottomRadius) +{ + static_cast<QConeGeometry *>(geometry())->setBottomRadius(bottomRadius); +} + +void QConeMesh::setRings(int rings) +{ + static_cast<QConeGeometry *>(geometry())->setRings(rings); +} + +void QConeMesh::setSlices(int slices) +{ + static_cast<QConeGeometry *>(geometry())->setSlices(slices); +} + +void QConeMesh::setLength(float length) +{ + static_cast<QConeGeometry *>(geometry())->setLength(length); +} + +bool QConeMesh::hasTopEndcap() const +{ + return static_cast<QConeGeometry *>(geometry())->hasTopEndcap(); +} + +bool QConeMesh::hasBottomEndcap() const +{ + return static_cast<QConeGeometry *>(geometry())->hasBottomEndcap(); +} + +float QConeMesh::topRadius() const +{ + return static_cast<QConeGeometry *>(geometry())->topRadius(); +} + +float QConeMesh::bottomRadius() const +{ + return static_cast<QConeGeometry *>(geometry())->bottomRadius(); +} + +int QConeMesh::rings() const +{ + return static_cast<QConeGeometry *>(geometry())->rings(); +} + +int QConeMesh::slices() const +{ + return static_cast<QConeGeometry *>(geometry())->slices(); +} + +float QConeMesh::length() const +{ + return static_cast<QConeGeometry *>(geometry())->length(); +} + +} // namespace Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/geometry/qconemesh.h b/src/render/geometry/qconemesh.h new file mode 100644 index 000000000..e6c62dc5b --- /dev/null +++ b/src/render/geometry/qconemesh.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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_QCONEMESH_H +#define QT3DRENDER_QCONEMESH_H + +#include <Qt3DRender/qt3drender_global.h> +#include <Qt3DRender/qgeometryrenderer.h> + +QT_BEGIN_NAMESPACE + + +namespace Qt3DRender { + +class QT3DRENDERSHARED_EXPORT QConeMesh : public QGeometryRenderer +{ + Q_OBJECT + Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged) + Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged) + Q_PROPERTY( bool hasTopEndcap READ hasTopEndcap WRITE setHasTopEndcap NOTIFY hasTopEndcapChanged ) + Q_PROPERTY( bool hasBottomEndcap READ hasBottomEndcap WRITE setHasBottomEndcap NOTIFY hasBottomEndcapChanged ) + Q_PROPERTY( float topRadius READ topRadius WRITE setTopRadius NOTIFY topRadiusChanged ) + Q_PROPERTY( float bottomRadius READ bottomRadius WRITE setBottomRadius NOTIFY bottomRadiusChanged ) + Q_PROPERTY(float length READ length WRITE setLength NOTIFY lengthChanged) +public: + explicit QConeMesh(Qt3DCore::QNode *parent = 0); + ~QConeMesh(); + + int rings() const; + int slices() const; + bool hasTopEndcap() const; + bool hasBottomEndcap() const; + float topRadius() const; + float bottomRadius() const; + float length() const; + +public Q_SLOTS: + void setHasTopEndcap( bool hasTopEndcap ); + void setHasBottomEndcap( bool hasBottomEndcap ); + void setTopRadius( float topRadius ); + void setBottomRadius( float bottomRadius ); + void setRings( int rings ); + void setSlices( int slices ); + void setLength( float length ); + +Q_SIGNALS: + void hasTopEndcapChanged( bool hasTopEndcap ); + void hasBottomEndcapChanged( bool hasBottomEndcap ); + void topRadiusChanged( float topRadius ); + void bottomRadiusChanged( float bottomRadius ); + void ringsChanged( int rings ); + void slicesChanged( int slices ); + void lengthChanged( float length ); + +private: + // As this is a default provided geometry renderer, no one should be able + // to modify the QGeometryRenderer's properties + + void setInstanceCount(int instanceCount); + void setPrimitiveCount(int primitiveCount); + void setBaseVertex(int baseVertex); + void setBaseInstance(int baseInstance); + void setRestartIndex(int index); + void setPrimitiveRestart(bool enabled); + void setGeometry(QGeometry *geometry); + void setPrimitiveType(PrimitiveType primitiveType); +}; + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QCONEMESH_H |