21#include <QtQuick3DUtils/private/qtquick3dutilsglobal_p.h>
22#include <QtQuick3DUtils/private/qssgdataref_p.h>
24#include <QtGui/QVector2D>
25#include <QtGui/QVector3D>
26#include <QtGui/QQuaternion>
27#include <QtGui/QMatrix3x3>
28#include <QtGui/QMatrix4x4>
29#include <QtGui/QColor>
31#include <QtCore/qdebug.h>
32#include <QtCore/QString>
33#include <QtCore/qloggingcategory.h>
34#include <QtCore/QIODevice>
35#include <QtCore/qmath.h>
37class tst_RotationDataClass;
49using QSSGRenderNodeVersionType = quint16;
69 bool hasId()
const {
return m_id != 0; }
122 [[nodiscard]]
bool isSet(quint32 v)
const {
return (m_value & v) != 0; }
135 return a.m_value == b.m_value;
150template<
int MINATTENUATION = 0,
int MAXATTENUATION = 1000>
152template<
int MINATTENUATION = 0,
int MAXATTENUATION = 1000>
185inline void flip(QMatrix4x4 &matrix)
188 float *writePtr(matrix.data());
190 writePtr[0 * 4 + 2] *= -1;
191 writePtr[1 * 4 + 2] *= -1;
192 writePtr[2 * 4 + 0] *= -1;
193 writePtr[2 * 4 + 1] *= -1;
195 writePtr[3 * 4 + 2] *= -1;
220template<
typename TDataType>
223 return QSSGDataRef<TDataType>(byteSize ?
reinterpret_cast<TDataType *>(baseData + offset) :
nullptr,
224 byteSize /
sizeof(TDataType));
230 return QVector3D(qDegreesToRadians(v.x()), qDegreesToRadians(v.y()), qDegreesToRadians(v.z()));
234 return QVector3D(qRadiansToDegrees(v.x()), qRadiansToDegrees(v.y()), qRadiansToDegrees(v.z()));
241 return QVector2D(absoluteCoordinates.x() -
float(r.x()), absoluteCoordinates.y() -
float(r.y()));
246 return QVector2D(
float(r.width() / 2.0),
float(r.height() / 2.0));
254 const QVector2D relativeCoords(toRectRelative(r, absoluteCoordinates));
255 const QVector2D halfD(halfDims(r));
256 const QVector2D normalized((relativeCoords.x() / halfD.x()) - 1.0f, (relativeCoords.y() / halfD.y()) - 1.0f);
257 return QVector2D(normalized.x() * halfD.x(), normalized.y() * halfD.y());
262 return { (rectRelativeCoords.x() / halfDims(r).x()) - 1.0f, (rectRelativeCoords.y() / halfDims(r).y()) - 1.0f };
269 return relativeToNormalizedCoordinates(r, toRectRelative(r, absoluteCoordinates));
274 return QVector2D(inRelativeCoords.x() +
float(r.x()), inRelativeCoords.y() +
float(r.y()));
287 , m_dirty(Dirty::Quaternion)
292 , m_dirty(Dirty::Euler)
298 m_dirty = Dirty::Quaternion;
303 m_quatRot = r.normalized();
304 m_dirty = Dirty::Euler;
309 if (a.m_dirty == Dirty::None && b.m_dirty == Dirty::None)
310 return fuzzyQuaternionCompare(a.m_quatRot, b.m_quatRot);
312 return fuzzyQuaternionCompare(a.toQuaternion(), b.toQuaternion());
319 if (a.m_dirty == Dirty::None)
320 return qFuzzyCompare(a.m_eulerRot, eulerRotation);
322 return qFuzzyCompare(a.toEulerAngles(), eulerRotation);
325 friend bool operator !=(
const RotationData &a,
const QVector3D &eulerRotation) {
return !(a == eulerRotation); }
328 friend bool operator !=(
const QVector3D &eulerRotation,
const RotationData &a) {
return !(a == eulerRotation); }
332 const QQuaternion normalizedRotation = rotation.normalized();
333 if (a.m_dirty == Dirty::None)
334 return fuzzyQuaternionCompare(a.m_quatRot, normalizedRotation);
336 return fuzzyQuaternionCompare(a.toQuaternion(), normalizedRotation);
345 if (m_dirty == Dirty::Euler) {
346 m_eulerRot = m_quatRot.toEulerAngles();
347 m_dirty = Dirty::None;
355 if (m_dirty == Dirty::Quaternion) {
356 m_quatRot = QQuaternion::fromEulerAngles(m_eulerRot).normalized();
357 m_dirty = Dirty::None;
366 friend class ::tst_RotationDataClass;
368 static constexpr double dotProduct(
const QQuaternion &q1,
const QQuaternion &q2)
noexcept
370 return double(q1.scalar()) *
double(q2.scalar())
371 +
double(q1.x()) *
double(q2.x())
372 +
double(q1.y()) *
double(q2.y())
373 +
double(q1.z()) *
double(q2.z());
376 [[nodiscard]]
static constexpr bool fuzzyQuaternionCompare(
const QQuaternion &a,
const QQuaternion &b)
380 if (a == b || a == -b)
382 return qFuzzyCompare(qAbs(dotProduct(a, b)), 1.0);
392 mutable QQuaternion m_quatRot;
393 mutable QVector3D m_eulerRot;
394 mutable Dirty m_dirty { Dirty::None };
401 if (!node->debugObjectName.isEmpty())
403 node->debugObjectName = src->objectName();
404 if (node->debugObjectName.isEmpty())
405 node->debugObjectName = QString::fromLatin1(src->metaObject()->className());
406 if (node->debugObjectName.isEmpty())
407 node->debugObjectName = QString::asprintf(
"%p", src);
Class representing 3D range or axis aligned bounding box.
void clearFlags(quint32 v=0xFFFFFFFF)
friend bool operator!=(const QSSGRenderFlag &a, const QSSGRenderFlag &b)
QSSGRenderFlag(quint32 v)
friend bool operator==(const QSSGRenderFlag &a, const QSSGRenderFlag &b)
void setFlag(quint32 v, bool on=true)
bool isSet(quint32 v) const
static constexpr size_t VersionBits
QSSGRenderStorageHandle()=default
VersionType version() const
QSSGRenderStorageHandle(ContextType ctx, VersionType version, IndexType index)
static constexpr size_t ContextBits
static constexpr size_t IndexBits
ContextType context() const
QQuaternion toQuaternion() const
RotationData(const QVector3D &r)
friend bool operator!=(const RotationData &a, const RotationData &b)
friend bool operator!=(const QVector3D &eulerRotation, const RotationData &a)
friend bool operator==(const QVector3D &eulerRotation, const RotationData &a)
friend bool operator!=(const RotationData &a, const QVector3D &eulerRotation)
QVector3D toEulerAngles() const
friend bool operator==(const RotationData &a, const QVector3D &eulerRotation)
QMatrix3x3 toRotationMatrix() const
friend bool operator==(const RotationData &a, const RotationData &b)
RotationData & operator=(const QVector3D &r) noexcept
void ensureDebugObjectName(T *node, QObject *src)
Q_DECL_CONSTEXPR float translateLinearAttenuation(float attenuation)
Q_DECL_CONSTEXPR float translateConstantAttenuation(float attenuation)
Q_DECL_CONSTEXPR float translateQuadraticAttenuation(float attenuation)
void flip(QMatrix4x4 &matrix)
QVector2D toRectRelative(const QRectF &r, const QVector2D &absoluteCoordinates)
QVector2D halfDims(const QRectF &r)
QVector2D toAbsoluteCoords(const QRectF &r, const QVector2D &inRelativeCoords)
QVector2D absoluteToNormalizedCoordinates(const QRectF &r, const QVector2D &absoluteCoordinates)
QVector2D relativeToNormalizedCoordinates(const QRectF &r, QVector2D rectRelativeCoords)
QVector2D toNormalizedRectRelative(const QRectF &r, QVector2D absoluteCoordinates)
QVector3D radToDeg(const QVector3D &v)
QSSGDataRef< TDataType > PtrAtOffset(quint8 *baseData, quint32 offset, quint32 byteSize)
Q_QUICK3DUTILS_EXPORT const char * nonNull(const char *src)
QVector3D degToRad(const QVector3D &v)
Combined button and popup list for selecting options.
QSSGRenderFlag QSSGRenderNodeTag
QSSGRenderStorageHandle< HandleType::Node > QSSGRenderNodeHandle
QSSGRenderStorageHandle< HandleType::Item2D > QSSGRenderItem2DHandle
QSSGRenderStorageHandle< HandleType::Model > QSSGRenderModelHandle
QSSGRenderStorageHandle< HandleType::Layer > QSSGRenderLayerHandle