Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquick3dnode.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dnode_p.h"
5#include "qquick3dnode_p_p.h"
6
7#include <QtQuick3DRuntimeRender/private/qssgrendernode_p.h>
8#include <QtQuick3DUtils/private/qssgutils_p.h>
9#include <QtQuick3D/private/qquick3dobject_p.h>
10
11#include <QtMath>
12
14
20
25
27{
28
29}
30
32{
33 Q_Q(QQuick3DNode);
34 if (isHidden == m_isHiddenInEditor)
35 return;
36 m_isHiddenInEditor = isHidden;
37 q->update();
38}
39
41{
42 Q_Q(QQuick3DNode);
43
44 // decompose the 4x4 affine transform into scale, rotation and translation
46 QQuaternion rotation;
48
50 q->setScale(scale);
51 q->setRotation(rotation);
52 q->setPosition(position);
53 }
54
55 // We set the local transform as-is regardless if it could be decomposed or not.
56 // We'd likely want some way to notify about this, but for now the transform
57 // can potentially change silently.
59 // Note: If any of the transform properties are set before the update
60 // the explicit local transform should be ignored by setting this value to false.
62
63 q->update();
64}
65
135
137 : QQuick3DObject(dd, parent)
138{
139 Q_ASSERT_X(QSSGRenderGraphObject::isNodeType(dd.type), "", "Type needs to be identified as a node type!");
140
141 Q_D(QQuick3DNode);
142 d->init();
143}
144
146
155float QQuick3DNode::x() const
156{
157 Q_D(const QQuick3DNode);
158 return d->m_position.x();
159}
160
169float QQuick3DNode::y() const
170{
171 Q_D(const QQuick3DNode);
172 return d->m_position.y();
173}
174
183float QQuick3DNode::z() const
184{
185 Q_D(const QQuick3DNode);
186 return d->m_position.z();
187}
188
196{
197 Q_D(const QQuick3DNode);
198 return d->m_rotation;
199}
200
209{
210 Q_D(const QQuick3DNode);
211 return d->m_position;
212}
213
214
221{
222 Q_D(const QQuick3DNode);
223 return d->m_scale;
224}
225
234{
235 Q_D(const QQuick3DNode);
236 return d->m_pivot;
237}
238
248{
249 Q_D(const QQuick3DNode);
250 return d->m_opacity;
251}
252
260{
261 Q_D(const QQuick3DNode);
262 return d->m_visible;
263}
264
273{
274 Q_D(const QQuick3DNode);
275 return d->m_staticFlags;
276}
277
279{
280 // The parent of a QQuick3DNode should never be anything else than a (subclass
281 // of) QQuick3DNode (but the children/leaf nodes can be something else).
282 return static_cast<QQuick3DNode *>(parentItem());
283}
284
295{
296 return mapDirectionToScene(QVector3D(0, 0, -1)).normalized();
297}
298
309{
310 return mapDirectionToScene(QVector3D(0, 1, 0)).normalized();
311}
312
323{
324 return mapDirectionToScene(QVector3D(1, 0, 0)).normalized();
325}
343
351{
352 Q_D(const QQuick3DNode);
353 return QQuaternion::fromRotationMatrix(QSSGUtils::mat44::getUpper3x3(d->sceneRotationMatrix())).normalized();
354}
355
366
375{
376 Q_D(const QQuick3DNode);
377 if (d->m_sceneTransformDirty)
378 const_cast<QQuick3DNodePrivate *>(d)->calculateGlobalVariables();
379 return d->m_sceneTransform;
380}
381
383{
384 Q_Q(QQuick3DNode);
385 m_sceneTransformDirty = false;
387 QQuick3DNode *parent = q->parentNode();
388 if (!parent) {
389 m_sceneTransform = localTransform;
391 return;
392 }
394
395 if (privateParent->m_sceneTransformDirty)
396 privateParent->calculateGlobalVariables();
397 m_sceneTransform = privateParent->m_sceneTransform * localTransform;
398
399 // Check if we have an ancestor with non-uniform scale. This will decide whether
400 // or not we can use the sceneTransform to extract sceneRotation and sceneScale.
401 m_hasInheritedUniformScale = privateParent->m_hasInheritedUniformScale;
403 const QVector3D ps = privateParent->m_scale;
404 m_hasInheritedUniformScale = qFuzzyCompare(ps.x(), ps.y()) && qFuzzyCompare(ps.x(), ps.z());
405 }
406}
407
412
414{
415 Q_Q(const QQuick3DNode);
416
418 // Ensure m_hasInheritedUniformScale is up to date
419 const_cast<QQuick3DNodePrivate *>(this)->calculateGlobalVariables();
420 }
421
423 // When we know that every node up to the root have a uniform scale, we can extract the
424 // rotation directly from the sceneTransform(). This is optimizing, since we reuse that
425 // matrix for more than just calculating the sceneRotation.
426 QMatrix4x4 rotationMatrix = q->sceneTransform();
427 QSSGUtils::mat44::normalize(rotationMatrix);
428 return rotationMatrix;
429 }
430
431 // When we have an ancestor that has a non-uniform scale, we cannot extract
432 // the rotation from the sceneMatrix directly. Instead, we need to calculate
433 // it separately, which is slightly more costly.
434 const QMatrix4x4 parentRotationMatrix = QQuick3DNodePrivate::get(q->parentNode())->sceneRotationMatrix();
435 return parentRotationMatrix * localRotationMatrix();
436}
437
439{
440 Q_Q(QQuick3DNode);
442 const QQuaternion prevRotation = QQuaternion::fromRotationMatrix(QSSGUtils::mat44::getUpper3x3(m_sceneTransform)).normalized();
444 QVector3D prevForward, prevUp, prevRight;
445 QVector3D newForward, newUp, newRight;
446 // Do direction (forward, up, right) calculations only if they have connections
447 bool emitDirectionChanges = (m_directionConnectionCount > 0);
448 if (emitDirectionChanges) {
449 // Instead of calling forward(), up() and right(), calculate them here.
450 // This way m_sceneTransform isn't updated due to m_sceneTransformDirty and
451 // common theDirMatrix operations are not duplicated.
453 prevForward = QSSGUtils::mat33::transform(theDirMatrix, QVector3D(0, 0, -1)).normalized();
454 prevUp = QSSGUtils::mat33::transform(theDirMatrix, QVector3D(0, 1, 0)).normalized();
455 prevRight = QSSGUtils::mat33::transform(theDirMatrix, QVector3D(1, 0, 0)).normalized();
456 }
457
459
461 const QQuaternion newRotation = QQuaternion::fromRotationMatrix(QSSGUtils::mat44::getUpper3x3(m_sceneTransform)).normalized();
463 if (emitDirectionChanges) {
465 newForward = QSSGUtils::mat33::transform(theDirMatrix, QVector3D(0, 0, -1)).normalized();
466 newUp = QSSGUtils::mat33::transform(theDirMatrix, QVector3D(0, 1, 0)).normalized();
467 newRight = QSSGUtils::mat33::transform(theDirMatrix, QVector3D(1, 0, 0)).normalized();
468 }
469
470 const bool positionChanged = prevPosition != newPosition;
471 const bool rotationChanged = prevRotation != newRotation;
472 const bool scaleChanged = !qFuzzyCompare(prevScale, newScale);
473
474 if (!positionChanged && !rotationChanged && !scaleChanged)
475 return;
476
477 emit q->sceneTransformChanged();
478
479 if (positionChanged)
480 emit q->scenePositionChanged();
481 if (rotationChanged)
482 emit q->sceneRotationChanged();
483 if (scaleChanged)
484 emit q->sceneScaleChanged();
485 if (emitDirectionChanges) {
486 const bool forwardChanged = prevForward != newForward;
487 const bool upChanged = prevUp != newUp;
488 const bool rightChanged = prevRight != newRight;
489 if (forwardChanged)
490 Q_EMIT q->forwardChanged();
491 if (upChanged)
492 Q_EMIT q->upChanged();
493 if (rightChanged)
494 Q_EMIT q->rightChanged();
495 }
496}
497
499{
500 // Return true if its likely that we need to emit
501 // the given signal when our global transform changes.
502 static const QMetaMethod sceneTransformSignal = QMetaMethod::fromSignal(&QQuick3DNode::sceneTransformChanged);
506
507 return (signal == sceneTransformSignal
508 || signal == scenePositionSignal
509 || signal == sceneRotationSignal
510 || signal == sceneScaleSignal);
511}
512
514{
515 // Return true if its likely that we need to emit
516 // the given signal when our global transform changes.
520
521 return (signal == forwardSignal
522 || signal == upSignal
523 || signal == rightSignal);
524}
525
527{
528 Q_D(QQuick3DNode);
529 // Since we want to avoid calculating the global transform in the frontend
530 // unnecessary, we keep track of the number of connections/QML bindings
531 // that needs it. If there are no connections, we can skip calculating it
532 // whenever our geometry changes (unless someone asks for it explicitly).
533 if (d->isSceneTransformRelatedSignal(signal))
534 d->m_sceneTransformConnectionCount++;
535 if (d->isDirectionRelatedSignal(signal))
536 d->m_directionConnectionCount++;
537}
538
540{
541 Q_D(QQuick3DNode);
542 if (d->isSceneTransformRelatedSignal(signal))
543 d->m_sceneTransformConnectionCount--;
544 if (d->isDirectionRelatedSignal(signal))
545 d->m_directionConnectionCount--;
546}
547
549{
550 Q_D(QQuick3DNode);
552 if (d->m_sceneTransformConnectionCount > 0 || d->m_directionConnectionCount > 0)
553 d->emitChangesToSceneTransform();
554}
555
557{
558 Q_Q(QQuick3DNode);
559 // Note: we recursively set m_sceneTransformDirty to true whenever our geometry
560 // changes. But we only set it back to false if someone actually queries our global
561 // transform (because only then do we need to calculate it). This means that if no
562 // one ever does that, m_sceneTransformDirty will remain true, perhaps through out
563 // the life time of the node. This is in contrast with the backend, which need to
564 // update dirty transform nodes for every scene graph sync (and clear the backend
565 // dirty transform flags - QQuick3DObjectPrivate::dirtyAttributes).
566 // This means that for most nodes, calling markSceneTransformDirty() should be
567 // cheap, since we normally expect to return early in the following test.
569 return;
570
572
575
576 auto children = QQuick3DObjectPrivate::get(q)->childItems;
577 for (auto child : children) {
578 if (auto node = qobject_cast<QQuick3DNode *>(child)) {
579 QQuick3DNodePrivate::get(node)->markSceneTransformDirty();
580 }
581 }
582}
583
585{
586 Q_D(QQuick3DNode);
587 if (qFuzzyCompare(d->m_position.x(), x))
588 return;
589
590 d->m_position.setX(x);
591 d->markSceneTransformDirty();
593 emit xChanged();
594 update();
595}
596
598{
599 Q_D(QQuick3DNode);
600 if (qFuzzyCompare(d->m_position.y(), y))
601 return;
602
603 d->m_position.setY(y);
604 d->markSceneTransformDirty();
606 emit yChanged();
607 update();
608}
609
611{
612 Q_D(QQuick3DNode);
613 if (qFuzzyCompare(d->m_position.z(), z))
614 return;
615
616 d->m_position.setZ(z);
617 d->markSceneTransformDirty();
619 emit zChanged();
620 update();
621}
622
624{
625 Q_D(QQuick3DNode);
626 if (d->m_rotation == rotation)
627 return;
628
629 d->m_hasExplicitLocalTransform = false;
630 d->m_rotation = rotation;
631 d->markSceneTransformDirty();
634
635 update();
636}
637
639{
640 Q_D(QQuick3DNode);
641 if (d->m_position == position)
642 return;
643
644 const bool xUnchanged = qFuzzyCompare(position.x(), d->m_position.x());
645 const bool yUnchanged = qFuzzyCompare(position.y(), d->m_position.y());
646 const bool zUnchanged = qFuzzyCompare(position.z(), d->m_position.z());
647
648 d->m_position = position;
649 d->markSceneTransformDirty();
651
652 if (!xUnchanged)
653 emit xChanged();
654 if (!yUnchanged)
655 emit yChanged();
656 if (!zUnchanged)
657 emit zChanged();
658
659 d->m_hasExplicitLocalTransform = false;
660
661 update();
662}
663
665{
666 Q_D(QQuick3DNode);
667 if (d->m_scale == scale)
668 return;
669
670 d->m_hasExplicitLocalTransform = false;
671 d->m_scale = scale;
672 d->markSceneTransformDirty();
674 update();
675}
676
678{
679 Q_D(QQuick3DNode);
680 if (d->m_pivot == pivot)
681 return;
682
683 d->m_hasExplicitLocalTransform = false;
684 d->m_pivot = pivot;
685 d->markSceneTransformDirty();
687 update();
688}
689
691{
692 Q_D(QQuick3DNode);
693 if (qFuzzyCompare(d->m_opacity, opacity))
694 return;
695
696 d->m_opacity = opacity;
698 update();
699}
700
701void QQuick3DNode::setVisible(bool visible)
702{
703 Q_D(QQuick3DNode);
704 if (d->m_visible == visible)
705 return;
706
707 d->m_visible = visible;
709 update();
710}
711
712void QQuick3DNode::setStaticFlags(int staticFlags)
713{
714 Q_D(QQuick3DNode);
715 if (d->m_staticFlags == staticFlags)
716 return;
717
718 d->m_staticFlags = staticFlags;
720 update();
721}
722
723void QQuick3DNode::setEulerRotation(const QVector3D &eulerRotation) {
724 Q_D(QQuick3DNode);
725
726 if (d->m_rotation == eulerRotation)
727 return;
728
729 d->m_hasExplicitLocalTransform = false;
730 d->m_rotation = eulerRotation;
731
733 d->markSceneTransformDirty();
735 update();
736}
737
753void QQuick3DNode::rotate(qreal degrees, const QVector3D &axis, TransformSpace space)
754{
755 Q_D(QQuick3DNode);
756
757 const QQuaternion addRotationQuat = QQuaternion::fromAxisAndAngle(axis, float(degrees));
758 const QMatrix4x4 addRotationMatrix = QMatrix4x4(addRotationQuat.toRotationMatrix());
759 QMatrix4x4 newRotationMatrix;
760
761 switch (space) {
762 case LocalSpace:
763 newRotationMatrix = d->localRotationMatrix() * addRotationMatrix;
764 break;
765 case ParentSpace:
766 newRotationMatrix = addRotationMatrix * d->localRotationMatrix();
767 break;
768 case SceneSpace:
769 if (const auto parent = parentNode()) {
770 const QMatrix4x4 lrm = d->localRotationMatrix();
771 const QMatrix4x4 prm = QQuick3DNodePrivate::get(parent)->sceneRotationMatrix();
772 newRotationMatrix = prm.inverted() * addRotationMatrix * prm * lrm;
773 } else {
774 newRotationMatrix = d->localRotationMatrix() * addRotationMatrix;
775 }
776 break;
777 }
778
779 const QQuaternion newRotationQuaternion = QQuaternion::fromRotationMatrix(QSSGUtils::mat44::getUpper3x3(newRotationMatrix)).normalized();
780
781 if (d->m_rotation == newRotationQuaternion)
782 return;
783
784 d->m_hasExplicitLocalTransform = false;
785 d->m_rotation = newRotationQuaternion;
786 d->markSceneTransformDirty();
787
790
791 update();
792}
793
795{
796 Q_D(QQuick3DNode);
797 if (!node) {
798 markAllDirty();
799 node = new QSSGRenderNode();
800 }
802 auto spacialNode = static_cast<QSSGRenderNode *>(node);
803 bool transformIsDirty = false;
804
805 if (spacialNode->pivot != d->m_pivot) {
806 transformIsDirty = true;
807 spacialNode->pivot = d->m_pivot;
808 }
809
810 if (!qFuzzyCompare(spacialNode->localOpacity, d->m_opacity)) {
811 spacialNode->localOpacity = d->m_opacity;
812 spacialNode->markDirty(QSSGRenderNode::DirtyFlag::OpacityDirty);
813 }
814
815 if (d->m_hasExplicitLocalTransform) {
816 spacialNode->localTransform = d->m_localTransform;
817 spacialNode->markDirty(QSSGRenderNode::DirtyFlag::TransformDirty);
818 d->m_hasExplicitLocalTransform = false;
819 } else {
820 if (!transformIsDirty && !qFuzzyCompare(d->m_position, QSSGUtils::mat44::getPosition(spacialNode->localTransform)))
821 transformIsDirty = true;
822
823 if (!transformIsDirty && !qFuzzyCompare(d->m_scale, QSSGUtils::mat44::getScale(spacialNode->localTransform)))
824 transformIsDirty = true;
825
826 if (!transformIsDirty && !qFuzzyCompare(d->m_rotation, QQuaternion::fromRotationMatrix(QSSGUtils::mat44::getUpper3x3(spacialNode->localTransform))))
827 transformIsDirty = true;
828
829 if (transformIsDirty) {
830 spacialNode->localTransform = QSSGRenderNode::calculateTransformMatrix(d->m_position, d->m_scale, d->m_pivot, d->m_rotation);;
831 spacialNode->markDirty(QSSGRenderNode::DirtyFlag::TransformDirty);
832 }
833 }
834
835 spacialNode->staticFlags = d->m_staticFlags;
836
837 // The Hidden in Editor flag overrides the visible value
838 if (d->m_isHiddenInEditor)
839 spacialNode->setState(QSSGRenderNode::LocalState::Active, false);
840 else
841 spacialNode->setState(QSSGRenderNode::LocalState::Active, d->m_visible);
842
844
845 return spacialNode;
846}
847
860{
861 return QSSGUtils::mat44::transform(sceneTransform(), localPosition);
862}
863
875
886QVector3D QQuick3DNode::mapPositionToNode(const QQuick3DNode *node, const QVector3D &localPosition) const
887{
888 const auto scenePositionSelf = mapPositionToScene(localPosition);
889 return node ? node->mapPositionFromScene(scenePositionSelf) : scenePositionSelf;
890}
891
903{
904 const auto scenePositionOther = node ? node->mapPositionToScene(localPosition) : localPosition;
905 return mapPositionFromScene(scenePositionOther);
906}
907
921{
922 QMatrix3x3 theDirMatrix = sceneTransform().normalMatrix();
923 return QSSGUtils::mat33::transform(theDirMatrix, localDirection);
924}
925
939{
941 theDirMatrix = theDirMatrix.transposed();
942 return QSSGUtils::mat33::transform(theDirMatrix, sceneDirection);
943}
944
960QVector3D QQuick3DNode::mapDirectionToNode(const QQuick3DNode *node, const QVector3D &localDirection) const
961{
962 const auto sceneDirectionSelf = mapDirectionToScene(localDirection);
963 return node ? node->mapDirectionFromScene(sceneDirectionSelf) : sceneDirectionSelf;
964}
965
982{
983 const auto sceneDirectionOther = node ? node->mapDirectionToScene(localDirection) : localDirection;
984 return mapDirectionFromScene(sceneDirectionOther);
985}
986
988{
989 Q_D(QQuick3DNode);
990
991 d->markSceneTransformDirty();
993}
994
1006{
1007 const Q_D(QQuick3DNode);
1008
1009 return d->m_rotation;
1010}
1011
1012void QQuick3DNode::itemChange(ItemChange change, const ItemChangeData &)
1013{
1014 if (change == QQuick3DObject::ItemParentHasChanged)
1015 QQuick3DNodePrivate::get(this)->markSceneTransformDirty();
1016}
1017
Definition lalr.h:136
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
QMatrix3x3 normalMatrix() const
Returns the normal matrix corresponding to this 4x4 transformation.
\inmodule QtCore
Definition qmetaobject.h:19
static QMetaMethod fromSignal(PointerToMemberFunction signal)
QObject * parent
Definition qobject.h:73
The QQuaternion class represents a quaternion consisting of a vector and scalar.
void setIsHiddenInEditor(bool isHidden)
bool isDirectionRelatedSignal(const QMetaMethod &signal) const
QMatrix4x4 localRotationMatrix() const
QMatrix4x4 sceneRotationMatrix() const
QQuick3DNodePrivate(QQuick3DObjectPrivate::Type t)
bool isSceneTransformRelatedSignal(const QMetaMethod &signal) const
void setLocalTransform(const QMatrix4x4 &transform)
static QQuick3DNodePrivate * get(QQuick3DNode *node)
QVector3D pivot
void eulerRotationChanged()
void rightChanged()
void rotationChanged()
void setRotation(const QQuaternion &rotation)
void setVisible(bool visible)
void connectNotify(const QMetaMethod &signal) override
virtual void itemChange(ItemChange, const ItemChangeData &) override
Q_INVOKABLE QVector3D mapDirectionFromNode(const QQuick3DNode *node, const QVector3D &localDirection) const
\qmlmethod vector3d QtQuick3D::Node::mapDirectionFromNode(QtQuick3D::Node node, vector3d localDirecti...
QVector3D sceneScale
Q_INVOKABLE QVector3D mapPositionFromScene(const QVector3D &scenePosition) const
\qmlmethod vector3d QtQuick3D::Node::mapPositionFromScene(vector3d scenePosition)
void disconnectNotify(const QMetaMethod &signal) override
QVector3D scenePosition
~QQuick3DNode() override
Q_INVOKABLE QVector3D mapDirectionFromScene(const QVector3D &sceneDirection) const
\qmlmethod vector3d QtQuick3D::Node::mapDirectionFromScene(vector3d sceneDirection)
void setEulerRotation(const QVector3D &eulerRotation)
void setScale(const QVector3D &scale)
Q_INVOKABLE void rotate(qreal degrees, const QVector3D &axis, QQuick3DNode::TransformSpace space)
\qmlmethod QtQuick3D::Node::rotate(real degrees, vector3d axis, enumeration space)
Q_INVOKABLE QVector3D mapPositionFromNode(const QQuick3DNode *node, const QVector3D &localPosition) const
\qmlmethod vector3d QtQuick3D::Node::mapPositionFromNode(QtQuick3D::Node node, vector3d localPosition...
void setPivot(const QVector3D &pivot)
void localOpacityChanged()
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void visibleChanged()
void xChanged()
void setStaticFlags(int staticFlags)
void setLocalOpacity(float opacity)
void markAllDirty() override
QMatrix4x4 sceneTransform
void sceneScaleChanged()
void setPosition(const QVector3D &position)
QVector3D forward
Q_INVOKABLE QVector3D mapPositionToScene(const QVector3D &localPosition) const
\qmlmethod vector3d QtQuick3D::Node::mapPositionToScene(vector3d localPosition)
QVector3D right
void yChanged()
void positionChanged()
void zChanged()
void sceneRotationChanged()
QQuick3DNode * parentNode() const
Q_INVOKABLE QVector3D mapPositionToNode(const QQuick3DNode *node, const QVector3D &localPosition) const
\qmlmethod vector3d QtQuick3D::Node::mapPositionToNode(QtQuick3D::Node node, vector3d localPosition)
void scenePositionChanged()
QSSGRenderGraphObject * updateSpatialNode(QSSGRenderGraphObject *node) override
void pivotChanged()
QQuaternion rotation
float localOpacity() const
\qmlproperty real QtQuick3D::Node::opacity
void setY(float y)
Q_INVOKABLE QVector3D mapDirectionToScene(const QVector3D &localDirection) const
\qmlmethod vector3d QtQuick3D::Node::mapDirectionToScene(vector3d localDirection)
void sceneTransformChanged()
void setX(float x)
Q_INVOKABLE QVector3D mapDirectionToNode(const QQuick3DNode *node, const QVector3D &localDirection) const
\qmlmethod vector3d QtQuick3D::Node::mapDirectionToNode(QtQuick3D::Node node, vector3d localDirection...
QQuick3DNode(QQuick3DNode *parent=nullptr)
\qmltype Node \inherits Object3D \inqmlmodule QtQuick3D
QVector3D eulerRotation
void setZ(float z)
void scaleChanged()
void staticFlagsChanged()
QQuaternion sceneRotation
void forwardChanged()
QVector3D position
QVector3D scale
void upChanged()
QQmlListProperty< QQuick3DObject > children()
static QQuick3DObjectPrivate * get(QQuick3DObject *item)
\qmltype Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DObject \inherits QtObject
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
QQuick3DObject * parent
\qmlproperty Object3D QtQuick3D::Object3D::parent This property holds the parent of the Object3D in a...
virtual QSSGRenderGraphObject * updateSpatialNode(QSSGRenderGraphObject *node)
virtual void markAllDirty()
static constexpr bool isNodeType(Type type) noexcept
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
QVector3D normalized() const noexcept
Returns the normalized unit vector form of this vector.
Definition qvectornd.h:695
constexpr float y() const noexcept
Returns the y coordinate of this point.
Definition qvectornd.h:671
constexpr float x() const noexcept
Returns the x coordinate of this point.
Definition qvectornd.h:670
constexpr float z() const noexcept
Returns the z coordinate of this point.
Definition qvectornd.h:672
QMatrix3x3 toRotationMatrix() const
auto signal
void ensureDebugObjectName(T *node, QObject *src)
QVector3D Q_QUICK3DUTILS_EXPORT transform(const QMatrix3x3 &m, const QVector3D &v)
Definition qssgutils.cpp:43
QMatrix3x3 Q_QUICK3DUTILS_EXPORT getUpper3x3(const QMatrix4x4 &m)
Definition qssgutils.cpp:51
QVector3D Q_QUICK3DUTILS_EXPORT transform(const QMatrix4x4 &m, const QVector3D &v)
Definition qssgutils.cpp:86
void Q_QUICK3DUTILS_EXPORT normalize(QMatrix4x4 &m)
Definition qssgutils.cpp:57
QVector3D Q_QUICK3DUTILS_EXPORT getScale(const QMatrix4x4 &m)
QVector3D Q_QUICK3DUTILS_EXPORT getPosition(const QMatrix4x4 &m)
Definition qssgutils.cpp:97
bool Q_QUICK3DUTILS_EXPORT decompose(const QMatrix4x4 &m, QVector3D &position, QVector3D &scale, QQuaternion &rotation)
Combined button and popup list for selecting options.
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLint y
GLuint GLenum GLenum transform
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLenum GLenum GLenum GLenum GLenum scale
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
#define Q_EMIT
#define emit
double qreal
Definition qtypes.h:187
QLayoutItem * child
[0]
static QMatrix4x4 calculateTransformMatrix(QVector3D position, QVector3D scale, QVector3D pivot, QQuaternion rotation)
Definition moc.h:23