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;
47using QSSGRenderNodeVersionType = quint16;
67 bool hasId()
const {
return m_id != 0; }
118 [[nodiscard]]
bool isSet(quint32 v)
const {
return (m_value & v) != 0; }
131 return a.m_value == b.m_value;
146template<
int MINATTENUATION = 0,
int MAXATTENUATION = 1000>
148template<
int MINATTENUATION = 0,
int MAXATTENUATION = 1000>
181inline void flip(QMatrix4x4 &matrix)
184 float *writePtr(matrix.data());
186 writePtr[0 * 4 + 2] *= -1;
187 writePtr[1 * 4 + 2] *= -1;
188 writePtr[2 * 4 + 0] *= -1;
189 writePtr[2 * 4 + 1] *= -1;
191 writePtr[3 * 4 + 2] *= -1;
216template<
typename TDataType>
219 return QSSGDataRef<TDataType>(byteSize ?
reinterpret_cast<TDataType *>(baseData + offset) :
nullptr,
220 byteSize /
sizeof(TDataType));
226 return QVector3D(qDegreesToRadians(v.x()), qDegreesToRadians(v.y()), qDegreesToRadians(v.z()));
230 return QVector3D(qRadiansToDegrees(v.x()), qRadiansToDegrees(v.y()), qRadiansToDegrees(v.z()));
237 return QVector2D(absoluteCoordinates.x() -
float(r.x()), absoluteCoordinates.y() -
float(r.y()));
242 return QVector2D(
float(r.width() / 2.0),
float(r.height() / 2.0));
250 const QVector2D relativeCoords(toRectRelative(r, absoluteCoordinates));
251 const QVector2D halfD(halfDims(r));
252 const QVector2D normalized((relativeCoords.x() / halfD.x()) - 1.0f, (relativeCoords.y() / halfD.y()) - 1.0f);
253 return QVector2D(normalized.x() * halfD.x(), normalized.y() * halfD.y());
258 return { (rectRelativeCoords.x() / halfDims(r).x()) - 1.0f, (rectRelativeCoords.y() / halfDims(r).y()) - 1.0f };
265 return relativeToNormalizedCoordinates(r, toRectRelative(r, absoluteCoordinates));
270 return QVector2D(inRelativeCoords.x() +
float(r.x()), inRelativeCoords.y() +
float(r.y()));
283 , m_dirty(Dirty::Quaternion)
288 , m_dirty(Dirty::Euler)
294 m_dirty = Dirty::Quaternion;
299 m_quatRot = r.normalized();
300 m_dirty = Dirty::Euler;
305 if (a.m_dirty == Dirty::None && b.m_dirty == Dirty::None)
306 return fuzzyQuaternionCompare(a.m_quatRot, b.m_quatRot);
308 return fuzzyQuaternionCompare(a.toQuaternion(), b.toQuaternion());
315 if (a.m_dirty == Dirty::None)
316 return qFuzzyCompare(a.m_eulerRot, eulerRotation);
318 return qFuzzyCompare(a.toEulerAngles(), eulerRotation);
321 friend bool operator !=(
const RotationData &a,
const QVector3D &eulerRotation) {
return !(a == eulerRotation); }
324 friend bool operator !=(
const QVector3D &eulerRotation,
const RotationData &a) {
return !(a == eulerRotation); }
328 const QQuaternion normalizedRotation = rotation.normalized();
329 if (a.m_dirty == Dirty::None)
330 return fuzzyQuaternionCompare(a.m_quatRot, normalizedRotation);
332 return fuzzyQuaternionCompare(a.toQuaternion(), normalizedRotation);
341 if (m_dirty == Dirty::Euler) {
342 m_eulerRot = m_quatRot.toEulerAngles();
343 m_dirty = Dirty::None;
351 if (m_dirty == Dirty::Quaternion) {
352 m_quatRot = QQuaternion::fromEulerAngles(m_eulerRot).normalized();
353 m_dirty = Dirty::None;
362 friend class ::tst_RotationDataClass;
364 static constexpr double dotProduct(
const QQuaternion &q1,
const QQuaternion &q2)
noexcept
366 return double(q1.scalar()) *
double(q2.scalar())
367 +
double(q1.x()) *
double(q2.x())
368 +
double(q1.y()) *
double(q2.y())
369 +
double(q1.z()) *
double(q2.z());
372 [[nodiscard]]
static constexpr bool fuzzyQuaternionCompare(
const QQuaternion &a,
const QQuaternion &b)
376 if (a == b || a == -b)
378 return qFuzzyCompare(qAbs(dotProduct(a, b)), 1.0);
388 mutable QQuaternion m_quatRot;
389 mutable QVector3D m_eulerRot;
390 mutable Dirty m_dirty { Dirty::None };
397 if (!node->debugObjectName.isEmpty())
399 node->debugObjectName = src->objectName();
400 if (node->debugObjectName.isEmpty())
401 node->debugObjectName = QString::fromLatin1(src->metaObject()->className());
402 if (node->debugObjectName.isEmpty())
403 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::Layer > QSSGRenderLayerHandle