diff options
Diffstat (limited to 'src/threed/geometry')
26 files changed, 0 insertions, 8971 deletions
diff --git a/src/threed/geometry/geometry.pri b/src/threed/geometry/geometry.pri deleted file mode 100644 index 7f6be75c..00000000 --- a/src/threed/geometry/geometry.pri +++ /dev/null @@ -1,28 +0,0 @@ -INCLUDEPATH += $$PWD -VPATH += $$PWD -HEADERS += geometry/qglcube.h \ - geometry/qglsphere.h \ - geometry/qgeometrydata.h \ - geometry/qlogicalvertex.h \ - geometry/qglbuilder.h \ - geometry/qglbezierpatches.h \ - geometry/qglmaterialcollection.h \ - geometry/qglteapot.h \ - geometry/qglcylinder.h \ - geometry/qgldome.h -SOURCES += qglcube.cpp \ - qglsphere.cpp \ - qgeometrydata.cpp \ - qglbuilder.cpp \ - qglsection.cpp \ - qglbezierpatches.cpp \ - qglmaterialcollection.cpp \ - qglteapot.cpp \ - qlogicalvertex.cpp \ - qglcylinder.cpp \ - qgldome.cpp -PRIVATE_HEADERS += qglteapot_data_p.h \ - qglbuilder_p.h \ - qglsection_p.h \ - qglteapot_data_p.h \ - qvector_utils_p.h diff --git a/src/threed/geometry/qgeometrydata.cpp b/src/threed/geometry/qgeometrydata.cpp deleted file mode 100644 index c56a8dc7..00000000 --- a/src/threed/geometry/qgeometrydata.cpp +++ /dev/null @@ -1,2030 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgeometrydata.h" -#include "qlogicalvertex.h" -#include "qglpainter.h" - -#include <QtOpenGL/qgl.h> -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QGeometryData - \brief The QGeometryData class encapsulates sets of geometry data. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - The QGeometryData class encloses a number of data arrays - that model most typical vertex data needs. The class provides a - store for all of the data types in the QGL::VertexAttribute enumeration. - - \table - \header - \o QGL::VertexAttribute - \o QGeometryData functions - \row - \o QGL::Position - \o appendVertex(), vertex(), vertices() - \row - \o QGL::Normal - \o appendNormal(), normal(), normals() - \row - \o QGL::Color - \o appendColor(), colorRef(), colors() - \row - \o QGL::TextureCoord0 - QGL::TextureCoord3 - \o appendTexCoord(), texCoordRef(), texCoords() - \row - \o QGL::CustomVertex0 - QGL::CustomVertex1, QGL::UserVertex - \o appendAttribute(), vector3DAttribute(), attributes() - \endtable - - Additionally the class provides the following features: - \list - \o appendVertex() for adding a QLogicalVertex() - \o logicalVertexAt() for return the data at an index as a QLogicalVertex() - \o hasField() to find if a particular data type is present - \o normalizeNormals() to reduce all normal vectors to unit length - \o boundingBox() to find the bounds of the geometry - \endlist - - It is up to the user of a QGeometryData instance to ensure that the - data has an equal number of items in each field. For example, if five - vertices are added and only two normals are added, the logical vertex at - position 3 will be corrupt, since it does not have a normal. - - While data is being accumulated the counts of different fields will vary, - since it may be convenient to add several vertices, then several normals, - colors or attributes at a time. However when a logical vertex is - constructed or when the data is sent to the GPU, counts of all fields - must be equal. - - QGeometryData uses explicit sharing with lazy creation of internal - data so that code like: - \code - QGeometryData myData; - if (processed) - myData = processedData(); - \endcode - is very inexpensive, since the first declaration and initialization - does not cause internal data to be created (only to be overwritten by the - assignment operation). - - Since QGeometryData is explicitly shared, variables of type - QGeometryData behave like references, and the underlying data is modified - by calling a non-const function on any variable which shares that data. - - To force an explicit copy call the detach() function. -*/ - -/*! - \typedef QGL::IndexArray - - This is a convenience for either QArray<ushort> (OpenGL/ES) or - QArray<int> (desktop OpenGL). -*/ - -class QGeometryDataPrivate -{ -public: - QGeometryDataPrivate(); - ~QGeometryDataPrivate(); - QGeometryDataPrivate *clone() const; - - QAtomicInt ref; - - QVector3DArray vertices; - QVector3DArray normals; - QArray<QColor4ub> colors; - QList<QCustomDataArray> attributes; - QList<QVector2DArray> textures; - QGL::IndexArray indices; - QGLVertexBundle vertexBundle; - QGLIndexBuffer indexBuffer; - bool uploadsViable; - bool modified; - QBox3D bb; - static const int ATTR_CNT = 32; - quint32 fields; - qint8 key[ATTR_CNT]; - quint8 size[ATTR_CNT]; - int count; - int reserved; - bool boxValid; - QGeometryData::BufferStrategy bufferStrategy; -}; - -QGeometryDataPrivate::QGeometryDataPrivate() - : ref(0) - , uploadsViable(true) - , modified(false) - , fields(0) - , count(0) - , reserved(-1) - , boxValid(true) - , bufferStrategy(QGeometryData::BufferIfPossible | QGeometryData::KeepClientData) -{ - qMemSet(key, -1, ATTR_CNT); - qMemSet(size, 0, ATTR_CNT); -} - -QGeometryDataPrivate::~QGeometryDataPrivate() -{ -} - -QGeometryDataPrivate *QGeometryDataPrivate::clone() const -{ - QGeometryDataPrivate *temp = new QGeometryDataPrivate; - temp->vertices = vertices; - temp->normals = normals; - temp->colors = colors; - temp->attributes = attributes; - temp->textures = textures; - temp->indices = indices; - temp->vertexBundle = vertexBundle; - temp->indexBuffer = indexBuffer; - temp->uploadsViable = uploadsViable; - temp->modified = modified; - temp->bb = bb; - temp->fields = fields; - qMemCopy(temp->key, key, ATTR_CNT); - qMemCopy(temp->size, size, ATTR_CNT); - temp->count = count; - temp->reserved = reserved; - temp->boxValid = boxValid; - temp->bufferStrategy = bufferStrategy; - return temp; -} - -/*! - \fn quint32 QGL::fieldMask(QGL::VertexAttribute attribute) - \relates QGeometryData - Returns an unsigned integer mask from the \a attribute. - - \sa QGeometryData::fields() -*/ - -/*! - \enum QGeometryData::BufferStrategyFlags - - This enum serves to describe how management of the data is handled - with respect to vertex buffer objects. The strategies are essentially a - combination of whether the client data is kept around after it has been - successfully uploaded to the GPU; and whether an upload is attempted at - all. - - If the data set is very small it may be pointless to use up a VBO, hence - in this case KeepClientData may be used resulting in no attempt to upload - the data and client side arrays used instead. - - \value InvalidStrategy No valid strategy has been specified. - \value KeepClientData Keep the client data, even after successful upload to the GPU. - \value BufferIfPossible Try to upload the data to the GPU. -*/ - -/*! - Construct an empty QGeometryData -*/ -QGeometryData::QGeometryData() - : d(0) -{ -} - -/*! - Construct QGeometryData as a copy of \a other -*/ -QGeometryData::QGeometryData(const QGeometryData &other) - : d(other.d) -{ - if (d) - d->ref.ref(); -} - -/*! - Construct an empty QGeometryData with the \a fields enabled. -*/ -QGeometryData::QGeometryData(quint32 fields) - : d(new QGeometryDataPrivate) -{ - d->ref.ref(); - const quint32 mask = 0x01; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (!(mask & fields)) continue; - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - enableField(attr); - } -} - -/*! - Destroys this QGeometryData recovering any resources. -*/ -QGeometryData::~QGeometryData() -{ - if (d && !d->ref.deref()) - delete d; -} - -/*! - Assigns this QGeometryData to be a copy of \a other. -*/ -QGeometryData &QGeometryData::operator=(const QGeometryData &other) -{ - if (d != other.d) - { - if (d && !d->ref.deref()) - delete d; - d = other.d; - if (d) - d->ref.ref(); - } - return *this; -} - -/*! - Appends the geometry in \a data to this. If this is empty, then all - fields of \a data are appended; otherwise (when this has existing fields) - only those fields that exist in both are appended. - - This does not change the indices - to reference the new geometry add - indices via the appendIndices() functions. -*/ -void QGeometryData::appendGeometry(const QGeometryData &data) -{ - if (data.d && data.count()) - { - detach(); - d->modified = true; - d->boxValid = false; - int cnt = data.d->count; - const quint32 mask = 0x01; - quint32 fields = d->fields | data.fields(); - d->fields = fields; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - enableField(attr); // might not be enabled if we had NO fields - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - d->vertices.append(data.d->vertices); - else if (attr == QGL::Normal) - d->normals.append(data.d->normals); - else // colors - d->colors.append(data.d->colors); - } - else if (attr < QGL::CustomVertex0) - { - d->textures[d->key[attr]].append(data.texCoords(attr)); - } - else - { - d->attributes[d->key[attr]].append(data.attributes(attr)); - } - } - } - d->count += cnt; - } -} - -/*! - Appends all the data fields in QLogicalVertex \a v to this - QGeometryData object. -*/ -int QGeometryData::appendVertex(const QLogicalVertex &v) -{ - create(); - d->modified = true; - if (d->boxValid) - d->bb.unite(v.vertex()); - quint32 fields = v.fields(); - const quint32 mask = 0x01; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - appendVertex(v.vertex()); - else if (attr == QGL::Normal) - appendNormal(v.normal()); - else - appendColor(v.color()); - } - else if (attr < QGL::CustomVertex0) - { - appendTexCoord(v.texCoord(attr), attr); - } - else - { - appendAttribute(v.attribute(attr), attr); - } - } - } - return d->count - 1; -} - -/*! - Returns a QLogicalVertex that references the \a{i}'th logical vertex - of this geometry. -*/ -QLogicalVertex QGeometryData::logicalVertexAt(int i) const -{ - return QLogicalVertex(*this, i); -} - -/*! - Normalize all the normal vectors in this geometry to unit length. -*/ -void QGeometryData::normalizeNormals() -{ - check(); - if (d) // nothng to do if its null - { - create(); - d->modified = true; - if (hasField(QGL::Normal)) - { - for (int i = 0; i < d->normals.count(); ++i) - d->normals[i].normalize(); - } - } -} - -/*! - Calculate and return a bounding box for the vertex data in this geometry. -*/ -QBox3D QGeometryData::boundingBox() const -{ - QBox3D box; - if (d) - { - if (d->boxValid) - { - box = d->bb; - } - else - { - for (int i = 0; i < d->count; ++i) - box.unite(d->vertices.at(i)); - d->bb = box; - } - } - return box; -} - -/*! - Returns the coordinates of the center of the geometry. - - The center is calculated as the centroid or geometric barycenter - of the vertices (the average of the vertices). For a convex hull this - is guaranteed to be inside the figure. -*/ -QVector3D QGeometryData::center() const -{ - QVector3D center; - for (int i = 0; i < d->vertices.count(); ++i) - center += d->vertices.at(i); - return center / (float)d->vertices.count(); -} - -/*! - Returns a copy of this geometry data with elements in reverse order. -*/ -QGeometryData QGeometryData::reversed() const -{ - QGeometryData r; - for (int i = count() - 1; i >= 0; --i) - r.appendVertex(logicalVertexAt(i)); - return r; -} - -/*! - Returns a copy of this geometry data with QGL::Position data translated by - the vector \a t. The other fields are unchanged. -*/ -QGeometryData QGeometryData::translated(const QVector3D &t) const -{ - QGeometryData r(*this); - r.detach(); - for (int i = 0; i < count(); ++i) - { - r.vertex(i) = r.vertexAt(i) + t; - } - return r; -} - -/*! - Modifies this geometry data by generating texture data based on QGL::Position - values. If \a orientation is Qt::Horizontal (the default) then x-coordinate - values are generated, and y-coordinate values are set to 0.0; otherwise - y-coordinate values are generated and x-coordinate values are set to 0.0. - The values are appended to the texture coordinate \a field. - - The method of calculation is based on the assumption that the vertex data - is a list of extents which span across the texture space horizontally, from - x = 0.0 to x = 1.0, in the case of Qt::Horizontal; or vertically in the - case of Qt::Vertical. The texture space of 1.0 is divided up proportionately - by the length of each extent. - - \image texture-coords-gen.png - - In this diagram the large blue numbers are the lengths of each extent, and - the texture coordinates generated are shown as \c{t(7/16, 1)} and so on. - - Thus the texture coordinate t0 for vertex v0, is 0.0; t1 for vertex v1 is - \c{(v1 - v0).length() / totalLength} and so on. - - The code to produce the texture coordinates for the quads in the image is: - \code - QGeometryData top; - - // add data to the primitive - top.appendVertex(QVector3D(0.0, 0.0, 0.0)); - top.appendVertex(QVector3D(6.0, 3.6, 0.0)); // (v1 - v0).length() = 7.0 - top.appendVertex(QVector3D(10.0, 0.6, 0.0)); // (v2 - v1).length() = 5.0 - top.appendVertex(QVector3D(13.0, 3.24, 0.0)); // (v3 - v2).length() = 4.0 - - // generate x (Qt::Horizontal) texture coordinates over the primitive - top.generateTextureCoordinates(); // spread over 7 + 5 + 4 = 16 - - // make a copy translated down, the copy has y texture coordinates all 0 - QGeometryData bottom = top.translated(QVector3D(0, 0, -1)); - - // now modify the top so its y texture coordinates are all 1 - for (int i = 0; i < top.count(); ++i) - top.texCoordRef(QGL::TextureCoord0).setY(1.0); - - displayList->addQuadsZipped(top, bottom); - \endcode -*/ -void QGeometryData::generateTextureCoordinates(Qt::Orientation orientation, QGL::VertexAttribute field) -{ - QArray<qreal> extents; - extents.append(0.0); - qreal totalExtents = 0.0; - QArray<QVector3D> v = vertices(); - for (int i = 0; i < v.count() - 1; ++i) - { - int n = (i + 1) % v.count(); - QVector3D e = v[n] - v[i]; - qreal extent = e.length(); - totalExtents += extent; - extents.append(totalExtents); - } - if (hasField(field)) - clear(field); - if (orientation == Qt::Horizontal) - { - for (int i = 0; i < v.count(); ++i) - appendTexCoord(QVector2D(extents[i] / totalExtents, 0.0), field); - } - else - { - for (int i = 0; i < v.count(); ++i) - appendTexCoord(QVector2D(0.0, extents[i] / totalExtents), field); - } -} - -/*! - Returns a QGeometryData instance containing alternating vertices from - this geometry and \a other. The resulting geometry contains N vertices - where \c{N == qMin(count(), other.count())}, and has only the fields - that are in both geometries. -*/ -QGeometryData QGeometryData::interleavedWith(const QGeometryData &other) const -{ - QGeometryData res; - check(); - other.check(); - if (d && other.d) - { - int cnt = qMax(d->count, other.d->count); - const quint32 mask = 0x01; - quint32 fields = d->fields & other.d->fields; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - res.enableField(attr); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - { - QArray<QVector3D> tmp; - for (int i = 0; i < cnt; ++i) - { - tmp.append(d->vertices.at(i)); - tmp.append(other.d->vertices.at(i)); - } - res.d->vertices = tmp; - } - else if (attr == QGL::Normal) - { - QArray<QVector3D> tmp; - for (int i = 0; i < cnt; ++i) - { - tmp.append(d->normals.at(i)); - tmp.append(other.d->normals.at(i)); - } - res.d->normals = tmp; - } - else // colors - { - QArray<QColor4ub> tmp; - for (int i = 0; i < cnt; ++i) - { - tmp.append(d->colors.at(i)); - tmp.append(other.d->colors.at(i)); - } - res.d->colors = tmp; - } - } - else if (attr < QGL::CustomVertex0) - { - QArray<QVector2D> tmp; - const QArray<QVector2D> txa = d->textures.at(d->key[attr]); - const QArray<QVector2D> txb = other.d->textures.at(other.d->key[attr]); - for (int i = 0; i < cnt; ++i) - { - tmp.append(txa.at(i)); - tmp.append(txb.at(i)); - } - res.d->textures[d->key[attr]] = tmp; - } - else - { - QCustomDataArray tmp; - const QCustomDataArray ata = d->attributes.at(d->key[attr]); - const QCustomDataArray atb = other.d->attributes.at(other.d->key[attr]); - for (int i = 0; i < cnt; ++i) - { - tmp.append(ata.at(i)); - tmp.append(atb.at(i)); - } - res.d->attributes[d->key[attr]] = tmp; - } - } - } - res.d->count = cnt * 2; - } - return res; -} - -/*! - Sets this QGeometryData to contain alternating vertices from - this geometry and \a other. The resulting geometry contains \c{N * 2} vertices - where \c{N == qMin(count(), other.count())}, and has only the fields - that are in both geometries. -*/ -void QGeometryData::interleaveWith(const QGeometryData &other) -{ - check(); - other.check(); - if (d && other.d) - { - create(); - d->modified = true; - d->boxValid = false; - int cnt = qMin(d->count, other.d->count); - const quint32 mask = 0x01; - quint32 fields = d->fields & other.d->fields; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - { - QArray<QVector3D> tmp; - for (int i = 0; i < cnt; ++i) - { - tmp.append(d->vertices.at(i)); - tmp.append(other.d->vertices.at(i)); - } - d->vertices = tmp; - } - else if (attr == QGL::Normal) - { - QArray<QVector3D> tmp; - for (int i = 0; i < cnt; ++i) - { - tmp.append(d->normals.at(i)); - tmp.append(other.d->normals.at(i)); - } - d->normals = tmp; - } - else // colors - { - QArray<QColor4ub> tmp; - for (int i = 0; i < cnt; ++i) - { - tmp.append(d->colors.at(i)); - tmp.append(other.d->colors.at(i)); - } - d->colors = tmp; - } - } - else if (attr < QGL::CustomVertex0) - { - QArray<QVector2D> tmp; - const QArray<QVector2D> txa = d->textures.at(d->key[attr]); - const QArray<QVector2D> txb = other.d->textures.at(other.d->key[attr]); - for (int i = 0; i < cnt; ++i) - { - tmp.append(txa.at(i)); - tmp.append(txb.at(i)); - } - d->textures[d->key[attr]] = tmp; - } - else - { - QCustomDataArray tmp; - const QCustomDataArray ata = d->attributes.at(d->key[attr]); - const QCustomDataArray atb = other.d->attributes.at(other.d->key[attr]); - for (int i = 0; i < cnt; ++i) - { - tmp.append(ata.at(i)); - tmp.append(atb.at(i)); - } - d->attributes[d->key[attr]] = tmp; - } - } - } - d->count = cnt * 2; - } -} - -/*! - Clear all data structures. The actual fields are retained, but they - have no contents. - \code - QGeometryData data; - data.appendVertex(a); - data.appendTexCoord(t); - - // prints "1" - qDebug() << data.count(); - - // x == a - QVector3D x = data.vertexAt(0); - - quint32 flds = QGL::fieldMask(QGL::Position) | QGL::fieldMask(QGL::TextureCoord0); - qDebug() << (flds == data.fields()); // prints "true" - - data.clear(); - qDebug() << data.count(); // prints "0" - QVector3D x = data.vertexAt(0); // asserts - no data in vertices - qDebug() << (flds == data.fields()); // still prints "true" - \endcode - - To clear a specific field and its data use \c{data.clear(field)} below. - - To clear all fields and data, simply set this to an empty geometry: - \code - data = QGeometryData(); - \endcode - */ -void QGeometryData::clear() -{ - if (d) - { - create(); - d->modified = true; - d->bb = QBox3D(); - d->boxValid = true; - const quint32 mask = 0x01; - quint32 fields = d->fields; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - d->vertices.clear(); - else if (attr == QGL::Normal) - d->normals.clear(); - else - d->colors.clear(); - } - else if (attr < QGL::CustomVertex0) - { - d->textures[d->key[field]].clear(); - } - else - { - d->attributes[d->key[field]].clear(); - } - } - } - d->count = 0; - } -} - -/*! - Clears the data from \a field, and removes the field. After this call - hasField() will return false for this field. -*/ -void QGeometryData::clear(QGL::VertexAttribute field) -{ - if (d && (QGL::fieldMask(field) & d->fields)) - { - create(); - d->modified = true; - if (field == QGL::Position) - { - d->bb = QBox3D(); - d->boxValid = true; - } - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - d->vertices.clear(); - else if (attr == QGL::Normal) - d->normals.clear(); - else - d->colors.clear(); - } - else if (attr < QGL::CustomVertex0) - { - d->textures[d->key[field]].clear(); - } - else - { - d->attributes[d->key[field]].clear(); - } - d->key[field] = -1; - d->fields = d->fields & ~QGL::fieldMask(field); - } -} - -/*! - Sets the geometry data to handle an \a amount of data. This is generally - not required unless its anticipated that a large amount of data will be - appended and realloc overhead is desired to be avoided. If \a amount is - less than the amount already reserved, or if this object has - more than the \a amount of data items, then this function exits without - doing anything. This function will never delete data. -*/ -void QGeometryData::reserve(int amount) -{ - if (d && (d->reserved > amount || d->reserved < d->count)) - return; - create(); - d->reserved = amount; - const quint32 mask = 0x01; - quint32 fields = d->fields; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - d->vertices.reserve(amount); - else if (attr == QGL::Normal) - d->normals.reserve(amount); - else - d->colors.reserve(amount); - } - else if (attr < QGL::CustomVertex0) - { - d->textures[d->key[field]].reserve(amount); - } - else - { - d->attributes[d->key[field]].reserve(amount); - } - } - } -} - -/*! - Draws this geometry on the \a painter, from \a start for \a count elements - in \a mode. The drawing \a mode is by default QGL::Triangles. This function - Also calls the upload() method to ensure that the geometry is resident on - the graphics hardware if appropriate. - - If the geometry is a point or line, then the \a drawWidth value specified the - width/size of the line/point. -*/ -void QGeometryData::draw(QGLPainter *painter, int start, int count, GLenum mode, qreal drawWidth) -{ - if (d && d->indices.size() && d->count) - { - upload(); - painter->clearAttributes(); - if (mode==QGL::Points) { -#if !defined(QT_OPENGL_ES_2) - ::glPointSize(drawWidth); -#endif - } else if (mode==QGL::LineStrip || mode == QGL::Lines) { - ::glLineWidth(drawWidth); - } - painter->setVertexBundle(d->vertexBundle); - if (count == 0) - count = d->indexBuffer.indexCount(); - painter->draw(QGL::DrawingMode(mode), d->indexBuffer, start, count); - } -} - -/*! - Uploads this geometry data to the graphics hardware if appropriate. If the - data is already uploaded and has not been modified since it was last - uploaded, then this function does nothing. - - If the bufferStrategy() does not specify QGL::BufferIfPossible then this - function does nothing. - - If the data was successfully uploaded, and the bufferStrategy() does not - specify QGL::KeepClientData then the data will be removed with a call to - the clear() function. - - If the data was successfully uploaded, on this call or previously, then this - function will return true. Otherwise it returns false. -*/ -bool QGeometryData::upload() -{ - bool vboUploaded = false; - bool iboUploaded = false; - - if (!d) - return false; - if (!d->modified) - return d->vertexBundle.isUploaded() && d->indexBuffer.isUploaded(); - - check(); - - // Need to recreate the buffers from the modified data. - d->vertexBundle = QGLVertexBundle(); - d->indexBuffer = QGLIndexBuffer(); - - // Copy the geometry data to the vertex buffer. - const quint32 mask = 0x01; - quint32 fields = d->fields; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (!(mask & fields)) - continue; - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr == QGL::Position) - d->vertexBundle.addAttribute(attr, d->vertices); - else if (attr == QGL::Normal) - d->vertexBundle.addAttribute(attr, d->normals); - else if (attr == QGL::Color) - d->vertexBundle.addAttribute(attr, d->colors); - else if (attr < QGL::CustomVertex0) - d->vertexBundle.addAttribute(attr, d->textures.at(d->key[field])); - else - d->vertexBundle.addAttribute(attr, d->attributes.at(d->key[field])); - } - - // Upload the buffer if requested, otherwise keep it client-side. - // Note: QGLVertexBundle will act as a client-side buffer if not uploaded. - if ((d->bufferStrategy & BufferIfPossible) != 0) - { - if (d->vertexBundle.upload()) - vboUploaded = true; - } - - // Copy the geometry data to the index buffer and upload if requested. - d->indexBuffer.setIndexes(d->indices); - if ((d->bufferStrategy & BufferIfPossible) != 0) - { - if (d->indexBuffer.upload()) - iboUploaded = true; - } - - d->modified = false; - - if (!(d->bufferStrategy & KeepClientData) && vboUploaded && iboUploaded) - clear(); - - return vboUploaded && iboUploaded; -} - -/*! - Sets the buffer \a strategy for this geometry. - - \sa bufferStrategy() -*/ -void QGeometryData::setBufferStrategy(QGeometryData::BufferStrategy strategy) -{ - if (!d || d->bufferStrategy != strategy) - { - create(); - d->modified = true; - d->bufferStrategy = strategy; - } -} - -/*! - Returns the buffer strategy for this geometry. The default is - \c{QGL::BufferIfPossible | QGL::KeepClientData}. - - \sa setBufferStrategy() -*/ -QGeometryData::BufferStrategy QGeometryData::bufferStrategy() const -{ - if (d) - return d->bufferStrategy; - return InvalidStrategy; -} - -/*! - Returns a reference to the vertex buffer for this geometry. - - \sa indexBuffer() -*/ -QGLVertexBundle QGeometryData::vertexBundle() const -{ - return d->vertexBundle; -} - -/*! - Returns a reference to the index buffer for this geometry. - - \sa vertexBundle() -*/ -QGLIndexBuffer QGeometryData::indexBuffer() const -{ - return d->indexBuffer; -} - -/*! - Appends \a index to the vertex index array. - - \sa appendIndices(), indices() -*/ -void QGeometryData::appendIndex(int index) -{ - create(); - d->modified = true; - d->indices.append(index); -} - -/*! - Appends \a index1, \a index2, and \a index3 to the geometry's - index array. - - \sa appendIndex(), indices() -*/ -void QGeometryData::appendIndices(int index1, int index2, int index3) -{ - create(); - d->modified = true; - d->indices.append(index1, index2, index3); -} - -/*! - Returns the index array that was created by appendIndex(). - - \sa appendIndex(), appendIndices() -*/ -QGL::IndexArray QGeometryData::indices() const -{ - if (d) - return d->indices; - else - return QGL::IndexArray(); -} - -/*! - Appends the \a indices to the geometry's index array. -*/ -void QGeometryData::appendIndices(const QGL::IndexArray &indices) -{ - create(); - d->modified = true; - d->indices.append(indices); -} - -/*! - Append the point \a v0 to this geometry data as a position field. -*/ -void QGeometryData::appendVertex(const QVector3D &v0) -{ - create(); - d->modified = true; - enableField(QGL::Position); - d->vertices.append(v0); - if (d->boxValid) - d->bb.unite(v0); - d->count = qMax(d->count, d->vertices.count()); -} - -/*! - Append the points \a v0 and \a v1 to this geometry data as position fields. -*/ -void QGeometryData::appendVertex(const QVector3D &v0, const QVector3D &v1) -{ - create(); - d->modified = true; - enableField(QGL::Position); - d->vertices.append(v0, v1); - if (d->boxValid) - { - d->bb.unite(v0); - d->bb.unite(v1); - } - d->count = qMax(d->count, d->vertices.count()); -} - -/*! - Append the points \a v0, \a v1 and \a v2 to this geometry data as position fields. -*/ -void QGeometryData::appendVertex(const QVector3D &v0, const QVector3D &v1, const QVector3D &v2) -{ - create(); - d->modified = true; - enableField(QGL::Position); - d->vertices.append(v0, v1, v2); - if (d->boxValid) - { - d->bb.unite(v0); - d->bb.unite(v1); - d->bb.unite(v2); - } - d->count = qMax(d->count, d->vertices.count()); -} - -/*! - Append the points \a v0, \a v1, \a v2 and \a v3 to this geometry data as position fields. -*/ -void QGeometryData::appendVertex(const QVector3D &v0, const QVector3D &v1, const QVector3D &v2, const QVector3D &v3) -{ - create(); - d->modified = true; - enableField(QGL::Position); - d->vertices.append(v0, v1, v2, v3); - if (d->boxValid) - { - d->bb.unite(v0); - d->bb.unite(v1); - d->bb.unite(v2); - d->bb.unite(v3); - } - d->count = qMax(d->count, d->vertices.count()); -} - -/*! - Append the float \a a0 to this geometry data, as an attribute \a field. -*/ -void QGeometryData::appendAttribute(float a0, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - d->attributes[d->key[field]].append(a0); - d->count = qMax(d->count, d->attributes[d->key[field]].count()); -} - -/*! - Append the float \a a0 and \a a1 to this geometry data, as an attribute \a field. -*/ -void QGeometryData::appendAttribute(float a0, float a1, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - d->attributes[d->key[field]].append(a0, a1); - d->count = qMax(d->count, d->attributes[d->key[field]].count()); -} - -/*! - Append the floats \a a0, \a a1 and \a a2 to this geometry data, as attribute \a field. -*/ -void QGeometryData::appendAttribute(float a0, float a1, float a2, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - d->attributes[d->key[field]].append(a0, a1, a2); - d->count = qMax(d->count, d->attributes[d->key[field]].count()); -} - -/*! - Append the floats \a a0, \a a1, \a a2 and \a a3 to this geometry data, as attribute \a field. -*/ -void QGeometryData::appendAttribute(float a0, float a1, float a2, float a3, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - d->attributes[d->key[field]].append(a0, a1, a2, a3); - d->count = qMax(d->count, d->attributes[d->key[field]].count()); -} - -/*! - Append the 2D point \a a to this geometry data, as an attribute \a field. -*/ -void QGeometryData::appendAttribute(const QVector2D &a, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - if (d->attributes.at(d->key[field]).isEmpty()) - d->attributes[d->key[field]].setElementType(QCustomDataArray::Vector2D); - d->attributes[d->key[field]].append(a); - d->count = qMax(d->count, d->attributes[d->key[field]].count()); -} - -/*! - Append the 3D point \a v to this geometry data, as an attribute \a field. -*/ -void QGeometryData::appendAttribute(const QVector3D &v, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - if (d->attributes.at(d->key[field]).isEmpty()) - d->attributes[d->key[field]].setElementType(QCustomDataArray::Vector3D); - d->attributes[d->key[field]].append(v); - d->count = qMax(d->count, d->attributes[d->key[field]].count()); -} - -/*! - Append the variant value \a a to this geometry data, as an attribute \a field. -*/ -void QGeometryData::appendAttribute(const QVariant &a, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - if (d->attributes.at(d->key[field]).isEmpty()) - { - // floats and doubles get handled "automatically" - float is default - if (a.type() == QVariant::Vector2D) - d->attributes[d->key[field]].setElementType(QCustomDataArray::Vector2D); - else if (a.type() == QVariant::Vector3D) - d->attributes[d->key[field]].setElementType(QCustomDataArray::Vector3D); - else if (a.type() == QVariant::Vector4D) - d->attributes[d->key[field]].setElementType(QCustomDataArray::Vector4D); - else if (a.type() == QVariant::Color) - d->attributes[d->key[field]].setElementType(QCustomDataArray::Color); - else - Q_ASSERT_X(false, "QGeometryData::appendAttribute", "bad type"); - } - d->attributes[d->key[field]].append(a); - d->count = qMax(d->count, d->attributes[d->key[field]].count()); -} - -/*! - Append the vector \a n0 to this geometry data, as a lighting normal. -*/ -void QGeometryData::appendNormal(const QVector3D &n0) -{ - create(); - d->modified = true; - enableField(QGL::Normal); - d->normals.append(n0); - d->count = qMax(d->count, d->normals.count()); -} - -/*! - Append the vectors \a n0 and \a n1 to this geometry data, as lighting normals. -*/ -void QGeometryData::appendNormal(const QVector3D &n0, const QVector3D &n1) -{ - create(); - d->modified = true; - enableField(QGL::Normal); - d->normals.append(n0, n1); - d->count = qMax(d->count, d->normals.count()); -} - -/*! - Append the vectors \a n0, \a n1 and \a n2 to this geometry data, as lighting normals. -*/ -void QGeometryData::appendNormal(const QVector3D &n0, const QVector3D &n1, const QVector3D &n2) -{ - create(); - d->modified = true; - enableField(QGL::Normal); - d->normals.append(n0, n1, n2); - d->count = qMax(d->count, d->normals.count()); -} - -/*! - Append the vectors \a n0, \a n1, \a n2 and \a n3 to this geometry data, as lighting normals. -*/ -void QGeometryData::appendNormal(const QVector3D &n0, const QVector3D &n1, const QVector3D &n2, const QVector3D &n3) -{ - create(); - d->modified = true; - enableField(QGL::Normal); - d->normals.append(n0, n1, n2, n3); - d->count = qMax(d->count, d->normals.count()); -} - -/*! - Append the point \a t0 to this geometry data, as an texture \a field. -*/ -void QGeometryData::appendTexCoord(const QVector2D &t0, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - d->textures[d->key[field]].append(t0); - d->count = qMax(d->count, d->textures[d->key[field]].count()); -} - -/*! - Append the points \a t0 and \a t1 to this geometry data, as texture \a{field}s. -*/ -void QGeometryData::appendTexCoord(const QVector2D &t0, const QVector2D &t1, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - d->textures[d->key[field]].append(t0, t1); - d->count = qMax(d->count, d->textures[d->key[field]].count()); -} - -/*! - Append the points \a t0, \a t1 and \a t2 to this geometry data, as texture \a{field}s. -*/ -void QGeometryData::appendTexCoord(const QVector2D &t0, const QVector2D &t1, const QVector2D &t2, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - d->textures[d->key[field]].append(t0, t1, t2); - d->count = qMax(d->count, d->textures[d->key[field]].count()); -} - -/*! - Append the points \a t0, \a t1, \a t2 and \a t3 to this geometry data, as texture \a{field}s. -*/ -void QGeometryData::appendTexCoord(const QVector2D &t0, const QVector2D &t1, const QVector2D &t2, const QVector2D &t3, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - enableField(field); - d->textures[d->key[field]].append(t0, t1, t2, t3); - d->count = qMax(d->count, d->textures[d->key[field]].count()); -} - -/*! - Append the color \a c0 to this geometry data, as an color field. -*/ -void QGeometryData::appendColor(const QColor4ub &c0) -{ - create(); - d->modified = true; - enableField(QGL::Color); - d->colors.append(c0); - d->count = qMax(d->count, d->colors.count()); -} - -/*! - Append the color \a c0 and \a c1 to this geometry data, as color fields. -*/ -void QGeometryData::appendColor(const QColor4ub &c0, const QColor4ub &c1) -{ - create(); - d->modified = true; - enableField(QGL::Color); - d->colors.append(c0, c1); - d->count = qMax(d->count, d->colors.count()); -} - -/*! - Append the color \a c0, \a c1 and \a c2 to this geometry data, as color fields. -*/ -void QGeometryData::appendColor(const QColor4ub &c0, const QColor4ub &c1, const QColor4ub &c2) -{ - create(); - d->modified = true; - enableField(QGL::Color); - d->colors.append(c0, c1, c2); - d->count = qMax(d->count, d->colors.count()); -} - -/*! - Append the color \a c0, \a c1, \a c2 and \a c3 to this geometry data, as color fields. -*/ -void QGeometryData::appendColor(const QColor4ub &c0, const QColor4ub &c1, const QColor4ub &c2, const QColor4ub &c3) -{ - create(); - d->modified = true; - enableField(QGL::Color); - d->colors.append(c0, c1, c2, c3); - d->count = qMax(d->count, d->colors.count()); -} - -/*! - Append the points in \a ary to this geometry data as position fields. -*/ -void QGeometryData::appendVertexArray(const QVector3DArray &ary) -{ - if (ary.count()) - { - create(); - d->modified = true; - d->boxValid = false; - enableField(QGL::Position); - d->vertices.append(ary); - d->count = qMax(d->count, d->vertices.count()); - } -} - -/*! - Append the points in \a ary to this geometry data, as an attribute \a field entries. -*/ -void QGeometryData::appendAttributeArray(const QCustomDataArray &ary, QGL::VertexAttribute field) -{ - if (ary.count()) - { - create(); - d->modified = true; - enableField(field); - d->attributes[d->key[field]].append(ary); - d->count = qMax(d->count, d->attributes[d->key[field]].count()); - } -} - -/*! - Append the vectors in \a ary to this geometry data, as lighting normals. -*/ -void QGeometryData::appendNormalArray(const QVector3DArray &ary) -{ - if (ary.count()) - { - create(); - d->modified = true; - enableField(QGL::Normal); - d->normals.append(ary); - d->count = qMax(d->count, d->normals.count()); - } -} - -/*! - Append the 2D points in \a ary to this geometry data, as texture \a field entries. -*/ -void QGeometryData::appendTexCoordArray(const QVector2DArray &ary, QGL::VertexAttribute field) -{ - if (ary.count()) - { - create(); - d->modified = true; - enableField(field); - d->textures[d->key[field]].append(ary); - d->count = qMax(d->count, d->textures[d->key[field]].count()); - } -} - -/*! - Append the colors in \a ary to this geometry data, as color fields. -*/ -void QGeometryData::appendColorArray(const QArray<QColor4ub> &ary) -{ - if (ary.count()) - { - create(); - d->modified = true; - enableField(QGL::Color); - d->colors.append(ary); - d->count = qMax(d->count, d->colors.count()); - } -} - -/*! - Returns a modifiable reference to the vertex data at index \a i. -*/ -QVector3D &QGeometryData::vertex(int i) -{ - create(); - d->modified = true; - d->boxValid = false; - return d->vertices[i]; -} - -/*! - Returns a copy of the vertex position data. -*/ -QVector3DArray QGeometryData::vertices() const -{ - if (d) - return d->vertices; - return QArray<QVector3D>(); -} - -/*! - \internal - Returns a pointer to the vertex data. -*/ -const QVector3DArray *QGeometryData::vertexData() const -{ - if (d) - return &d->vertices; - return 0; -} - - -/*! - Returns a non-modifiable reference to the vertex position data at index \a i. -*/ -const QVector3D &QGeometryData::vertexAt(int i) const -{ - Q_ASSERT(hasField(QGL::Position)); - return d->vertices.at(i); -} - -/*! - Returns a modifiable reference to the normal data at index \a i. -*/ -QVector3D &QGeometryData::normal(int i) -{ - create(); - d->modified = true; - return d->normals[i]; -} - -/*! - Returns a non-modifiable reference to the normal data at index \a i. -*/ -const QVector3D &QGeometryData::normalAt(int i) const -{ - Q_ASSERT(hasField(QGL::Normal)); - return d->normals.at(i); -} - -/*! - Returns a copy of the lighting normal data. -*/ -QVector3DArray QGeometryData::normals() const -{ - if (d) - return d->normals; - return QArray<QVector3D>(); -} - -/*! - Returns a modifiable reference to the color data at index \a i. -*/ -QColor4ub &QGeometryData::color(int i) -{ - create(); - d->modified = true; - return d->colors[i]; -} - -/*! - Returns a non-modifiable reference to the color data at index \a i. -*/ -const QColor4ub &QGeometryData::colorAt(int i) const -{ - Q_ASSERT(hasField(QGL::Color)); - return d->colors.at(i); -} - -/*! - Returns a copy of the color data. -*/ -QArray<QColor4ub> QGeometryData::colors() const -{ - if (d) - return d->colors; - return QArray<QColor4ub>(); -} - -/*! - Returns a modifiable reference to the \a field texture coordinate data at index \a i. -*/ -QVector2D &QGeometryData::texCoord(int i, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - return d->textures[d->key[field]][i]; -} - -/*! - Returns a copy of the \a field texture coordinate data. -*/ -QVector2DArray QGeometryData::texCoords(QGL::VertexAttribute field) const -{ - return hasField(field) ? d->textures.at(d->key[field]) : QVector2DArray(); -} - -/*! - Returns a non-modifiable reference to the texture coordinate data at index \a i for \a field. -*/ -const QVector2D &QGeometryData::texCoordAt(int i, QGL::VertexAttribute field) const -{ - Q_ASSERT(hasField(field)); - return d->textures.at(d->key[field]).at(i); -} - -/*! - Returns a modifiable reference to the float \a field attribute data at index \a i. -*/ -float &QGeometryData::floatAttribute(int i, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - QCustomDataArray &ary = d->attributes[d->key[field]]; - Q_ASSERT(ary.elementType() == QCustomDataArray::Float); - return ary.m_array[i]; -} - -/*! - Returns a modifiable reference to the 2D vector \a field attribute data at index \a i. -*/ -QVector2D &QGeometryData::vector2DAttribute(int i, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - QCustomDataArray &ary = d->attributes[d->key[field]]; - Q_ASSERT(ary.elementType() == QCustomDataArray::Vector2D); - float *data = ary.m_array.data(); - QVector2D *v = reinterpret_cast<QVector2D*>(data + i*2); - return *v; -} - -/*! - Returns a modifiable reference to the 3D vector \a field attribute data at index \a i. -*/ -QVector3D &QGeometryData::vector3DAttribute(int i, QGL::VertexAttribute field) -{ - create(); - d->modified = true; - QCustomDataArray &ary = d->attributes[d->key[field]]; - Q_ASSERT(ary.elementType() == QCustomDataArray::Vector3D); - float *data = ary.m_array.data(); - QVector3D *v = reinterpret_cast<QVector3D*>(data + i*2); - return *v; -} - -/*! - Returns a copy of the \a field attribute data. -*/ -QCustomDataArray QGeometryData::attributes(QGL::VertexAttribute field) const -{ - return hasField(field) ? d->attributes.at(d->key[field]) : QCustomDataArray(); -} - -/*! - Returns a copy of the float \a field attribute data at index \a i. -*/ -float QGeometryData::floatAttributeAt(int i, QGL::VertexAttribute field) const -{ - Q_ASSERT(hasField(field)); - return d->attributes.at(d->key[field]).floatAt(i); -} - -/*! - Returns a copy of the 2D vector \a field attribute data at index \a i. -*/ -QVector2D QGeometryData::vector2DAttributeAt(int i, QGL::VertexAttribute field) const -{ - Q_ASSERT(hasField(field)); - return d->attributes.at(d->key[field]).vector2DAt(i); -} - -/*! - Returns a copy of the 3D vector \a field attribute data at index \a i. -*/ -QVector3D QGeometryData::vector3DAttributeAt(int i, QGL::VertexAttribute field) const -{ - Q_ASSERT(hasField(field)); - return d->attributes.at(d->key[field]).vector3DAt(i); -} - -/*! - Returns the attribute value for the \a field, suitable for passing - to QGLPainter. - - \sa QGLPainter::setVertexAttribute() -*/ -QGLAttributeValue QGeometryData::attributeValue(QGL::VertexAttribute field) const -{ - if (hasField(field)) - { - if (field < QGL::TextureCoord0) - { - if (field == QGL::Position) - return QGLAttributeValue(d->vertices); - else if (field == QGL::Normal) - return QGLAttributeValue(d->normals); - else if (field == QGL::Color) - return QGLAttributeValue(d->colors); - } - else - { - if (field < QGL::CustomVertex0) - return QGLAttributeValue(d->textures.at(d->key[field])); - else - return QGLAttributeValue(d->attributes.at(d->key[field])); - } - } - return QGLAttributeValue(); -} - -/*! - Returns true if this geometry has the field corresponding to \a attr. Note - that it is still possible for no data to have been added for that field. -*/ -bool QGeometryData::hasField(QGL::VertexAttribute attr) const -{ - if (d) - return d->key[attr] != -1; - return false; -} - -/*! - Enables this geometry to contain data of type \a field. Generally it is - not necessary to call this function since it is called by all the append - functions. -*/ -void QGeometryData::enableField(QGL::VertexAttribute field) -{ - if (d && d->key[field] != -1) - return; - create(); - d->modified = true; - Q_ASSERT(field < d->ATTR_CNT); // don't expand that enum too much - d->fields |= (1 << field); - switch (field) - { - case QGL::Position: - d->key[QGL::Position] = 0; - d->size[QGL::Position] = 3; - if (d->reserved > 0) - d->vertices.reserve(d->reserved); - break; - case QGL::Normal: - d->key[QGL::Normal] = 1; - d->size[QGL::Normal] = 3; - if (d->reserved > 0) - d->normals.reserve(d->reserved); - break; - case QGL::Color: - d->key[QGL::Color] = 2; - d->size[QGL::Color] = 1; - if (d->reserved > 0) - d->colors.reserve(d->reserved); - break; - case QGL::TextureCoord0: - case QGL::TextureCoord1: - case QGL::TextureCoord2: - d->textures.append(QVector2DArray()); - d->key[field] = d->textures.count() - 1; - d->size[field] = 2; - if (d->reserved > 0) - d->textures[d->key[field]].reserve(d->reserved); - break; - default: - // Custom and User vertex attributes. - d->attributes.append(QCustomDataArray()); - d->key[field] = d->attributes.count() - 1; - d->size[field] = d->attributes.at(d->key[field]).elementSize(); - if (d->reserved > 0) - d->attributes[d->key[field]].reserve(d->reserved); - break; - } -} - -/*! - Return a bit-mask of the supported fields in this geometry. The - QGL::VertexAttribute enum can be recovered from this bit-mask by - \code - quint32 fields = fields(); - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(fields); - \endcode -*/ -quint32 QGeometryData::fields() const -{ - if (d) - return d->fields; - return 0; -} - -/*! - Returns the count of logical vertices stored. This is effectively - the max() of QArray::count() over all of the enabled data types. -*/ -int QGeometryData::count() const -{ - if (d) - return d->count; - return 0; -} - -/*! - Returns the count of data stored in \a field. This will always be at - most count(), but could be less. -*/ -int QGeometryData::count(QGL::VertexAttribute field) const -{ - int result = 0; - if (d && (QGL::fieldMask(field) & d->fields)) - { - if (field < QGL::TextureCoord0) - { - if (field == QGL::Position) - result = d->vertices.count(); - else if (field == QGL::Normal) - result = d->normals.count(); - else - result = d->colors.count(); - } - else if (field < QGL::CustomVertex0) - { - result = d->textures[d->key[field]].count(); - } - else - { - result = d->attributes[d->key[field]].count(); - } - } - return result; -} - -/*! - Returns true if this geometry is identical to the \a other; and false otherwise. -*/ -bool QGeometryData::operator==(const QGeometryData &other) const -{ - bool isEqual = false; - if (d) - { - if (d == other.d) - { - isEqual = true; - } - else - { - if (other.d && d->fields == other.d->fields && d->count == other.d->count) - { - const quint32 mask = 0x01; - quint32 fields = d->fields; - isEqual = true; - for (int field = 0; fields && isEqual; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - isEqual = (d->vertices == other.d->vertices); - else if (attr == QGL::Normal) - isEqual = (d->normals == other.d->normals); - else // colors - isEqual = (d->colors == other.d->colors); - } - else if (attr < QGL::CustomVertex0) - { - isEqual = (d->textures.at(d->key[attr]) == other.d->textures.at(d->key[attr])); - } - else - { - QArray<float> me = d->attributes.at(d->key[attr]).toFloatArray(); - QArray<float> him = other.d->attributes.at(d->key[attr]).toFloatArray(); - isEqual = (me == him); - } - } - } - } - } - } - else - { - isEqual = other.isNull(); - } - return isEqual; -} - -/*! - Returns true if this geometry is empty - that is it contains no vertices - or other data - and returns false otherwise. If an existing geometry has - been made empty by a call to clear() then this will be true (but isNull() - will be false). - - \sa isNull() -*/ -bool QGeometryData::isEmpty() const -{ - bool empty = true; - if (d) - empty = d->count == 0; - return empty; -} - -/*! - Returns true if this geometry is uninitialized - that is it contains no - internal data structures. A newly constructed QGeometryData object is - null until some data is added or changed. - - \sa isEmpty() -*/ -bool QGeometryData::isNull() const -{ - return d == NULL; -} - -/*! - Returns the number of index values stored in this geometry data. - - This value is exactly the same as indices().size() (but does not - incur the copy). -*/ -int QGeometryData::indexCount() const -{ - if (d) - return d->indices.size(); - return 0; -} - -void QGeometryData::create() -{ - if (!d) // lazy creation of data block - { - d = new QGeometryDataPrivate; - d->ref.ref(); - } -} - -/*! - Force this geometry to ensure it has its own unshared internal data - block, making a copy in the case that it is currently shared. -*/ -void QGeometryData::detach() -{ - create(); - if (d->ref.load() > 1) // being shared, must detach - { - QGeometryDataPrivate *temp = d->clone(); - d->ref.deref(); - d = temp; - d->ref.ref(); - } -} - -/*! - \fn quint64 QGeometryData::id() const - Return an opaque value that can be used to identify which data block is - being used by this QGeometryData instance. See the class documentation - relating to explicit sharing. -*/ - -#ifndef QT_NO_DEBUG -void QGeometryData::check() const -{ - if (!d) - return; - const quint32 mask = 0x01; - quint32 fields = d->fields; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - { - if (d->vertices.count() < d->count) - qWarning("QGeometryData - expected %d vertices, only %d found!", - d->count, d->vertices.count()); - } - else if (attr == QGL::Normal) - { - if (d->normals.count() < d->count) - qWarning("QGeometryData - expected %d normals, only %d found!", - d->count, d->normals.count()); - } - else - { - if (d->colors.count() < d->count) - qWarning("QGeometryData - expected %d colors, only %d found!", - d->count, d->colors.count()); - } - } - else if (attr < QGL::CustomVertex0) - { - if (d->textures.at(d->key[field]).count() < d->count) - qWarning("QGeometryData - expected %d texture coordinates for" - "QGL::TextureCoord%d, only %d found!", - d->count, field - QGL::TextureCoord0, d->textures.at(d->key[field]).count()); - } - else - { - if (d->attributes.at(d->key[field]).count() < d->count) - qWarning("QGeometryData - expected %d attributes for" - "QGL::CustomVertex%d, only %d found!", - d->count, field - QGL::CustomVertex0, d->attributes.at(d->key[field]).count()); - } - } - } -} -#endif - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug dbg, const QGeometryData &vertices) -{ - dbg << "QGeometryData" << &vertices << " size:" << vertices.count() -#ifndef QT_NO_DEBUG - << "data block id:" << vertices.id() -#endif - ; - quint32 fields = vertices.fields(); - const quint32 mask = 0x01; - for (int field = 0; fields; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - { - dbg << " vertices:" << vertices.count(attr); - dbg << vertices.vertices(); - } - else if (attr == QGL::Normal) - { - dbg << " normals:" << vertices.count(attr); - dbg << vertices.normals(); - } - else - { - dbg << " colors:" << vertices.count(attr); - dbg << vertices.colors(); - } - } - else if (attr < QGL::CustomVertex0) - { - dbg << " textures:" << (attr - QGL::TextureCoord0) << vertices.count(attr); - dbg << vertices.texCoords(attr); - } - else - { - dbg << " custom:" << (attr - QGL::CustomVertex0) << vertices.count(attr); - dbg << vertices.texCoords(attr); - } - } - } - if (vertices.indexCount() > 0) - { - dbg << " indices:" << vertices.indices(); - } - return dbg; -} - -QT_END_NAMESPACE - -#endif diff --git a/src/threed/geometry/qgeometrydata.h b/src/threed/geometry/qgeometrydata.h deleted file mode 100644 index bab4588e..00000000 --- a/src/threed/geometry/qgeometrydata.h +++ /dev/null @@ -1,213 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGEOMETRYDATA_H -#define QGEOMETRYDATA_H - -#include "qcolor4ub.h" -#include "qglnamespace.h" -#include "qglindexbuffer.h" -#include "qglvertexbundle.h" -#include "qglattributevalue.h" -#include "qcustomdataarray.h" -#include "qbox3d.h" -#include "qarray.h" -#include "qvector2darray.h" -#include "qvector3darray.h" - -QT_BEGIN_NAMESPACE - -class QGeometryDataPrivate; -class QLogicalVertex; -class QGLPainter; - -namespace QGL -{ - inline quint32 fieldMask(QGL::VertexAttribute f) { return (quint32)0x01 << f; } - -#if defined(QT_OPENGL_ES) - typedef QArray<ushort> IndexArray; -#else - typedef QArray<uint> IndexArray; -#endif -}; - -class Q_QT3D_EXPORT QGeometryData -{ -public: - QGeometryData(); - QGeometryData(const QGeometryData &); - QGeometryData(quint32 fields); - ~QGeometryData(); - - QGeometryData &operator=(const QGeometryData &); - - void appendGeometry(const QGeometryData &data); - int appendVertex(const QLogicalVertex &v); - void normalizeNormals(); - QBox3D boundingBox() const; - QVector3D center() const; - - QGeometryData reversed() const; - QGeometryData translated(const QVector3D &) const; - void generateTextureCoordinates(Qt::Orientation orientation = Qt::Horizontal, - QGL::VertexAttribute attribute = QGL::TextureCoord0); - QGeometryData interleavedWith(const QGeometryData &other) const; - void interleaveWith(const QGeometryData &other); - void clear(); - void clear(QGL::VertexAttribute); - void reserve(int amount); - void draw(QGLPainter *painter, int start, int count, GLenum mode = QGL::Triangles, qreal drawWidth=1.0); - bool upload(); - enum BufferStrategyFlags - { - InvalidStrategy = 0x00, - KeepClientData = 0x01, - BufferIfPossible = 0x02, - }; - Q_DECLARE_FLAGS(BufferStrategy, BufferStrategyFlags) - void setBufferStrategy(BufferStrategy strategy); - BufferStrategy bufferStrategy() const; - QGLVertexBundle vertexBundle() const; - QGLIndexBuffer indexBuffer() const; - - void appendIndex(int index); - void appendIndices(int index1, int index2, int index3); - void appendIndices(const QGL::IndexArray &indices); - QGL::IndexArray indices() const; - - void appendVertex(const QVector3D &v0); - void appendVertex(const QVector3D &v0, const QVector3D &v1); - void appendVertex(const QVector3D &v0, const QVector3D &v1, const QVector3D &v2); - void appendVertex(const QVector3D &v0, const QVector3D &v1, const QVector3D &v2, const QVector3D &v3); - - void appendAttribute(float a, QGL::VertexAttribute field = QGL::CustomVertex0); - void appendAttribute(float a, float b, QGL::VertexAttribute field = QGL::CustomVertex0); - void appendAttribute(float a, float b, float c, QGL::VertexAttribute field = QGL::CustomVertex0); - void appendAttribute(float a, float b, float c, float d, QGL::VertexAttribute field = QGL::CustomVertex0); - void appendAttribute(const QVector2D &a, QGL::VertexAttribute field = QGL::CustomVertex0); - void appendAttribute(const QVector3D &a, QGL::VertexAttribute field = QGL::CustomVertex0); - void appendAttribute(const QVariant &a, QGL::VertexAttribute field = QGL::CustomVertex0); - - void appendNormal(const QVector3D &n0); - void appendNormal(const QVector3D &n0, const QVector3D &n1); - void appendNormal(const QVector3D &n0, const QVector3D &n1, const QVector3D &n2); - void appendNormal(const QVector3D &n0, const QVector3D &n1, const QVector3D &n2, const QVector3D &n3); - - void appendTexCoord(const QVector2D &t0, QGL::VertexAttribute field = QGL::TextureCoord0); - void appendTexCoord(const QVector2D &t0, const QVector2D &t1, QGL::VertexAttribute field = QGL::TextureCoord0); - void appendTexCoord(const QVector2D &t0, const QVector2D &t1, const QVector2D &t2, QGL::VertexAttribute field = QGL::TextureCoord0); - void appendTexCoord(const QVector2D &t0, const QVector2D &t1, const QVector2D &t2, const QVector2D &t3, QGL::VertexAttribute field = QGL::TextureCoord0); - - void appendColor(const QColor4ub &c0); - void appendColor(const QColor4ub &c0, const QColor4ub &c1); - void appendColor(const QColor4ub &c0, const QColor4ub &c1, const QColor4ub &c2); - void appendColor(const QColor4ub &c0, const QColor4ub &c1, const QColor4ub &c2, const QColor4ub &c3); - - void appendVertexArray(const QVector3DArray &ary); - void appendAttributeArray(const QCustomDataArray &ary, QGL::VertexAttribute field = QGL::CustomVertex0); - void appendNormalArray(const QVector3DArray &ary); - void appendTexCoordArray(const QVector2DArray &ary, QGL::VertexAttribute field = QGL::TextureCoord0); - void appendColorArray(const QArray<QColor4ub> &ary); - - QLogicalVertex logicalVertexAt(int i) const; - - QVector3DArray vertices() const; - QVector3D &vertex(int i); - const QVector3D &vertexAt(int i) const; - - QVector3DArray normals() const; - QVector3D &normal(int i); - const QVector3D &normalAt(int i) const; - - QArray<QColor4ub> colors() const; - QColor4ub &color(int i); - const QColor4ub &colorAt(int i) const; - - QVector2DArray texCoords(QGL::VertexAttribute field = QGL::TextureCoord0) const; - QVector2D &texCoord(int i, QGL::VertexAttribute field = QGL::TextureCoord0); - const QVector2D &texCoordAt(int i, QGL::VertexAttribute field = QGL::TextureCoord0) const; - - float &floatAttribute(int i, QGL::VertexAttribute field = QGL::CustomVertex0); - QVector2D &vector2DAttribute(int i, QGL::VertexAttribute field = QGL::CustomVertex0); - QVector3D &vector3DAttribute(int i, QGL::VertexAttribute field = QGL::CustomVertex0); - QCustomDataArray attributes(QGL::VertexAttribute field = QGL::CustomVertex0) const; - float floatAttributeAt(int i, QGL::VertexAttribute field = QGL::CustomVertex0) const; - QVector2D vector2DAttributeAt(int i, QGL::VertexAttribute field = QGL::CustomVertex0) const; - QVector3D vector3DAttributeAt(int i, QGL::VertexAttribute field = QGL::CustomVertex0) const; - - QGLAttributeValue attributeValue(QGL::VertexAttribute field) const; - bool hasField(QGL::VertexAttribute field) const; - void enableField(QGL::VertexAttribute field); - quint32 fields() const; - int count() const; - int count(QGL::VertexAttribute field) const; - int indexCount() const; - bool operator==(const QGeometryData &other) const; - bool isEmpty() const; - bool isNull() const; - void detach(); -#ifndef QT_NO_DEBUG - quint64 id() const { return (quint64)d; } -#endif -protected: - const QVector3DArray *vertexData() const; -private: - void create(); -#ifndef QT_NO_DEBUG - void check() const; -#else - void check() const {} -#endif - friend class QLogicalVertex; - - QGeometryDataPrivate *d; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QGeometryData::BufferStrategy); - -#ifndef QT_NO_DEBUG_STREAM -Q_QT3D_EXPORT QDebug operator<<(QDebug dbg, const QGeometryData &vertices); -#endif - -QT_END_NAMESPACE - -#endif // QGEOMETRYDATA_H diff --git a/src/threed/geometry/qglbezierpatches.cpp b/src/threed/geometry/qglbezierpatches.cpp deleted file mode 100644 index e01ab471..00000000 --- a/src/threed/geometry/qglbezierpatches.cpp +++ /dev/null @@ -1,813 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglbezierpatches.h" -#include "qglbuilder.h" -#include "qray3d.h" -#include "qtriangle3d.h" -#include <QtCore/qnumeric.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QGLBezierPatches - \brief The QGLBezierPatches class represents 3D geometry as a set of Bezier bicubic patches. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - Bezier bicubic patches represent a curved 3D surface by four fixed - control points at indices 0, 3, 12, and 15, together with twelve - additional floating control points that define the surface - curvature. Bezier geometry objects are made up of one or more - such patches to define the surface of an object. - - The application specifies the vertex position data to the - constructor, and can optionally provide an index array. - The class interprets groups of 16 vertices as the control - points for successive patches. - - A mesh defined by QGLBezierPatches is subdivided into flat - triangles for rendering when the \c{<<} operator is used - to add the patches to a QGLBuilder. - - Many curved 3D objects can be defined as being made up of Bezier - bicubic patches, stitched together into a mesh. The most famous - Bezier bicubic object is probably the classic 3D "Utah Teapot", - first rendered in 1975. The QGLTeapot class provides a built-in - implementation of this object for testing purposes. - - If texture co-ordinates are supplied via setTextureCoords(), - then patch texture co-ordinates will be derived from the - specified values as the patches are subdivided. Otherwise, - QGLBezierPatches will generate texture co-ordinates for each - patch based on the default square from (0, 0) to (1, 1). - The first vertex in the patch corresponds to (0, 0), - and the opposite vertex in the patch corresponds to (1, 1). - - \sa QGLBuilder, QGLTeapot -*/ - -class QGLBezierPatchesPrivate -{ -public: - QGLBezierPatchesPrivate() - : subdivisionDepth(4) {} - QGLBezierPatchesPrivate(const QGLBezierPatchesPrivate *other) - : positions(other->positions) - , textureCoords(other->textureCoords) - , subdivisionDepth(other->subdivisionDepth) {} - - void copy(const QGLBezierPatchesPrivate *other) - { - positions = other->positions; - textureCoords = other->textureCoords; - subdivisionDepth = other->subdivisionDepth; - } - - void subdivide(QGLBuilder *list) const; - qreal intersection - (const QRay3D &ray, bool anyIntersection, QVector2D *texCoord, int *patch) const; - - QVector3DArray positions; - QVector2DArray textureCoords; - int subdivisionDepth; -}; - -// Temporary patch data for performing sub-divisions. -class QGLBezierPatch -{ -public: - // Control points for this mesh. - QVector3D points[16]; - - // Triangle mesh indices of the control points at each corner. - int indices[4]; - - QVector3D normal(qreal s, qreal t) const; - void convertToTriangles - (QGeometryData *prim, - qreal xtex, qreal ytex, qreal wtex, qreal htex); - void subDivide(QGLBezierPatch &patch1, QGLBezierPatch &patch2, - QGLBezierPatch &patch3, QGLBezierPatch &patch4); - void createNewCorners(QGLBezierPatch &patch1, QGLBezierPatch &patch2, - QGLBezierPatch &patch3, QGLBezierPatch &patch4, - QGeometryData *prim, - qreal xtex, qreal ytex, qreal wtex, qreal htex); - void recursiveSubDivide - (QGeometryData *prim, - int depth, qreal xtex, qreal ytex, qreal wtex, qreal htex); - qreal intersection - (qreal result, int depth, const QRay3D &ray, bool anyIntersection, - qreal xtex, qreal ytex, qreal wtex, qreal htex, QVector2D *tc); -}; - -static int const cornerOffsets[] = {0, 3, 12, 15}; -static qreal const cornerS[] = {0.0f, 1.0f, 0.0f, 1.0f}; -static qreal const cornerT[] = {0.0f, 0.0f, 1.0f, 1.0f}; - -// Helper functions for calculating the components of the Bernstein -// polynomial and its derivative that make up the surface. -static inline qreal b0(qreal v) -{ - return (1.0f - v) * (1.0f - v) * (1.0f - v); -} -static inline qreal b1(qreal v) -{ - return 3.0f * v * (1.0f - v) * (1.0f - v); -} -static inline qreal b2(qreal v) -{ - return 2.0f * v * v * (1.0f - v); -} -static inline qreal b3(qreal v) -{ - return v * v * v; -} -static inline qreal db0(qreal v) -{ - return -3.0f * (1.0f - v) * (1.0f - v); -} -static inline qreal db1(qreal v) -{ - return -6.0f * v * (1.0f - v) + 3.0f * (1.0f - v) * (1.0f - v); -} -static inline qreal db2(qreal v) -{ - return -3.0f * v * v + 6.0f * v * (1.0f - v); -} -static inline qreal db3(qreal v) -{ - return 3.0f * v * v; -} - -// Compute the normal at a specific point in the patch. -// The s and t values vary between 0 and 1. -QVector3D QGLBezierPatch::normal(qreal s, qreal t) const -{ - qreal a[4]; - qreal b[4]; - qreal tx, ty, tz; - qreal sx, sy, sz; - - // Compute the derivative of the surface in t. - a[0] = b0(s); - a[1] = b1(s); - a[2] = b2(s); - a[3] = b3(s); - b[0] = db0(t); - b[1] = db1(t); - b[2] = db2(t); - b[3] = db3(t); - tx = 0.0f; - ty = 0.0f; - tz = 0.0f; - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - tx += a[i] * points[j * 4 + i].x() * b[j]; - ty += a[i] * points[j * 4 + i].y() * b[j]; - tz += a[i] * points[j * 4 + i].z() * b[j]; - } - } - - // Compute the derivative of the surface in s. - a[0] = db0(s); - a[1] = db1(s); - a[2] = db2(s); - a[3] = db3(s); - b[0] = b0(t); - b[1] = b1(t); - b[2] = b2(t); - b[3] = b3(t); - sx = 0.0f; - sy = 0.0f; - sz = 0.0f; - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - sx += a[i] * points[j * 4 + i].x() * b[j]; - sy += a[i] * points[j * 4 + i].y() * b[j]; - sz += a[i] * points[j * 4 + i].z() * b[j]; - } - } - - // The normal is the cross-product of the two derivatives, - // normalized to a unit vector. - QVector3D n = QVector3D::normal(QVector3D(sx, sy, sz), QVector3D(tx, ty, tz)); - if (n.isNull()) { - // A zero normal may occur if one of the patch edges is zero-length. - // We correct for this by substituting an overall patch normal that - // we compute from two of the sides that are not zero in length. - QVector3D sides[4]; - QVector3D vectors[2]; - sides[0] = points[3] - points[0]; - sides[1] = points[15] - points[3]; - sides[2] = points[12] - points[15]; - sides[3] = points[0] - points[12]; - int i = 0; - int j = 0; - vectors[0] = QVector3D(1.0f, 0.0f, 0.0f); - vectors[1] = QVector3D(0.0f, 1.0f, 0.0f); - while (i < 2 && j < 4) { - if (sides[j].isNull()) - ++j; - else - vectors[i++] = sides[j++]; - } - n = QVector3D::normal(vectors[0], vectors[1]); - } - return n; -} - -// Convert this patch into flat triangles. -void QGLBezierPatch::convertToTriangles - (QGeometryData *prim, - qreal xtex, qreal ytex, qreal wtex, qreal htex) -{ - // The edges are considered ok if they have a non-zero length. - // Zero-length edges can occur in triangular-shaped patches. - // There is no point generating triangles along such edges. - bool edge1ok = (points[0] != points[3]); - bool edge2ok = (points[0] != points[12]); - bool edge3ok = (points[12] != points[15]); - bool edge4ok = (points[15] != points[3]); - - // Find the mid-point on the patch by averaging the corners. - QVector3D mid = (points[0] + points[3] + points[12] + points[15]) / 4.0f; - - // Allocate a triangle mesh vertex for the mid-point. - int midIndex = prim->count(); - prim->appendVertex(mid); - prim->appendNormal(normal(0.5f, 0.5f)); - prim->appendTexCoord - (QVector2D(xtex + wtex / 2.0f, ytex + htex / 2.0f)); - - // Divide the patch into 4 triangles pointing at the center. - if (edge1ok) - prim->appendIndices(indices[0], indices[1], midIndex); - if (edge2ok) - prim->appendIndices(indices[2], indices[0], midIndex); - if (edge3ok) - prim->appendIndices(indices[3], indices[2], midIndex); - if (edge4ok) - prim->appendIndices(indices[1], indices[3], midIndex); -} - -// Sub-divide a Bezier curve (p1, p2, p3, p4) into two new -// Bezier curves (l1, l2, l3, l4) and (r1, r2, r3, r4). -static void subDivideBezierCurve - (const QVector3D &p1, const QVector3D &p2, - const QVector3D &p3, const QVector3D &p4, - QVector3D &l1, QVector3D &l2, QVector3D &l3, QVector3D &l4, - QVector3D &r1, QVector3D &r2, QVector3D &r3, QVector3D &r4) -{ - l1 = p1; - l2 = (p1 + p2) / 2.0f; - QVector3D h = (p2 + p3) / 2.0f; - l3 = (l2 + h) / 2.0f; - r3 = (p3 + p4) / 2.0f; - r2 = (h + r3) / 2.0f; - l4 = r1 = (l3 + r2) / 2.0f; - r4 = p4; -} - -// Sub-divide this patch into four new patches. The triangle mesh -// is used to allocate vertices for the corners of the new patches. -void QGLBezierPatch::subDivide - (QGLBezierPatch &patch1, QGLBezierPatch &patch2, - QGLBezierPatch &patch3, QGLBezierPatch &patch4) -{ - // Sub-divide the Bezier curves for the control rows to create - // four rows of 8 control points. These define the left and - // right halves of the patch. - QVector3D row1[8]; - QVector3D row2[8]; - QVector3D row3[8]; - QVector3D row4[8]; - subDivideBezierCurve - (points[0], points[1], points[2], points[3], - row1[0], row1[1], row1[2], row1[3], row1[4], row1[5], row1[6], row1[7]); - subDivideBezierCurve - (points[4], points[5], points[6], points[7], - row2[0], row2[1], row2[2], row2[3], row2[4], row2[5], row2[6], row2[7]); - subDivideBezierCurve - (points[8], points[9], points[10], points[11], - row3[0], row3[1], row3[2], row3[3], row3[4], row3[5], row3[6], row3[7]); - subDivideBezierCurve - (points[12], points[13], points[14], points[15], - row4[0], row4[1], row4[2], row4[3], row4[4], row4[5], row4[6], row4[7]); - - // Now sub-divide the 8 columns to create the four new patches. - subDivideBezierCurve - (row1[0], row2[0], row3[0], row4[0], - patch1.points[0], patch1.points[4], patch1.points[8], patch1.points[12], - patch3.points[0], patch3.points[4], patch3.points[8], patch3.points[12]); - subDivideBezierCurve - (row1[1], row2[1], row3[1], row4[1], - patch1.points[1], patch1.points[5], patch1.points[9], patch1.points[13], - patch3.points[1], patch3.points[5], patch3.points[9], patch3.points[13]); - subDivideBezierCurve - (row1[2], row2[2], row3[2], row4[2], - patch1.points[2], patch1.points[6], patch1.points[10], patch1.points[14], - patch3.points[2], patch3.points[6], patch3.points[10], patch3.points[14]); - subDivideBezierCurve - (row1[3], row2[3], row3[3], row4[3], - patch1.points[3], patch1.points[7], patch1.points[11], patch1.points[15], - patch3.points[3], patch3.points[7], patch3.points[11], patch3.points[15]); - subDivideBezierCurve - (row1[4], row2[4], row3[4], row4[4], - patch2.points[0], patch2.points[4], patch2.points[8], patch2.points[12], - patch4.points[0], patch4.points[4], patch4.points[8], patch4.points[12]); - subDivideBezierCurve - (row1[5], row2[5], row3[5], row4[5], - patch2.points[1], patch2.points[5], patch2.points[9], patch2.points[13], - patch4.points[1], patch4.points[5], patch4.points[9], patch4.points[13]); - subDivideBezierCurve - (row1[6], row2[6], row3[6], row4[6], - patch2.points[2], patch2.points[6], patch2.points[10], patch2.points[14], - patch4.points[2], patch4.points[6], patch4.points[10], patch4.points[14]); - subDivideBezierCurve - (row1[7], row2[7], row3[7], row4[7], - patch2.points[3], patch2.points[7], patch2.points[11], patch2.points[15], - patch4.points[3], patch4.points[7], patch4.points[11], patch4.points[15]); -} - -void QGLBezierPatch::createNewCorners - (QGLBezierPatch &patch1, QGLBezierPatch &patch2, - QGLBezierPatch &patch3, QGLBezierPatch &patch4, - QGeometryData *prim, - qreal xtex, qreal ytex, qreal wtex, qreal htex) -{ - // Add vertices for the new patch corners we have created. - qreal hwtex = wtex / 2.0f; - qreal hhtex = htex / 2.0f; - int topPointIndex = prim->count(); - int leftPointIndex = topPointIndex + 1; - int midPointIndex = topPointIndex + 2; - int rightPointIndex = topPointIndex + 3; - int bottomPointIndex = topPointIndex + 4; - - prim->appendVertex(patch1.points[3]); - prim->appendNormal(normal(0.5f, 0.0f)); - prim->appendTexCoord(QVector2D(xtex + hwtex, ytex)); - - prim->appendVertex(patch1.points[12]); - prim->appendNormal(normal(0.0f, 0.5f)); - prim->appendTexCoord(QVector2D(xtex, ytex + hhtex)); - - prim->appendVertex(patch1.points[15]); - prim->appendNormal(normal(0.5f, 0.5f)); - prim->appendTexCoord(QVector2D(xtex + hwtex, ytex + hhtex)); - - prim->appendVertex(patch2.points[15]); - prim->appendNormal(normal(1.0f, 0.5f)); - prim->appendTexCoord(QVector2D(xtex + wtex, ytex + hhtex)); - - prim->appendVertex(patch3.points[15]); - prim->appendNormal(normal(0.5f, 1.0f)); - prim->appendTexCoord(QVector2D(xtex + hwtex, ytex + htex)); - - // Copy the indices for the corners of the new patches. - patch1.indices[0] = indices[0]; - patch1.indices[1] = topPointIndex; - patch1.indices[2] = leftPointIndex; - patch1.indices[3] = midPointIndex; - patch2.indices[0] = topPointIndex; - patch2.indices[1] = indices[1]; - patch2.indices[2] = midPointIndex; - patch2.indices[3] = rightPointIndex; - patch3.indices[0] = leftPointIndex; - patch3.indices[1] = midPointIndex; - patch3.indices[2] = indices[2]; - patch3.indices[3] = bottomPointIndex; - patch4.indices[0] = midPointIndex; - patch4.indices[1] = rightPointIndex; - patch4.indices[2] = bottomPointIndex; - patch4.indices[3] = indices[3]; -} - -// Recursively sub-divide a patch into triangles. -void QGLBezierPatch::recursiveSubDivide - (QGeometryData *prim, - int depth, qreal xtex, qreal ytex, qreal wtex, qreal htex) -{ - if (depth <= 1) { - convertToTriangles(prim, xtex, ytex, wtex, htex); - } else { - QGLBezierPatch patch1, patch2, patch3, patch4; - subDivide(patch1, patch2, patch3, patch4); - createNewCorners(patch1, patch2, patch3, patch4, prim, xtex, ytex, wtex, htex); - --depth; - qreal hwtex = wtex / 2.0f; - qreal hhtex = htex / 2.0f; - patch1.recursiveSubDivide(prim, depth, xtex, ytex, hwtex, hhtex); - patch2.recursiveSubDivide(prim, depth, xtex + hwtex, ytex, hwtex, hhtex); - patch3.recursiveSubDivide(prim, depth, xtex, ytex + hhtex, hwtex, hhtex); - patch4.recursiveSubDivide(prim, depth, xtex + hwtex, ytex + hhtex, hwtex, hhtex); - } -} - -void QGLBezierPatchesPrivate::subdivide(QGLBuilder *list) const -{ - QGeometryData prim; - int count = positions.size(); - for (int posn = 0; (posn + 15) < count; posn += 16) { - // Construct a QGLBezierPatch object from the next high-level patch. - QGLBezierPatch patch; - for (int vertex = 0; vertex < 16; ++vertex) - patch.points[vertex] = positions[posn + vertex]; - QVector2D tex1, tex2; - if (!textureCoords.isEmpty()) { - tex1 = textureCoords[(posn / 16) * 2]; - tex2 = textureCoords[(posn / 16) * 2 + 1]; - } else { - tex1 = QVector2D(0.0f, 0.0f); - tex2 = QVector2D(1.0f, 1.0f); - } - qreal xtex = tex1.x(); - qreal ytex = tex1.y(); - qreal wtex = tex2.x() - xtex; - qreal htex = tex2.y() - ytex; - for (int corner = 0; corner < 4; ++corner) { - QVector3D n = patch.normal(cornerS[corner], cornerT[corner]); - patch.indices[corner] = prim.count(); - prim.appendVertex(patch.points[cornerOffsets[corner]]); - prim.appendNormal(n); - prim.appendTexCoord - (QVector2D(xtex + wtex * cornerS[corner], - ytex + htex * cornerT[corner])); - } - - // Subdivide the patch and generate the final triangles. - patch.recursiveSubDivide(&prim, subdivisionDepth, - xtex, ytex, wtex, htex); - } - list->addTriangles(prim); -} - -static inline qreal combineResults(qreal result, qreal t) -{ - if (qIsNaN(result)) - return t; - if (t >= 0.0f) - return result < 0.0f ? t : qMin(result, t); - else - return result >= 0.0f ? result : qMax(result, t); -} - -qreal QGLBezierPatch::intersection - (qreal result, int depth, const QRay3D& ray, bool anyIntersection, - qreal xtex, qreal ytex, qreal wtex, qreal htex, QVector2D *tc) -{ - // Check the convex hull of the patch for an intersection. - // If no intersection with the convex hull, then there is - // no point subdividing this patch further. - QBox3D box; - for (int point = 0; point < 16; ++point) - box.unite(points[point]); - if (!box.intersects(ray)) - return result; - - // Are we at the lowest point of subdivision yet? - if (depth <= 1) { - // Divide the patch into two triangles and intersect with those. - QTriangle3D triangle1(points[0], points[3], points[12]); - qreal t = triangle1.intersection(ray); - if (!qIsNaN(t)) { - result = combineResults(result, t); - if (result == t) { - QVector2D uv = triangle1.uv(ray.point(t)); - QVector2D tp(xtex, ytex); - QVector2D tq(xtex + wtex, ytex); - QVector2D tr(xtex, ytex + htex); - *tc = uv.x() * tp + uv.y() * tq + (1 - uv.x() - uv.y()) * tr; - } - } else { - QTriangle3D triangle2(points[3], points[15], points[12]); - qreal t = triangle2.intersection(ray); - if (!qIsNaN(t)) { - result = combineResults(result, t); - if (result == t) { - QVector2D uv = triangle2.uv(ray.point(t)); - QVector2D tp(xtex + wtex, ytex); - QVector2D tq(xtex + wtex, ytex + htex); - QVector2D tr(xtex, ytex + htex); - *tc = uv.x() * tp + uv.y() * tq + (1 - uv.x() - uv.y()) * tr; - } - } - } - } else { - // Subdivide the patch to find the point of intersection. - QGLBezierPatch patch1, patch2, patch3, patch4; - subDivide(patch1, patch2, patch3, patch4); - --depth; - qreal hwtex = wtex / 2.0f; - qreal hhtex = htex / 2.0f; - result = patch1.intersection - (result, depth, ray, anyIntersection, - xtex, ytex, hwtex, hhtex, tc); - if (anyIntersection && !qIsNaN(result)) - return result; - result = patch2.intersection - (result, depth, ray, anyIntersection, - xtex + hwtex, ytex, hwtex, hhtex, tc); - if (anyIntersection && !qIsNaN(result)) - return result; - result = patch3.intersection - (result, depth, ray, anyIntersection, - xtex, ytex + hhtex, hwtex, hhtex, tc); - if (anyIntersection && !qIsNaN(result)) - return result; - result = patch4.intersection - (result, depth, ray, anyIntersection, - xtex + hwtex, ytex + hhtex, hwtex, hhtex, tc); - } - return result; -} - -qreal QGLBezierPatchesPrivate::intersection - (const QRay3D &ray, bool anyIntersection, QVector2D *texCoord, int *bestPatch) const -{ - int count = positions.size(); - qreal result = qSNaN(); - QVector2D tc; - if (bestPatch) - *bestPatch = -1; - for (int posn = 0; (posn + 15) < count; posn += 16) { - QGLBezierPatch patch; - for (int vertex = 0; vertex < 16; ++vertex) - patch.points[vertex] = positions[posn + vertex]; - QVector2D tex1, tex2; - if (!textureCoords.isEmpty()) { - tex1 = textureCoords[(posn / 16) * 2]; - tex2 = textureCoords[(posn / 16) * 2 + 1]; - } else { - tex1 = QVector2D(0.0f, 0.0f); - tex2 = QVector2D(1.0f, 1.0f); - } - qreal xtex = tex1.x(); - qreal ytex = tex1.y(); - qreal wtex = tex2.x() - xtex; - qreal htex = tex2.y() - ytex; - qreal prev = result; - result = patch.intersection - (result, subdivisionDepth, ray, anyIntersection, - xtex, ytex, wtex, htex, &tc); - if (bestPatch && result != prev) - *bestPatch = posn / 16; - if (anyIntersection && !qIsNaN(result)) - break; - } - if (texCoord && !qIsNaN(result)) - *texCoord = tc; - return result; -} - -/*! - Constructs an empty Bezier patch list. - - \sa setPositions() -*/ -QGLBezierPatches::QGLBezierPatches() - : d_ptr(new QGLBezierPatchesPrivate()) -{ -} - -/*! - Constructs a copy of \a other. - - \sa operator=() -*/ -QGLBezierPatches::QGLBezierPatches(const QGLBezierPatches &other) - : d_ptr(new QGLBezierPatchesPrivate(other.d_ptr.data())) -{ -} - -/*! - Destroys this Bezier patch list. -*/ -QGLBezierPatches::~QGLBezierPatches() -{ -} - -/*! - Assigns \a other to this Bezier patch list. -*/ -QGLBezierPatches &QGLBezierPatches::operator= - (const QGLBezierPatches &other) -{ - if (this != &other) - d_ptr->copy(other.d_ptr.data()); - return *this; -} - -/*! - Returns the positions of the vertices in the Bezier patches. - - \sa setPositions(), textureCoords() -*/ -QVector3DArray QGLBezierPatches::positions() const -{ - Q_D(const QGLBezierPatches); - return d->positions; -} - -/*! - Sets the \a positions of the vertices in the Bezier patches. - - \sa positions(), setTextureCoords() -*/ -void QGLBezierPatches::setPositions(const QVector3DArray &positions) -{ - Q_D(QGLBezierPatches); - d->positions = positions; -} - -/*! - Returns the texture co-ordinates for the Bezier patches. - Each patch consumes two elements from the texture - co-ordinate array, defining the opposite corners. - - The default is an empty array, which indicates that each - patch will generate texture co-ordinates in the range - (0, 0) to (1, 1). - - \sa setTextureCoords(), positions() -*/ -QVector2DArray QGLBezierPatches::textureCoords() const -{ - Q_D(const QGLBezierPatches); - return d->textureCoords; -} - -/*! - Sets the texture co-ordinates for the Bezier patches to - the elements of \a textureCoords. Each patch consumes - two elements from \a textureCoords, defining the opposite - corners. - - If \a textureCoords is empty, then each patch will generate - texture co-ordinates in the range (0, 0) to (1, 1). - - \sa textureCoords(), setPositions() -*/ -void QGLBezierPatches::setTextureCoords(const QVector2DArray &textureCoords) -{ - Q_D(QGLBezierPatches); - d->textureCoords = textureCoords; -} - -/*! - Returns the depth of subdivision to use when converting the - Bezier geometry into triangles. The default value is 4. - - \sa setSubdivisionDepth() -*/ -int QGLBezierPatches::subdivisionDepth() const -{ - Q_D(const QGLBezierPatches); - return d->subdivisionDepth; -} - -/*! - Sets the depth of subdivision to use when converting the - Bezier geometry into triangles to \a value. - - \sa subdivisionDepth() -*/ -void QGLBezierPatches::setSubdivisionDepth(int value) -{ - Q_D(QGLBezierPatches); - d->subdivisionDepth = value; -} - -/*! - Transforms the positions() in this Bezier geometry object - according to \a matrix. - - \sa transformed() -*/ -void QGLBezierPatches::transform(const QMatrix4x4 &matrix) -{ - Q_D(QGLBezierPatches); - d->positions.transform(matrix); -} - -/*! - Returns a new Bezier geometry object that results from transforming - this object's positions() according to \a matrix. - - \sa transform() -*/ -QGLBezierPatches QGLBezierPatches::transformed(const QMatrix4x4 &matrix) const -{ - QGLBezierPatches result(*this); - result.d_ptr->positions.transform(matrix); - return result; -} - -/*! - Returns true if \a ray intersects this Bezier geometry object; - false otherwise. - - \sa intersection() -*/ -bool QGLBezierPatches::intersects(const QRay3D &ray) const -{ - Q_D(const QGLBezierPatches); - return !qIsNaN(d->intersection(ray, true, 0, 0)); -} - -/*! - Returns the t value at which \a ray intersects this Bezier - geometry object, or not-a-number if there is no intersection. - - When the \a ray intersects this object, the return value is a - parametric value that can be passed to QRay3D::point() to determine - the actual intersection point, as shown in the following example: - - \code - qreal t = patches.intersection(ray); - QVector3D pt; - if (qIsNaN(t)) { - qWarning("no intersection occurred"); - else - pt = ray.point(t); - \endcode - - If \a ray intersects the object multiple times, the returned - t will be the smallest t value, corresponding to the first - intersection of the \a ray with the object. The t value may - be negative if the first intersection occurs in the reverse - direction of \a ray. - - The intersection is determined by subdividing the patches into - triangles and intersecting with those triangles. A pruning - algorithm is used to discard patches whose convex hull do not - intersect with \a ray. - - If \a texCoord is not null, then it will return the texture - co-ordinate of the intersection point. - - If \a patch is not null, then it will return the index of the - patch that contains the intersection, or -1 if there is no - intersection. - - \sa intersects() -*/ -qreal QGLBezierPatches::intersection(const QRay3D &ray, QVector2D *texCoord, int *patch) const -{ - Q_D(const QGLBezierPatches); - return d->intersection(ray, false, texCoord, patch); -} - -/*! - \relates QGLBezierPatches - - Subdivides the Bezier patch data in \a patches into triangles - and adds them to the specified display \a list. -*/ -QGLBuilder &operator<<(QGLBuilder &list, const QGLBezierPatches &patches) -{ - patches.d_ptr->subdivide(&list); - return list; -} - -QT_END_NAMESPACE diff --git a/src/threed/geometry/qglbezierpatches.h b/src/threed/geometry/qglbezierpatches.h deleted file mode 100644 index 4a4d042c..00000000 --- a/src/threed/geometry/qglbezierpatches.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLBEZIERPATCHES_H -#define QGLBEZIERPATCHES_H - -#include "qvector2darray.h" -#include "qvector3darray.h" -#include <QtCore/qscopedpointer.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class QGLBezierPatchesPrivate; -class QGLBuilder; -class QRay3D; - -class Q_QT3D_EXPORT QGLBezierPatches -{ -public: - QGLBezierPatches(); - QGLBezierPatches(const QGLBezierPatches &other); - virtual ~QGLBezierPatches(); - - QGLBezierPatches &operator=(const QGLBezierPatches &other); - - QVector3DArray positions() const; - void setPositions(const QVector3DArray &positions); - - QVector2DArray textureCoords() const; - void setTextureCoords(const QVector2DArray &textureCoords); - - int subdivisionDepth() const; - void setSubdivisionDepth(int value); - - void transform(const QMatrix4x4 &matrix); - QGLBezierPatches transformed(const QMatrix4x4 &matrix) const; - - bool intersects(const QRay3D &ray) const; - qreal intersection(const QRay3D &ray, QVector2D *texCoord = 0, int *patch = 0) const; - -private: - QScopedPointer<QGLBezierPatchesPrivate> d_ptr; - - Q_DECLARE_PRIVATE(QGLBezierPatches) - - friend Q_QT3D_EXPORT QGLBuilder &operator<<(QGLBuilder &list, const QGLBezierPatches &patches); -}; - -Q_QT3D_EXPORT QGLBuilder &operator<<(QGLBuilder &list, const QGLBezierPatches &patches); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/threed/geometry/qglbuilder.cpp b/src/threed/geometry/qglbuilder.cpp deleted file mode 100644 index 1a73d9ca..00000000 --- a/src/threed/geometry/qglbuilder.cpp +++ /dev/null @@ -1,1382 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglbuilder.h" -#include "qglbuilder_p.h" -#include "qglsection_p.h" -#include "qglmaterialcollection.h" -#include "qglpainter.h" -#include "qgeometrydata.h" -#include "qvector_utils_p.h" - -#include <QtGui/qvector2d.h> - -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QGLBuilder - \brief The QGLBuilder class constructs geometry for efficient display. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - \tableofcontents - - Use a QGLBuilder to build up vertex, index, texture and other data - during application initialization. The finalizedSceneNode() function - returns an optimized scene which can be efficiently and flexibly - displayed during frames of rendering. It is suited to writing loaders - for 3D models, and for programatically creating geometry. - - \section1 Geometry Building - - QGLBuilder makes the job of getting triangles on the GPU simple. It - calculates indices and normals for you, then uploads the data. While - it has addQuads() and other functions to deal with quads, all data is - represented as triangles for portability. - - The simplest way to use QGLBuilder is to send a set of geometry - values to it using QGeometryData in the constructor: - - \code - MyView::MyView() : QGLView() - { - // in the constructor construct a builder on the stack - QGLBuilder builder; - QGeometryData triangle; - QVector3D a(2, 2, 0); - QVector3D b(-2, 2, 0); - QVector3D c(0, -2, 0); - triangle.appendVertex(a, b, c); - - // When adding geometry, QGLBuilder automatically creates lighting normals - builder << triangle; - - // obtain the scene from the builder - m_scene = builder.finalizedSceneNode(); - - // apply effects at app initialization time - QGLMaterial *mat = new QGLMaterial; - mat->setDiffuseColor(Qt::red); - m_scene->setMaterial(mat); - } - \endcode - - Then during rendering the scene is used to display the results: - \code - MyView::paintGL(QGLPainter *painter) - { - m_scene->draw(painter); - } - \endcode - - QGLBuilder automatically generates index values and normals - on-the-fly during geometry building. During building, simply send - primitives to the builder as a sequence of vertices, and - vertices that are the same will be referenced by a single index - automatically. - - Primitives will have standard normals generated automatically - based on vertex winding. - - Consider the following code for OpenGL to draw a quad with corner - points A, B, C and D : - - \code - float vertices[12] = - { - -1.0, -1.0, -1.0, // A - 1.0, -1.0, -1.0, // B - 1.0, 1.0, 1.0, // C - -1.0, 1.0, 1.0 // D - }; - float normals[12] = { 0.0f }; - for (int i = 0; i < 12; i += 3) - { - normals[i] = 0.0; - normals[i+1] = -sqrt(2.0); - normals[i+2] = sqrt(2.0); - } - GLuint indices[6] = { - 0, 1, 2, // triangle A-B-C - 0, 2, 3 // triangle A-C-D - }; - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vertices); - glNormalPointer(3, GL_FLOAT, 0, normals); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices); - \endcode - - With QGLBuilder this code becomes: - - \code - float vertices[12] = - { - -1.0, -1.0, -1.0, // A - 1.0, -1.0, -1.0, // B - 1.0, 1.0, 1.0, // C - -1.0, 1.0, 1.0 // D - }; - QGLBuilder quad; - QGeometryData data; - data.appendVertexArray(QArray<QVector3D>::fromRawData( - reinterpret_cast<const QVector3D*>(vertices), 4)); - quad.addQuads(data); - \endcode - - The data primitive is added to the list, as two triangles, indexed to - removed the redundant double storage of B & C - just the same as the - OpenGL code. - - QGLBuilder will also calculate a normal for the quad and apply it - to the vertices. - - In this trivial example the indices are easily calculated, however - in more complex geometry it is easy to introduce bugs by trying - to manually control indices. Extra work is required to generate, - track and store the index values correctly. - - Bugs such as trying to index two vertices with different data - - one with texture data and one without - into one triangle can - easily result. The picture becomes more difficult when smoothing - groups are introduced - see below. - - Using indices is always preferred since it saves space on the GPU, - and makes the geometry perform faster during application run time. - - \section2 Removing Epsilon Errors - - Where vertices are generated by modelling packages or tools, or - during computation in code, very frequently rounding errors will - result in several vertices being generated that are actually - the same vertex but are separated by tiny amounts. At best these - duplications waste space on the GPU but at worst can introduce - visual artifacts that mar the image displayed. - - Closing paths, generating solids of rotation, or moving model - sections out and back can all introduce these types of epsilon - errors, resulting in "cracks" or artifacts on display. - - QGLBuilder's index generation process uses a fuzzy match that - coalesces all vertex values at a point - even if they are out by - a tiny amount - and references them with a single index. - - \section2 Lighting Normals and Null Triangles - - QGLBuilder functions calculate lighting normals, when building - geometry. This saves the application programmer from having to write - code to calculate them. Normals for each triangle (a, b, c) are - calculated as the QVector3D::normal(a, b, c). - - If lighting normals are explicitly supplied when using QGLBuilder, - then this calculation is not done. This may save on build time. - - As an optimization, QGLBuilder skips null triangles, that is ones - with zero area, where it can. Such triangles generate no fragments on - the GPU, and thus do not display but nonetheless can take up space - and processing power. - - Null triangles can easily occur when calculating vertices results - in two vertices coinciding, or three vertices lying on the same line. - - This skipping is done using the lighting normals cross-product. If the - cross-product is a null vector then the triangle is null. - - When lighting normals are specified explicitly the skipping - optimization is suppressed, so if for some reason null triangles are - required to be retained, then specify normals for each logical vertex. - - See the documentation below of the individual addTriangle() and other - functions for more details. - - \section2 Raw Triangle Mode - - Where generation of indices and normals is not needed - for example if - porting an existing application, it is possible to do a raw import of - triangle data, without using any of QGLBuilder's processing. - - To do this ensure that indices are placed in the QGeometryData passed to - the addTriangles() function, and this will trigger \bold{raw triangle} mode. - - When adding triangles in this way ensure that all appropriate values - have been correctly set, and that the normals, indices and other data - are correctly calculated, since no checking is done. - - When writing new applications, simply leave construction of normals and - indices to the QGLBuilder - - \section1 Rendering and QGLSceneNode items. - - QGLSceneNodes are used to manage application of local transformations, - materials and effects. - - QGLBuilder generates a root level QGLSceneNode, which can be accessed - with the sceneNode() function. Under this a new node is created for - each section of geometry, and also by using pushNode() and popNode(). - - To organize geometry for painting with different materials and effects - call the newNode() function: - - \code - QGLSceneNode *box = builder.newNode(); - box->setMaterial(wood); - \endcode - - Many nodes may be created this way, but they will be optimized into - a small number of buffers under the one scene when the - finalizedSceneNode() function is called. - - \image soup.png - - Here the front can is a set of built geometry and the other two are - scene nodes that reference it, without copying any geometry. - - \snippet qt3d/builder/builder.cpp 0 - - QGLSceneNodes can be used after the builder is created to cheaply - copy and redisplay the whole scene. Or to reference parts of the geometry - use the functions newNode() or pushNode() and popNode() to manage - QGLSceneNode generation while building geometry. - - To draw the resulting built geometry simply call the draw method of the - build geometry. - - \snippet qt3d/builder/builder.cpp 1 - - Call the \l{QGLSceneNode::palette()}{palette()} function on the sceneNode() - to get the QGLMaterialCollection for the node, and place textures - and materials into it. - - Built geometry will typically share the one palette. Either create a - palette, and pass it to the \l{QGLBuilder::QGLBuilder()}{constructor}; - or pass no arguments to the constructor and the QGLBuilder - will create a palette: - - \snippet qt3d/builder/builder.cpp 2 - - These may then be applied as needed throughout the building of the - geometry using the integer reference, \c{canMat} in the above code. - - See the QGLSceneNode documentation for more. - - \section1 Using Sections - - During initialization of the QGLBuilder, while accumulating - geometry, the geometry data in a QGLBuilder is placed into - sections - there must be at least one section. - - Call the newSection() function to create a new section: - - \snippet qt3d/builder/builder.cpp 3 - - Here separate sections for the rounded outside cylinder and flat top and - bottom of the soup can model makes for the appearance of a sharp edge - between them. If the sides and top and bottom were in the same section - QGLBuilder would attempt to average the normals around the edge resulting - in an unrealistic effect. - - In 3D applications this concept is referred to as - \l{http://www.google.com/search?smoothing+groups}{smoothing groups}. Within - a section (smoothing group) all normals are averaged making it appear - as one smoothly shaded surface. - - The can has 3 smoothing groups - bottom, top and sides. - - This mesh of a Q is a faceted model - it has 0 smoothing groups: - - \image faceted-q.png - - To create geometry with a faceted appearance call newSection() with - an argument of QGL::Faceted thus \c{newSection(QGL::Faceted)}. - - Faceted geometry is suitable for small models, where hard edges are - desired between every face - a dice, gem or geometric solid for example. - - If no section has been created when geometry is added a new section is - created automatically. This section will have its smoothing set - to QGL::Smooth. - - To create a faceted appearance rather than accepting the automatically - created section the << operator can also be used: - - \code - QGLBuilder builder; - QGeometryData triangles; - triangles.appendVertices(a, b, c); - builder << QGL::Faceted << triangles; - \endcode - - \section2 Geometry Data in a Section - - Management of normals and vertices for smoothing, and other data is - handled automatically by the QGLBuilder instance. - - Within a section, incoming geometry data will be coalesced and - indices created to reference the fewest possible copies of the vertex - data. For example, in smooth geometry all copies of a vertex are - coalesced into one, and referenced by indices. - - One of the few exceptions to this is the case where texture data forms - a \i seam and a copy of a vertex must be created to carry the two - texture coordinates either side of the seam. - - \image texture-seam.png - - Coalescing has the effect of packing geometry data into the - smallest space possible thus improving cache coherence and performance. - - Again all this is managed automatically by QGLBuilder and all - that is required is to create smooth or faceted sections, and add - geometry to them. - - Each QGLSection references a contiguous range of vertices in a - QGLBuilder. - - \section1 Finalizing and Retrieving the Scene - - Once the geometry has been accumulated in the QGLBuilder instance, the - finalizedSceneNode() method must be called to retrieve the optimized - scene. This function serves to normalize the geometry and optimize - it for display. - - While it may be convenient to get pointers to sub nodes in the scene - during construction, it is important to retrieve the root of the scene - so that the memory consumed by the scene can be recovered. The builder - will create a QGLMaterialCollection; and there may be geometry, materials - and other resources: these are all parented onto the root scene node. - These can easily be recovered by deleting the root scene node: - - \code - MyView::MyView() : QGLView() - { - // in the constructor construct a builder on the stack - QGLBuilder builder; - - // add geometry as shown above - builder << triangles; - - // obtain the scene from the builder & take ownership - m_scene = builder.finalizedSceneNode(); - } - - MyView::~MyView() - { - // recover all scene resources - delete m_scene; - } - \endcode - - Alternatively set the scene's parent to ensure resource recovery - \c{m_scene->setParent(this)}. - - -*/ - -QGLBuilderPrivate::QGLBuilderPrivate(QGLBuilder *parent) - : currentSection(0) - , currentNode(0) - , rootNode(0) - , defThreshold(5) - , q(parent) -{ -} - -QGLBuilderPrivate::~QGLBuilderPrivate() -{ - qDeleteAll(sections); - if (rootNode) - { - qWarning("Destroying QGLBuilder but finalizedSceneNode() not called"); - delete rootNode; - } -} - -/*! - Construct a new QGLBuilder using \a materials for the palette. If the - \a materials argument is null, then a new palette is created. -*/ -QGLBuilder::QGLBuilder(QGLMaterialCollection *materials) - : dptr(new QGLBuilderPrivate(this)) -{ - dptr->rootNode = new QGLSceneNode; - if (!materials) - materials = new QGLMaterialCollection(dptr->rootNode); - dptr->rootNode->setPalette(materials); -} - -/*! - Destroys this QGLBuilder recovering any resources. -*/ -QGLBuilder::~QGLBuilder() -{ - delete dptr; -} - -/*! - Helper function to calculate the normal for and set it on vertices - in \a i, \a j and \a k in triangle data \a p. If the triangle in - data \a p is a null triangle (area == 0) then the function returns - false, otherwise it returns true. -*/ -static inline void setNormals(int i, int j, int k, QGeometryData &p, const QVector3D &n) -{ - p.normal(i) = n; - p.normal(j) = n; - p.normal(k) = n; -} - -static bool qCalculateNormal(int i, int j, int k, QGeometryData &p, QVector3D *vec = 0) -{ - QVector3D norm; - QVector3D *n = &norm; - if (vec) - n = vec; - bool nullTriangle = false; - *n = QVector3D::crossProduct(p.vertexAt(j) - p.vertexAt(i), - p.vertexAt(k) - p.vertexAt(j)); - if (qFskIsNull(n->x())) - n->setX(0.0f); - if (qFskIsNull(n->y())) - n->setY(0.0f); - if (qFskIsNull(n->z())) - n->setZ(0.0f); - if (n->isNull()) - { - nullTriangle = true; - } - else - { - setNormals(i, j, k, p, *n); - } - return nullTriangle; -} - -/*! - \internal - Helper function to actually add the vertices to geometry. -*/ -void QGLBuilderPrivate::addTriangle(int i, int j, int k, - const QGeometryData &p, int &count) -{ - if (currentSection == 0) - q->newSection(); - QLogicalVertex a(p, i); - QLogicalVertex b(p, j); - QLogicalVertex c(p, k); - currentSection->append(a, b, c); - count += 3; -} - -/*! - Add \a triangles - a series of one or more triangles - to this builder. - - The data is broken into groups of 3 vertices, each processed as a triangle. - - If \a triangles has less than 3 vertices this function exits without - doing anything. Any vertices at the end of the list under a multiple - of 3 are ignored. - - If no normals are supplied in \a triangles, a normal is calculated; as - the cross-product \c{(b - a) x (c - a)}, for each group of 3 - logical vertices \c{a(triangle, i), b(triangle, i+1), c(triangle, i+2)}. - - In the case of a degenerate triangle, where the cross-product is null, - that triangle is skipped. Supplying normals suppresses this behaviour - (and means any degenerate triangles will be added to the geometry). - - \bold{Raw Triangle Mode} - - If \a triangles has indices specified then no processing of any kind is - done and all the geometry is simply dumped in to the builder. - - This \bold{raw triangle} mode is for advanced use, and it is assumed that - the user knows what they are doing, in particular that the indices - supplied are correct, and normals are supplied and correct. - - Normals are not calculated in raw triangle mode, and skipping of null - triangles is likewise not performed. See the section on - \l{raw-triangle-mode}{raw triangle mode} - in the class documentation above. - - \sa addQuads(), operator>>() -*/ -void QGLBuilder::addTriangles(const QGeometryData &triangles) -{ - if (triangles.count() < 3) - return; - if (triangles.indexCount() > 0) - { - // raw triangle mode - if (dptr->currentSection == 0) - newSection(); - dptr->currentSection->appendGeometry(triangles); - dptr->currentSection->appendIndices(triangles.indices()); - dptr->currentNode->setCount(dptr->currentNode->count() + triangles.indexCount()); - } - else - { - QGeometryData t = triangles; - bool calcNormal = !t.hasField(QGL::Normal); - if (calcNormal) - { - QVector3DArray nm(t.count()); - t.appendNormalArray(nm); - } - bool skip = false; - int k = 0; - for (int i = 0; i < t.count() - 2; i += 3) - { - if (calcNormal) - skip = qCalculateNormal(i, i+1, i+2, t); - if (!skip) - dptr->addTriangle(i, i+1, i+2, t, k); - } - dptr->currentNode->setCount(dptr->currentNode->count() + k); - } -} - -/*! - Add \a quads - a series of one or more quads - to this builder. - - If \a quads has less than four vertices this function exits without - doing anything. - - One normal per quad is calculated if \a quads does not have normals. - For this reason quads should have all four vertices in the same plane. - If the vertices do not lie in the same plane, use addTriangleStrip() - to add two adjacent triangles instead. - - Since internally \l{geometry-building}{quads are stored as two triangles}, - each quad is actually divided in half into two triangles. - - Degenerate triangles are skipped in the same way as addTriangles(). - - \sa addTriangles(), addTriangleStrip() -*/ -void QGLBuilder::addQuads(const QGeometryData &quads) -{ - if (quads.count() < 4) - return; - QGeometryData q = quads; - bool calcNormal = !q.hasField(QGL::Normal); - if (calcNormal) - { - QVector3DArray nm(q.count()); - q.appendNormalArray(nm); - } - bool skip = false; - int k = 0; - QVector3D norm; - for (int i = 0; i < q.count(); i += 4) - { - if (calcNormal) - skip = qCalculateNormal(i, i+1, i+2, q, &norm); - if (!skip) - dptr->addTriangle(i, i+1, i+2, q, k); - if (skip) - skip = qCalculateNormal(i, i+2, i+3, q, &norm); - if (!skip) - { - if (calcNormal) - setNormals(i, i+2, i+3, q, norm); - dptr->addTriangle(i, i+2, i+3, q, k); - } - } - dptr->currentNode->setCount(dptr->currentNode->count() + k); -} - -/*! - Adds to this section a set of connected triangles defined by \a fan. - - N triangular faces are generated, where \c{N == fan.count() - 2}. Each - face contains the 0th vertex in \a fan, followed by the i'th and i+1'th - vertex - where i takes on the values from 1 to \c{fan.count() - 1}. - - If \a fan has less than three vertices this function exits without - doing anything. - - This function is similar to the OpenGL mode GL_TRIANGLE_FAN. It - generates a number of triangles all sharing one common vertex, which - is the 0'th vertex of the \a fan. - - Normals are calculated as for addTriangle(), given the above ordering. - There is no requirement or assumption that all triangles lie in the - same plane. Degenerate triangles are skipped in the same way as - addTriangles(). - - \sa addTriangulatedFace() -*/ -void QGLBuilder::addTriangleFan(const QGeometryData &fan) -{ - if (fan.count() < 3) - return; - QGeometryData f = fan; - bool calcNormal = !f.hasField(QGL::Normal); - if (calcNormal) - { - QVector3DArray nm(f.count()); - f.appendNormalArray(nm); - } - int k = 0; - bool skip = false; - for (int i = 1; i < f.count() - 1; ++i) - { - if (calcNormal) - skip = qCalculateNormal(0, i, i+1, f); - if (!skip) - dptr->addTriangle(0, i, i+1, f, k); - } - dptr->currentNode->setCount(dptr->currentNode->count() + k); -} - -/*! - Adds to this section a set of connected triangles defined by \a strip. - - N triangular faces are generated, where \c{N == strip.count() - 2}. - The triangles are generated from vertices 0, 1, & 2, then 2, 1 & 3, - then 2, 3 & 4, and so on. In other words every second triangle has - the first and second vertices switched, as a new triangle is generated - from each successive set of three vertices. - - If \a strip has less than three vertices this function exits without - doing anything. - - Normals are calculated as for addTriangle(), given the above ordering. - - This function is very similar to the OpenGL mode GL_TRIANGLE_STRIP. It - generates triangles along a strip whose two sides are the even and odd - vertices. - - \sa addTriangulatedFace() -*/ -void QGLBuilder::addTriangleStrip(const QGeometryData &strip) -{ - if (strip.count() < 3) - return; - QGeometryData s = strip; - bool calcNormal = !s.hasField(QGL::Normal); - if (calcNormal) - { - QVector3DArray nm(s.count()); - s.appendNormalArray(nm); - } - bool skip = false; - int k = 0; - for (int i = 0; i < s.count() - 2; ++i) - { - if (i % 2) - { - if (calcNormal) - skip = qCalculateNormal(i+1, i, i+2, s); - if (!skip) - dptr->addTriangle(i+1, i, i+2, s, k); - } - else - { - if (calcNormal) - skip = qCalculateNormal(i, i+1, i+2, s); - if (!skip) - dptr->addTriangle(i, i+1, i+2, s, k); - } - } - dptr->currentNode->setCount(dptr->currentNode->count() + k); -} - -/*! - Adds to this section a set of quads defined by \a strip. - - If \a strip has less than four vertices this function exits without - doing anything. - - The first quad is formed from the 0'th, 2'nd, 3'rd and 1'st vertices. - The second quad is formed from the 2'nd, 4'th, 5'th and 3'rd vertices, - and so on, as shown in this diagram: - - \image quads.png - - One normal per quad is calculated if \a strip does not have normals. - For this reason quads should have all four vertices in the same plane. - If the vertices do not lie in the same plane, use addTriangles() instead. - - Since internally \l{geometry-building}{quads are stored as two triangles}, - each quad is actually divided in half into two triangles. - - Degenerate triangles are skipped in the same way as addTriangles(). - - \sa addQuads(), addTriangleStrip() -*/ -void QGLBuilder::addQuadStrip(const QGeometryData &strip) -{ - if (strip.count() < 4) - return; - QGeometryData s = strip; - bool calcNormal = !s.hasField(QGL::Normal); - if (calcNormal) - { - QVector3DArray nm(s.count()); - s.appendNormalArray(nm); - } - bool skip = false; - QVector3D norm; - int k = 0; - for (int i = 0; i < s.count() - 3; i += 2) - { - if (calcNormal) - skip = qCalculateNormal(i, i+2, i+3, s, &norm); - if (!skip) - dptr->addTriangle(i, i+2, i+3, s, k); - if (skip) - skip = qCalculateNormal(i, i+3, i+1, s, &norm); - if (!skip) - { - if (calcNormal) - setNormals(i, i+3, i+1, s, norm); - dptr->addTriangle(i, i+3, i+1, s, k); - } - } - dptr->currentNode->setCount(dptr->currentNode->count() + k); -} - -/*! - Adds to this section a polygonal face made of triangular sub-faces, - defined by \a face. The 0'th vertex is used for the center, while - the subsequent vertices form the perimeter of the face, which must - at minimum be a triangle. - - If \a face has less than four vertices this function exits without - doing anything. - - This function provides functionality similar to the OpenGL mode GL_POLYGON, - except it divides the face into sub-faces around a \bold{central point}. - The center and perimeter vertices must lie in the same plane (unlike - triangle fan). If they do not normals will be incorrectly calculated. - - \image triangulated-face.png - - Here the sub-faces are shown divided by green lines. Note how this - function handles some re-entrant (non-convex) polygons, whereas - addTriangleFan will not support such polygons. - - If required, the center point can be calculated using the center() function - of QGeometryData: - - \code - QGeometryData face; - face.appendVertex(perimeter.center()); // perimeter is a QGeometryData - face.appendVertices(perimeter); - builder.addTriangulatedFace(face); - \endcode - - N sub-faces are generated where \c{N == face.count() - 2}. - - Each triangular sub-face consists of the center; followed by the \c{i'th} - and \c{((i + 1) % N)'th} vertex. The last face generated then is - \c{(center, face[N - 1], face[0]}, the closing face. Note that the closing - face is automatically created, unlike addTriangleFan(). - - If no normals are supplied in the vertices of \a face, normals are - calculated as per addTriangle(). One normal is calculated, since a - faces vertices lie in the same plane. - - Degenerate triangles are skipped in the same way as addTriangles(). - - \sa addTriangleFan(), addTriangles() -*/ -void QGLBuilder::addTriangulatedFace(const QGeometryData &face) -{ - if (face.count() < 4) - return; - QGeometryData f; - f.appendGeometry(face); - int cnt = f.count(); - bool calcNormal = !f.hasField(QGL::Normal); - if (calcNormal) - { - QVector3DArray nm(cnt); - f.appendNormalArray(nm); - } - bool skip = false; - QVector3D norm; - int k = 0; - for (int i = 1; i < cnt; ++i) - { - int n = i + 1; - if (n == cnt) - n = 1; - if (calcNormal) - { - skip = qCalculateNormal(0, i, n, f); - if (norm.isNull() && !skip) - { - norm = f.normalAt(0); - for (int i = 0; i < cnt; ++i) - f.normal(i) = norm; - } - } - if (!skip) - dptr->addTriangle(0, i, n, f, k); - } - dptr->currentNode->setCount(dptr->currentNode->count() + k); -} - -/*! - Add a series of quads by 'interleaving' \a top and \a bottom. - - This function behaves like quadStrip(), where the odd-numbered vertices in - the input primitive are from \a top and the even-numbered vertices from - \a bottom. - - It is trivial to do extrusions using this function: - - \code - // create a series of quads for an extruded edge along -Y - addQuadsInterleaved(topEdge, topEdge.translated(QVector3D(0, -1, 0)); - \endcode - - N quad faces are generated where \c{N == min(top.count(), bottom.count() - 1}. - If \a top or \a bottom has less than 2 elements, this functions does - nothing. - - Each face is formed by the \c{i'th} and \c{(i + 1)'th} - vertices of \a bottom, followed by the \c{(i + 1)'th} and \c{i'th} - vertices of \a top. - - If the vertices in \a top and \a bottom are the perimeter vertices of - two polygons then this function can be used to generate quads which form - the sides of a \l{http://en.wikipedia.org/wiki/Prism_(geometry)}{prism} - with the polygons as the prisms top and bottom end-faces. - - \image quad-extrude.png - - In the diagram above, the \a top is shown in orange, and the \a bottom in - dark yellow. The first generated quad, (a, b, c, d) is generated in - the order shown by the blue arrow. - - To create such a extruded prismatic solid, complete with top and bottom cap - polygons, given just the top edge do this: - \code - QGeometryData top = buildTopEdge(); - QGeometryData bottom = top.translated(QVector3D(0, 0, -1)); - builder.addQuadsInterleaved(top, bottom); - builder.addTriangulatedFace(top); - builder.addTriangulatedFace(bottom.reversed()); - \endcode - The \a bottom QGeometryData must be \bold{reversed} so that the correct - winding for an outward facing polygon is obtained. -*/ -void QGLBuilder::addQuadsInterleaved(const QGeometryData &top, - const QGeometryData &bottom) -{ - if (top.count() < 2 || bottom.count() < 2) - return; - QGeometryData zipped = bottom.interleavedWith(top); - bool calcNormal = !zipped.hasField(QGL::Normal); - if (calcNormal) - { - QVector3DArray nm(zipped.count()); - zipped.appendNormalArray(nm); - } - bool skip = false; - QVector3D norm; - int k = 0; - for (int i = 0; i < zipped.count() - 2; i += 2) - { - if (calcNormal) - skip = qCalculateNormal(i, i+2, i+3, zipped, &norm); - if (!skip) - dptr->addTriangle(i, i+2, i+3, zipped, k); - if (skip) - skip = qCalculateNormal(i, i+3, i+1, zipped, &norm); - if (!skip) - { - if (calcNormal) - setNormals(i, i+3, i+1, zipped, norm); - dptr->addTriangle(i, i+3, i+1, zipped, k); - } - } - dptr->currentNode->setCount(dptr->currentNode->count() + k); -} - -/*! - \fn void QGLBuilder::addPane(QSizeF size) - Convenience function to create a quad centered on the origin, - lying in the Z=0 plane, with width (x dimension) and height - (y dimension) specified by \a size. -*/ - -/*! - \fn void QGLBuilder::addPane(qreal size) - Convenience method to add a single quad of dimensions \a size wide by - \a size high in the z = 0 plane, centered on the origin. The quad has - texture coordinates of (0, 0) at the bottom left and (1, 1) at the top - right. The default value for \a size is 1.0, resulting in a quad - from QVector3D(-0.5, -0.5, 0.0) to QVector3D(0.5, 0.5, 0.0). -*/ - -/*! - \internal -*/ -void QGLBuilderPrivate::adjustSectionNodes(QGLSection *sec, - int offset, const QGeometryData &geom) -{ - QList<QGLSceneNode*> children = sec->nodes(); - QList<QGLSceneNode*>::iterator it = children.begin(); - QList<QGLSceneNode*> deleted; - for ( ; it != children.end(); ++it) - adjustNodeTree(*it, offset, geom, deleted); -} - -/*! - \internal - Adjust \a top by incrementing its start by \a offset, and setting its - geometry to \a geom. Find the cumulative total of indexes - - QGLSceneNode::count() - for \a top and all its children. If this total is - equal to zero, then delete that node. -*/ -int QGLBuilderPrivate::adjustNodeTree(QGLSceneNode *top, - int offset, const QGeometryData &geom, - QList<QGLSceneNode*> &deleted) -{ - int totalItems = 0; - if (top && !deleted.contains(top)) - { - top->setStart(top->start() + offset); - top->setGeometry(geom); - totalItems = top->count(); - QList<QGLSceneNode*> children = top->children(); - QList<QGLSceneNode*>::iterator it = children.begin(); - for ( ; it != children.end(); ++it) - { - totalItems += adjustNodeTree(*it, offset, geom, deleted); - } - if (totalItems == 0 && top->objectName().isEmpty()) - { - delete top; - deleted.append(top); - } - } - return totalItems; -} - -/*! - \internal - Returns a count of all the items referenced by this node - and all its children. -*/ -static int recursiveCount(QGLSceneNode *top) -{ - int totalItems = 0; - if (top) - { - totalItems = top->count(); - QList<QGLSceneNode*> children = top->children(); - QList<QGLSceneNode*>::const_iterator it = children.constBegin(); - for ( ; it != children.constEnd(); ++it) - totalItems += recursiveCount(*it); - } - return totalItems; -} - -static int nodeCount(const QList<QGLSceneNode*> &list) -{ - int total = 0; - QList<QGLSceneNode*>::const_iterator it = list.constBegin(); - for ( ; it != list.constEnd(); ++it) - total += recursiveCount(*it); - return total; -} - -static inline void warnIgnore(int secCount, QGLSection *s, int vertCount, int nodeCount, - const char *msg) -{ - qWarning("Ignoring section %d (%p) with %d vertices and" - " %d indexes - %s", secCount, s, vertCount, nodeCount, msg); -} - -/*! - Finish the building of this geometry, optimize it for rendering, and return a - pointer to the detached top-level scene node (root node). - - Since the scene is detached from the builder object, the builder itself - may be deleted or go out of scope while the scene lives on: - - \code - void MyView::MyView() - { - QGLBuilder builder; - // construct geometry - m_thing = builder.finalizedSceneNode(); - } - - void MyView::~MyView() - { - delete m_thing; - } - - void MyView::paintGL() - { - m_thing->draw(painter); - } - \endcode - - The root node will have a child node for each section that was created - during geometry building. - - This method must be called exactly once after building the scene. - - \bold{Calling code takes ownership of the scene.} In particular take care - to either explicitly destroy the scene when it is no longer needed - as shown - above. - - For more complex applications parent each finalized scene node onto a QObject - so it will be implictly cleaned up by Qt. If you use QGLSceneNode::setParent() - to do this, you can save an explicit call to addNode() since if setParent() - detects that the new parent is a QGLSceneNode it will call addNode() for you: - - \code - // here a top level node for the app is created, and parented to the view - QGLSceneNode *topNode = new QGLSceneNode(this); - - QGLBuilder b1; - // build geometry - - QGLSceneNode *thing = b1.finalizedSceneNode(); - - // does a QObject::setParent() to manage memory, and also adds to the scene - // graph, so no need to call topNode->addNode(thing) - thing->setParent(topNode); - - QGLBuilder b2; - // build more geometry - QGLSceneNode *anotherThing = b2.finalizedSceneNode(); - - // again parent on get addNode for free - anotherThing->setParent(topNode); - \endcode - - If this builder is destroyed without calling this method to take - ownership of the scene, a warning will be printed on the console and the - scene will be deleted. If this method is called more than once, on the - second and subsequent calls a warning is printed and NULL is returned. - - This function does the following: - \list - \o packs all geometry data from sections into QGLSceneNode instances - \o recalculates QGLSceneNode start() and count() for the scene - \o deletes all QGLBuilder's internal data structures - \o returns the top level scene node that references the geometry - \o sets the internal pointer to the top level scene node to NULL - \endlist - - \sa sceneNode() -*/ -QGLSceneNode *QGLBuilder::finalizedSceneNode() -{ - if (dptr->rootNode == 0) - { - qWarning("QGLBuilder::finalizedSceneNode() called twice"); - return 0; - } - QGeometryData g; - QMap<quint32, QGeometryData> geos; - QMap<QGLSection*, int> offsets; - for (int i = 0; i < dptr->sections.count(); ++i) - { - // pack sections that have the same fields into one geometry - QGLSection *s = dptr->sections.at(i); - QGL::IndexArray indices = s->indices(); - int icnt = indices.size(); - int ncnt = nodeCount(s->nodes()); - int scnt = s->count(); - if (scnt == 0 || icnt == 0 || ncnt == 0) - { - if (!qgetenv("Q_WARN_EMPTY_MESH").isEmpty()) - { - if (ncnt == 0) - warnIgnore(scnt, s, icnt, ncnt, "nodes empty"); - else if (scnt == 0) - warnIgnore(scnt, s, icnt, ncnt, "geometry count zero"); - else - warnIgnore(scnt, s, icnt, ncnt, "index count zero"); - } - continue; - } - s->normalizeNormals(); - int sectionOffset = 0; - int sectionIndexOffset = 0; - if (geos.contains(s->fields())) - { - QGeometryData &gd = geos[s->fields()]; - sectionOffset = gd.count(); - sectionIndexOffset = gd.indexCount(); - offsets.insert(s, sectionIndexOffset); - gd.appendGeometry(*s); - for (int i = 0; i < icnt; ++i) - indices[i] += sectionOffset; - gd.appendIndices(indices); - } - else - { - g = QGeometryData(*s); - geos.insert(s->fields(), g); - } - } - while (dptr->sections.count() > 0) - { - QGLSection *s = dptr->sections.takeFirst(); - dptr->adjustSectionNodes(s, offsets[s], geos[s->fields()]); - delete s; - } - QGLSceneNode *tmp = dptr->rootNode; - dptr->rootNode = 0; // indicates root node detached - return tmp; -} - -/*! - Creates a new section with smoothing mode set to \a smooth. By default - \a smooth is QGL::Smooth. - - A section must be created before any geometry or new nodes can be added - to the builder. However one is created automatically by addTriangle() - and the other add functions; and also by newNode(), pushNode() or popNode() - if needed. - - The internal node stack - see pushNode() and popNode() - is cleared, - and a new top-level QGLSceneNode is created for this section by calling - newNode(). - - \sa newNode(), pushNode() -*/ -void QGLBuilder::newSection(QGL::Smoothing smooth) -{ - new QGLSection(this, smooth); // calls addSection -} - -void QGLBuilder::addSection(QGLSection *sec) -{ - dptr->currentSection = sec; - sec->setMapThreshold(dptr->defThreshold); - dptr->sections.append(sec); - dptr->nodeStack.clear(); - newNode(); -} - -/*! - \internal - Returns the current section, in which new geometry is being added. -*/ -QGLSection *QGLBuilder::currentSection() const -{ - return dptr->currentSection; -} - -/*! - \internal - Returns a list of the sections of the geometry in this builder. -*/ -QList<QGLSection*> QGLBuilder::sections() const -{ - return dptr->sections; -} - -/*! - \internal - Test function only. -*/ -void QGLBuilder::setDefaultThreshold(int t) -{ - dptr->defThreshold = t; -} - -/*! - Returns the root scene node of the geometry created by this builder. - - \sa newNode(), newSection() -*/ -QGLSceneNode *QGLBuilder::sceneNode() -{ - return dptr->rootNode; -} - -/*! - Creates a new QGLSceneNode and makes it current. A pointer to the new - node is returned. The node is added into the scene at the same level - as the currentNode(). - - The node is set to reference the geometry starting from the next - vertex created, such that currentNode()->start() will return the - index of this next vertex. - - \sa newSection() -*/ -QGLSceneNode *QGLBuilder::newNode() -{ - if (dptr->currentSection == 0) - { - newSection(); // calls newNode() - return dptr->currentNode; - } - QGLSceneNode *parentNode = dptr->rootNode; - if (dptr->nodeStack.count() > 0) - parentNode = dptr->nodeStack.last(); - dptr->currentNode = new QGLSceneNode(parentNode); - dptr->currentNode->setPalette(parentNode->palette()); - dptr->currentNode->setStart(dptr->currentSection->indexCount()); - if (dptr->nodeStack.count() == 0) - dptr->currentSection->addNode(dptr->currentNode); - return dptr->currentNode; -} - -/*! - Returns a pointer to the current scene node, within the current section. - - If there is no current section then newSection() will be called to - create one. - - \sa newNode(), newSection() -*/ -QGLSceneNode *QGLBuilder::currentNode() -{ - if (dptr->currentSection == 0) - newSection(); // calls newNode() - return dptr->currentNode; -} - -/*! - Creates a new scene node that is a child of the current node and, - makes it the current node. A pointer to the new node is returned. - The previous current node is saved on a stack and it may - be made current again by calling popNode(). - - \sa popNode(), newNode() -*/ -QGLSceneNode *QGLBuilder::pushNode() -{ - if (dptr->currentSection == 0) - newSection(); // calls newNode() - QGLSceneNode *parentNode = dptr->currentNode; - dptr->nodeStack.append(parentNode); - dptr->currentNode = new QGLSceneNode(parentNode); - dptr->currentNode->setStart(dptr->currentSection->indexCount()); - dptr->currentNode->setPalette(parentNode->palette()); - return dptr->currentNode; -} - -/*! - Removes the node from the top of the stack, makes a copy of it, and - makes the copy current. - - If the stack is empty, behaviour is undefined. In debug mode, calling - this function when the stack is empty will cause an assert. - - A pointer to the new current node is returned. - - The node is set to reference the geometry starting from the next - vertex created, such that QGLSceneNode::start() will return the - index of this next vertex. - - \sa pushNode(), newNode() -*/ -QGLSceneNode *QGLBuilder::popNode() -{ - if (dptr->currentSection == 0) - newSection(); // calls newNode() - int cnt = dptr->currentSection->indexCount(); - QGLSceneNode *s = dptr->nodeStack.takeLast(); // assert here - QGLSceneNode *parentNode = dptr->rootNode; - if (dptr->nodeStack.count() > 0) - parentNode = dptr->nodeStack.last(); - dptr->currentNode = s->cloneNoChildren(parentNode); - dptr->currentNode->setStart(cnt); - dptr->currentNode->setCount(0); - dptr->currentNode->setPalette(parentNode->palette()); - if (dptr->nodeStack.count() == 0) - dptr->currentSection->addNode(dptr->currentNode); - return dptr->currentNode; -} - -/*! - Returns the palette for this builder. This is the QGLMaterialCollection - pointer that was passed to the constructor; or if that was null a new - QGLMaterialCollection. This function returns the same result as - \c{sceneNode()->palette()}. - - \sa sceneNode() -*/ -QGLMaterialCollection *QGLBuilder::palette() -{ - return dptr->rootNode->palette(); -} - -/*! - \relates QGLBuilder - Convenience operator for creating a new section in \a builder with \a smoothing. - - \code - // equivalent to builder.newSection(QGL::Faceted) - builder << QGL::Faceted; - \endcode -*/ -QGLBuilder& operator<<(QGLBuilder& builder, const QGL::Smoothing& smoothing) -{ - builder.newSection(smoothing); - return builder; -} - -/*! - \relates QGLBuilder - Convenience operator for adding \a triangles to the \a builder. - - \code - // equivalent to builder.addTriangles(triangles); - builder << triangles; - \endcode -*/ -QGLBuilder& operator<<(QGLBuilder& builder, const QGeometryData& triangles) -{ - builder.addTriangles(triangles); - return builder; -} - -QT_END_NAMESPACE diff --git a/src/threed/geometry/qglbuilder.h b/src/threed/geometry/qglbuilder.h deleted file mode 100644 index 31382e36..00000000 --- a/src/threed/geometry/qglbuilder.h +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLBuilder_H -#define QGLBuilder_H - -#include <QtCore/qvector.h> -#include <QtCore/qlist.h> -#include <QtGui/qvector3d.h> -#include <QtOpenGL/qgl.h> - -#include "qglnamespace.h" -#include "qglscenenode.h" -#include "qglattributevalue.h" -#include "qgeometrydata.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class QGLSection; -class QGLMaterialCollection; -class QGLBuilderPrivate; -class QGLPainter; - -class Q_QT3D_EXPORT QGLBuilder -{ -public: - explicit QGLBuilder(QGLMaterialCollection *materials = 0); - virtual ~QGLBuilder(); - - // section management - void newSection(QGL::Smoothing sm = QGL::Smooth); - - // scene management - QGLSceneNode *sceneNode(); - QGLSceneNode *currentNode(); - QGLSceneNode *newNode(); - QGLSceneNode *pushNode(); - QGLSceneNode *popNode(); - QGLMaterialCollection *palette(); - QGLSceneNode *finalizedSceneNode(); - - // geometry building by primitive - void addTriangles(const QGeometryData &triangle); - void addQuads(const QGeometryData &quad); - void addTriangleFan(const QGeometryData &fan); - void addTriangleStrip(const QGeometryData &strip); - void addTriangulatedFace(const QGeometryData &face); - void addQuadStrip(const QGeometryData &strip); - void addQuadsInterleaved(const QGeometryData &top, - const QGeometryData &bottom); - inline void addPane(qreal size = 1.0f); - inline void addPane(QSizeF size); - -protected: - // internal and test functions - QGLSection *currentSection() const; - QList<QGLSection*> sections() const; - void setDefaultThreshold(int); - -private: - Q_DISABLE_COPY(QGLBuilder); - void addSection(QGLSection *section); - - friend class QGLSection; - - QGLBuilderPrivate *dptr; -}; - -inline void QGLBuilder::addPane(qreal size) -{ - addPane(QSizeF(size, size)); -} - -inline void QGLBuilder::addPane(QSizeF size) -{ - QSizeF f = size / 2.0f; - QVector2D a(-f.width(), -f.height()); - QVector2D b(f.width(), -f.height()); - QVector2D c(f.width(), f.height()); - QVector2D d(-f.width(), f.height()); - QVector2D ta(0.0f, 0.0f); - QVector2D tb(1.0f, 0.0f); - QVector2D tc(1.0f, 1.0f); - QVector2D td(0.0f, 1.0f); - QGeometryData quad; - quad.appendVertex(a, b, c, d); - quad.appendTexCoord(ta, tb, tc, td); - addQuads(quad); -} - -Q_QT3D_EXPORT QGLBuilder& operator<<(QGLBuilder& builder, const QGL::Smoothing& smoothing); -Q_QT3D_EXPORT QGLBuilder& operator<<(QGLBuilder& builder, const QGeometryData& triangles); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGLBuilder_H diff --git a/src/threed/geometry/qglbuilder_p.h b/src/threed/geometry/qglbuilder_p.h deleted file mode 100644 index 237f7219..00000000 --- a/src/threed/geometry/qglbuilder_p.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLBuilder_P_H -#define QGLBuilder_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qglbuilder.h" - -#include <QtCore/qmap.h> -#include <QPointer> - -QT_BEGIN_NAMESPACE - -class QGLBuilder; -class QGLSection; -class QGeometryData; - -class QGLBuilderPrivate -{ -public: - QGLBuilderPrivate(QGLBuilder *parent); - ~QGLBuilderPrivate(); - inline void setDirty(bool dirty = true); - void addTriangle(int a, int b, int c, const QGeometryData &p, int &count); - void adjustSectionNodes(QGLSection *sec, int offset, const QGeometryData &geom); - int adjustNodeTree(QGLSceneNode *top, int offset, const QGeometryData &geom, - QList<QGLSceneNode*> &deleted); - - QList<QGLSection*> sections; - QGLSection *currentSection; - QList<QGLSceneNode*> nodeStack; - QGLSceneNode *currentNode; - QGLSceneNode *rootNode; - int defThreshold; - QGLBuilder *q; -}; - -QT_END_NAMESPACE - -#endif // QGLBuilder_P_H diff --git a/src/threed/geometry/qglcube.cpp b/src/threed/geometry/qglcube.cpp deleted file mode 100644 index 6775dba9..00000000 --- a/src/threed/geometry/qglcube.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglcube.h" -#include "qglbuilder.h" -#include "qvector3darray.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QGLCube - \brief The QGLCube class represents the geometry of simple six-sided cube in 3D space. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - The following example adds a cube of 2 units on a side to a - geometry builder, and draws it at (10, 25, 0) in a QGLPainter: - - \code - QGLBuilder list; - list.newSection(QGL::Faceted); - list << QGLCube(2); - painter->translate(10, 25, 0); - list.draw(painter); - \endcode - - QGLCube will create a default set of texture coordinates that shows - the same texture of all six faces. -*/ - -/*! - \fn QGLCube::QGLCube(qreal size) - - Constructs the geometry for a regular cube of \a size - units on a side. -*/ - -/*! - \fn qreal QGLCube::size() const - - Returns the size of this cube. - - \sa setSize() -*/ - -/*! - \fn void QGLCube::setSize(qreal size) - - Sets the \a size of this cube. - - \sa size() -*/ - -static const int vertexDataLen = 6 * 4 * 3; - -static const float vertexData[vertexDataLen] = { - -0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - -0.5f, 0.5f, -0.5f, - - -0.5f, 0.5f, -0.5f, - -0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, -0.5f, - - 0.5f, 0.5f, -0.5f, - 0.5f, 0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, -0.5f, - - 0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, 0.5f, - -0.5f, -0.5f, 0.5f, - -0.5f, -0.5f, -0.5f, - - 0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - -0.5f, -0.5f, 0.5f, - - 0.5f, 0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, - -0.5f, 0.5f, -0.5f -}; - -static const int texCoordDataLen = 4 * 2; - -static const float texCoordData[texCoordDataLen] = { - 1.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 0.0f, 0.0f -}; - -/*! - \relates QGLCube - - Builds the geometry for \a cube within the specified - geometry \a builder. - - This operator specifies the positions, and 2D texture - co-ordinates for all of the vertices that make up the cube. - Normals will be calculated by the \a builder, depending on its - current section's smoothing setting. -*/ -QGLBuilder& operator<<(QGLBuilder& builder, const QGLCube& cube) -{ - QGeometryData op; - - QVector3DArray vrts = QVector3DArray::fromRawData( - reinterpret_cast<const QVector3D *>(vertexData), vertexDataLen / 3); - if (cube.size() != 1.0f) - vrts.scale(cube.size()); - - op.appendVertexArray(vrts); - - QVector2DArray texx = QVector2DArray::fromRawData( - reinterpret_cast<const QVector2D *>(texCoordData), texCoordDataLen / 2); - - for (int i = 0; i < 6; ++i) - op.appendTexCoordArray(texx); - - builder.addQuads(op); - return builder; -} - -QT_END_NAMESPACE diff --git a/src/threed/geometry/qglcube.h b/src/threed/geometry/qglcube.h deleted file mode 100644 index f9914a04..00000000 --- a/src/threed/geometry/qglcube.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLCUBE_H -#define QGLCUBE_H - -#include "qt3dglobal.h" - -#include <QtGui/qvector2d.h> -#include "qvector2darray.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class QGLBuilder; - -class Q_QT3D_EXPORT QGLCube -{ -public: - explicit QGLCube(qreal size = 1.0f) : m_size(size) {} - - qreal size() const { return m_size; } - void setSize(qreal size) { m_size = size; } - -private: - qreal m_size; -}; - -Q_QT3D_EXPORT QGLBuilder& operator<<(QGLBuilder& builder, const QGLCube& cube); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/threed/geometry/qglcylinder.cpp b/src/threed/geometry/qglcylinder.cpp deleted file mode 100644 index 717b86a2..00000000 --- a/src/threed/geometry/qglcylinder.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglcylinder.h" -#include "qglbuilder.h" -#include "qvector2darray.h" -#include "qvector3darray.h" -#include <QtCore/qmath.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QGLCylinder - \brief The QGLCylinder class represents the geometry of a simple cylinder/cone in 3D space. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - The following example creates a cone with a top diameter of 1 unit, - a bottom diameter of of 2 units in diameter and height of 3 units. - - It then draws it at (10, 25, 0) in a QGLPainter: - - \code - QGLBuilder builder; - builder << QGLCylinder(1.0,2.0,3.0); - QGLSceneNode *node = builder.finalizedSceneNode(); - - painter.translate(10, 25, 0); - node->draw(&painter); - \endcode - - Note that the bottom circle of the cylinder will always be centred at (0,0,0) - unless otherwise transformed after cylinder creation. - - The QGLCylinder class specifies positions, normals and 2D texture - co-ordinates for all of the vertices that make up the cylinder. - - The texture co-ordinates are fixed at construction time. This - is because constructing the cylinder can involve generating additional - vertices which need to interpolate the texture co-ordinates of their - neighboring vertices. - - The QGLCylinder is divided into slices and layers. The slices value - indicate number of triangular sections into which the top and bottom - circles of the cylinder are broken into. Consequently it also sets the - number of facets which run the length of the cylinder. More slices - results in a smoother circumference. - - The layers value indicates the number of longitudinal sections the - cylinder is broken into. Fewer layers means that the side facets of the - cylinder will be made up of fewer, very long, triangles, while a higher - number of layers will produce many and smaller triangles. Often it is - desirable to avoid large triangles as they may cause inefficiencies in - texturing/lighting on certain platforms. - - The end-caps and sides of the cylinder are independent sections of the - scene-graph, and so may be textured separately. - - Textures are wrapped around the sides of thecylinder in such a way that - the texture may distort across the x axis if the top and bottom diameters - of the cylinder differ (ie. the cylinder forms a truncated cone). Textures - begin and end at the centre points of the top and bottom end-caps of the - cylinder. This wrapping means that textures on either end-cap may be - distorted. - - Texture coordinates are assigned as shown below. - - \image cylinder-texture-coords.png - - It is worth noting that the cylinder class can, in fact, be used to generate - any regular solid polygonal prism. A rectangular prism can be created, for - example, by creating a 4 sided cylinder. Likewise a hexagonal prism is - simply a 6 sided cylinder. - - With this knowledge, and an understanding of the texture coordinate mapping, - it is possible to make custom textures which will be usable with these - three dimensional objects. - - \sa QGLBuilder -*/ - - -/*! - \fn QGLCylinder::QGLCylinder(qreal diameterTop, qreal diameterBase , qreal height, int slices, int layers, bool top, bool base) - - Constructs the geometry for a cylinder with top of diameter \a diameterTop, - a base of diameter \a diameterBase, and a height of \a height. - - The resultant mesh will be divided around the vertical axis of the cylinder - into \a slices individual wedges, and shall be formed of \a layers stacked - to form the cylinder. - - If the values for \a top or \a base are true, then the cylinder will be - created with solid endcaps. Otherwise, it shall form a hollow pipe. - - units on a side. -*/ - - -/*! - \fn qreal QGLCylinder::diameterTop() const - - Returns the diameter of the top of the cylinder. - - The default value is 1. - - \sa setDiameterTop() -*/ - -/*! - \fn void QGLCylinder::setDiameterTop(qreal diameter) - - Sets the diameter of the top of this cylinder to \a diameter. - - \sa diameterTop() -*/ - -/*! - \fn qreal QGLCylinder::diameterBottom() const - - Returns the diameter of the bottom of the cylinder. - - The default value is 1. - - \sa setDiameterBottom() -*/ - -/*! - \fn void QGLCylinder::setDiameterBottom(qreal diameter) - - Sets the diameter of the bottom of this cylinder to \a diameter. - - \sa diameterBottom() -*/ - -/*! - \fn qreal QGLCylinder::height() const - - Returns the height of the cylinder. - - The default value is 1.0 - - \sa setDiameterBottom() -*/ - -/*! - \fn void QGLCylinder::setHeight(qreal height) - - Sets the height of this cylinder to \a height. - - \sa diameterBottom() -*/ - - -/*! - \fn int QGLCylinder::slices() const - - Returns the number of triangular slices the cylinder is divided into - around its polar axis. - - The default is 6. - - \sa setSlices() -*/ - -/*! - \fn int QGLCylinder::setSlices(int slices) - - Sets the number of triangular \a slices the cylinder is divided into - around its polar axis. - - \sa slices() -*/ - -/*! - \fn int QGLCylinder::layers() const - - Returns the number of cylindrical layers the cylinder is divided into - along its height. - - The default is 3. - - \sa setLayers() -*/ - -/*! - \fn int QGLCylinder::setLayers(int layers) - - Sets the number of stacked \a layers the cylinder is divided into - along its height. - - \sa layers() -*/ - -/*! - \fn bool QGLCylinder::topEnabled() const - - Returns true if the top of the cyclinder will be created when - building the mesh. - - The default is true. - - \sa setTopEnabled() -*/ - -/*! - \fn void QGLCylinder::setTopEnabled(bool top) - - Set whether the top end-cap of the cylinder will be created when - building the mesh. If \a top is true, the end-cap will be created. - - \sa topEnabled() -*/ - -/*! - \fn bool QGLCylinder::baseEnabled() const - - Returns true if the base of the cyclinder will be created when - building the mesh. - - The default is true. - - \sa setBaseEnabled() -*/ - -/*! - \fn void QGLCylinder::setBaseEnabled(bool base) - - Set whether the base end-cap of the cylinder will be created when - building the mesh. If \a base is true, the end-cap will be created. - - \sa baseEnabled() -*/ - -/*! - \relates QGLCylinder - - Builds the geometry for \a cylinder within the specified - geometry \a builder. -*/ - -QGLBuilder& operator<<(QGLBuilder& builder, const QGLCylinder& cylinder) -{ - /* ASSERT(cylinder.diameterBottom()>=0 && - cylinder.diameterTop()>=0 && - cylinder.height()>0);*/ - - qreal numSlices = qreal(cylinder.slices()); - qreal numLayers = qreal(cylinder.layers()); - qreal topRadius = cylinder.diameterTop()/2.0; - qreal bottomRadius = cylinder.diameterBottom()/2.0; - - qreal angle = 0; - qreal angleIncrement = (2.0 * M_PI) / numSlices; - qreal radius = topRadius; - qreal radiusIncrement = qreal(bottomRadius-topRadius)/ numLayers; - qreal height = qreal(cylinder.height()); - qreal heightDecrement = height/numLayers; - - qreal textureHeight = 1.0; - qreal textureDecrement = 1.0/numLayers; - - QGeometryData oldLayer; - - //Generate vertices for the next layer of cylinder - for (int layerCount=0; layerCount<=cylinder.layers(); layerCount++) { - QGeometryData newLayer; - - //Generate a circle of vertices for this layer. - for (int i=0; i<cylinder.slices(); i++) - { - newLayer.appendVertex(QVector3D(radius * qCos(angle), - radius * qSin(angle), - height)); - angle+=angleIncrement; - } - angle = 0; - // Generate texture coordinates (including an extra seam vertex for textures). - newLayer.appendVertex(newLayer.vertex(0)); - newLayer.generateTextureCoordinates(); - for (int i = 0; i < newLayer.count(); i++) newLayer.texCoord(i).setY(textureHeight); - - //Special cases for top end-cap - if (layerCount==0 && cylinder.topEnabled()) { - //Draw end-cap at top - QGeometryData top; - builder.newSection(); - builder.currentNode()->setObjectName(QStringLiteral("Cylinder Top")); - top.appendVertex(newLayer.center()); - top.appendVertexArray(newLayer.vertices()); - //Generate a circle of texture vertices for this layer. - top.appendTexCoord(QVector2D(0.5,0.5)); - - for (int i=1; i<top.count(); i++) - { - top.appendTexCoord(QVector2D(0.5*qCos(angle)+0.5, 0.5*qSin(angle)+0.5)); - angle+=angleIncrement; - } - angle = 0; - builder.addTriangulatedFace(top); - } - - - //Add a new cylinder layer to the mesh - if (layerCount>0) - { - //If it's the first section, create a cylinder sides section - if (layerCount==1) { - builder.newSection(); - builder.currentNode()->setObjectName(QStringLiteral("Cylinder Sides")); - } - builder.addQuadsInterleaved(oldLayer, newLayer); - } - - //Special cases for bottom end-cap - if (layerCount==cylinder.layers() && cylinder.baseEnabled()) { - //Draw end-cap at bottom - QGeometryData base; - builder.newSection(); - builder.currentNode()->setObjectName(QStringLiteral("Cylinder Base")); - base.appendVertexArray(newLayer.vertices()); - base.appendVertex(newLayer.center()); - //Generate a circle of texture vertices for this layer. - for (int i=1; i<base.count(); i++) - { - base.appendTexCoord(QVector2D(0.5*qCos(angle)+0.5, 0.5*qSin(angle)+0.5)); - angle+=angleIncrement; - } - base.appendTexCoord(QVector2D(0.5,0.5)); - angle = 0; - - //we need to reverse the above to draw it properly - windings! - builder.addTriangulatedFace(base.reversed()); - } - - //Keep the current layer for drawing the next segment of the cylinder - oldLayer.clear(); - oldLayer.appendGeometry(newLayer); - radius+=radiusIncrement; - height-=heightDecrement; - textureHeight-=textureDecrement; - } - - return builder; -} - -QT_END_NAMESPACE diff --git a/src/threed/geometry/qglcylinder.h b/src/threed/geometry/qglcylinder.h deleted file mode 100644 index a33adba2..00000000 --- a/src/threed/geometry/qglcylinder.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLCYLINDER_H -#define QGLCYLINDER_H - -#include "qt3dglobal.h" -#include "qglmaterialcollection.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class QGLBuilder; -class QVector2D; - -class Q_QT3D_EXPORT QGLCylinder -{ -public: - explicit QGLCylinder(qreal diameterTop = 1.0f, qreal diameterBase = 1.0f, qreal height = 1.0f, int slices = 6, int layers = 3, bool top = true, bool base = true) - : m_diameterTop(diameterTop), m_diameterBottom(diameterBase), m_height(height), m_slices(slices), m_layers(layers), m_top(top), m_base(base) {} - - //Cylinder dimensions - qreal diameterTop() const {return m_diameterTop;} - void setDiameterTop(qreal diameter) {m_diameterTop=diameter;} - - qreal diameterBottom() const {return m_diameterBottom;} - void setDiameterBottom(qreal diameter) {m_diameterBottom=diameter;} - - qreal height() const {return m_height;} - void setHeight(qreal height) {m_height = height;} - - //Cylinder geometrical subdivisions - int slices() const {return m_slices;} - void setSlices(int slices) {m_slices = slices;} - - int layers() const {return m_layers;} - void setLayers(int layers) {m_layers = layers;} - - //End-caps attached? - bool topEnabled() const {return m_top;} - void setTopEnabled(bool top) {m_top = top;} - - bool baseEnabled() const {return m_base;} - void setBaseEnabled(bool base) {m_base = base;} - -protected: - qreal m_diameterTop; - qreal m_diameterBottom; - qreal m_height; - - int m_slices; - int m_layers; - - bool m_top; - bool m_base; -}; - -Q_QT3D_EXPORT QGLBuilder& operator<<(QGLBuilder& builder, const QGLCylinder& cylinder); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGLCYLINDER_H diff --git a/src/threed/geometry/qgldome.cpp b/src/threed/geometry/qgldome.cpp deleted file mode 100644 index 949ccaa9..00000000 --- a/src/threed/geometry/qgldome.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgldome.h" -#include "qglbuilder.h" -#include <QtCore/qmath.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QGLDome - \brief The QGLDome class represents the geometry of a simple hemisphere in 3D space. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - The following example creates a dome of 2 units in diameter and - draws it at (10, 25, 0) in a QGLPainter: - - \code - QGLBuilder builder; - builder << QGLDome(2); - QGLSceneNode *node = builder.finalizedSceneNode(); - - painter.translate(10, 25, 0); - node->draw(&painter); - \endcode - - The QGLDome class specifies positions, normals and 2D texture - co-ordinates for all of the vertices that make up the sphere. - - The texture co-ordinates are fixed at construction time. This - is because constructing the sphere can involve generating additional - vertices which need to interpolate the texture co-ordinates of their - neighboring vertices. - - The default mode of QGLDome is half of a "UV sphere", which divides - the object up into longitudinal and latitudinal sections. The longitudinal - slices meet at the pole, which in a single unit dome is defined to - be at (0, 0, +0.5) and (0, 0, -0.5). This choice is the simplest to - texture map as the texture will only distort along the x-axis of the - 2D texture. However the density of vertices is significantly higher at - the poles than it is elsewhere on the sphere and is a poor choice if a - uniform density of pixels from the texture map is required. - - \sa QGLBuilder -*/ - -/*! - \fn QGLDome::QGLDome(qreal diameter, int depth, bool base) - - Creates a dome of \a diameter across (default is 1). When the dome - is recursively subdivided into triangles, it will be subdivided no more - than \a depth times (between 1 and 5, default is 3). - - If \a base is true, the dome will be drawn with a bottom circle, creating - an enclosed solid. -*/ - -/*! - Destroys this dome object. -*/ -QGLDome::~QGLDome() -{ -} - -/*! - \fn qreal QGLDome::diameter() const - - Returns the diameter of this dome. The default is 1. - - \sa setDiameter() -*/ - -/*! - \fn void QGLDome::setDiameter(qreal diameter) - - Sets the diameter of this dome to \a diameter. - - \sa diameter() -*/ - -/*! - \fn int QGLDome::subdivisionDepth() const - - Returns the maximum depth when this hemisphere is subdivided into - triangles. The default is 3. The following picture shows the effect - of depth values between 1 and 5 for a UV sphere (hemisphere subdivision - depth shares this scheme). - - \image sphere-detail.png - - \sa setSubdivisionDepth(), QGLSphere::subdivisionDepth() -*/ - -/*! - \fn void QGLDome::setSubdivisionDepth(int depth) - - Sets the maximum \a depth when this hemisphere is subdivided into triangles. - - \sa subdivisionDepth() -*/ - -/*! - \fn bool QGLDome::baseEnabled() const - - Returns true if the base of the dome will be created when - building the mesh. - - The default is true. - - \sa setBaseEnabled() -*/ - -/*! - \fn void QGLDome::setBaseEnabled(bool base) - - Set whether the bottom of the dome will be created when - building the mesh. If \a base is true, the end-cap will be - created. - - \sa baseEnabled() -*/ - -/*! - \relates QGLDome - - Builds the geometry for \a dome within the specified - geometry \a builder. -*/ -QGLBuilder& operator<<(QGLBuilder& builder, const QGLDome& dome) -{ - qreal radius = dome.diameter() / 2.0f; - - // Determine the number of slices and stacks to generate. - int divisions = dome.subdivisionDepth(); - if (divisions < 1) - divisions = 1; - else if (divisions > 5) - divisions = 5; - int stacks = 2 * (1 << divisions); - int slices = 2 * stacks; - stacks = stacks>>1; - - // Precompute sin/cos values for the slices and stacks. - const int maxSlices = 4 * (1 << 5) + 1; - const int maxStacks = 2 * (1 << 5) + 1; - qreal sliceSin[maxSlices]; - qreal sliceCos[maxSlices]; - qreal stackSin[maxStacks]; - qreal stackCos[maxStacks]; - for (int slice = 0; slice < slices; ++slice) { - qreal angle = 2 * M_PI * slice / slices; - sliceSin[slice] = qFastSin(angle); - sliceCos[slice] = qFastCos(angle); - } - sliceSin[slices] = sliceSin[0]; // Join first and last slice. - sliceCos[slices] = sliceCos[0]; - - const qreal halfPi=M_PI/2.0; - - for (int stack = 0; stack <= stacks; ++stack) { - qreal angle = halfPi * stack / stacks; - stackSin[stack] = qFastSin(angle); - stackCos[stack] = qFastCos(angle); - } - stackSin[0] = 0.0f; // Come to a point at the poles. - stackSin[stacks] = 1.0f; - - builder.newSection(); - builder.currentNode()->setObjectName(QStringLiteral("Dome")); - // Create the stacks for the dome part of the dome - for (int stack = 0; stack < stacks; ++stack) { - QGeometryData prim; - qreal z = radius * stackCos[stack]; - qreal nextz = radius * stackCos[stack + 1]; - qreal s = stackSin[stack]; - qreal nexts = stackSin[stack + 1]; - qreal c = stackCos[stack]; - qreal nextc = stackCos[stack + 1]; - qreal r = radius * s; - qreal nextr = radius * nexts; - for (int slice = 0; slice <= slices; ++slice) { - prim.appendVertex(QVector3D(nextr * sliceSin[slice], nextr * sliceCos[slice], nextz)); - prim.appendNormal(QVector3D(sliceSin[slice] * nexts, sliceCos[slice] * nexts, nextc)); - prim.appendTexCoord(QVector2D(1.0f - qreal(slice) / slices, 1.0f - qreal(stack + 1) / stacks)); - - prim.appendVertex(QVector3D(r * sliceSin[slice], r * sliceCos[slice], z)); - prim.appendNormal(QVector3D(sliceSin[slice] * s, sliceCos[slice] * s, c)); - prim.appendTexCoord(QVector2D(1.0f - qreal(slice) / slices, 1.0f - qreal(stack) / stacks)); - } - builder.addQuadStrip(prim); - } - - if (dome.baseEnabled()) { - //Draw end-cap at bottom - builder.newSection(); - builder.currentNode()->setObjectName(QStringLiteral("Base")); - - //Generate a circle of vertices for this layer. - QGeometryData tempBase; - - tempBase.appendVertex(QVector3D(0,0,0)); - tempBase.appendTexCoord(QVector2D(0.5,0.5)); - for (int slice=0; slice<=slices+1; slice++) - { - tempBase.appendVertex(QVector3D(radius * sliceCos[slice], radius * sliceSin[slice], 0)); - tempBase.appendTexCoord(QVector2D(0.5*sliceCos[slice]+0.5, 0.5*sliceSin[slice]+0.5)); - } - - //we need to reverse the above to draw it properly - windings! - builder.addTriangulatedFace(tempBase.reversed()); - } - return builder; -} - -QT_END_NAMESPACE - diff --git a/src/threed/geometry/qgldome.h b/src/threed/geometry/qgldome.h deleted file mode 100644 index 3f3ea3eb..00000000 --- a/src/threed/geometry/qgldome.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLDOME_H -#define QGLDOME_H - -#include "qt3dglobal.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class QGLBuilder; - -class Q_QT3D_EXPORT QGLDome -{ -public: - explicit QGLDome(qreal diameter = 1.0f, int depth = 3, bool baseEnabled = true) - : m_diameter(diameter), m_subdivisionDepth(depth), m_baseEnabled(baseEnabled) {} - virtual ~QGLDome(); - - qreal diameter() const { return m_diameter; } - void setDiameter(qreal diameter) { m_diameter = diameter; } - - int subdivisionDepth() const { return m_subdivisionDepth; } - void setSubdivisionDepth(int depth) { m_subdivisionDepth = depth; } - - bool baseEnabled() const {return m_baseEnabled; } - void setBaseEnabled(bool baseEnabled) {m_baseEnabled = baseEnabled;} - -private: - qreal m_diameter; - int m_subdivisionDepth; - bool m_baseEnabled; -}; - -Q_QT3D_EXPORT QGLBuilder& operator<<(QGLBuilder& builder, const QGLDome& dome); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/threed/geometry/qglmaterialcollection.cpp b/src/threed/geometry/qglmaterialcollection.cpp deleted file mode 100644 index 0f396837..00000000 --- a/src/threed/geometry/qglmaterialcollection.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglmaterialcollection.h" -#include "qglmaterial_p.h" -#include <QtCore/qlist.h> -#include <QtCore/qhash.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QGLMaterialCollection - \brief The QGLMaterialCollection class manages groups of materials. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::enablers - - Managing more complex 3d graphics with several materials is easier when the - materials can be referred to as a collection. This is the role of the - QGLMaterialCollection class. - - Plug-ins implementing 3D formats may make the materials defined in - the format available to the application via a QGLMaterialCollection. - - The collection is also optimised for the case where many small objects - must refer to materials - such as faces in a mesh, or particles. In - this case the materials can be specified as a short data type using an - offset into the collection, rather than the material name. - - When building up a collection, meshes that refer to the various materials - can check off which ones are used by calling markMaterialAsUsed(), and then - remove spurious unused materials by calling removeUnusedMaterials(). This - technique is suitable for models loaded from a model file where a large - number of materials may be specified but only a few of those materials - are used by the particular mesh selected from the scene. - - To make a material available from a collection, call addMaterial(). To - retrieve a material from the collection call removeMaterial(). - - The collection takes ownership of the QGLMaterial - objects passed to it by the addMaterial() function. These - objects will be destroyed when the collection is destroyed. -*/ - -class QGLMaterialCollectionPrivate -{ -public: - QGLMaterialCollectionPrivate() - { - } - - QList<QGLMaterial *> materials; - QHash<QString, int> materialNames; -}; - -/*! - Construct a new empty QGLMaterialCollection object. The \a parent - is set as the parent of this object. -*/ -QGLMaterialCollection::QGLMaterialCollection(QObject *parent) - : QObject(parent) - , d_ptr(new QGLMaterialCollectionPrivate) -{ -} - -/*! - Destroy this collection. All material objects referred to by this - collection will be destroyed. -*/ -QGLMaterialCollection::~QGLMaterialCollection() -{ - // The QGLMaterial QObject's are reparented to the collection - // when addMaterial() is called, so the QObject destructor - // will take care of cleaning them up for us. -} - -/*! - Returns a pointer to the material corresponding to \a index; or null - if \a index is out of range or the material has been removed. - - Here's an example of searching for a material with a given ambient - \c{color} in the collection \c{materials}: - - \code - for (int colorIndex; colorIndex < materials->size(); ++colorIndex) { - if (material(colorIndex) && - material(colorIndex)->ambientColor() == color) - break; - } - if (colorIndex < materials->size()) - myObject->setMaterial(colorIndex); - \endcode -*/ -QGLMaterial *QGLMaterialCollection::material(int index) const -{ - Q_D(const QGLMaterialCollection); - return d->materials.value(index, 0); -} - -/*! - \overload - - Returns the material associated with \a name in this collection; - null if \a name is not present or the material has been removed. -*/ -QGLMaterial *QGLMaterialCollection::material(const QString &name) const -{ - Q_D(const QGLMaterialCollection); - int index = d->materialNames.value(name, -1); - if (index >= 0) - return d->materials[index]; - else - return 0; -} - -/*! - Returns true if this collection contains \a material; false otherwise. - - \sa indexOf() -*/ -bool QGLMaterialCollection::contains(QGLMaterial *material) const -{ - return material && material->d_func()->collection == this; -} - -/*! - \overload - - Returns true if this collection contains a material called \a name; - false otherwise. - - \sa indexOf() -*/ -bool QGLMaterialCollection::contains(const QString &name) const -{ - Q_D(const QGLMaterialCollection); - return d->materialNames.contains(name); -} - -/*! - Returns the index of \a material in this collection; -1 if - \a material is not present in this collection. - - \sa contains() -*/ -int QGLMaterialCollection::indexOf(QGLMaterial *material) const -{ - if (material && material->d_func()->collection == this) - return material->d_func()->index; - else - return -1; -} - -/*! - \overload - - Returns the index of the material called \a name in this collection; - -1 if \a name is not present in this collection. - - \sa contains() -*/ -int QGLMaterialCollection::indexOf(const QString &name) const -{ - Q_D(const QGLMaterialCollection); - return d->materialNames.value(name, -1); -} - -/*! - Returns the name of the material at \a index in this material collection; - a null QString if \a index is out of range. -*/ -QString QGLMaterialCollection::materialName(int index) const -{ - Q_D(const QGLMaterialCollection); - if (index >= 0 && index < d->materials.count()) { - QGLMaterial *material = d->materials[index]; - if (material) { - // Use the name in the private data block just in case the - // application has modified objectName() since adding. - return material->d_func()->name; - } - } - return QString(); -} - -/*! - Returns true if the material at \a index in this collection has been - marked as used by markMaterialAsUsed(). - - \sa markMaterialAsUsed() -*/ -bool QGLMaterialCollection::isMaterialUsed(int index) const -{ - QGLMaterial *mat = material(index); - if (mat) - return mat->d_func()->used; - else - return false; -} - -/*! - Flags the material corresponding to the \a index as used. Some model files - may contain a range of materials, applying to various objects in the scene. - - When a particular object is loaded from the file, many of those - materials may not be used in that object. This wastes space, - with many spurious materials being stored. - - Use this method during model loading or construction to mark off - materials that have been used. Materials so marked will not - be removed by removeUnusedMaterials(). - - \sa removeUnusedMaterials(), isMaterialUsed() -*/ -void QGLMaterialCollection::markMaterialAsUsed(int index) -{ - QGLMaterial *mat = material(index); - if (mat) - mat->d_func()->used = true; -} - -/*! - Removes and deletes materials which have not been marked as used. - - \sa markMaterialAsUsed(), isMaterialUsed() -*/ -void QGLMaterialCollection::removeUnusedMaterials() -{ - Q_D(QGLMaterialCollection); - for (int index = 0; index < d->materials.size(); ++index) { - QGLMaterial *material = d->materials[index]; - if (material && !material->d_func()->used) - delete removeMaterial(index); - } -} - -/*! - Adds \a material to this collection and returns its new index. The - collection takes ownership of the material and will delete it when the - collection is destroyed. Initially the \a material is marked as unused. - - The QObject::objectName() of \a material at the time addMaterial() - is called will be used as the material's name within this collection. - Changes to the object name after the material is added are ignored. - - If \a material is already present in this collection, then this - function will return the index that was previously assigned. - - Returns -1 if \a material has been added to another collection. - - \sa removeMaterial(), markMaterialAsUsed() -*/ -int QGLMaterialCollection::addMaterial(QGLMaterial *material) -{ - Q_D(QGLMaterialCollection); - Q_ASSERT(material); - - // Allocate a new index for the material. - int index = d->materials.count(); - - // Record the index in the private data attached to the material. - // This allows us to find the material's index quickly later. - QGLMaterialPrivate *dm = material->d_func(); - if (dm->collection) { - if (dm->collection == this) - return dm->index; - return -1; - } - dm->collection = this; - dm->index = index; - dm->name = material->objectName(); - dm->used = false; - - // Add the material to this collection. - material->setParent(this); - d->materials.append(material); - if (!dm->name.isEmpty()) - d->materialNames[dm->name] = index; - connect(material, SIGNAL(destroyed()), this, SLOT(materialDeleted())); - return index; -} - -/*! - Removes all instances of \a material from this collection. - The \a material object is not deleted and can be reused. - - Does nothing if \a material is null or not a member of - this collection. - - \sa addMaterial() -*/ -void QGLMaterialCollection::removeMaterial(QGLMaterial *material) -{ - Q_D(QGLMaterialCollection); - if (!material) - return; - - // Check the material's owning collection. - QGLMaterialPrivate *dm = material->d_func(); - if (dm->collection != this) - return; - - // Remove the material from the collection. - d->materials[dm->index] = 0; - if (!dm->name.isEmpty()) - d->materialNames.remove(dm->name); - material->setParent(0); - - // Detach from the owning collection. - dm->collection = 0; - dm->index = -1; -} - -/*! - Removes the material at \a index from this collection, and returns - a pointer to the material. - - Since the collection is designed for fast lookup by index, the - the stored material pointer is set to null but the \a index - otherwise remains valid. -*/ -QGLMaterial *QGLMaterialCollection::removeMaterial(int index) -{ - Q_D(QGLMaterialCollection); - - // Bail out if the material is invalid. - if (index < 0 || index >= d->materials.count()) - return 0; - QGLMaterial *material = d->materials[index]; - if (!material) - return 0; - - // Remove the material from the collection. - QGLMaterialPrivate *dm = material->d_func(); - d->materials[index] = 0; - if (!dm->name.isEmpty()) - d->materialNames.remove(dm->name); - material->setParent(0); - - // Detach from the owning collection. - dm->collection = 0; - dm->index = -1; - return material; -} - -/*! - Returns true if this collection is empty, false otherwise. - - \sa size() -*/ -bool QGLMaterialCollection::isEmpty() const -{ - Q_D(const QGLMaterialCollection); - return d->materials.isEmpty(); -} - -/*! - Returns the number of (possibly null) materials in this collection. - Null materials result from calling removeMaterial(). - - \sa isEmpty() -*/ -int QGLMaterialCollection::size() const -{ - Q_D(const QGLMaterialCollection); - return d->materials.size(); -} - -/*! - \internal - Responds to the destroyed() signal by calling removeMaterial() on the - material about to be deleted; -*/ -void QGLMaterialCollection::materialDeleted() -{ - removeMaterial(qobject_cast<QGLMaterial *>(sender())); -} - -QT_END_NAMESPACE diff --git a/src/threed/geometry/qglmaterialcollection.h b/src/threed/geometry/qglmaterialcollection.h deleted file mode 100644 index 0ef8efd1..00000000 --- a/src/threed/geometry/qglmaterialcollection.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLMATERIALCOLLECTION_H -#define QGLMATERIALCOLLECTION_H - -#include <QtCore/qobject.h> - -#include "qt3dglobal.h" -#include "qglmaterial.h" -#include "qgltexture2d.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class QGLMaterialCollectionPrivate; - -class Q_QT3D_EXPORT QGLMaterialCollection : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QGLMaterialCollection) - Q_DISABLE_COPY(QGLMaterialCollection) -public: - QGLMaterialCollection(QObject *parent = 0); - virtual ~QGLMaterialCollection(); - - QGLMaterial *material(int index) const; - QGLMaterial *material(const QString &name) const; - - bool contains(QGLMaterial *material) const; - bool contains(const QString &name) const; - - int indexOf(QGLMaterial *material) const; - int indexOf(const QString &name) const; - - QString materialName(int index) const; - - bool isMaterialUsed(int index) const; - void markMaterialAsUsed(int index); - void removeUnusedMaterials(); - - int addMaterial(QGLMaterial *material); - void removeMaterial(QGLMaterial *material); - QGLMaterial *removeMaterial(int index); - - bool isEmpty() const; - int size() const; - -private Q_SLOTS: - void materialDeleted(); - -private: - QScopedPointer<QGLMaterialCollectionPrivate> d_ptr; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGLMATERIALCOLLECTION_H diff --git a/src/threed/geometry/qglsection.cpp b/src/threed/geometry/qglsection.cpp deleted file mode 100644 index f60e9ffc..00000000 --- a/src/threed/geometry/qglsection.cpp +++ /dev/null @@ -1,700 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglsection_p.h" -#include "qglbuilder_p.h" -#include "qarray.h" -#include "qvector_utils_p.h" - -#include <QtGui/qvector3d.h> -#include <QtCore/qdebug.h> -#include <QtCore/qpointer.h> -#include <QtCore/qmap.h> -#include <QtCore/qbitarray.h> - -#include <limits.h> - -QT_BEGIN_NAMESPACE - -/*! - \internal - \class QGLSection - \brief The QGLSection class clusters like geometry in a QGLBuilder. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - QGLSection instances partition a QGLBuilder into related sections, - while the builder is being initialized with geometry data. - - Once the builder is initialized, and geometry building is complete - the QGLSection instances are destroyed and the data is uploaded to the - graphics hardware. - - The QGLSection class is a work horse for the QGLBuilder, and it - takes care of automatically managing vertex data. As such - for usual use cases, its functionality will not need to be referenced - directly. For low-level access to geometry, QGLSection provides a - range of accessors to reference geometry data during scene building. - - Within a section, incoming geometry data will be coalesced and - indexes created to reference the fewest possible copies of the vertex - data. For example, in smooth geometry all copies of a vertex are - coalesced into one, and referenced by indices - except in the case - where texture data forms a \i seam and a copy must be created to carry - the two texture coordinates of the seam. - - This is handled automatically by QGLSection, to pack data into the - smallest space possible thus improving cache coherence and performance. - - All the vertices in a QGLSection are treated with the same - \l{QGL::Smoothing}{smoothing}, and have the same - \l{QLogicalVertex::Type}{data types}. - - Each QGLSection references a contiguous range of vertices in a - QGLBuilder. - - A QGLBuilder instance has the \l{QGLBuilder::newSection()}{newSection()} - function which creates a new QGLSection to reference its data. Use this - to construct new QGLSection instances, or alternatively construct - a new QGLSection() and pass a non-null QGLBuilder pointer. - - These functions all return QVector values. QVector instances are - implicitly shared, thus the copies are inexpensive unless a - non-const function is called on them, triggering a copy-on-write. - - Generally for adding geometry, use append(). This function simply - calls virtual protected functions appendSmooth() (for smoothed vertices) - and appendFaceted() (for faceted vertices). See QGLBuilder for a - discussion of smoothing. -*/ - -// allow QVector3D's to be stored in a QMap -inline bool operator<(const QVector3D &a, const QVector3D &b) -{ - if (qFskCompare(a.x(), b.x())) - { - if (qFskCompare(a.y(), b.y())) - { - if (qFskCompare(a.z(), b.z())) - { - return false; // equal so not less-than - } - else - { - return a.z() < b.z(); - } - } - else - { - return a.y() < b.y(); - } - } - else - { - return a.x() < b.x(); - } -} - -static inline bool qSameDirection(const QVector3D &a , const QVector3D &b) -{ - bool res = false; - if (!a.isNull() && !b.isNull()) - { - float dot = QVector3D::dotProduct(a, b); - res = qFskCompare((qreal)dot, a.length() * b.length()); - } - return res; -} - -class QGLSectionPrivate -{ -public: - QGLSectionPrivate(const QVector3DArray *ary) - : vec_data(ary) - , it(vec_map.end()) - , map_threshold(5) - , number_mapped(0) - , start_ptr(-1) - , end_ptr(-1) - { - normIndices.fill(-1, 32); - } - - ~QGLSectionPrivate() {} - - bool normalAccumulated(int index, const QVector3D &norm) const - { - if (index >= normIndices.size()) - return false; - int ptr = normIndices.at(index); - while (ptr != -1) - { - int val_ptr = normPtrs.at(ptr); - //if (normValues.at(val_ptr) == norm) - if (qSameDirection(normValues.at(val_ptr), norm)) - return true; - ptr = normPtrs.at(ptr+1); - } - return false; - } - - void accumulateNormal(int index, const QVector3D &norm) - { - int new_norm_index = normValues.size(); - normValues.append(norm); - if (normIndices.size() <= index) - { - int old_size = normIndices.size(); - normIndices.extend(32); - for (int i = old_size; i < normIndices.size(); ++i) - normIndices[i] = -1; - } - int new_norm_ptr = normPtrs.size(); - normPtrs.append(new_norm_index); // even ptrs point to vector value - normPtrs.append(-1); // odd ptrs point to next in normPtr linked list - if (normIndices.at(index) == -1) - { - normIndices[index] = new_norm_ptr; - } - else - { - int norm_ptr = normIndices.at(index); - while (normPtrs.at(norm_ptr + 1) != -1) - { - norm_ptr = normPtrs.at(norm_ptr + 1); - } - normPtrs[norm_ptr+1] = new_norm_ptr; - } - } - - void mapVertex(const QVector3D &v, int ix) - { - Q_UNUSED(ix); - Q_UNUSED(v); - static bool seeded = false; - if (!seeded) - qsrand(31415); - Q_ASSERT(vec_data->at(ix) == v); - if ((vec_data->size() - number_mapped) > map_threshold) - { - int to_map = vec_data->size() - number_mapped; - QArray<int, 100> shuffle(to_map, -1); - for (int i = number_mapped, k = 0; i < vec_data->size(); ++i, ++k) - shuffle[k] = i; - for (int n = to_map; n > 1; --n) - { - int k = qrand() % n; - int tmp = shuffle[k]; - shuffle[k] = shuffle[n - 1]; - shuffle[n - 1] = tmp; - } - for (int i = 0; i < to_map; ++i) - vec_map.insertMulti(vec_data->at(shuffle.at(i)), shuffle.at(i)); - number_mapped += to_map; - } - } - - int nextIndex() - { - int result = -1; - if (end_ptr != -1) - { - // first look through the unmapped items - while (start_ptr <= end_ptr && result == -1) - { - // search from the end and beginning, favouring the end - most often - // its in the last few we added, sometimes in the first ones - if (qFskCompare(vec_data->at(end_ptr--), target)) - result = end_ptr+1; - else if (start_ptr <= end_ptr && qFskCompare(vec_data->at(end_ptr--), target)) - result = end_ptr+1; - else if (start_ptr <= end_ptr && qFskCompare(vec_data->at(start_ptr++), target)) - result = start_ptr-1; - } - // if that found nothing, have a look at the map - if (result == -1) - { - start_ptr = -1; - end_ptr = -1; - it = vec_map.constEnd(); - if (vec_map.size() > 0) - it = vec_map.find(target); - } - } - if (it != vec_map.constEnd()) - { - // if there was something in the map see if its still on target - if (qFskCompare(it.key(), target)) - { - result = it.value(); - ++it; // increment to find more insertMulti instances - } - else - { - // not on target - flag that we're done here - it = vec_map.constEnd(); - } - } - return result; - } - - int findVertex(const QVector3D &v) - { - end_ptr = vec_data->size() - 1; // last one not in QMap - start_ptr = number_mapped; // first one not in QMap - target = v; - return nextIndex(); - } - - // mapper - int index; - QVector3D target; - const QVector3DArray *vec_data; - QMap<QVector3D, int> vec_map; - QMap<int, int> index_map; - QMap<QVector3D,int>::const_iterator it; - int map_threshold; // if more than this is unmapped, do a mapping run - int number_mapped; // how many vertices have been mapped - int start_ptr; - int end_ptr; - - QArray<int, 32> normIndices; - QArray<int, 32> normPtrs; - QArray<QVector3D, 32> normValues; - - QList<QGLSceneNode*> nodes; -}; - -/*! - \internal - Construct a new QGLSection on \a builder, and with smoothing \a s. - By default the smoothing is QGL::Smooth. - - See QGLBuilder for a discussion of smoothing. - - The pointer \a list must be non-null, and in debug mode, unless QT_NO_DEBUG is - defined, this function will assert if \a list is null. - - The following lines of code have identical effect: - \code - QGLSection *s = myDisplayList->newSection(QGL::Faceted); - QGLSection *s2 = new QGLSection(myDisplayList, QGL::Faceted); - \endcode -*/ -QGLSection::QGLSection(QGLBuilder *builder, QGL::Smoothing s) - : m_smoothing(s) - , d(0) -{ - Q_ASSERT(builder); - enableField(QGL::Position); - Q_ASSERT(vertexData()); - d = new QGLSectionPrivate(vertexData()); - builder->addSection(this); -} - -/*! - \internal - Destroy this QGLSection, recovering any resources. -*/ -QGLSection::~QGLSection() -{ - delete d; -} - -/*! - \internal - Reserve capacity for \a amount items. This may avoid realloc - overhead when a large number of items will be appended. -*/ -void QGLSection::reserve(int amount) -{ - QGeometryData::reserve(amount); - d->normIndices.reserve(amount); - d->normPtrs.reserve(amount * 2); - d->normValues.reserve(amount); -} - -/*! - \internal - Adds the logical vertices \a a, \a b and \c to this section. All - should have the same fields. This function is exactly equivalent to - \code - append(a); append(b); append(c); - \endcode - - \sa appendSmooth(), appendFaceted() -*/ -void QGLSection::append(const QLogicalVertex &a, const QLogicalVertex &b, const QLogicalVertex &c) -{ - Q_ASSERT(a.fields() == b.fields() && b.fields() == c.fields()); - if (!a.hasField(QGL::Normal)) - { - appendFaceted(a, b, c); - } - else - { - if (m_smoothing == QGL::Smooth) - appendSmooth(a, b, c); - else - appendFaceted(a, b, c); - } -} - -/*! - \internal - Adds the logical vertex \a lv to this section. - - Otherwise, if the \a lv does have a lighting normal; then the - vertex processing depends on the smoothing property of this section. - If this section has smoothing QGL::Smooth, then the append will be done - by calling appendSmooth(); or if this section has smoothing QGL::Faceted, - then the append will be done by calling appendFaceted(). - - \sa appendSmooth(), appendFaceted() -*/ -void QGLSection::append(const QLogicalVertex &lv) -{ - if (!lv.hasField(QGL::Normal)) - { - appendFaceted(lv); - } - else - { - if (m_smoothing == QGL::Smooth) - appendSmooth(lv); - else - appendFaceted(lv); - } -} - -static bool qCompareByAttributes(const QLogicalVertex &a, const QLogicalVertex &b) -{ - static const quint32 ATTRS_AND_TEXTURES = (0xFFFFFFFF << QGL::TextureCoord0); - quint32 af = a.fields() & ATTRS_AND_TEXTURES; - quint32 bf = b.fields() & ATTRS_AND_TEXTURES; - if (af != bf) - return false; - quint32 flds = af | bf; - const quint32 mask = 0x01; - flds >>= QGL::TextureCoord0; - for (int i = QGL::TextureCoord0; flds; ++i, flds >>= 1) - { - if (flds & mask) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(i); - if (attr < QGL::CustomVertex0) - { - if (!qFskCompare(a.texCoord(attr), b.texCoord(attr))) - return false; - } - else - { - QVariant v1 = a.attribute(attr); - QVariant v2 = b.attribute(attr); - if (v1.type() == (QVariant::Type)QMetaType::Float) - return qFskCompare(v1.toFloat(), v2.toFloat()); - else if (v1.type() == QVariant::Vector2D) - return qFskCompare(qVariantValue<QVector2D>(v1), qVariantValue<QVector2D>(v2)); - else if (v1.type() == QVariant::Vector3D) - return qFskCompare(qVariantValue<QVector3D>(v1), qVariantValue<QVector3D>(v2)); - else - return v1 == v2; - } - } - } - return true; -} - -int QGLSection::appendOne(const QLogicalVertex &lv) -{ -#ifndef QT_NO_DEBUG_STREAM - if (count() && lv.fields() != fields()) - { - qDebug() << "Warning: adding" << lv << "fields:" << lv.fields() - << "fields do not match existing:" << fields() - << "create new section first?"; - } -#endif - int index = appendVertex(lv); - d->mapVertex(lv.vertex(), index); - appendIndex(index); - return index; -} - -/*! - \internal - Adds the logical vertex \a lv to this section of a builder. - - Two QLogicalVertex instances a and b are treated as being duplicates for - the purpose of smoothing, if \c{qFuzzyCompare(a.vertex(), b.vertex())} is - true - - All duplicate occurrences of a vertex are coalesced, that is replaced - by a GL index referencing the one copy. - - In order to draw \a lv as part of a smooth continuous surface, with - no distinct edge, duplicates of vertex \a lv are coalesced into one - (within this section) and the normal for that one set to the average of - the incoming unique normals. - - The incoming vertex \a lv is not treated as a duplicate if \a lv has - different texture coordinates or attributes. This occurs for example - in the case of a texture seam, where two different texture coordinates - are required at the same point on the geometry. - - In that case a new duplicate vertex is added to carry the unique - texture coordinates or attributes. When new vertex copies are added in - this way all copies receive the averaged normals. - - Call this function to add the vertices of a smooth face to the section - of a builder, or use: - - \code - myDisplayList->newSection(QGLBuilder::Smooth); - myDisplayList->addTriangle(a, b, c); - \endcode - - In smooth surfaces, the vertex and its normal is only sent to the - graphics hardware once (not once per face), thus smooth geometry may - consume fewer resources. - - \sa appendFaceted(), updateTexCoord(), QGLBuilder::newSection() -*/ -void QGLSection::appendSmooth(const QLogicalVertex &lv) -{ - Q_ASSERT(lv.hasField(QGL::Position)); - Q_ASSERT(lv.hasField(QGL::Normal)); - - int found_index = d->findVertex(lv.vertex()); - bool coalesce = false; - if (found_index == -1) - { - int newIndex = appendOne(lv); - d->accumulateNormal(newIndex, lv.normal()); - } - else - { - while (!coalesce && found_index != -1) - { - if (qCompareByAttributes(lv, logicalVertexAt(found_index))) - coalesce = true; - else - found_index = d->nextIndex(); - } - if (!coalesce) // texture or attributes prevented coalesce - { - // new vert to carry tex/attrib data - d->accumulateNormal(appendOne(lv), lv.normal()); - } - else - { - appendIndex(found_index); - while (found_index != -1) - { - if (!d->normalAccumulated(found_index, lv.normal())) - { - normal(found_index) += lv.normal(); - d->accumulateNormal(found_index, lv.normal()); - } - found_index = d->nextIndex(); - } - } - } -} - - -void QGLSection::appendSmooth(const QLogicalVertex &lv, int index) -{ - Q_ASSERT(lv.hasField(QGL::Position)); - Q_ASSERT(lv.hasField(QGL::Normal)); - - int found_index = -1; - QMap<int, int>::const_iterator it = d->index_map.constFind(index); - if (it != d->index_map.constEnd()) - found_index = it.value(); - if (found_index == -1) - { - int newIndex = appendVertex(lv); - d->index_map.insert(index, newIndex); - appendIndex(newIndex); - d->accumulateNormal(newIndex, lv.normal()); - } - else - { - appendIndex(found_index); - if (!d->normalAccumulated(found_index, lv.normal())) - { - normal(found_index) += lv.normal(); - d->accumulateNormal(found_index, lv.normal()); - } - } -} - -/*! - \internal - Add the logical vertex \a lv to this section of a builder. - - The vertex will be drawn as a distinct edge, instead of just part of a - continuous smooth surface. To acheive this the vertex value of \a lv - is duplicated for each unique normal in the current section. - - Note that duplication is only for unique normals: if a vertex is already - present with a given normal it is coalesced and simply referenced by index. - As for appendSmooth() vertices are not coalesced in this way if \a lv - has a different texture coordinate or attribute than its duplicate. - - In faceted surfaces, the vertex is sent to the graphics hardware once for - each normal it has, and thus may consume more resources. - - \sa appendSmooth(), updateTexCoord(), QGLBuilder::newSection() -*/ -void QGLSection::appendFaceted(const QLogicalVertex &lv) -{ - Q_ASSERT(lv.hasField(QGL::Position)); - int found_index = d->findVertex(lv.vertex()); - bool coalesce = false; - while (!coalesce && found_index != -1) - { - if (logicalVertexAt(found_index) == lv) - coalesce = true; - else - found_index = d->nextIndex(); - } - if (coalesce) // found - { - appendIndex(found_index); - } - else - { - appendOne(lv); - } -} - -/*! - \internal - Returns the current map threshold for this section. The threshold is the - point at which the section switches from using a plain QArray - with - linear performance ie O(n) - to using a QMap - with approx O(log n). These - structures are used for looking up vertices during the index generation and - normals calculation. - - The default value is 50. - - \sa setMapThreshold() -*/ -int QGLSection::mapThreshold() const -{ - return d->map_threshold; -} - -/*! - \internal - Sets the current map threshold to \a t for this section. - - \sa mapThreshold() -*/ -void QGLSection::setMapThreshold(int t) -{ - d->map_threshold = t; -} - -/*! - \internal - Returns a list of the QGLSceneNode instances associated with this section. -*/ -QList<QGLSceneNode*> QGLSection::nodes() const -{ - return d->nodes; -} - -/*! - \internal - Adds the \a node to the list of QGLSceneNode instances associated with - this section. -*/ -void QGLSection::addNode(QGLSceneNode *node) -{ - d->nodes.append(node); -} - -/*! - \internal - Deletes the \a node from the list of QGLSceneNode instances associated - with this section. Returns true if the \a node was found, false - otherwise. -*/ -bool QGLSection::deleteNode(QGLSceneNode *node) -{ - int ix = d->nodes.indexOf(node); - if (ix != -1) - { - d->nodes.removeAt(ix); - return true; - } - return false; -} - -#ifndef QT_NO_DEBUG_STREAM -/*! - \internal - Output a string representation of \a section to a debug stream \a dbg. - \relates QGLSection -*/ -QDebug operator<<(QDebug dbg, const QGLSection §ion) -{ - dbg.space() - << "QGLSection(" << §ion - << "- count:" << section.count() - << "- smoothing mode:" << (section.smoothing() == QGL::Smooth ? - "QGL::Smooth" : "QGL::Faceted") << "\n"; - QGL::IndexArray indices = section.indices(); - for (int i = 0; i < section.count(); ++i) - { - int ix = indices[i]; - dbg << section.logicalVertexAt(ix) << "\n"; - } - dbg << ")\n"; - return dbg.space(); -} -#endif - -QT_END_NAMESPACE diff --git a/src/threed/geometry/qglsection_p.h b/src/threed/geometry/qglsection_p.h deleted file mode 100644 index 8d6847ac..00000000 --- a/src/threed/geometry/qglsection_p.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLSECTION_H -#define QGLSECTION_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qglpainter.h" -#include "qlogicalvertex.h" -#include "qbox3d.h" -#include "qglnamespace.h" - -#include <QtOpenGL/qgl.h> -#include <QtGui/qmatrix4x4.h> - -QT_BEGIN_NAMESPACE - -class QGLPainter; -class QGLBuilder; -class QGLSectionPrivate; -class QGeometryData; -class QGLSceneNode; - -class Q_QT3D_EXPORT QGLSection : public QGeometryData -{ -public: - QGLSection(QGLBuilder *d, QGL::Smoothing sm = QGL::Smooth); - ~QGLSection(); - - void reserve(int amount); - - void append(const QLogicalVertex &lv); - void append(const QLogicalVertex &a, const QLogicalVertex &b, const QLogicalVertex &c); - void appendSmooth(const QLogicalVertex &lv); - void appendSmooth(const QLogicalVertex &lv, int index); - void appendSmooth(const QLogicalVertex &a, const QLogicalVertex &b, const QLogicalVertex &c) - { - appendSmooth(a); - appendSmooth(b); - appendSmooth(c); - } - void appendFaceted(const QLogicalVertex &lv); - void appendFaceted(const QLogicalVertex &a, const QLogicalVertex &b, const QLogicalVertex &c) - { - appendFaceted(a); - appendFaceted(b); - appendFaceted(c); - } - - inline QGL::Smoothing smoothing() const; - inline void setSmoothing(QGL::Smoothing s); - int mapThreshold() const; - void setMapThreshold(int); - QList<QGLSceneNode*> nodes() const; - void addNode(QGLSceneNode *node); - bool deleteNode(QGLSceneNode *node); -private: - Q_DISABLE_COPY(QGLSection); - friend class QGLBuilder; - - int appendOne(const QLogicalVertex &vertex); - - QGL::Smoothing m_smoothing; - QGLSectionPrivate *d; -}; - -inline QGL::Smoothing QGLSection::smoothing() const -{ - return m_smoothing; -} - -inline void QGLSection::setSmoothing(QGL::Smoothing s) -{ - m_smoothing = s; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug dbg, const QGLSection §ion); -#endif - -QT_END_NAMESPACE - -#endif // QGLSECTION_H diff --git a/src/threed/geometry/qglsphere.cpp b/src/threed/geometry/qglsphere.cpp deleted file mode 100644 index f3b3856b..00000000 --- a/src/threed/geometry/qglsphere.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglsphere.h" -#include "qglbuilder.h" -#include <QtCore/qmath.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QGLSphere - \brief The QGLSphere class represents the geometry of a simple sphere in 3D space. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - The following example creates a sphere of 2 units in diameter and - draws it at (10, 25, 0) in a QGLPainter: - - \code - QGLBuilder builder; - builder << QGLSphere(2); - QGLSceneNode *node = builder.finalizedSceneNode(); - - painter.translate(10, 25, 0); - node->draw(&painter); - \endcode - - The QGLSphere class specifies positions, normals and 2D texture - co-ordinates for all of the vertices that make up the sphere. - - The texture co-ordinates are fixed at construction time. This - is because constructing the sphere can involve generating additional - vertices which need to interpolate the texture co-ordinates of their - neighboring vertices. - - The default mode of QGLSphere is a "UV sphere", which divides the - sphere up into longitudinal and latitudinal sections. The longitudinal - slices meet at the poles, which in a single unit sphere are defined to - be at (0, 0, +0.5) and (0, 0, -0.5). This choice is the simplest to - texture map as the texture will only distort along the x-axis of the - 2D texture. However the density of vertices is significantly higher at - the poles than it is elsewhere on the sphere and is a poor choice if a - uniform density of pixels from the texture map is required. - - \sa QGLBuilder -*/ - -/*! - \fn QGLSphere::QGLSphere(qreal diameter, int depth) - - Creates a sphere of \a diameter across (default is 1). When the sphere - is recursively subdivided into triangles, it will be subdivided no more - than \a depth times (between 1 and 10, default is 5). -*/ - -/*! - Destroys this sphere object. -*/ -QGLSphere::~QGLSphere() -{ -} - -/*! - \fn qreal QGLSphere::diameter() const - - Returns the diameter of this sphere. The default is 1. - - \sa setDiameter() -*/ - -/*! - \fn void QGLSphere::setDiameter(qreal diameter) - - Sets the diameter of this sphere to \a diameter. - - \sa diameter() -*/ - -/*! - \fn int QGLSphere::subdivisionDepth() const - - Returns the maximum depth when this sphere is subdivided into triangles. - The default is 5. The following picture shows the effect of depth - values between 1 and 10 for a UV sphere: - - \image sphere-detail.png - - \table - \header \o Level of Detail \o Number of Triangles - \row \o 1 \o 64 - \row \o 2 \o 128 - \row \o 3 \o 256 - \row \o 4 \o 512 - \row \o 5 \o 1024 - \row \o 6 \o 2048 - \row \o 7 \o 4096 - \row \o 8 \o 8192 - \row \o 9 \o 16384 - \row \o 10 \o 32768 - \endtable - - \sa setSubdivisionDepth() -*/ - -/*! - \fn void QGLSphere::setSubdivisionDepth(int depth) - - Sets the maximum \a depth when this sphere is subdivided into triangles. - - \sa subdivisionDepth() -*/ - -/*! - \relates QGLSphere - - Builds the geometry for \a sphere within the specified - geometry \a builder. -*/ -QGLBuilder& operator<<(QGLBuilder& builder, const QGLSphere& sphere) -{ - qreal radius = sphere.diameter() / 2.0f; - - // Determine the number of slices and stacks to generate. - static int const slicesAndStacks[] = { - 8, 4, - 8, 8, - 16, 8, - 16, 16, - 32, 16, - 32, 32, - 64, 32, - 64, 64, - 128, 64, - 128, 128 - }; - int divisions = sphere.subdivisionDepth(); - if (divisions < 1) - divisions = 1; - else if (divisions > 10) - divisions = 10; - int stacks = slicesAndStacks[divisions * 2 - 1]; - int slices = slicesAndStacks[divisions * 2 - 2]; - - // Precompute sin/cos values for the slices and stacks. - const int maxSlices = 128 + 1; - const int maxStacks = 128 + 1; - qreal sliceSin[maxSlices]; - qreal sliceCos[maxSlices]; - qreal stackSin[maxStacks]; - qreal stackCos[maxStacks]; - for (int slice = 0; slice < slices; ++slice) { - qreal angle = 2 * M_PI * slice / slices; - sliceSin[slice] = qFastSin(angle); - sliceCos[slice] = qFastCos(angle); - } - sliceSin[slices] = sliceSin[0]; // Join first and last slice. - sliceCos[slices] = sliceCos[0]; - for (int stack = 0; stack <= stacks; ++stack) { - qreal angle = M_PI * stack / stacks; - stackSin[stack] = qFastSin(angle); - stackCos[stack] = qFastCos(angle); - } - stackSin[0] = 0.0f; // Come to a point at the poles. - stackSin[stacks] = 0.0f; - - // Create the stacks. - for (int stack = 0; stack < stacks; ++stack) { - QGeometryData prim; - qreal z = radius * stackCos[stack]; - qreal nextz = radius * stackCos[stack + 1]; - qreal s = stackSin[stack]; - qreal nexts = stackSin[stack + 1]; - qreal c = stackCos[stack]; - qreal nextc = stackCos[stack + 1]; - qreal r = radius * s; - qreal nextr = radius * nexts; - for (int slice = 0; slice <= slices; ++slice) { - prim.appendVertex - (QVector3D(nextr * sliceSin[slice], - nextr * sliceCos[slice], nextz)); - prim.appendNormal - (QVector3D(sliceSin[slice] * nexts, - sliceCos[slice] * nexts, nextc)); - prim.appendTexCoord - (QVector2D(1.0f - qreal(slice) / slices, - 1.0f - qreal(stack + 1) / stacks)); - - prim.appendVertex - (QVector3D(r * sliceSin[slice], - r * sliceCos[slice], z)); - prim.appendNormal - (QVector3D(sliceSin[slice] * s, - sliceCos[slice] * s, c)); - prim.appendTexCoord - (QVector2D(1.0f - qreal(slice) / slices, - 1.0f - qreal(stack) / stacks)); - } - builder.addQuadStrip(prim); - } - - return builder; -} - -QT_END_NAMESPACE diff --git a/src/threed/geometry/qglsphere.h b/src/threed/geometry/qglsphere.h deleted file mode 100644 index aa4e6cd3..00000000 --- a/src/threed/geometry/qglsphere.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLSPHERE_H -#define QGLSPHERE_H - -#include "qt3dglobal.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class QGLBuilder; - -class Q_QT3D_EXPORT QGLSphere -{ -public: - explicit QGLSphere(qreal diameter = 1.0f, int depth = 5) - : m_diameter(diameter), m_subdivisionDepth(depth) {} - virtual ~QGLSphere(); - - qreal diameter() const { return m_diameter; } - void setDiameter(qreal diameter) { m_diameter = diameter; } - - int subdivisionDepth() const { return m_subdivisionDepth; } - void setSubdivisionDepth(int depth) { m_subdivisionDepth = depth; } - -private: - qreal m_diameter; - int m_subdivisionDepth; -}; - -Q_QT3D_EXPORT QGLBuilder& operator<<(QGLBuilder& builder, const QGLSphere& sphere); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/threed/geometry/qglteapot.cpp b/src/threed/geometry/qglteapot.cpp deleted file mode 100644 index 175c6e9b..00000000 --- a/src/threed/geometry/qglteapot.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglteapot.h" -#include "qglteapot_data_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QGLTeapot - \brief The QGLTeapot class represents a 3D teapot object. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - The classic 3D "Utah Teapot" was originally drawn by Martin Newell - in 1975. The vertex data was made publicly available by him and - it has been a standard 3D test object ever since. - - For more information on the history of the "Utah Teapot", see - Wikipedia, http://en.wikipedia.org/wiki/Utah_teapot. - - The following example code uses QGLTeapot to draw a teapot of size - 0.5 at the origin: - - \code - QGLBuilder builder; - builder << QGLTeapot(); - teapot = builder.finalizedSceneNode(); - - painter.modelViewMatrix().scale(0.5f); - teapot->draw(painter); - \endcode - - The QGLTeapot object contains a lot of vertex data once it has - been subdivided into triangles. It is recommended that instances - of this class be created at startup, added to a QGLBuilder, - and then the finalized scene node can be reused over and over. - - \sa QGLBezierPatches -*/ - -/*! - Constructs a new 3D teapot geometry object. -*/ -QGLTeapot::QGLTeapot() -{ - QVector3DArray positions; - for (int pindex = 0; pindex < teapotPatchCount * 16; ++pindex) { - int vindex = teapotPatchData[pindex]; - positions.append(teapotBezierVertexData[vindex * 3], - teapotBezierVertexData[vindex * 3 + 1], - teapotBezierVertexData[vindex * 3 + 2]); - } - setPositions(positions); - setSubdivisionDepth(teapotDepth); -} - -/*! - Destroys this teapot geometry object. -*/ -QGLTeapot::~QGLTeapot() -{ -} - -QT_END_NAMESPACE diff --git a/src/threed/geometry/qglteapot.h b/src/threed/geometry/qglteapot.h deleted file mode 100644 index 904e4910..00000000 --- a/src/threed/geometry/qglteapot.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLTEAPOT_H -#define QGLTEAPOT_H - -#include "qglbezierpatches.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class Q_QT3D_EXPORT QGLTeapot : public QGLBezierPatches -{ -public: - QGLTeapot(); - ~QGLTeapot(); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/threed/geometry/qglteapot_data_p.h b/src/threed/geometry/qglteapot_data_p.h deleted file mode 100644 index 56554822..00000000 --- a/src/threed/geometry/qglteapot_data_p.h +++ /dev/null @@ -1,408 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLTEAPOT_DATA_P_H -#define QGLTEAPOT_DATA_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qglbezierpatches.h" - -// Generated from teapot.txt by meshcvt, depth = 4 - -#define teapotBezierVertexCount 306 -#define teapotBezierVertexStride 3 -#define teapotPatchCount 32 -#define teapotDepth 4 -static float const teapotBezierVertexData[] = { - 0.700000f, 0.450000f, -0.000000f, - 0.700000f, 0.450000f, 0.392000f, - 0.392000f, 0.450000f, 0.700000f, - 0.000000f, 0.450000f, 0.700000f, - 0.668750f, 0.515625f, -0.000000f, - 0.668750f, 0.515625f, 0.374500f, - 0.374500f, 0.515625f, 0.668750f, - 0.000000f, 0.515625f, 0.668750f, - 0.718750f, 0.515625f, -0.000000f, - 0.718750f, 0.515625f, 0.402500f, - 0.402500f, 0.515625f, 0.718750f, - 0.000000f, 0.515625f, 0.718750f, - 0.750000f, 0.450000f, -0.000000f, - 0.750000f, 0.450000f, 0.420000f, - 0.420000f, 0.450000f, 0.750000f, - 0.000000f, 0.450000f, 0.750000f, - -0.392000f, 0.450000f, 0.700000f, - -0.700000f, 0.450000f, 0.392000f, - -0.700000f, 0.450000f, -0.000000f, - -0.374500f, 0.515625f, 0.668750f, - -0.668750f, 0.515625f, 0.374500f, - -0.668750f, 0.515625f, -0.000000f, - -0.402500f, 0.515625f, 0.718750f, - -0.718750f, 0.515625f, 0.402500f, - -0.718750f, 0.515625f, -0.000000f, - -0.420000f, 0.450000f, 0.750000f, - -0.750000f, 0.450000f, 0.420000f, - -0.750000f, 0.450000f, -0.000000f, - -0.700000f, 0.450000f, -0.392000f, - -0.392000f, 0.450000f, -0.700000f, - 0.000000f, 0.450000f, -0.700000f, - -0.668750f, 0.515625f, -0.374500f, - -0.374500f, 0.515625f, -0.668750f, - 0.000000f, 0.515625f, -0.668750f, - -0.718750f, 0.515625f, -0.402500f, - -0.402500f, 0.515625f, -0.718750f, - 0.000000f, 0.515625f, -0.718750f, - -0.750000f, 0.450000f, -0.420000f, - -0.420000f, 0.450000f, -0.750000f, - 0.000000f, 0.450000f, -0.750000f, - 0.392000f, 0.450000f, -0.700000f, - 0.700000f, 0.450000f, -0.392000f, - 0.374500f, 0.515625f, -0.668750f, - 0.668750f, 0.515625f, -0.374500f, - 0.402500f, 0.515625f, -0.718750f, - 0.718750f, 0.515625f, -0.402500f, - 0.420000f, 0.450000f, -0.750000f, - 0.750000f, 0.450000f, -0.420000f, - 0.875000f, 0.187500f, -0.000000f, - 0.875000f, 0.187500f, 0.490000f, - 0.490000f, 0.187500f, 0.875000f, - 0.000000f, 0.187500f, 0.875000f, - 1.000000f, -0.075000f, -0.000000f, - 1.000000f, -0.075000f, 0.560000f, - 0.560000f, -0.075000f, 1.000000f, - 0.000000f, -0.075000f, 1.000000f, - 1.000000f, -0.300000f, -0.000000f, - 1.000000f, -0.300000f, 0.560000f, - 0.560000f, -0.300000f, 1.000000f, - 0.000000f, -0.300000f, 1.000000f, - -0.490000f, 0.187500f, 0.875000f, - -0.875000f, 0.187500f, 0.490000f, - -0.875000f, 0.187500f, -0.000000f, - -0.560000f, -0.075000f, 1.000000f, - -1.000000f, -0.075000f, 0.560000f, - -1.000000f, -0.075000f, -0.000000f, - -0.560000f, -0.300000f, 1.000000f, - -1.000000f, -0.300000f, 0.560000f, - -1.000000f, -0.300000f, -0.000000f, - -0.875000f, 0.187500f, -0.490000f, - -0.490000f, 0.187500f, -0.875000f, - 0.000000f, 0.187500f, -0.875000f, - -1.000000f, -0.075000f, -0.560000f, - -0.560000f, -0.075000f, -1.000000f, - 0.000000f, -0.075000f, -1.000000f, - -1.000000f, -0.300000f, -0.560000f, - -0.560000f, -0.300000f, -1.000000f, - 0.000000f, -0.300000f, -1.000000f, - 0.490000f, 0.187500f, -0.875000f, - 0.875000f, 0.187500f, -0.490000f, - 0.560000f, -0.075000f, -1.000000f, - 1.000000f, -0.075000f, -0.560000f, - 0.560000f, -0.300000f, -1.000000f, - 1.000000f, -0.300000f, -0.560000f, - 1.000000f, -0.525000f, -0.000000f, - 1.000000f, -0.525000f, 0.560000f, - 0.560000f, -0.525000f, 1.000000f, - 0.000000f, -0.525000f, 1.000000f, - 0.750000f, -0.637500f, -0.000000f, - 0.750000f, -0.637500f, 0.420000f, - 0.420000f, -0.637500f, 0.750000f, - 0.000000f, -0.637500f, 0.750000f, - 0.750000f, -0.675000f, -0.000000f, - 0.750000f, -0.675000f, 0.420000f, - 0.420000f, -0.675000f, 0.750000f, - 0.000000f, -0.675000f, 0.750000f, - -0.560000f, -0.525000f, 1.000000f, - -1.000000f, -0.525000f, 0.560000f, - -1.000000f, -0.525000f, -0.000000f, - -0.420000f, -0.637500f, 0.750000f, - -0.750000f, -0.637500f, 0.420000f, - -0.750000f, -0.637500f, -0.000000f, - -0.420000f, -0.675000f, 0.750000f, - -0.750000f, -0.675000f, 0.420000f, - -0.750000f, -0.675000f, -0.000000f, - -1.000000f, -0.525000f, -0.560000f, - -0.560000f, -0.525000f, -1.000000f, - 0.000000f, -0.525000f, -1.000000f, - -0.750000f, -0.637500f, -0.420000f, - -0.420000f, -0.637500f, -0.750000f, - 0.000000f, -0.637500f, -0.750000f, - -0.750000f, -0.675000f, -0.420000f, - -0.420000f, -0.675000f, -0.750000f, - 0.000000f, -0.675000f, -0.750000f, - 0.560000f, -0.525000f, -1.000000f, - 1.000000f, -0.525000f, -0.560000f, - 0.420000f, -0.637500f, -0.750000f, - 0.750000f, -0.637500f, -0.420000f, - 0.420000f, -0.675000f, -0.750000f, - 0.750000f, -0.675000f, -0.420000f, - -0.800000f, 0.262500f, -0.000000f, - -0.800000f, 0.262500f, 0.150000f, - -0.750000f, 0.375000f, 0.150000f, - -0.750000f, 0.375000f, -0.000000f, - -1.150000f, 0.262500f, -0.000000f, - -1.150000f, 0.262500f, 0.150000f, - -1.250000f, 0.375000f, 0.150000f, - -1.250000f, 0.375000f, -0.000000f, - -1.350000f, 0.262500f, -0.000000f, - -1.350000f, 0.262500f, 0.150000f, - -1.500000f, 0.375000f, 0.150000f, - -1.500000f, 0.375000f, -0.000000f, - -1.350000f, 0.150000f, -0.000000f, - -1.350000f, 0.150000f, 0.150000f, - -1.500000f, 0.150000f, 0.150000f, - -1.500000f, 0.150000f, -0.000000f, - -0.750000f, 0.375000f, -0.150000f, - -0.800000f, 0.262500f, -0.150000f, - -1.250000f, 0.375000f, -0.150000f, - -1.150000f, 0.262500f, -0.150000f, - -1.500000f, 0.375000f, -0.150000f, - -1.350000f, 0.262500f, -0.150000f, - -1.500000f, 0.150000f, -0.150000f, - -1.350000f, 0.150000f, -0.150000f, - -1.350000f, 0.037500f, -0.000000f, - -1.350000f, 0.037500f, 0.150000f, - -1.500000f, -0.075000f, 0.150000f, - -1.500000f, -0.075000f, -0.000000f, - -1.250000f, -0.187500f, -0.000000f, - -1.250000f, -0.187500f, 0.150000f, - -1.325000f, -0.281250f, 0.150000f, - -1.325000f, -0.281250f, -0.000000f, - -1.000000f, -0.300000f, 0.150000f, - -0.950000f, -0.450000f, 0.150000f, - -0.950000f, -0.450000f, -0.000000f, - -1.500000f, -0.075000f, -0.150000f, - -1.350000f, 0.037500f, -0.150000f, - -1.325000f, -0.281250f, -0.150000f, - -1.250000f, -0.187500f, -0.150000f, - -0.950000f, -0.450000f, -0.150000f, - -1.000000f, -0.300000f, -0.150000f, - 0.850000f, -0.037500f, -0.000000f, - 0.850000f, -0.037500f, 0.330000f, - 0.850000f, -0.450000f, 0.330000f, - 0.850000f, -0.450000f, -0.000000f, - 1.300000f, -0.037500f, -0.000000f, - 1.300000f, -0.037500f, 0.330000f, - 1.550000f, -0.337500f, 0.330000f, - 1.550000f, -0.337500f, -0.000000f, - 1.150000f, 0.300000f, -0.000000f, - 1.150000f, 0.300000f, 0.125000f, - 1.200000f, 0.262500f, 0.125000f, - 1.200000f, 0.262500f, -0.000000f, - 1.350000f, 0.450000f, -0.000000f, - 1.350000f, 0.450000f, 0.125000f, - 1.650000f, 0.450000f, 0.125000f, - 1.650000f, 0.450000f, -0.000000f, - 0.850000f, -0.450000f, -0.330000f, - 0.850000f, -0.037500f, -0.330000f, - 1.550000f, -0.337500f, -0.330000f, - 1.300000f, -0.037500f, -0.330000f, - 1.200000f, 0.262500f, -0.125000f, - 1.150000f, 0.300000f, -0.125000f, - 1.650000f, 0.450000f, -0.125000f, - 1.350000f, 0.450000f, -0.125000f, - 1.400000f, 0.487500f, -0.000000f, - 1.400000f, 0.487500f, 0.125000f, - 1.762500f, 0.496875f, 0.125000f, - 1.762500f, 0.496875f, -0.000000f, - 1.450000f, 0.487500f, -0.000000f, - 1.450000f, 0.487500f, 0.075000f, - 1.725000f, 0.506250f, 0.075000f, - 1.725000f, 0.506250f, -0.000000f, - 1.400000f, 0.450000f, -0.000000f, - 1.400000f, 0.450000f, 0.075000f, - 1.600000f, 0.450000f, 0.075000f, - 1.600000f, 0.450000f, -0.000000f, - 1.762500f, 0.496875f, -0.125000f, - 1.400000f, 0.487500f, -0.125000f, - 1.725000f, 0.506250f, -0.075000f, - 1.450000f, 0.487500f, -0.075000f, - 1.600000f, 0.450000f, -0.075000f, - 1.400000f, 0.450000f, -0.075000f, - 0.000000f, 0.825000f, -0.000000f, - 0.000000f, 0.825000f, 0.001000f, - 0.001000f, 0.825000f, -0.000000f, - 0.400000f, 0.825000f, -0.000000f, - 0.400000f, 0.825000f, 0.225000f, - 0.225000f, 0.825000f, 0.400000f, - 0.000000f, 0.825000f, 0.400000f, - 0.000000f, 0.675000f, -0.000000f, - 0.100000f, 0.600000f, -0.000000f, - 0.100000f, 0.600000f, 0.056000f, - 0.056000f, 0.600000f, 0.100000f, - 0.000000f, 0.600000f, 0.100000f, - -0.001000f, 0.825000f, -0.000000f, - -0.225000f, 0.825000f, 0.400000f, - -0.400000f, 0.825000f, 0.225000f, - -0.400000f, 0.825000f, -0.000000f, - -0.056000f, 0.600000f, 0.100000f, - -0.100000f, 0.600000f, 0.056000f, - -0.100000f, 0.600000f, -0.000000f, - 0.000000f, 0.825000f, -0.001000f, - -0.400000f, 0.825000f, -0.225000f, - -0.225000f, 0.825000f, -0.400000f, - 0.000000f, 0.825000f, -0.400000f, - -0.100000f, 0.600000f, -0.056000f, - -0.056000f, 0.600000f, -0.100000f, - 0.000000f, 0.600000f, -0.100000f, - 0.225000f, 0.825000f, -0.400000f, - 0.400000f, 0.825000f, -0.225000f, - 0.056000f, 0.600000f, -0.100000f, - 0.100000f, 0.600000f, -0.056000f, - 0.200000f, 0.525000f, -0.000000f, - 0.200000f, 0.525000f, 0.112000f, - 0.112000f, 0.525000f, 0.200000f, - 0.000000f, 0.525000f, 0.200000f, - 0.650000f, 0.525000f, -0.000000f, - 0.650000f, 0.525000f, 0.364000f, - 0.364000f, 0.525000f, 0.650000f, - 0.000000f, 0.525000f, 0.650000f, - 0.650000f, 0.450000f, -0.000000f, - 0.650000f, 0.450000f, 0.364000f, - 0.364000f, 0.450000f, 0.650000f, - 0.000000f, 0.450000f, 0.650000f, - -0.112000f, 0.525000f, 0.200000f, - -0.200000f, 0.525000f, 0.112000f, - -0.200000f, 0.525000f, -0.000000f, - -0.364000f, 0.525000f, 0.650000f, - -0.650000f, 0.525000f, 0.364000f, - -0.650000f, 0.525000f, -0.000000f, - -0.364000f, 0.450000f, 0.650000f, - -0.650000f, 0.450000f, 0.364000f, - -0.650000f, 0.450000f, -0.000000f, - -0.200000f, 0.525000f, -0.112000f, - -0.112000f, 0.525000f, -0.200000f, - 0.000000f, 0.525000f, -0.200000f, - -0.650000f, 0.525000f, -0.364000f, - -0.364000f, 0.525000f, -0.650000f, - 0.000000f, 0.525000f, -0.650000f, - -0.650000f, 0.450000f, -0.364000f, - -0.364000f, 0.450000f, -0.650000f, - 0.000000f, 0.450000f, -0.650000f, - 0.112000f, 0.525000f, -0.200000f, - 0.200000f, 0.525000f, -0.112000f, - 0.364000f, 0.525000f, -0.650000f, - 0.650000f, 0.525000f, -0.364000f, - 0.364000f, 0.450000f, -0.650000f, - 0.650000f, 0.450000f, -0.364000f, - 0.000000f, -0.750000f, -0.000000f, - 0.750000f, -0.675000f, -0.000000f, - 0.750000f, -0.675000f, -0.420000f, - 0.420000f, -0.675000f, -0.750000f, - 0.000000f, -0.675000f, -0.750000f, - 0.750000f, -0.712500f, -0.000000f, - 0.750000f, -0.712500f, -0.420000f, - 0.420000f, -0.712500f, -0.750000f, - 0.000000f, -0.712500f, -0.750000f, - 0.712500f, -0.750000f, -0.000000f, - 0.712500f, -0.750000f, -0.399000f, - 0.399000f, -0.750000f, -0.712500f, - 0.000000f, -0.750000f, -0.712500f, - -0.420000f, -0.675000f, -0.750000f, - -0.750000f, -0.675000f, -0.420000f, - -0.750000f, -0.675000f, -0.000000f, - -0.420000f, -0.712500f, -0.750000f, - -0.750000f, -0.712500f, -0.420000f, - -0.750000f, -0.712500f, -0.000000f, - -0.399000f, -0.750000f, -0.712500f, - -0.712500f, -0.750000f, -0.399000f, - -0.712500f, -0.750000f, -0.000000f, - -0.750000f, -0.675000f, 0.420000f, - -0.420000f, -0.675000f, 0.750000f, - 0.000000f, -0.675000f, 0.750000f, - -0.750000f, -0.712500f, 0.420000f, - -0.420000f, -0.712500f, 0.750000f, - 0.000000f, -0.712500f, 0.750000f, - -0.712500f, -0.750000f, 0.399000f, - -0.399000f, -0.750000f, 0.712500f, - 0.000000f, -0.750000f, 0.712500f, - 0.420000f, -0.675000f, 0.750000f, - 0.750000f, -0.675000f, 0.420000f, - 0.420000f, -0.712500f, 0.750000f, - 0.750000f, -0.712500f, 0.420000f, - 0.399000f, -0.750000f, 0.712500f, - 0.712500f, -0.750000f, 0.399000f -}; - -static ushort const teapotPatchData[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 3, 16, 17, 18, 7, 19, 20, 21, 11, 22, 23, 24, 15, 25, 26, 27, - 18, 28, 29, 30, 21, 31, 32, 33, 24, 34, 35, 36, 27, 37, 38, 39, - 30, 40, 41, 0, 33, 42, 43, 4, 36, 44, 45, 8, 39, 46, 47, 12, - 12, 13, 14, 15, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 15, 25, 26, 27, 51, 60, 61, 62, 55, 63, 64, 65, 59, 66, 67, 68, - 27, 37, 38, 39, 62, 69, 70, 71, 65, 72, 73, 74, 68, 75, 76, 77, - 39, 46, 47, 12, 71, 78, 79, 48, 74, 80, 81, 52, 77, 82, 83, 56, - 56, 57, 58, 59, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 59, 66, 67, 68, 87, 96, 97, 98, 91, 99, 100, 101, 95, 102, 103, 104, - 68, 75, 76, 77, 98, 105, 106, 107, 101, 108, 109, 110, 104, 111, 112, 113, - 77, 82, 83, 56, 107, 114, 115, 84, 110, 116, 117, 88, 113, 118, 119, 92, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 123, 136, 137, 120, 127, 138, 139, 124, 131, 140, 141, 128, 135, 142, 143, 132, - 132, 133, 134, 135, 144, 145, 146, 147, 148, 149, 150, 151, 68, 152, 153, 154, - 135, 142, 143, 132, 147, 155, 156, 144, 151, 157, 158, 148, 154, 159, 160, 68, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 164, 177, 178, 161, 168, 179, 180, 165, 172, 181, 182, 169, 176, 183, 184, 173, - 173, 174, 175, 176, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 176, 183, 184, 173, 188, 197, 198, 185, 192, 199, 200, 189, 196, 201, 202, 193, - 203, 203, 203, 203, 206, 207, 208, 209, 210, 210, 210, 210, 211, 212, 213, 214, - 203, 203, 203, 203, 209, 216, 217, 218, 210, 210, 210, 210, 214, 219, 220, 221, - 203, 203, 203, 203, 218, 223, 224, 225, 210, 210, 210, 210, 221, 226, 227, 228, - 203, 203, 203, 203, 225, 229, 230, 206, 210, 210, 210, 210, 228, 231, 232, 211, - 211, 212, 213, 214, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 214, 219, 220, 221, 236, 245, 246, 247, 240, 248, 249, 250, 244, 251, 252, 253, - 221, 226, 227, 228, 247, 254, 255, 256, 250, 257, 258, 259, 253, 260, 261, 262, - 228, 231, 232, 211, 256, 263, 264, 233, 259, 265, 266, 237, 262, 267, 268, 241, - 269, 269, 269, 269, 278, 279, 280, 281, 274, 275, 276, 277, 270, 271, 272, 273, - 269, 269, 269, 269, 281, 288, 289, 290, 277, 285, 286, 287, 273, 282, 283, 284, - 269, 269, 269, 269, 290, 297, 298, 299, 287, 294, 295, 296, 284, 291, 292, 293, - 269, 269, 269, 269, 299, 304, 305, 278, 296, 302, 303, 274, 293, 300, 301, 270 -}; - -#endif diff --git a/src/threed/geometry/qlogicalvertex.cpp b/src/threed/geometry/qlogicalvertex.cpp deleted file mode 100644 index 84dc09ae..00000000 --- a/src/threed/geometry/qlogicalvertex.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qlogicalvertex.h" -#include "qvector_utils_p.h" - -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QLogicalVertex - \brief The QLogicalVertex class references QGeometryData at a single vertex. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::geometry - - QLogicalVertex instances are a convenience class for use with - QGeometryData. A QLogicalVertex simply references through to the data - in a QGeometryData for a particular vertex, providing accessors to fetch - position, texture coordinates, and other values. - - Create a QLogicalVertex referring to a particular QGeometryData instance: - \code - QGeometryData data; - data.appendVertex(QVector3D(1, 2, 3)); - - // construct a QLogicalVertex referring to the first vertex in data - // the QGeometryData is implicitly shared with lv - QLogicalVertex lv(data, 0); - // lv.vertex() == QVector3D(1, 2, 3) - \endcode - This is inexpensive and no new storage is allocated for the actual data, - just the reference and index. - - With logical vertices instances referencing large QGeometryData instances, - avoid modifying the instance: - \code - // careful - assigning to a QLogicalVertex which refers to an external - // QGeometryData will result in a possibly expensive copy-on-write - lv.setVertex(3, 2, 1); - \endcode - - Create a QLogicalVertex with its own QGeometryData internally: - \code - QLogicalVertex lv; - // no copy on write here - internal QGeometryData is not shared - lv.setVertex(1, 2, 3); - \endcode - - Assign an instance of QLogicalVertex: - \code - QLogicalVertex lv2; - lv2 = data.logicalVertexAt(0); - \endcode - Although lv2 gets its own internal QGeometryData which is then immediately - thrown away by the assignment, because of lazy initialization in - QGeometryData the cost is negligible. - - Use the fields() and hasField() functions to determine if a particular - field is present in the vertex. Accessing non-existent data will cause - an assert in debug mode (from the underlying QArray), and give - undefined behaviour in release mode. - - \sa QGeometryData, QGLBuilder -*/ - -/*! - \fn QLogicalVertex::QLogicalVertex() - Constructs a new invalid QLogicalVertex which has no data. -*/ - -/*! - \fn QLogicalVertex::QLogicalVertex(QGeometryData data, int index) - Constructs a new QLogicalVertex referencing the \a data at \a index. - Note that if this QLogicalVertex is modified, by calling vertex() or - setNormal() for example, then a copy-on-write for \a data will be - triggered. -*/ - -/*! - \fn QLogicalVertex::QLogicalVertex(const QVector3D &a) - Constructs a new QLogicalVertex with a vertex set to \a a. -*/ - -/*! - \fn QLogicalVertex::QLogicalVertex(const QVector3D &a, const QVector3D &n); - Constructs a new QLogicalVertex with a vertex set to \a a, and normal set to \a n. -*/ - -/*! - \fn QLogicalVertex::QLogicalVertex(const QVector3D &a, const QVector3D &n, const QVector2D &t) - Constructs a new QLogicalVertex with its vertex value set to \a a, normal set - to \a n, and texture set to \a t. By default \a n is the null QVector3D, - and \a t is the InvalidTexCoord. If \a n is null then hasType(QLogicalVertex::Normal) - will return false. Likewise if \a t is the InvalidTexCoord then - hasType(QLogicalVertex::Texture) will return false. -*/ - -/*! - \fn QLogicalVertex::QLogicalVertex(const QVector3D &a, QColor4ub color) - Constructs a new QLogicalVertex with its vertex value set to \a a, - color value set to \a color. -*/ - -/*! - \fn QLogicalVertex::~QLogicalVertex() - Destroys this QLogicalVertex reclaiming any resources. -*/ - -/*! - \fn const QVector3D &QLogicalVertex::vertex() const - Returns a const reference to the vertex value for this vertex. -*/ - -/*! - \fn void QLogicalVertex::setVertex(const QVector3D &v) - Sets the vertex value for this vertex to \a v. -*/ - -/*! - \fn QVector3D &QLogicalVertex::vertex() - Returns a modifiable reference to the vertex value. -*/ - -/*! - \fn QLogicalVertex::operator QVector3D () - Returns a copy of the vertex value, by casting as a QVector3D. This - allows passing of a QLogicalVertex to functions that expect a QVector3D. -*/ - -/*! - \fn QVariant QLogicalVertex::attribute(QGL::VertexAttribute field) const - Returns the attribute value for \a field. The \a field defaults - to QGL::CustomVertex0. -*/ - -/*! - \fn void QLogicalVertex::setAttribute(float value, QGL::VertexAttribute field) - Sets the float attribute \a value at \a field. The \a field - defaults to QGL::CustomVertex0. -*/ - -/*! - \fn void QLogicalVertex::setAttribute(const QVector2D &v, QGL::VertexAttribute field) - Sets the QVector2D attribute \a v at \a field. The \a field - defaults to QGL::CustomVertex0. -*/ - -/*! - \fn void QLogicalVertex::setAttribute(const QVector3D &v, QGL::VertexAttribute field) - Sets the QVector3D attribute \a v at \a field. The \a field - defaults to QGL::CustomVertex0. -*/ - -/*! - \fn float &QLogicalVertex::floatAttribute(QGL::VertexAttribute field) - Returns a modifiable reference to the attribute at \a field, which - must be a float. The \a field defaults to QGL::CustomVertex0. -*/ - -/*! - \fn QVector2D &QLogicalVertex::vector2DAttribute(QGL::VertexAttribute field) - Returns a modifiable reference to the attribute at \a field, which - must be a QVector2D. The \a field defaults to QGL::CustomVertex0. -*/ - -/*! - \fn QVector3D &QLogicalVertex::vector3DAttribute(QGL::VertexAttribute field = QGL::CustomVertex0); - Returns a modifiable reference to the attribute at \a field, which - must be a QVector3D. The \a field defaults to QGL::CustomVertex0. -*/ - -/*! - \fn float QLogicalVertex::floatAttribute(QGL::VertexAttribute field) const - Returns the attribute at \a field. The \a field defaults to QGL::CustomVertex0. - The attribute must be a float value. -*/ - -/*! - \fn QVector2D QLogicalVertex::vector2DAttribute(QGL::VertexAttribute field) const - Returns the attribute at \a field. The \a field defaults to QGL::CustomVertex0. - The attribute must be a QVector2D value. -*/ - -/*! - \fn QVector3D QLogicalVertex::vector3DAttribute(QGL::VertexAttribute field) const - Returns the attribute at \a field. The \a field defaults to QGL::CustomVertex0. - The attribute must be a QVector3D value. -*/ - -/*! - \fn QCustomDataArray::ElementType QLogicalVertex::attributeType(QGL::VertexAttribute field) - Returns the element type for the attribute \a field. -*/ - -/*! - \fn const QVector3D &QLogicalVertex::normal() const - Returns a const reference to the normal value for this vertex. -*/ - -/*! - \fn void QLogicalVertex::setNormal(const QVector3D &n) - Sets the normal value for this vertex to \a n. -*/ - -/*! - \fn QVector3D &QLogicalVertex::normal() - Returns a modifiable reference to the normal value for this vertex. -*/ - -/*! - \fn QVector2D QLogicalVertex::texCoord(QGL::VertexAttribute field) const - Returns a copy of the texture coordinate value at \a field for this vertex. - The \a field defaults to QGL::TextureCoord0. -*/ - -/*! - \fn void QLogicalVertex::setTexCoord(const QVector2D &t, QGL::VertexAttribute field) - Sets the texture coordinate at \a field for this vertex to \a t. - The \a field defaults to QGL::TextureCoord0. -*/ - -/*! - \fn QVector2D &QLogicalVertex::texCoordRef(QGL::VertexAttribute field) - Returns a modifiable reference to the texture coordinate for this vertex. - The \a field defaults to QGL::TextureCoord0. -*/ - -/*! - \fn QColor4ub QLogicalVertex::color() const - Returns a const reference to the color value for this vertex. -*/ - -/*! - \fn void QLogicalVertex::setColor(const QColor4ub &c) - Sets the color value for this vertex to \a c. -*/ - -/*! - \fn QColor4ub &QLogicalVertex::colorRef() - Returns a modifiable reference to the color value for this vertex. -*/ - -/*! - \fn bool QLogicalVertex::hasField(QGL::VertexAttribute type) const - Returns true if this vertex has data field \a type, and false otherwise. - - In general check to see if a logical vertex has a particular field - type before attempting to access it. In debug mode accessing a - non-existent field will cause an assert; but in release mode the - behaviour is undefined. -*/ - -/*! - \fn quint32 QLogicalVertex::fields() const - Returns a bit-mask of the fields in this logical vertex. Test the - fields like this: - \code - if (vertex.fields() & QGL::fieldMask(QGL::TextureCoord0)) - tex = vertex.texCoord(); - \endcode - - \sa QGeometryData::fields() -*/ - -/*! - \fn int QLogicalVertex::index() const - Returns the index at which this logical vertex's data is located in - its associated QGeometryData; or -1 if this vertex is null. -*/ - -/*! - \fn QGeometryData QLogicalVertex::data() const - Returns a copy of the QGeometryData underlying this vertex. Note that - the copy is not expensive in terms of performance due to implicit sharing - unless the copy is modified (causing a copy-on-write). - - \sa QLogicalVertex::index() -*/ - -/*! - \fn QGeometryData data() const - Returns a copy of the QGeometryData associated with this vertex. Note - that as long as the copy is not modified, this method is not expensive. -*/ - -/*! - \fn bool QLogicalVertex::isNull() const - Returns true if this vertex is null. - - \sa QLogicalVertex() -*/ - -/*! - Returns true if \a rhs has exactly the same fields as this logical - vertex, and each of those are equal to the corresponding field of the \a rhs. - - If either are null, then false is returned. -*/ -bool QLogicalVertex::operator==(const QLogicalVertex &rhs) const -{ - if (isNull() || rhs.isNull()) - return false; - if (this == &rhs) - return true; - if (m_data.fields() != rhs.fields()) - return false; - const quint32 mask = 0x01; - quint32 fields = m_data.fields(); - for (int field = 0; fields; ++field, fields >>= 1) - { - if (mask & fields) - { - QGL::VertexAttribute attr = static_cast<QGL::VertexAttribute>(field); - if (attr < QGL::TextureCoord0) - { - if (attr == QGL::Position) - { - if (!qFskCompare(vertex(), rhs.vertex())) - return false; - } - else if (attr == QGL::Normal) - { - if (!qFskCompare(normal(), rhs.normal())) - return false; - } - else - { - if (color() != rhs.color()) - return false; - } - } - else if (attr < QGL::CustomVertex0) - { - if (!qFskCompare(texCoord(attr), rhs.texCoord(attr))) - return false; - } - else - { - if (attribute(attr) != rhs.attribute(attr)) - return false; - } - } - } - return true; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug dbg, const QLogicalVertex &lv) -{ - dbg.nospace(); - dbg << "QLogicalVertex("; - if (lv.isNull()) - { - dbg << " NULL"; - } - else - { - if (lv.hasField(QGL::Position)) - dbg << "V:" << QVector3D(lv.vertex()); - else - dbg << " (No Vertex)"; - if (lv.hasField(QGL::Normal)) - dbg << "N:" << QVector3D(lv.normal()); - else - dbg << " (No Normal)"; - if (lv.hasField(QGL::TextureCoord0)) - dbg << "T:" << QVector2D(lv.texCoord()); - else - dbg << " (No Texture)"; - if (lv.hasField(QGL::Color)) - dbg << "C:" << QColor4ub(lv.color()); - else - dbg << " (No Color)"; - } - dbg << " )"; - return dbg.space(); -} -#endif - -QT_END_NAMESPACE diff --git a/src/threed/geometry/qlogicalvertex.h b/src/threed/geometry/qlogicalvertex.h deleted file mode 100644 index 3a5d9b6b..00000000 --- a/src/threed/geometry/qlogicalvertex.h +++ /dev/null @@ -1,328 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QLOGICALVERTEX_H -#define QLOGICALVERTEX_H - -#include "qgeometrydata.h" -#include "qcustomdataarray.h" - -QT_BEGIN_NAMESPACE - -// uncomment this to perform heavy checking of QLogicalVertex -// #define QT3D_DEBUG_QLOGICALVERTEX 1 - -class QLogicalVertex -{ -public: - inline QLogicalVertex(); - inline QLogicalVertex(QGeometryData data, int index); - inline QLogicalVertex(const QVector3D &a); - inline QLogicalVertex(const QVector3D &a, const QVector3D &n); - inline QLogicalVertex(const QVector3D &a, const QVector3D &n, const QVector2D &t); - inline QLogicalVertex(const QVector3D &a, QColor4ub color); - ~QLogicalVertex() {} - - inline const QVector3D &vertex() const; - inline void setVertex(const QVector3D &v); - inline QVector3D &vertex(); - - operator QVector3D () { return vertex(); } - - inline QVariant attribute(QGL::VertexAttribute field = QGL::CustomVertex0) const; - inline void setAttribute(float value, QGL::VertexAttribute attr); - inline void setAttribute(const QVector2D &v, QGL::VertexAttribute field = QGL::CustomVertex0); - inline void setAttribute(const QVector3D &v, QGL::VertexAttribute field = QGL::CustomVertex0); - inline float &floatAttribute(QGL::VertexAttribute field = QGL::CustomVertex0); - inline QVector2D &vector2DAttribute(QGL::VertexAttribute field = QGL::CustomVertex0); - inline QVector3D &vector3DAttribute(QGL::VertexAttribute field = QGL::CustomVertex0); - inline float floatAttribute(QGL::VertexAttribute field = QGL::CustomVertex0) const; - inline QVector2D vector2DAttribute(QGL::VertexAttribute field = QGL::CustomVertex0) const; - inline QVector3D vector3DAttribute(QGL::VertexAttribute field = QGL::CustomVertex0) const; - inline QCustomDataArray::ElementType attributeType(QGL::VertexAttribute field = QGL::CustomVertex0); - - inline const QVector3D &normal() const; - inline void setNormal(const QVector3D &n); - inline QVector3D &normal(); - - inline const QColor4ub &color() const; - inline void setColor(const QColor4ub &c); - inline QColor4ub &colorRef(); - - inline const QVector2D &texCoord(QGL::VertexAttribute attr = QGL::TextureCoord0) const; - inline void setTexCoord(const QVector2D &t, QGL::VertexAttribute attr = QGL::TextureCoord0); - inline QVector2D &texCoordRef(QGL::VertexAttribute attr = QGL::TextureCoord0); - - inline bool hasField(QGL::VertexAttribute type) const; - inline quint32 fields() const; - inline int index() const; - inline QGeometryData data() const; - inline bool isNull() const; - - bool operator==(const QLogicalVertex &rhs) const; - -private: - QGeometryData m_data; - int m_index; -}; - -inline QLogicalVertex::QLogicalVertex() - : m_index(-1) -{ -} - -inline QLogicalVertex::QLogicalVertex(QGeometryData data, int index) - : m_data(data) - , m_index(index) -{ - Q_ASSERT(index < data.count()); -#ifdef QT3D_DEBUG_QLOGICALVERTEX - data.check(); -#endif -} - -inline QLogicalVertex::QLogicalVertex(const QVector3D &a) - : m_index(0) -{ - m_data.appendVertex(a); -} - -inline QLogicalVertex::QLogicalVertex(const QVector3D &a, const QVector3D &n) - : m_index(0) -{ - m_data.appendVertex(a); - m_data.appendNormal(n); -} - -inline QLogicalVertex::QLogicalVertex(const QVector3D &a, const QVector3D &n, const QVector2D &t) - : m_index(0) -{ - m_data.appendVertex(a); - m_data.appendNormal(n); - m_data.appendTexCoord(t); -} - -inline QLogicalVertex::QLogicalVertex(const QVector3D &a, QColor4ub color) - : m_index(0) -{ - m_data.appendVertex(a); - m_data.appendColor(color); -} - -inline const QVector3D &QLogicalVertex::vertex() const -{ - return m_data.vertexAt(m_index); -} - -inline void QLogicalVertex::setVertex(const QVector3D &v) -{ - if (m_index == -1) - m_index = 0; - if (m_index == m_data.count(QGL::Position)) - m_data.appendVertex(v); - else - m_data.vertex(m_index) = v; -} - -inline QVector3D &QLogicalVertex::vertex() -{ - return m_data.vertex(m_index); -} - -inline QVariant QLogicalVertex::attribute(QGL::VertexAttribute attr) const -{ - return m_data.attributes(attr).at(m_index); -} - -inline void QLogicalVertex::setAttribute(float v, QGL::VertexAttribute attr) -{ - if (m_index == -1) - m_index = 0; - if (m_index == m_data.count(attr)) - m_data.appendAttribute(v, attr); - else - m_data.floatAttribute(m_index, attr) = v; -} - -inline void QLogicalVertex::setAttribute(const QVector2D &v, QGL::VertexAttribute attr) -{ - if (m_index == -1) - m_index = 0; - if (m_index == m_data.count(attr)) - m_data.appendAttribute(v, attr); - else - m_data.vector2DAttribute(m_index, attr) = v; -} - -inline void QLogicalVertex::setAttribute(const QVector3D &v, QGL::VertexAttribute attr) -{ - if (m_index == -1) - m_index = 0; - if (m_index == m_data.count(attr)) - m_data.appendAttribute(v, attr); - else - m_data.vector3DAttribute(m_index, attr) = v; -} - -inline float &QLogicalVertex::floatAttribute(QGL::VertexAttribute field) -{ - return m_data.floatAttribute(m_index, field); -} - -inline QVector2D &QLogicalVertex::vector2DAttribute(QGL::VertexAttribute field) -{ - return m_data.vector2DAttribute(m_index, field); -} - -inline QVector3D &QLogicalVertex::vector3DAttribute(QGL::VertexAttribute field) -{ - - return m_data.vector3DAttribute(m_index, field); -} - -inline float QLogicalVertex::floatAttribute(QGL::VertexAttribute field) const -{ - return m_data.floatAttributeAt(m_index, field); -} - -inline QVector2D QLogicalVertex::vector2DAttribute(QGL::VertexAttribute field) const -{ - return m_data.vector2DAttributeAt(m_index, field); -} - -inline QVector3D QLogicalVertex::vector3DAttribute(QGL::VertexAttribute field) const -{ - return m_data.vector3DAttributeAt(m_index, field); -} - -inline QCustomDataArray::ElementType QLogicalVertex::attributeType(QGL::VertexAttribute field) -{ - return m_data.attributes(field).elementType(); -} - -inline const QVector3D &QLogicalVertex::normal() const -{ - return m_data.normalAt(m_index); -} - -inline void QLogicalVertex::setNormal(const QVector3D &n) -{ - if (m_index == -1) - m_index = 0; - if (m_index == m_data.count(QGL::Normal)) - m_data.appendNormal(n); - else - m_data.normal(m_index) = n; -} - -inline QVector3D &QLogicalVertex::normal() -{ - return m_data.normal(m_index); -} - -inline const QVector2D &QLogicalVertex::texCoord(QGL::VertexAttribute attr) const -{ - return m_data.texCoordAt(m_index, attr); -} - -inline void QLogicalVertex::setTexCoord(const QVector2D &t, QGL::VertexAttribute attr) -{ - Q_ASSERT(attr >= QGL::TextureCoord0 && attr <= QGL::TextureCoord2); - if (m_index == -1) - m_index = 0; - if (m_index == m_data.count(attr)) - m_data.appendTexCoord(t, attr); - else - m_data.texCoord(m_index, attr) = t; -} - -inline QVector2D &QLogicalVertex::texCoordRef(QGL::VertexAttribute attr) -{ - return m_data.texCoord(m_index, attr); -} - -inline const QColor4ub &QLogicalVertex::color() const -{ - return m_data.colorAt(m_index); -} - -inline void QLogicalVertex::setColor(const QColor4ub &c) -{ - if (m_index == -1) - m_index = 0; - if (m_index == m_data.count(QGL::Color)) - m_data.appendColor(c); - else - m_data.color(m_index) = c; -} - -inline QColor4ub &QLogicalVertex::colorRef() -{ - return m_data.color(m_index); -} - -inline bool QLogicalVertex::hasField(QGL::VertexAttribute attr) const -{ - return m_data.hasField(attr); -} - -inline quint32 QLogicalVertex::fields() const -{ - return m_data.fields(); -} - -inline int QLogicalVertex::index() const -{ - return m_index; -} - -inline bool QLogicalVertex::isNull() const -{ - return (m_index == -1); -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug dbg, const QLogicalVertex §ion); -#endif - -QT_END_NAMESPACE - -#endif // QLOGICALVERTEX_H diff --git a/src/threed/geometry/qvector_utils_p.h b/src/threed/geometry/qvector_utils_p.h deleted file mode 100644 index 3350ad6f..00000000 --- a/src/threed/geometry/qvector_utils_p.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 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 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QVECTOR_UTILS_P_H -#define QVECTOR_UTILS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/qvector3d.h> -#include <QtGui/qvector2d.h> - -// Replacement for qFuzzyCompare(QVector3D, QVector3D) and friends, -// for a specific case where the results are going to be rendered -// by the GPU onto a display. -// -// The accuracy of this comparison should not change. Especially it -// should not change when you go from doubles to floats or when -// you get close to zero. If two verts or lighting normals are -// the same to within 5 places of floating point accuracy then they -// will dislay as being on top of each other. -// -// Also this avoids doing 3 floating point multiplications every time -// since the normal qFuzzyIsNull does a mul to scale the epsilon when -// close to zero. - -inline bool qFskIsNull(double d) -{ - return qAbs(d) <= 0.00001; -} - -inline bool qFskIsNull(float f) -{ - return qAbs(f) <= 0.00001f; -} - -inline bool qFskCompare(float a, float b) -{ - return qFskIsNull(a - b); -} - -inline bool qFskCompare(double a, double b) -{ - return qFskIsNull(a - b); -} - -inline bool qFskCompare(const QVector3D &a, const QVector3D &b) -{ - return ( - qFskIsNull(a.x() - b.x()) && - qFskIsNull(a.y() - b.y()) && - qFskIsNull(a.z() - b.z()) - ); -} - -inline bool qFskCompare(const QVector2D &a, const QVector2D &b) -{ - return ( - qFskIsNull(a.x() - b.x()) && - qFskIsNull(a.y() - b.y()) - ); -} - -#endif // QVECTOR_UTILS_P_H |