1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dmorphtarget_p.h"
5
6#include <QtQuick3DRuntimeRender/private/qssgrendermorphtarget_p.h>
7#include <QtQml/QQmlFile>
8
9QT_BEGIN_NAMESPACE
10
11/*!
12 \qmltype MorphTarget
13 \inherits Object
14 \inqmlmodule QtQuick3D
15 \brief Defines the properties of a morph target.
16
17 Each \e MorphTarget is a morph target for a \l{Morphing Animation}{vertex animation}. The degree
18 of morphing is controlled by changing the \l {weight} property.
19
20 \qml
21 MorphTarget {
22 id: morphtarget0
23 attributes: MorphTarget.Position | MorphTarget.Normal
24 weight: 0.5
25 }
26 \endqml
27
28 The \l {Qt Quick 3D - Morphing Example}{morphing example} shows how to use a morph target.
29*/
30
31QQuick3DMorphTarget::QQuick3DMorphTarget(QQuick3DObject *parent)
32 : QQuick3DObject(*(new QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type::MorphTarget)), parent) {}
33
34QQuick3DMorphTarget::~QQuick3DMorphTarget()
35{
36}
37
38/*!
39 \qmlproperty float MorphTarget::weight
40
41 Specifies the weight of the current morph target. The weight is the multiplication factor used
42 by the linear interpolation. A weight of 1 means that this target is fully applied. A weight of
43 0 means that it has no influence.
44*/
45
46float QQuick3DMorphTarget::weight() const
47{
48 return m_weight;
49}
50
51/*!
52 \qmlproperty enumeration MorphTarget::attributes
53
54 Specifies the set of attributes of the current morph target.
55 In order to animate vertex attributes in morphing, the mesh must
56 contain those target attributes and the morph target must have the
57 attributes enabled.
58
59 The attributes for a morph target are specified by OR-ing together the following values:
60 \value MorphTarget.Position animates the vertex positions
61 \value MorphTarget.Normal animates the normal vectors
62 \value MorphTarget.Tangent animates the tangent vectors
63 \value MorphTarget.Binormal animates the binormal vectors
64 \value MorphTarget.TexCoord0 animates the texture coordinate 0 vectors
65 \value MorphTarget.TexCoord1 animates the texture coordinate 1 vectors
66 \value MorphTarget.Color animates the vertex color vectors
67*/
68
69QQuick3DMorphTarget::MorphTargetAttributes QQuick3DMorphTarget::attributes() const
70{
71 return m_attributes;
72}
73
74void QQuick3DMorphTarget::markAllDirty()
75{
76 m_dirtyAttributes = 0xffffffff;
77 QQuick3DObject::markAllDirty();
78}
79
80void QQuick3DMorphTarget::setWeight(float weight)
81{
82 if (m_weight == weight)
83 return;
84
85 m_weight = weight;
86 emit weightChanged();
87 markDirty(type: WeightDirty);
88}
89
90void QQuick3DMorphTarget::setAttributes(MorphTargetAttributes attributes)
91{
92 if (m_attributes == attributes)
93 return;
94
95 m_attributes = attributes;
96 m_numAttribs = 0;
97 int flags = attributes;
98 while (flags) {
99 m_numAttribs += flags & 0x1;
100 flags >>= 1;
101 }
102 emit attributesChanged();
103 markDirty(type: MorphTargetAttributesDirty);
104}
105
106QSSGRenderGraphObject *QQuick3DMorphTarget::updateSpatialNode(QSSGRenderGraphObject *node)
107{
108 if (!node) {
109 markAllDirty();
110 node = new QSSGRenderMorphTarget();
111 }
112 QQuick3DObject::updateSpatialNode(node);
113 auto modelNode = static_cast<QSSGRenderMorphTarget *>(node);
114 if (m_dirtyAttributes & WeightDirty)
115 modelNode->weight = m_weight;
116 if (m_dirtyAttributes & MorphTargetAttributesDirty)
117 modelNode->attributes = QSSGRenderMorphTarget::InputAttributes(int(m_attributes));
118
119 m_dirtyAttributes = 0;
120
121 return modelNode;
122}
123
124void QQuick3DMorphTarget::markDirty(QQuick3DMorphTarget::QSSGMorphTargetDirtyType type)
125{
126 if (!(m_dirtyAttributes & quint32(type))) {
127 m_dirtyAttributes |= quint32(type);
128 update();
129 }
130}
131
132size_t QQuick3DMorphTarget::numAttribs()
133{
134 return m_numAttribs;
135}
136
137QT_END_NAMESPACE
138

source code of qtquick3d/src/quick3d/qquick3dmorphtarget.cpp