1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
7\page quick3d-vertex-skinning
11Qt Quick 3D supports vertex skinning for skeletal animation of mesh geometries.
13See the \l {Qt Quick 3D - Simple Skinning Example}{Simple Skinning Example} for a practical
14demonstration of skeletal animation.
16In most cases, application developers will not be using the skinning API manually. The normal workflow is to
17use an external content creation tool to define the skeleton and the skin (this is sometimes also referred to
18as \e rigging), and then use the \l {Balsam Asset Import Tool} to convert the asset to Qt Quick 3D's native format.
20\section1 Defining a skeleton
22The basis of skeletal animation is the \l {Skeleton}. This is an abstract representation of how the model
23can move, inspired by how a physical skeleton works for vertebrates. The "bones" of the skeleton
24is represented by a hierarchy of \l {Joint} nodes. These do not necessarily need to represent actual
33 skeletonRoot: qmlskeleton
37 skeletonRoot: qmlskeleton
42 skeletonRoot: qmlskeleton
49\section1 Connecting a skeleton to a model
51To apply a skeleton to a model, set the model's \l {Model::skeleton}{skeleton} property:
59In order for the skeleton to have an effect, the model's \l {Model::geometry}{geometry} needs to include
60skinning information. This is done by including \l {QQuick3DGeometry::addAttribute}{vertex attributes} with
61\c JointSemantic and \c WeightSemantic in the vertex buffer.
63The \c JointSemantic attribute determines \e which of the joints in the skeleton can influence a
64given vertex. This uses the index values specified by \l {Joint::index}{Joint.index}. Since this attribute
65contains 4 indexes, a maximum of 4 joints can influence one vertex.
67The \c WeightSemantic attribute describes the \e strength of the influence of those joints. It
68contains four floating point values, each value determining the weight given to the joint with the
69index at the corresponding position in the \c JointSemantic attribute.
71For example, given the skeleton above, if a vertex has these attributes:
74\li \c JointSemantic attribute
75\li \c WeightSemantic attribute
77\li \c {QVector4D(2, 0, 0, 0)}
78\li \c {QVector4D(1.0, 0.0, 0.0, 0.0)}
80that vertex will be 100% influenced by \e joint2, and it will move exactly as much as that
81joint. The last three indexes in the \c JointSemantic attribute are ignored since the
82corresponding weights are \c {0.0}.
84As another example, with these attributes:
87\li \c JointSemantic attribute
88\li \c WeightSemantic attribute
90\li \c {QVector4D(1, 2, 0, 0)}
91\li \c {QVector4D(0.5, 0.25, 0.0, 0.0)}
93the vertex will be moved by 50% of \e joint1's movement plus 25% of \e joint2's movement.
95In addition, since the skeleton is an abstract representation, the model need to specify geometry
96information for the joints. For performance reasons, this is not done by specifying the information
97directly. Instead, \l {Model::inverseBindPoses}{Model.inverseBindPoses} contains the \e inverse of the
98transformation matrix needed to move each joint to its initial position.
100\section1 Animating the skeleton
102Transforming a joint in a skeleton will move all vertexes connected to that joint. Since Joint
103inheriths from \l {Node}, a skeleton can be animated simply by using standard \l[QtQuick QML]
104{Animation}{QML animations}.
109 property: "eulerRotation.z"
117While it is possible to create complex animations by nesting \l
118{SequentialAnimation}, \l {ParallelAnimation} and \l {NumberAnimation}, it is generally more
119convenient to use \l {Qt Quick Timeline Overview}{timeline animations} for animating skinned models.