Flutter Engine
The Flutter Engine
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
17namespace impeller {
18namespace scene {
19namespace importer {
20
21//------------------------------------------------------------------------------
22/// VerticesBuilder
23///
24
25std::unique_ptr<VerticesBuilder> VerticesBuilder::MakeUnskinned() {
26 return std::make_unique<UnskinnedVerticesBuilder>();
27}
28
29std::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.
40template <typename SourceType>
41static 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>
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,
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,
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
81std::map<VerticesBuilder::AttributeType, VerticesBuilder::AttributeProperties>
82 VerticesBuilder::kAttributeTypes = {
84 {.offset_bytes = offsetof(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),
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
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
140void 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
GrTriangulator::Vertex Vertex
void WriteFBVertices(fb::MeshPrimitiveT &primitive) const override
void SetAttributeFromBuffer(AttributeType attribute, ComponentType component_type, const void *buffer_start, size_t attribute_stride_bytes, size_t attribute_count) override
void SetAttributeFromBuffer(AttributeType attribute, ComponentType component_type, const void *buffer_start, size_t attribute_stride_bytes, size_t attribute_count) override
void WriteFBVertices(fb::MeshPrimitiveT &primitive) const override
static std::unique_ptr< VerticesBuilder > MakeUnskinned()
static std::unique_ptr< VerticesBuilder > MakeSkinned()
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)
DlColor color
SkBitmap source
Definition: examples.cpp:28
struct MyStruct s
GAsyncResult * result
#define FML_DCHECK(condition)
Definition: logging.h:103
static float max(float r, float g, float b)
Definition: hsl.cpp:49
dst
Definition: cp.py:12
fb::Vec3 ToFBVec3(const Vector3 v)
Definition: conversions.cc:74
fb::Vec4 ToFBVec4(const Vector4 v)
Definition: conversions.cc:78
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,...
fb::Vec2 ToFBVec2(const Vector2 v)
Definition: conversions.cc:70
fb::Color ToFBColor(const Color c)
Definition: conversions.cc:82
static std::map< VerticesBuilder::ComponentType, VerticesBuilder::ComponentProperties > kComponentTypes
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.
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.
float Scalar
Definition: scalar.h:18
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
Definition: SkVx.h:680