Qt Quick 3D supports vertex skinning for skeletal animation of mesh geometries.
见 Simple Skinning Example for a practical demonstration of skeletal animation.
In most cases, application developers will not be using the skinning API manually. The normal workflow is to use an external content creation tool to define the skeleton and the skin (this is sometimes also referred to as rigging ), and then use the 香脂资产导入工具 to convert the asset to Qt Quick 3D's native format.
The basis of skeletal animation is the Skeleton . This is an abstract representation of how the model can move, inspired by how a physical skeleton works for vertebrates. The "bones" of the skeleton is represented by a hierarchy of Joint nodes. These do not necessarily need to represent actual bones, of course.
Skeleton { id: qmlskeleton Joint { id: joint0 index: 0 skeletonRoot: qmlskeleton Joint { id: joint1 index: 1 skeletonRoot: qmlskeleton } Joint { id: joint2 index: 2 skeletonRoot: qmlskeleton } } }
To apply a skeleton to a model, set the model's skeleton 特性:
Model {
    skeleton: qmlskeleton
    ...
					
					
						In order for the skeleton to have an effect, the model's
						
							geometry
						
						needs to include skinning information. This is done by including
						
							vertex attributes
						
						with
						
JointSemantic
						
						and
						
WeightSemantic
						
						in the vertex buffer.
					
						The
						
JointSemantic
						
						attribute determines
						
							which
						
						of the joints in the skeleton can influence a given vertex. This uses the index values specified by
						
							Joint.index
						
						. Since this attribute contains 4 indexes, a maximum of 4 joints can influence one vertex.
					
						The
						
WeightSemantic
						
						attribute describes the
						
							strength
						
						of the influence of those joints. It contains four floating point values, each value determining the weight given to the joint with the index at the corresponding position in the
						
JointSemantic
						
						属性。
					
For example, given the skeleton above, if a vertex has these attributes:
| 
JointSemantic
									属性 | 
WeightSemantic
									属性 | 
|---|---|
| 
QVector4D(2, 0, 0, 0)
								 | 
QVector4D(1.0, 0.0, 0.0, 0.0)
								 | 
						that vertex will be 100% influenced by
						
							joint2
						
						, and it will move exactly as much as that joint. The last three indexes in the
						
JointSemantic
						
						attribute are ignored since the corresponding weights are
						
0.0
						
						.
					
As another example, with these attributes:
| 
JointSemantic
									属性 | 
WeightSemantic
									属性 | 
|---|---|
| 
QVector4D(1, 2, 0, 0)
								 | 
QVector4D(0.5, 0.25, 0.0, 0.0)
								 | 
the vertex will be moved by 50% of joint1 's movement plus 25% of joint2 's movement.
In addition, since the skeleton is an abstract representation, the model need to specify geometry information for the joints. For performance reasons, this is not done by specifying the information directly. Instead, Model.inverseBindPoses 包含 inverse of the transformation matrix needed to move each joint to its initial position.
Transforming a joint in a skeleton will move all vertexes connected to that joint. Since Joint inheriths from Node , a skeleton can be animated simply by using standard QML animations .
NumberAnimation { target: joint1 property: "eulerRotation.z" duration: 5000 from: -90 to: 90 running: true }
While it is possible to create complex animations by nesting SequentialAnimation , ParallelAnimation and NumberAnimation , it is generally more convenient to use timeline animations for animating skinned models.