| Flutter Impeller |

vertices_builder.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
5 #include "impeller/scene/importer/vertices_builder.h"
6
7 #include <cstring>
8 #include <limits>
9 #include <memory>
10 #include <type_traits>
11
12 #include "flutter/fml/logging.h"
13 #include "impeller/scene/importer/conversions.h"
14 #include "impeller/scene/importer/scene_flatbuffers.h"
15
16 namespace impeller {
17 namespace scene {
18 namespace importer {
19
20 //------------------------------------------------------------------------------
21 /// VerticesBuilder
22 ///
23
24 std::unique_ptr<VerticesBuilder> VerticesBuilder::MakeUnskinned() {
25 return std::make_unique<UnskinnedVerticesBuilder>();
26 }
27
28 std::unique_ptr<VerticesBuilder> VerticesBuilder::MakeSkinned() {
29 return std::make_unique<SkinnedVerticesBuilder>();
30 }
31
32 VerticesBuilder::VerticesBuilder() = default;
33
34 VerticesBuilder::~VerticesBuilder() = default;
35
36 /// @brief Reads a numeric component from `source` and returns a 32bit float.
37 /// If `normalized` is `true`, signed SourceTypes convert to a range of
38 /// -1 to 1, and unsigned SourceTypes convert to a range of 0 to 1.
39 template <typename SourceType>
40 static Scalar ToScalar(const void* source, size_t index, bool normalized) {
41 const SourceType* s = reinterpret_cast<const SourceType*>(source) + index;
42 Scalar result = static_cast<Scalar>(*s);
43 if (normalized) {
44 constexpr SourceType divisor = std::is_integral_v<SourceType>
45 ? std::numeric_limits<SourceType>::max()
46 : 1;
47 result = static_cast<Scalar>(*s) / static_cast<Scalar>(divisor);
48 }
49 return result;
50 }
51
52 /// @brief A ComponentWriter which simply converts all of an attribute's
53 /// components to normalized scalar form.
54 static void PassthroughAttributeWriter(
55 Scalar* destination,
56 const void* source,
57 const VerticesBuilder::ComponentProperties& component,
58 const VerticesBuilder::AttributeProperties& attribute) {
59 FML_DCHECK(attribute.size_bytes ==
60 attribute.component_count * sizeof(Scalar));
61 for (size_t component_i = 0; component_i < attribute.component_count;
62 component_i++) {
63 *(destination + component_i) =
64 component.convert_proc(source, component_i, true);
65 }
66 }
67
68 /// @brief A ComponentWriter which converts four vertex indices to scalars.
69 static void JointsAttributeWriter(
70 Scalar* destination,
71 const void* source,
72 const VerticesBuilder::ComponentProperties& component,
73 const VerticesBuilder::AttributeProperties& attribute) {
74 FML_DCHECK(attribute.component_count == 4);
75 for (int i = 0; i < 4; i++) {
76 *(destination + i) = component.convert_proc(source, i, false);
77 }
78 }
79
80 std::map<VerticesBuilder::AttributeType, VerticesBuilder::AttributeProperties>
81 VerticesBuilder::kAttributeTypes = {
82 {VerticesBuilder::AttributeType::kPosition,
83 {.offset_bytes = offsetof(UnskinnedVerticesBuilder::Vertex, position),
84 .size_bytes = sizeof(UnskinnedVerticesBuilder::Vertex::position),
85 .component_count = 3,
86 .write_proc = PassthroughAttributeWriter}},
87 {VerticesBuilder::AttributeType::kNormal,
88 {.offset_bytes = offsetof(UnskinnedVerticesBuilder::Vertex, normal),
89 .size_bytes = sizeof(UnskinnedVerticesBuilder::Vertex::normal),
90 .component_count = 3,
91 .write_proc = PassthroughAttributeWriter}},
92 {VerticesBuilder::AttributeType::kTangent,
93 {.offset_bytes = offsetof(UnskinnedVerticesBuilder::Vertex, tangent),
94 .size_bytes = sizeof(UnskinnedVerticesBuilder::Vertex::tangent),
95 .component_count = 4,
96 .write_proc = PassthroughAttributeWriter}},
97 {VerticesBuilder::AttributeType::kTextureCoords,
98 {.offset_bytes =
99 offsetof(UnskinnedVerticesBuilder::Vertex, texture_coords),
100 .size_bytes =
101 sizeof(UnskinnedVerticesBuilder::Vertex::texture_coords),
102 .component_count = 2,
103 .write_proc = PassthroughAttributeWriter}},
104 {VerticesBuilder::AttributeType::kColor,
105 {.offset_bytes = offsetof(UnskinnedVerticesBuilder::Vertex, color),
106 .size_bytes = sizeof(UnskinnedVerticesBuilder::Vertex::color),
107 .component_count = 4,
108 .write_proc = PassthroughAttributeWriter}},
109 {VerticesBuilder::AttributeType::kJoints,
110 {.offset_bytes = offsetof(SkinnedVerticesBuilder::Vertex, joints),
111 .size_bytes = sizeof(SkinnedVerticesBuilder::Vertex::joints),
112 .component_count = 4,
113 .write_proc = JointsAttributeWriter}},
114 {VerticesBuilder::AttributeType::kWeights,
115 {.offset_bytes = offsetof(SkinnedVerticesBuilder::Vertex, weights),
116 .size_bytes = sizeof(SkinnedVerticesBuilder::Vertex::weights),
117 .component_count = 4,
118 .write_proc = JointsAttributeWriter}}};
119
120 static std::map<VerticesBuilder::ComponentType,
121 VerticesBuilder::ComponentProperties>
122 kComponentTypes = {
123 {VerticesBuilder::ComponentType::kSignedByte,
124 {.size_bytes = sizeof(int8_t), .convert_proc = ToScalar<int8_t>}},
125 {VerticesBuilder::ComponentType::kUnsignedByte,
126 {.size_bytes = sizeof(int8_t), .convert_proc = ToScalar<uint8_t>}},
127 {VerticesBuilder::ComponentType::kSignedShort,
128 {.size_bytes = sizeof(int16_t), .convert_proc = ToScalar<int16_t>}},
129 {VerticesBuilder::ComponentType::kUnsignedShort,
130 {.size_bytes = sizeof(int16_t), .convert_proc = ToScalar<uint16_t>}},
131 {VerticesBuilder::ComponentType::kSignedInt,
132 {.size_bytes = sizeof(int32_t), .convert_proc = ToScalar<int32_t>}},
133 {VerticesBuilder::ComponentType::kUnsignedInt,
134 {.size_bytes = sizeof(int32_t), .convert_proc = ToScalar<uint32_t>}},
135 {VerticesBuilder::ComponentType::kFloat,
136 {.size_bytes = sizeof(float), .convert_proc = ToScalar<float>}},
137 };
138
139 void VerticesBuilder::WriteAttribute(void* destination,
140 size_t destination_stride_bytes,
141 AttributeType attribute,
142 ComponentType component_type,
143 const void* source,
144 size_t attribute_stride_bytes,
145 size_t attribute_count) {
146 const ComponentProperties& component_props = kComponentTypes[component_type];
147 const AttributeProperties& attribute_props = kAttributeTypes[attribute];
148 for (size_t i = 0; i < attribute_count; i++) {
149 const uint8_t* src =
150 reinterpret_cast<const uint8_t*>(source) + attribute_stride_bytes * i;
151 uint8_t* dst = reinterpret_cast<uint8_t*>(destination) +
152 i * destination_stride_bytes + attribute_props.offset_bytes;
153
154 attribute_props.write_proc(reinterpret_cast<Scalar*>(dst), src,
155 component_props, attribute_props);
156 }
157 }
158
159 //------------------------------------------------------------------------------
160 /// UnskinnedVerticesBuilder
161 ///
162
163 UnskinnedVerticesBuilder::UnskinnedVerticesBuilder() = default;
164
165 UnskinnedVerticesBuilder::~UnskinnedVerticesBuilder() = default;
166
167 void UnskinnedVerticesBuilder::WriteFBVertices(
168 fb::MeshPrimitiveT& primitive) const {
169 auto vertex_buffer = fb::UnskinnedVertexBufferT();
170 vertex_buffer.vertices.resize(0);
171 for (auto& v : vertices_) {
172 vertex_buffer.vertices.push_back(fb::Vertex(
173 ToFBVec3(v.position), ToFBVec3(v.normal), ToFBVec4(v.tangent),
174 ToFBVec2(v.texture_coords), ToFBColor(v.color)));
175 }
176 primitive.vertices.Set(std::move(vertex_buffer));
177 }
178
179 void UnskinnedVerticesBuilder::SetAttributeFromBuffer(
180 AttributeType attribute,
181 ComponentType component_type,
182 const void* buffer_start,
183 size_t attribute_stride_bytes,
184 size_t attribute_count) {
185 if (attribute_count > vertices_.size()) {
186 vertices_.resize(attribute_count, Vertex());
187 }
188 WriteAttribute(vertices_.data(), // destination
189 sizeof(Vertex), // destination_stride_bytes
190 attribute, // attribute
191 component_type, // component_type
192 buffer_start, // source
193 attribute_stride_bytes, // attribute_stride_bytes
194 attribute_count); // attribute_count
195 }
196
197 //------------------------------------------------------------------------------
198 /// SkinnedVerticesBuilder
199 ///
200
201 SkinnedVerticesBuilder::SkinnedVerticesBuilder() = default;
202
203 SkinnedVerticesBuilder::~SkinnedVerticesBuilder() = default;
204
205 void SkinnedVerticesBuilder::WriteFBVertices(
206 fb::MeshPrimitiveT& primitive) const {
207 auto vertex_buffer = fb::SkinnedVertexBufferT();
208 vertex_buffer.vertices.resize(0);
209 for (auto& v : vertices_) {
210 auto unskinned_attributes = fb::Vertex(
211 ToFBVec3(v.vertex.position), ToFBVec3(v.vertex.normal),
212 ToFBVec4(v.vertex.tangent), ToFBVec2(v.vertex.texture_coords),
213 ToFBColor(v.vertex.color));
214 vertex_buffer.vertices.push_back(fb::SkinnedVertex(
215 unskinned_attributes, ToFBVec4(v.joints), ToFBVec4(v.weights)));
216 }
217 primitive.vertices.Set(std::move(vertex_buffer));
218 }
219
220 void SkinnedVerticesBuilder::SetAttributeFromBuffer(
221 AttributeType attribute,
222 ComponentType component_type,
223 const void* buffer_start,
224 size_t attribute_stride_bytes,
225 size_t attribute_count) {
226 if (attribute_count > vertices_.size()) {
227 vertices_.resize(attribute_count, Vertex());
228 }
229 WriteAttribute(vertices_.data(), // destination
230 sizeof(Vertex), // destination_stride_bytes
231 attribute, // attribute
232 component_type, // component_type
233 buffer_start, // source
234 attribute_stride_bytes, // attribute_stride_bytes
235 attribute_count); // attribute_count
236 }
237
238 } // namespace importer
239 } // namespace scene
240 } // namespace impeller
impeller::scene::importer::ToScalar
static Scalar ToScalar(const void *source, size_t index, bool normalized)
Reads a numeric component from source and returns a 32bit float. If normalized is true,...
Definition: vertices_builder.cc:40
impeller::scene::importer::VerticesBuilder::VerticesBuilder
VerticesBuilder()
impeller::scene::importer::VerticesBuilder::AttributeType::kNormal
@ kNormal
impeller::scene::importer::VerticesBuilder::ComponentProperties::convert_proc
ComponentConverter convert_proc
Definition: vertices_builder.h:52
impeller::scene::importer::UnskinnedVerticesBuilder::~UnskinnedVerticesBuilder
virtual ~UnskinnedVerticesBuilder() override
impeller::scene::importer::VerticesBuilder::AttributeType::kJoints
@ kJoints
impeller::Scalar
float Scalar
Definition: scalar.h:15
impeller::scene::importer::VerticesBuilder::AttributeProperties
Definition: vertices_builder.h:61
impeller::scene::importer::VerticesBuilder::AttributeType
AttributeType
Definition: vertices_builder.h:38
impeller::scene::importer::VerticesBuilder::ComponentType::kUnsignedByte
@ kUnsignedByte
impeller::scene::importer::VerticesBuilder::AttributeProperties::component_count
size_t component_count
Definition: vertices_builder.h:64
impeller::scene::importer::VerticesBuilder::AttributeType::kWeights
@ kWeights
impeller::scene::importer::SkinnedVerticesBuilder::SetAttributeFromBuffer
void SetAttributeFromBuffer(AttributeType attribute, ComponentType component_type, const void *buffer_start, size_t attribute_stride_bytes, size_t attribute_count) override
Definition: vertices_builder.cc:220
impeller::scene::importer::SourceType
SourceType
Definition: types.h:11
impeller::scene::importer::VerticesBuilder::ComponentType::kUnsignedShort
@ kUnsignedShort
impeller::scene::importer::UnskinnedVerticesBuilder::Vertex::tangent
Vector4 tangent
Definition: vertices_builder.h:106
impeller::scene::importer::SkinnedVerticesBuilder::SkinnedVerticesBuilder
SkinnedVerticesBuilder()
impeller::scene::importer::SkinnedVerticesBuilder::Vertex::joints
Vector4 joints
Definition: vertices_builder.h:139
conversions.h
impeller::scene::importer::VerticesBuilder::ComponentType::kSignedInt
@ kSignedInt
impeller::scene::importer::SkinnedVerticesBuilder::Vertex
Definition: vertices_builder.h:137
impeller::scene::importer::ToFBVec2
fb::Vec2 ToFBVec2(const Vector2 v)
Definition: conversions.cc:70
impeller::scene::importer::kComponentTypes
static std::map< VerticesBuilder::ComponentType, VerticesBuilder::ComponentProperties > kComponentTypes
Definition: vertices_builder.cc:122
impeller::scene::importer::VerticesBuilder::AttributeType::kPosition
@ kPosition
impeller::scene::importer::JointsAttributeWriter
static void JointsAttributeWriter(Scalar *destination, const void *source, const VerticesBuilder::ComponentProperties &component, const VerticesBuilder::AttributeProperties &attribute)
A ComponentWriter which converts four vertex indices to scalars.
Definition: vertices_builder.cc:69
impeller::scene::importer::UnskinnedVerticesBuilder::WriteFBVertices
void WriteFBVertices(fb::MeshPrimitiveT &primitive) const override
Definition: vertices_builder.cc:167
impeller::scene::importer::VerticesBuilder::~VerticesBuilder
virtual ~VerticesBuilder()
impeller::scene::importer::VerticesBuilder::AttributeType::kTangent
@ kTangent
impeller::scene::importer::UnskinnedVerticesBuilder::Vertex::color
Color color
Definition: vertices_builder.h:108
impeller::scene::importer::VerticesBuilder::MakeSkinned
static std::unique_ptr< VerticesBuilder > MakeSkinned()
Definition: vertices_builder.cc:28
impeller::scene::importer::SkinnedVerticesBuilder::Vertex::weights
Vector4 weights
Definition: vertices_builder.h:140
impeller::scene::importer::VerticesBuilder::ComponentType::kUnsignedInt
@ kUnsignedInt
impeller::scene::importer::UnskinnedVerticesBuilder::Vertex::texture_coords
Vector2 texture_coords
Definition: vertices_builder.h:107
impeller::scene::importer::UnskinnedVerticesBuilder::Vertex::position
Vector3 position
Definition: vertices_builder.h:104
impeller::scene::importer::ToFBVec3
fb::Vec3 ToFBVec3(const Vector3 v)
Definition: conversions.cc:74
impeller::scene::importer::UnskinnedVerticesBuilder::Vertex
Definition: vertices_builder.h:103
impeller::scene::importer::VerticesBuilder::AttributeProperties::size_bytes
size_t size_bytes
Definition: vertices_builder.h:63
impeller::scene::importer::PassthroughAttributeWriter
static void PassthroughAttributeWriter(Scalar *destination, const void *source, const VerticesBuilder::ComponentProperties &component, const VerticesBuilder::AttributeProperties &attribute)
A ComponentWriter which simply converts all of an attribute's components to normalized scalar form.
Definition: vertices_builder.cc:54
impeller::scene::importer::UnskinnedVerticesBuilder::UnskinnedVerticesBuilder
UnskinnedVerticesBuilder()
impeller::scene::importer::VerticesBuilder::ComponentProperties
Definition: vertices_builder.h:50
impeller::scene::importer::ToFBColor
fb::Color ToFBColor(const Color c)
Definition: conversions.cc:82
impeller::scene::importer::UnskinnedVerticesBuilder::SetAttributeFromBuffer
void SetAttributeFromBuffer(AttributeType attribute, ComponentType component_type, const void *buffer_start, size_t attribute_stride_bytes, size_t attribute_count) override
Definition: vertices_builder.cc:179
impeller::scene::importer::VerticesBuilder::ComponentType::kSignedShort
@ kSignedShort
impeller::scene::importer::SkinnedVerticesBuilder::WriteFBVertices
void WriteFBVertices(fb::MeshPrimitiveT &primitive) const override
Definition: vertices_builder.cc:205
impeller::scene::importer::VerticesBuilder::WriteAttribute
static void WriteAttribute(void *destination, size_t destination_stride_bytes, AttributeType attribute, ComponentType component_type, const void *source, size_t attribute_stride_bytes, size_t attribute_count)
Definition: vertices_builder.cc:139
impeller::scene::importer::VerticesBuilder::MakeUnskinned
static std::unique_ptr< VerticesBuilder > MakeUnskinned()
Definition: vertices_builder.cc:24
impeller::scene::importer::VerticesBuilder::AttributeProperties::offset_bytes
size_t offset_bytes
Definition: vertices_builder.h:62
impeller::scene::importer::SkinnedVerticesBuilder::~SkinnedVerticesBuilder
virtual ~SkinnedVerticesBuilder() override
impeller::scene::importer::VerticesBuilder::ComponentType::kSignedByte
@ kSignedByte
vertices_builder.h
impeller::scene::importer::VerticesBuilder::AttributeType::kColor
@ kColor
impeller::scene::importer::VerticesBuilder::ComponentType::kFloat
@ kFloat
impeller::scene::importer::UnskinnedVerticesBuilder::Vertex::normal
Vector3 normal
Definition: vertices_builder.h:105
impeller::scene::importer::VerticesBuilder::AttributeProperties::write_proc
AttributeWriter write_proc
Definition: vertices_builder.h:65
impeller::scene::importer::VerticesBuilder::ComponentType
ComponentType
Definition: vertices_builder.h:28
impeller
Definition: aiks_context.cc:10
impeller::scene::importer::VerticesBuilder::AttributeType::kTextureCoords
@ kTextureCoords
impeller::scene::importer::ToFBVec4
fb::Vec4 ToFBVec4(const Vector4 v)
Definition: conversions.cc:78