Skip to content

Commit 7230705

Browse files
bderoloic-sharma
authored andcommitted
[Impeller Scene] Convert vertex positions to match Impeller's clip space orientation (flutter#38174)
1 parent 09c4fbf commit 7230705

File tree

4 files changed

+133
-87
lines changed

4 files changed

+133
-87
lines changed

impeller/scene/importer/importer_gltf.cc

+6-7
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,12 @@ namespace impeller {
2222
namespace scene {
2323
namespace importer {
2424

25-
static const std::map<std::string, VerticesBuilder::Attribute> kAttributes = {
26-
{"POSITION", VerticesBuilder::Attribute::kPosition},
27-
{"NORMAL", VerticesBuilder::Attribute::kNormal},
28-
{"TANGENT", VerticesBuilder::Attribute::kTangent},
29-
{"TEXCOORD_0", VerticesBuilder::Attribute::kTextureCoords},
30-
{"COLOR_0", VerticesBuilder::Attribute::kColor},
31-
};
25+
static const std::map<std::string, VerticesBuilder::AttributeType> kAttributes =
26+
{{"POSITION", VerticesBuilder::AttributeType::kPosition},
27+
{"NORMAL", VerticesBuilder::AttributeType::kNormal},
28+
{"TANGENT", VerticesBuilder::AttributeType::kTangent},
29+
{"TEXCOORD_0", VerticesBuilder::AttributeType::kTextureCoords},
30+
{"COLOR_0", VerticesBuilder::AttributeType::kColor}};
3231

3332
static bool WithinRange(int index, size_t size) {
3433
return index >= 0 && static_cast<size_t>(index) < size;

impeller/scene/importer/importer_unittests.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ TEST(ImporterTest, CanParseGLTF) {
3838
auto& vertex = mesh.vertices[0];
3939

4040
Vector3 position = ToVector3(vertex.position());
41-
ASSERT_VECTOR3_NEAR(position, Vector3(-0.0100185, -0.522907, 0.133178));
41+
ASSERT_VECTOR3_NEAR(position, Vector3(-0.0100185, -0.522907, -0.133178));
4242

4343
Vector3 normal = ToVector3(vertex.normal());
4444
ASSERT_VECTOR3_NEAR(normal, Vector3(0.556997, -0.810833, 0.179733));

impeller/scene/importer/vertices_builder.cc

+93-60
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <limits>
99
#include <type_traits>
1010

11+
#include "flutter/fml/logging.h"
1112
#include "impeller/scene/importer/conversions.h"
1213
#include "impeller/scene/importer/scene_flatbuffers.h"
1314

@@ -17,29 +18,6 @@ namespace importer {
1718

1819
VerticesBuilder::VerticesBuilder() = default;
1920

20-
std::map<VerticesBuilder::Attribute, VerticesBuilder::AttributeProperties>
21-
VerticesBuilder::kAttributes = {
22-
{VerticesBuilder::Attribute::kPosition,
23-
{.offset_bytes = offsetof(Vertex, position),
24-
.size_bytes = sizeof(Vertex::position),
25-
.component_count = 3}},
26-
{VerticesBuilder::Attribute::kNormal,
27-
{.offset_bytes = offsetof(Vertex, normal),
28-
.size_bytes = sizeof(Vertex::normal),
29-
.component_count = 3}},
30-
{VerticesBuilder::Attribute::kTangent,
31-
{.offset_bytes = offsetof(Vertex, tangent),
32-
.size_bytes = sizeof(Vertex::tangent),
33-
.component_count = 4}},
34-
{VerticesBuilder::Attribute::kTextureCoords,
35-
{.offset_bytes = offsetof(Vertex, texture_coords),
36-
.size_bytes = sizeof(Vertex::texture_coords),
37-
.component_count = 2}},
38-
{VerticesBuilder::Attribute::kColor,
39-
{.offset_bytes = offsetof(Vertex, color),
40-
.size_bytes = sizeof(Vertex::color),
41-
.component_count = 4}}};
42-
4321
void VerticesBuilder::WriteFBVertices(std::vector<fb::Vertex>& vertices) const {
4422
vertices.resize(0);
4523
for (auto& v : vertices_) {
@@ -49,64 +27,119 @@ void VerticesBuilder::WriteFBVertices(std::vector<fb::Vertex>& vertices) const {
4927
}
5028
}
5129

52-
/// @brief Reads a contiguous sequence of numeric components from `source` and
53-
/// writes them to `destination` as 32bit floats. Signed SourceTypes
54-
/// convert to a range of -1 to 1, and unsigned SourceTypes convert to a
55-
/// range of 0 to 1.
30+
/// @brief Reads a numeric component from `source` and returns a 32bit float.
31+
/// Signed SourceTypes convert to a range of -1 to 1, and unsigned
32+
/// SourceTypes convert to a range of 0 to 1.
5633
template <typename SourceType>
57-
static void WriteComponentsAsScalars(void* destination,
58-
const void* source,
59-
size_t component_count) {
34+
static Scalar ToNormalizedScalar(const void* source, size_t index) {
6035
constexpr SourceType divisor = std::is_integral_v<SourceType>
6136
? std::numeric_limits<SourceType>::max()
6237
: 1;
63-
for (size_t i = 0; i < component_count; i++) {
64-
const SourceType* s = reinterpret_cast<const SourceType*>(source) + i;
65-
Scalar v = static_cast<Scalar>(*s) / static_cast<Scalar>(divisor);
66-
Scalar* dest = reinterpret_cast<Scalar*>(destination) + i;
67-
*dest = v;
38+
const SourceType* s = reinterpret_cast<const SourceType*>(source) + index;
39+
return static_cast<Scalar>(*s) / static_cast<Scalar>(divisor);
40+
}
41+
42+
/// @brief A ComponentWriter which simply converts all of an attribute's
43+
/// components to normalized scalar form.
44+
static void PassthroughAttributeWriter(
45+
Scalar* destination,
46+
const void* source,
47+
const VerticesBuilder::ComponentProperties& component,
48+
const VerticesBuilder::AttributeProperties& attribute) {
49+
FML_DCHECK(attribute.size_bytes ==
50+
attribute.component_count * sizeof(Scalar));
51+
for (size_t component_i = 0; component_i < attribute.component_count;
52+
component_i++) {
53+
*(destination + component_i) = component.convert_proc(source, component_i);
6854
}
6955
}
7056

71-
static std::map<
72-
VerticesBuilder::ComponentType,
73-
std::function<
74-
void(void* destination, const void* source, size_t component_count)>>
75-
kAttributeWriters = {
57+
/// @brief A ComponentWriter which converts a Vector3 position from
58+
/// right-handed GLTF space to left-handed Impeller space.
59+
static void PositionAttributeWriter(
60+
Scalar* destination,
61+
const void* source,
62+
const VerticesBuilder::ComponentProperties& component,
63+
const VerticesBuilder::AttributeProperties& attribute) {
64+
FML_DCHECK(attribute.component_count == 3);
65+
*(destination + 0) = component.convert_proc(source, 0);
66+
*(destination + 1) = component.convert_proc(source, 1);
67+
*(destination + 2) = -component.convert_proc(source, 2);
68+
}
69+
70+
std::map<VerticesBuilder::AttributeType, VerticesBuilder::AttributeProperties>
71+
VerticesBuilder::kAttributeTypes = {
72+
{VerticesBuilder::AttributeType::kPosition,
73+
{.offset_bytes = offsetof(Vertex, position),
74+
.size_bytes = sizeof(Vertex::position),
75+
.component_count = 3,
76+
.write_proc = PositionAttributeWriter}},
77+
{VerticesBuilder::AttributeType::kNormal,
78+
{.offset_bytes = offsetof(Vertex, normal),
79+
.size_bytes = sizeof(Vertex::normal),
80+
.component_count = 3,
81+
.write_proc = PassthroughAttributeWriter}},
82+
{VerticesBuilder::AttributeType::kTangent,
83+
{.offset_bytes = offsetof(Vertex, tangent),
84+
.size_bytes = sizeof(Vertex::tangent),
85+
.component_count = 4,
86+
.write_proc = PassthroughAttributeWriter}},
87+
{VerticesBuilder::AttributeType::kTextureCoords,
88+
{.offset_bytes = offsetof(Vertex, texture_coords),
89+
.size_bytes = sizeof(Vertex::texture_coords),
90+
.component_count = 2,
91+
.write_proc = PassthroughAttributeWriter}},
92+
{VerticesBuilder::AttributeType::kColor,
93+
{.offset_bytes = offsetof(Vertex, color),
94+
.size_bytes = sizeof(Vertex::color),
95+
.component_count = 4,
96+
.write_proc = PassthroughAttributeWriter}}};
97+
98+
static std::map<VerticesBuilder::ComponentType,
99+
VerticesBuilder::ComponentProperties>
100+
kComponentTypes = {
76101
{VerticesBuilder::ComponentType::kSignedByte,
77-
WriteComponentsAsScalars<int8_t>},
102+
{.size_bytes = sizeof(int8_t),
103+
.convert_proc = ToNormalizedScalar<int8_t>}},
78104
{VerticesBuilder::ComponentType::kUnsignedByte,
79-
WriteComponentsAsScalars<uint8_t>},
105+
{.size_bytes = sizeof(int8_t),
106+
.convert_proc = ToNormalizedScalar<uint8_t>}},
80107
{VerticesBuilder::ComponentType::kSignedShort,
81-
WriteComponentsAsScalars<int16_t>},
108+
{.size_bytes = sizeof(int16_t),
109+
.convert_proc = ToNormalizedScalar<int16_t>}},
82110
{VerticesBuilder::ComponentType::kUnsignedShort,
83-
WriteComponentsAsScalars<uint16_t>},
111+
{.size_bytes = sizeof(int16_t),
112+
.convert_proc = ToNormalizedScalar<uint16_t>}},
84113
{VerticesBuilder::ComponentType::kSignedInt,
85-
WriteComponentsAsScalars<int32_t>},
114+
{.size_bytes = sizeof(int32_t),
115+
.convert_proc = ToNormalizedScalar<int32_t>}},
86116
{VerticesBuilder::ComponentType::kUnsignedInt,
87-
WriteComponentsAsScalars<uint32_t>},
117+
{.size_bytes = sizeof(int32_t),
118+
.convert_proc = ToNormalizedScalar<uint32_t>}},
88119
{VerticesBuilder::ComponentType::kFloat,
89-
WriteComponentsAsScalars<float>},
120+
{.size_bytes = sizeof(float),
121+
.convert_proc = ToNormalizedScalar<float>}},
90122
};
91123

92-
void VerticesBuilder::SetAttributeFromBuffer(Attribute attribute,
124+
void VerticesBuilder::SetAttributeFromBuffer(AttributeType attribute,
93125
ComponentType component_type,
94126
const void* buffer_start,
95-
size_t stride_bytes,
96-
size_t count) {
97-
if (count > vertices_.size()) {
98-
vertices_.resize(count, Vertex());
127+
size_t attribute_stride_bytes,
128+
size_t attribute_count) {
129+
if (attribute_count > vertices_.size()) {
130+
vertices_.resize(attribute_count, Vertex());
99131
}
100132

101-
const auto& properties = kAttributes[attribute];
102-
const auto& writer = kAttributeWriters[component_type];
103-
for (size_t i = 0; i < count; i++) {
104-
const char* source =
105-
reinterpret_cast<const char*>(buffer_start) + stride_bytes * i;
106-
char* destination =
107-
reinterpret_cast<char*>(&vertices_.data()[i]) + properties.offset_bytes;
133+
const ComponentProperties& component_props = kComponentTypes[component_type];
134+
const AttributeProperties& attribute_props = kAttributeTypes[attribute];
135+
for (size_t i = 0; i < attribute_count; i++) {
136+
const uint8_t* source = reinterpret_cast<const uint8_t*>(buffer_start) +
137+
attribute_stride_bytes * i;
138+
uint8_t* destination = reinterpret_cast<uint8_t*>(&vertices_.data()[i]) +
139+
attribute_props.offset_bytes;
108140

109-
writer(destination, source, properties.component_count);
141+
attribute_props.write_proc(reinterpret_cast<Scalar*>(destination), source,
142+
component_props, attribute_props);
110143
}
111144
}
112145

impeller/scene/importer/vertices_builder.h

+33-19
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,6 @@ namespace importer {
1717

1818
class VerticesBuilder {
1919
public:
20-
enum class Attribute {
21-
kPosition,
22-
kNormal,
23-
kTangent,
24-
kTextureCoords,
25-
kColor,
26-
};
27-
2820
enum class ComponentType {
2921
kSignedByte = 5120,
3022
kUnsignedByte,
@@ -35,26 +27,48 @@ class VerticesBuilder {
3527
kFloat,
3628
};
3729

30+
enum class AttributeType {
31+
kPosition,
32+
kNormal,
33+
kTangent,
34+
kTextureCoords,
35+
kColor,
36+
};
37+
38+
using ComponentConverter =
39+
std::function<Scalar(const void* source, size_t byte_offset)>;
40+
struct ComponentProperties {
41+
size_t size_bytes = 0;
42+
ComponentConverter convert_proc;
43+
};
44+
45+
struct AttributeProperties;
46+
using AttributeWriter =
47+
std::function<void(Scalar* destination,
48+
const void* source,
49+
const ComponentProperties& component_props,
50+
const AttributeProperties& attribute_props)>;
51+
struct AttributeProperties {
52+
size_t offset_bytes = 0;
53+
size_t size_bytes = 0;
54+
size_t component_count = 0;
55+
AttributeWriter write_proc;
56+
};
57+
3858
VerticesBuilder();
3959

4060
void WriteFBVertices(std::vector<fb::Vertex>& vertices) const;
4161

42-
void SetAttributeFromBuffer(Attribute attribute,
62+
void SetAttributeFromBuffer(AttributeType attribute,
4363
ComponentType component_type,
4464
const void* buffer_start,
45-
size_t stride_bytes,
46-
size_t count);
65+
size_t attribute_stride_bytes,
66+
size_t attribute_count);
4767

4868
private:
49-
struct AttributeProperties {
50-
size_t offset_bytes;
51-
size_t size_bytes;
52-
size_t component_count;
53-
};
54-
55-
static std::map<VerticesBuilder::Attribute,
69+
static std::map<VerticesBuilder::AttributeType,
5670
VerticesBuilder::AttributeProperties>
57-
kAttributes;
71+
kAttributeTypes;
5872

5973
struct Vertex {
6074
Vector3 position;

0 commit comments

Comments
 (0)