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