| Flutter Impeller |

Public Member Functions | Static Public Member Functions | List of all members
impeller::scene::Skin Class Referencefinal

`#include <skin.h>`

## Public Member Functions
| ~Skin ()
| Skin (Skin &&)
Skin & | operator= (Skin &&)
std::shared_ptr< Texture > | GetJointsTexture (Allocator &allocator)

## Static Public Member Functions
static std::unique_ptr< Skin > | MakeFromFlatbuffer (const fb::Skin &skin, const std::vector< std::shared_ptr< Node >> &scene_nodes)

## Detailed Description

Definition at line 18 of file skin.h.

## Constructor & Destructor Documentation

## ◆ ~Skin()

impeller::scene::Skin::~Skin | ( |  | ) |
| default

## ◆ Skin()

impeller::scene::Skin::Skin | ( | Skin && |  | ) |
| default

## Member Function Documentation

## ◆ GetJointsTexture()

std::shared_ptr< Texture > impeller::scene::Skin::GetJointsTexture | ( | Allocator & | allocator | ) |

Definition at line 65 of file skin.cc.

65 {
66 // Each joint has a matrix. 1 matrix = 16 floats. 1 pixel = 4 floats.
67 // Therefore, each joint needs 4 pixels.
68 auto required_pixels = joints_.size() * 4;
69 auto dimension_size = std::max(
70 2u,
71 Allocation::NextPowerOfTwoSize(std::ceil(std::sqrt(required_pixels))));
72
73 impeller::TextureDescriptor texture_descriptor;
74 texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
75 texture_descriptor.format = PixelFormat::kR32G32B32A32Float;
76 texture_descriptor.size = {dimension_size, dimension_size};
77 texture_descriptor.mip_count = 1u;
78
79 auto result = allocator.CreateTexture(texture_descriptor);
80 result->SetLabel("Joints Texture");
81 if (!result) {
82 FML_LOG(ERROR) << "Could not create joint texture.";
83 return nullptr;
84 }
85
86 std::vector<Matrix> joints;
87 joints.resize(result->GetSize().Area() / 4, Matrix());
88 FML_DCHECK(joints.size() >= joints_.size());
89 for (size_t joint_i = 0; joint_i < joints_.size(); joint_i++) {
90 const Node* joint = joints_[joint_i].get();
91 if (!joint) {
92 // When a joint is missing, just let it remain as an identity matrix.
93 continue;
94 }
95
96 // Compute a model space matrix for the joint by walking up the bones to the
97 // skeleton root.
98 while (joint && joint->IsJoint()) {
99 joints[joint_i] = joint->GetLocalTransform() * joints[joint_i];
100 joint = joint->GetParent();
101 }
102
103 // Get the joint transform relative to the default pose of the bone by
104 // incorporating the joint's inverse bind matrix. The inverse bind matrix
105 // transforms from model space to the default pose space of the joint. The
106 // result is a model space matrix that only captures the difference between
107 // the joint's default pose and the joint's current pose in the scene. This
108 // is necessary because the skinned model's vertex positions (which _define_
109 // the default pose) are all in model space.
110 joints[joint_i] = joints[joint_i] * inverse_bind_matrices_[joint_i];
111 }
112
113 if (!result->SetContents(reinterpret_cast<uint8_t*>(joints.data()),
114 joints.size() * sizeof(Matrix))) {
115 FML_LOG(ERROR) << "Could not set contents of joint texture.";
116 return nullptr;
117 }
118
119 return result;
120 }

References impeller::Allocator::CreateTexture(), impeller::TextureDescriptor::format, impeller::scene::Node::GetLocalTransform(), impeller::scene::Node::GetParent(), impeller::scene::Node::IsJoint(), impeller::kHostVisible, impeller::kR32G32B32A32Float, impeller::TextureDescriptor::mip_count, impeller::Allocation::NextPowerOfTwoSize(), impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

## ◆ MakeFromFlatbuffer()

std::unique_ptr< Skin > impeller::scene::Skin::MakeFromFlatbuffer | ( | const fb::Skin & | skin,
|  | const std::vector< std::shared_ptr< Node >> & | scene_nodes
| ) |  |
| static

Definition at line 19 of file skin.cc.

21 {
22 if (!skin.joints() || !skin.inverse_bind_matrices() ||
23 skin.joints()->size() != skin.inverse_bind_matrices()->size()) {
24 VALIDATION_LOG << "Skin data is missing joints or bind matrices.";
25 return nullptr;
26 }
27
28 Skin result;
29
30 result.joints_.reserve(skin.joints()->size());
31 for (auto joint : *skin.joints()) {
32 if (joint < 0 || static_cast<size_t>(joint) > scene_nodes.size()) {
33 VALIDATION_LOG << "Skin joint index out of range.";
34 result.joints_.push_back(nullptr);
35 continue;
36 }
37 if (scene_nodes[joint]) {
38 scene_nodes[joint]->SetIsJoint(true);
39 }
40 result.joints_.push_back(scene_nodes[joint]);
41 }
42
43 result.inverse_bind_matrices_.reserve(skin.inverse_bind_matrices()->size());
44 for (size_t matrix_i = 0; matrix_i < skin.inverse_bind_matrices()->size();
45 matrix_i++) {
46 const auto* ip_matrix = skin.inverse_bind_matrices()->Get(matrix_i);
47 Matrix matrix = ip_matrix ? importer::ToMatrix(*ip_matrix) : Matrix();
48
49 result.inverse_bind_matrices_.push_back(matrix);
50 // Overwrite the joint transforms with the inverse bind pose.
51 result.joints_[matrix_i]->SetGlobalTransform(matrix.Invert());
52 }
53
54 return std::make_unique<Skin>(std::move(result));
55 }

References impeller::Matrix::Invert(), impeller::scene::importer::ToMatrix(), and VALIDATION_LOG.

## ◆ operator=()

Skin & impeller::scene::Skin::operator= | ( | Skin && |  | ) |
| default

The documentation for this class was generated from the following files:

- impeller/scene/skin.h
- impeller/scene/skin.cc

impeller::Allocation::NextPowerOfTwoSize
static uint32_t NextPowerOfTwoSize(uint32_t x)
Definition: allocation.cc:41
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:41
impeller::TextureDescriptor::mip_count
size_t mip_count
Definition: texture_descriptor.h:43
impeller::StorageMode::kHostVisible
@ kHostVisible
impeller::scene::Skin::Skin
Skin(Skin &&)
impeller::PixelFormat::kR32G32B32A32Float
@ kR32G32B32A32Float
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:42
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:39
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:38
impeller::scene::importer::ToMatrix
Matrix ToMatrix(const std::vector< double > &m)
Definition: conversions.cc:15