42 std::uint16_t vertex_format_flags = 0;
43 ctx.
read16<std::endian::little>(
reinterpret_cast<std::byte*
>(&vertex_format_flags), 1);
46 std::uint8_t bones_per_vertex = 0;
49 ctx.
read8(
reinterpret_cast<std::byte*
>(&bones_per_vertex), 1);
53 std::uint32_t vertex_count = 0;
54 ctx.
read32<std::endian::little>(
reinterpret_cast<std::byte*
>(&vertex_count), 1);
57 std::size_t vertex_stride = 0;
60 vertex_stride +=
sizeof(float) * 3;
64 vertex_stride +=
sizeof(float) * 2;
68 vertex_stride +=
sizeof(float) * 3;
72 vertex_stride +=
sizeof(float) * 4;
76 vertex_stride +=
sizeof(float) * 4;
80 vertex_stride +=
sizeof(std::uint16_t) * bones_per_vertex;
84 vertex_stride +=
sizeof(float) * bones_per_vertex;
88 vertex_stride +=
sizeof(float) * 3;
92 std::vector<std::byte> vertex_data(vertex_count * vertex_stride);
95 if constexpr (std::endian::native == std::endian::little)
97 ctx.
read8(vertex_data.data(), vertex_count * vertex_stride);
101 std::byte* vertex_data_offset = vertex_data.data();
102 for (std::uint32_t i = 0; i < vertex_count; ++i)
106 ctx.
read32<std::endian::little>(vertex_data_offset, 3);
107 vertex_data_offset +=
sizeof(float) * 3;
111 ctx.
read32<std::endian::little>(vertex_data_offset, 2);
112 vertex_data_offset +=
sizeof(float) * 2;
116 ctx.
read32<std::endian::little>(vertex_data_offset, 3);
117 vertex_data_offset +=
sizeof(float) * 3;
121 ctx.
read32<std::endian::little>(vertex_data_offset, 4);
122 vertex_data_offset +=
sizeof(float) * 4;
126 ctx.
read32<std::endian::little>(vertex_data_offset, 4);
127 vertex_data_offset +=
sizeof(float) * 4;
131 ctx.
read16<std::endian::little>(vertex_data_offset, bones_per_vertex);
132 vertex_data_offset +=
sizeof(std::uint16_t) * bones_per_vertex;
136 ctx.
read32<std::endian::little>(vertex_data_offset, bones_per_vertex);
137 vertex_data_offset +=
sizeof(float) * bones_per_vertex;
141 ctx.
read32<std::endian::little>(vertex_data_offset, 3);
142 vertex_data_offset +=
sizeof(float) * 3;
148 std::unique_ptr<render::model> model = std::make_unique<render::model>();
152 model->set_vertex_offset(0);
153 model->set_vertex_stride(vertex_stride);
159 std::vector<gl::vertex_input_attribute> attributes(std::popcount(vertex_format_flags));
161 std::uint32_t vertex_offset = 0;
162 std::uint32_t attribute_index = 0;
166 auto& attribute = attributes[attribute_index];
168 attribute.binding = 0;
170 attribute.offset = vertex_offset;
172 vertex_offset += 3 *
sizeof(float);
177 auto& attribute = attributes[attribute_index];
179 attribute.binding = 0;
181 attribute.offset = vertex_offset;
183 vertex_offset += 2 *
sizeof(float);
188 auto& attribute = attributes[attribute_index];
190 attribute.binding = 0;
192 attribute.offset = vertex_offset;
194 vertex_offset += 3 *
sizeof(float);
199 auto& attribute = attributes[attribute_index];
201 attribute.binding = 0;
203 attribute.offset = vertex_offset;
205 vertex_offset += 4 *
sizeof(float);
210 auto& attribute = attributes[attribute_index];
212 attribute.binding = 0;
214 attribute.offset = vertex_offset;
216 vertex_offset += 4 *
sizeof(float);
221 auto& attribute = attributes[attribute_index];
223 attribute.binding = 0;
224 switch (bones_per_vertex)
242 attribute.offset = vertex_offset;
244 vertex_offset += bones_per_vertex *
sizeof(std::uint16_t);
249 auto& attribute = attributes[attribute_index];
251 attribute.binding = 0;
252 switch (bones_per_vertex)
270 attribute.offset = vertex_offset;
272 vertex_offset += bones_per_vertex *
sizeof(float);
277 auto& attribute = attributes[attribute_index];
279 attribute.binding = 0;
281 attribute.offset = vertex_offset;
288 model->get_vertex_array() = std::make_shared<gl::vertex_array>(attributes);
291 ctx.
read32<std::endian::little>(
reinterpret_cast<std::byte*
>(&model->get_bounds()), 6);
294 std::uint16_t material_count = 0;
295 ctx.
read16<std::endian::little>(
reinterpret_cast<std::byte*
>(&material_count), 1);
298 model->get_groups().resize(material_count);
301 for (
auto& group: model->get_groups())
304 std::uint8_t material_name_length = 0;
305 ctx.
read8(
reinterpret_cast<std::byte*
>(&material_name_length), 1);
308 std::string material_name(
static_cast<std::size_t
>(material_name_length),
'\0');
309 ctx.
read8(
reinterpret_cast<std::byte*
>(material_name.data()), material_name_length);
312 group.id = hash::fnv1a32<char>(material_name);
318 ctx.
read32<std::endian::little>(
reinterpret_cast<std::byte*
>(&group.first_vertex), 1);
321 ctx.
read32<std::endian::little>(
reinterpret_cast<std::byte*
>(&group.vertex_count), 1);
324 std::string material_filename = material_name +
".mtl";
325 std::replace(material_filename.begin(), material_filename.end(),
'_',
'-');
337 std::uint16_t bone_count = 0;
338 ctx.
read16<std::endian::little>(
reinterpret_cast<std::byte*
>(&bone_count), 1);
344 for (std::uint16_t i = 0; i < bone_count; ++i)
348 ctx.
read32<std::endian::little>(
reinterpret_cast<std::byte*
>(&bone_name), 1);
351 std::uint16_t bone_parent_index = i;
352 ctx.
read16<std::endian::little>(
reinterpret_cast<std::byte*
>(&bone_parent_index), 1);
361 ctx.
read32<std::endian::little>(
reinterpret_cast<std::byte*
>(&bone_transform.
rotation.
r), 1);
362 ctx.
read32<std::endian::little>(
reinterpret_cast<std::byte*
>(bone_transform.
rotation.
i.
data()), 3);
365 bone_transform.
scale = {1, 1, 1};
368 float bone_length = 0.0f;
369 ctx.
read32<std::endian::little>(
reinterpret_cast<std::byte*
>(&bone_length), 1);
A material is associated with exactly one shader program and contains a set of material properties wh...
static std::unique_ptr< T > load(::resource_manager &resource_manager, deserialize_context &ctx)
Loads a resource.
Manages the loading, caching, and saving of resources.
std::shared_ptr< T > load(const std::filesystem::path &path)
Loads and caches a resource.
Skeletal animation skeleton.
void set_bone_transform(bone_index_type index, const bone_transform_type &transform)
Sets the transform of a bone, relative to its parent bone.
bone_index_type add_bones(std::size_t bone_count)
Add one or more bones to the skeleton.
void update_rest_pose()
Updates the rest pose of the skeleton.
void set_bone_parent(bone_index_type child_index, bone_index_type parent_index)
Sets the parent of a bone.
void set_bone_name(bone_index_type index, hash::fnv1a32_t name)
Sets the name of a bone.
constexpr std::uint16_t vertex_attribute_morph_target
constexpr std::uint16_t vertex_attribute_color
constexpr std::uint16_t vertex_attribute_bone_index
constexpr std::uint16_t vertex_attribute_uv
constexpr std::uint16_t vertex_attribute_tangent
constexpr std::uint16_t vertex_attribute_normal
constexpr std::uint16_t vertex_attribute_bone_weight
constexpr std::uint16_t vertex_attribute_position
@ static_draw
Data will be modified once, by the application, and used many times, for drawing commands.
@ triangle_list
Separate triangle primitives.
@ bone_index
Vertex bone indices (uvec4)
@ tangent
Vertex tangent (vec4)
@ target
Vertex morph target (vec3)
@ normal
Vertex normal (vec3)
@ color
Vertex color (vec4)
@ bone_weight
Vertex bone weights (vec4)
@ uv
Vertex UV texture coordinates (vec2)
@ position
Vertex position (vec3)
Provides access to a deserialization state.
std::size_t read16(std::byte *data, std::size_t count) noexcept(false)
Reads 16-bit (word) data.
std::size_t read32(std::byte *data, std::size_t count) noexcept(false)
Reads 32-bit (double word) data.
virtual std::size_t read8(std::byte *data, std::size_t count) noexcept(false)=0
Reads 8-bit (byte) data.
32-bit FNV-1a hash value.
scalar_type r
Quaternion real part.
vector_type i
Quaternion imaginary part.
constexpr element_type * data() noexcept
Returns a pointer to the element array.