Flutter Engine
The Flutter Engine
skin.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <cmath>
8#include <memory>
9#include <vector>
10
11#include "flutter/fml/logging.h"
15
16namespace impeller {
17namespace scene {
18
19std::unique_ptr<Skin> Skin::MakeFromFlatbuffer(
20 const fb::Skin& skin,
21 const std::vector<std::shared_ptr<Node>>& scene_nodes) {
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
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}
56
57Skin::Skin() = default;
58
59Skin::~Skin() = default;
60
61Skin::Skin(Skin&&) = default;
62
63Skin& Skin::operator=(Skin&&) = default;
64
65std::shared_ptr<Texture> Skin::GetJointsTexture(Allocator& allocator) {
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,
72
73 impeller::TextureDescriptor texture_descriptor;
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}
121
122} // namespace scene
123} // namespace impeller
static uint32_t NextPowerOfTwoSize(uint32_t x)
Definition: allocation.cc:41
An object that allocates device memory.
Definition: allocator.h:22
std::shared_ptr< Texture > CreateTexture(const TextureDescriptor &desc)
Definition: allocator.cc:49
Node * GetParent() const
Definition: node.cc:240
bool IsJoint() const
Definition: node.cc:341
Matrix GetLocalTransform() const
Definition: node.cc:282
std::shared_ptr< Texture > GetJointsTexture(Allocator &allocator)
Definition: skin.cc:65
static std::unique_ptr< Skin > MakeFromFlatbuffer(const fb::Skin &skin, const std::vector< std::shared_ptr< Node > > &scene_nodes)
Definition: skin.cc:19
Skin & operator=(Skin &&)
GAsyncResult * result
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_DCHECK(condition)
Definition: logging.h:103
static float max(float r, float g, float b)
Definition: hsl.cpp:49
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
Matrix ToMatrix(const std::vector< double > &m)
Definition: conversions.cc:15
SK_API sk_sp< PrecompileColorFilter > Matrix()
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
Definition: SkVx.h:706
SIN Vec< N, float > ceil(const Vec< N, float > &x)
Definition: SkVx.h:702
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
#define ERROR(message)
Definition: elf_loader.cc:260
#define VALIDATION_LOG
Definition: validation.h:73