#pragma once // Frostbite skinned MeshSet resources: one level of detail's triangles, and how each vertex is // weighted to the skeleton's bones. Only what a skinned mesh needs; the layout was worked out // on skate.'s costume meshes, first by gBGYo's ReSkate fork (github.com/gBGYo/ReSkate). #include "binary_io.h" #include #include #include #include #include #include namespace dingosdk::frostbite { struct MeshLod { Guid chunk; // the geometry chunk: the vertex buffer, then the index buffer std::uint32_t vertex_bytes{}, index_bytes{}; }; // The `lod`-th level of detail (0 the finest) of a MeshSet resource. Throws for a layout this // reader does not know. [[nodiscard]] MeshLod read_mesh_lod(std::span resource, std::size_t lod); // What a geometry comparison needs, of any MeshSet of the known layout, skinned or not and // whatever its index size: how many levels of detail it has, a level's geometry chunk, and // where that level's vertices are. Nothing of the skinning is read, so a mesh the skinned // reader refuses for its bones still gives its positions. Throws for another layout, and for // positions that are not three floats. [[nodiscard]] std::size_t mesh_lod_count(std::span resource); [[nodiscard]] MeshLod mesh_lod_geometry(std::span resource, std::size_t lod); [[nodiscard]] std::vector> read_mesh_positions(std::span resource, std::size_t lod, std::span geometry); // A level of detail's geometry chunk and buffer sizes, of either layout check_mesh_lod reads (the // skinned one, and world meshes' static one); `lods` gets how many levels there are. [[nodiscard]] MeshLod any_mesh_lod_geometry(std::span resource, std::size_t lod, std::size_t* lods = nullptr); // What is wrong with a level of detail's geometry as the GPU would read it, a skinned or a static // MeshSet: a section whose vertices or indices run past their buffer, or a triangle that // names a vertex outside its section. Empty when it is sound. `index_format` gets the level's // index format (33: 16-bit; anything else is read as 32-bit). Throws for another layout. [[nodiscard]] std::vector check_mesh_lod(std::span resource, std::size_t lod, std::span geometry, std::uint32_t* index_format = nullptr); struct SkinnedVertex { std::array position{}; // model space std::array bones{}; // skeleton bones std::array weights{}; // summing to 255; 0 for an unused influence }; struct SkinnedMesh { std::vector vertices; std::vector triangles; // vertex indices, three a triangle }; // That level's sections as one mesh, from its geometry chunk. Throws when they do not fit. [[nodiscard]] SkinnedMesh read_skinned_mesh(std::span resource, std::size_t lod, std::span geometry); }