6#include <QtQuick3D/private/qquick3dobject_p.h>
8#include <QtQuick/QQuickWindow>
208 if (m_positions == newPositions)
210 m_positions = newPositions;
217 return m_primitiveMode;
222 if (m_primitiveMode == newPrimitiveMode)
226 if (newPrimitiveMode < Points || newPrimitiveMode >
Triangles) {
227 qWarning() <<
"Invalid primitive mode specified";
232 if (!supportsTriangleFanPrimitive()) {
233 qWarning() <<
"TriangleFan is not supported by the current backend";
238 m_primitiveMode = newPrimitiveMode;
243void ProceduralMesh::requestUpdate()
245 if (!m_updateRequested) {
247 m_updateRequested =
true;
251void ProceduralMesh::updateGeometry()
253 m_updateRequested =
false;
260 const auto expectedLength = m_positions.
size();
261 bool hasPositions = !m_positions.
isEmpty();
267 bool hasNormals = m_normals.
size() >= expectedLength;
268 bool hasTangents = m_tangents.
size() >= expectedLength;
269 bool hasBinormals = m_binormals.
size() >= expectedLength;
270 bool hasUV0s = m_uv0s.
size() >= expectedLength;
271 bool hasUV1s = m_uv1s.
size() >= expectedLength;
272 bool hasColors = m_colors.
size() >= expectedLength;
273 bool hasJoints = m_joints.
size() >= expectedLength;
274 bool hasWeights = m_weights.
size() >= expectedLength;
275 bool hasIndexes = !m_indexes.
isEmpty();
279 addAttribute(Attribute::Semantic::PositionSemantic,
offset, Attribute::ComponentType::F32Type);
280 offset += 3 *
sizeof(float);
284 addAttribute(Attribute::Semantic::NormalSemantic,
offset, Attribute::ComponentType::F32Type);
285 offset += 3 *
sizeof(float);
289 addAttribute(Attribute::Semantic::TangentSemantic,
offset, Attribute::ComponentType::F32Type);
290 offset += 3 *
sizeof(float);
294 addAttribute(Attribute::Semantic::BinormalSemantic,
offset, Attribute::ComponentType::F32Type);
295 offset += 3 *
sizeof(float);
299 addAttribute(Attribute::Semantic::TexCoord0Semantic,
offset, Attribute::ComponentType::F32Type);
300 offset += 2 *
sizeof(float);
304 addAttribute(Attribute::Semantic::TexCoord1Semantic,
offset, Attribute::ComponentType::F32Type);
305 offset += 2 *
sizeof(float);
309 addAttribute(Attribute::Semantic::ColorSemantic,
offset, Attribute::ComponentType::F32Type);
310 offset += 4 *
sizeof(float);
314 addAttribute(Attribute::Semantic::JointSemantic,
offset, Attribute::ComponentType::F32Type);
315 offset += 4 *
sizeof(float);
319 addAttribute(Attribute::Semantic::WeightSemantic,
offset, Attribute::ComponentType::F32Type);
320 offset += 4 *
sizeof(float);
324 addAttribute(Attribute::Semantic::IndexSemantic, 0, Attribute::ComponentType::U32Type);
332 vertexBufferData.
reserve(bufferSize /
sizeof(
float));
352 const auto &normal = m_normals[
i];
353 vertexBufferData.
append(normal.x());
354 vertexBufferData.
append(normal.y());
355 vertexBufferData.
append(normal.z());
359 const auto &binormal = m_binormals[
i];
360 vertexBufferData.
append(binormal.x());
361 vertexBufferData.
append(binormal.y());
362 vertexBufferData.
append(binormal.z());
366 const auto &tangent = m_tangents[
i];
367 vertexBufferData.
append(tangent.x());
368 vertexBufferData.
append(tangent.y());
369 vertexBufferData.
append(tangent.z());
373 const auto &uv0 = m_uv0s[
i];
374 vertexBufferData.
append(uv0.x());
375 vertexBufferData.
append(uv0.y());
379 const auto &uv1 = m_uv1s[
i];
380 vertexBufferData.
append(uv1.x());
381 vertexBufferData.
append(uv1.y());
385 const auto &
color = m_colors[
i];
393 const auto &joint = m_joints[
i];
394 vertexBufferData.
append(joint.x());
395 vertexBufferData.
append(joint.y());
396 vertexBufferData.
append(joint.z());
397 vertexBufferData.
append(joint.w());
401 const auto &
weight = m_weights[
i];
410 QByteArray vertexBuffer(
reinterpret_cast<char *
>(vertexBufferData.
data()), bufferSize);
417 indexBuffer.
reserve(indexLength *
sizeof(
unsigned int));
419 const auto &
index = m_indexes[
i];
420 indexBuffer.
append(
reinterpret_cast<const char *
>(&
index),
sizeof(
unsigned int));
428 for (
const auto &subset : m_subsets) {
433 bool outOfRange =
false;
434 for (
qsizetype i = subset->offset();
i < subset->offset() + subset->count(); ++
i) {
438 if (
i < m_indexes.
size()) {
460 addSubset(subset->offset(), subset->count(), subsetMinBounds, subsetMaxBounds, subset->name());
462 qWarning(
"Skipping invalid subset: Out of Range");
469void ProceduralMesh::subsetDestroyed(
QObject *subset)
475bool ProceduralMesh::supportsTriangleFanPrimitive()
const
477 static bool supportQueried =
false;
478 static bool triangleFanSupported =
false;
479 if (!supportQueried) {
487 supportQueried =
true;
493 return triangleFanSupported;
498 if (subset ==
nullptr)
506 self->requestUpdate();
526 self->requestUpdate();
536 if (m_indexes == newIndexes)
538 m_indexes = newIndexes;
550 if (m_normals == newNormals)
552 m_normals = newNormals;
564 if (m_tangents == newTangents)
566 m_tangents = newTangents;
578 if (m_binormals == newBinormals)
580 m_binormals = newBinormals;
592 if (m_uv0s == newUv0s)
606 if (m_uv1s == newUv1s)
620 if (m_colors == newColors)
622 m_colors = newColors;
634 if (m_joints == newJoints)
636 m_joints = newJoints;
648 if (m_weights == newWeights)
650 m_weights = newWeights;
659 ProceduralMesh::qmlAppendProceduralMeshSubset,
660 ProceduralMesh::qmlProceduralMeshSubsetCount,
661 ProceduralMesh::qmlProceduralMeshSubsetAt,
662 ProceduralMesh::qmlClearProceduralMeshSubset);
672 if (m_offset == newOffset)
675 m_offset = newOffset;
687 if (m_count == newCount)
702 if (m_name == newName)
void setCount(int newCount)
void setOffset(int newOffset)
void setName(const QString &newName)
ProceduralMesh()
\qmlproperty List<QVector3D> ProceduralMesh::positions The positions attribute list.
void setUv1s(const QList< QVector2D > &newUv1s)
void setWeights(const QList< QVector4D > &newWeights)
void primitiveModeChanged()
QList< QVector4D > joints
void setPositions(const QList< QVector3D > &newPositions)
QList< QVector3D > positions
QList< QVector4D > colors
void setTangents(const QList< QVector3D > &newTangents)
QList< QVector3D > binormals
void setNormals(const QList< QVector3D > &newNormals)
void setJoints(const QList< QVector4D > &newJoints)
PrimitiveMode primitiveMode
void setBinormals(const QList< QVector3D > &newBinormals)
void setIndexes(const QList< unsigned int > &newIndexes)
void setUv0s(const QList< QVector2D > &newUv0s)
void setPrimitiveMode(PrimitiveMode newPrimitiveMode)
QQmlListProperty< ProceduralMeshSubset > subsets
QList< QVector3D > normals
QList< QVector4D > weights
QList< unsigned int > indexes
QList< QVector3D > tangents
void setColors(const QList< QVector4D > &newColors)
void reserve(qsizetype size)
Attempts to allocate memory for at least size bytes.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
qsizetype size() const noexcept
bool isEmpty() const noexcept
qsizetype removeAll(const AT &t)
void reserve(qsizetype size)
void append(parameter_type t)
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
The QQmlListProperty class allows applications to expose list-like properties of QObject-derived clas...
Attribute::Semantic int int stride
Returns the byte stride of the vertex buffer.
void setPrimitiveType(PrimitiveType type)
Sets the primitive type used for rendering to type.
void setStride(int stride)
Sets the stride of the vertex buffer to stride, measured in bytes.
void addAttribute(Attribute::Semantic semantic, int offset, Attribute::ComponentType componentType)
Adds vertex attribute description.
void setVertexData(const QByteArray &data)
Sets the vertex buffer data.
Attribute::Semantic int offset
void clear()
Resets the geometry to its initial state, clearing previously set vertex and index data as well as at...
void setBounds(const QVector3D &min, const QVector3D &max)
Sets the bounding volume of the geometry to the cube defined by the points min and max.
void setIndexData(const QByteArray &data)
Sets the index buffer to data.
QPointer< QQuick3DSceneManager > sceneManager
static QQuick3DObjectPrivate * get(QQuick3DObject *item)
\macro QT_RESTRICTED_CAST_FROM_ASCII
void clear()
Clears the contents of the string and makes it null.
void push_back(QChar c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
qsizetype count(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
The QVector3D class represents a vector or vertex in 3D space.
constexpr void setX(float x) noexcept
Sets the x coordinate of this point to the given finite x coordinate.
constexpr void setY(float y) noexcept
Sets the y coordinate of this point to the given finite y coordinate.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
constexpr void setZ(float z) noexcept
Sets the z coordinate of this point to the given finite z coordinate.
constexpr float z() const noexcept
Returns the z coordinate of this point.
Combined button and popup list for selecting options.
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
GLuint GLuint GLfloat weight
const void GLsizei GLsizei stride
GLenum GLuint GLintptr offset
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
QNetworkAccessManager manager