112 lines
2.4 KiB
C++
112 lines
2.4 KiB
C++
#include "assets/file_parsers/threedtk_pose_loader.hpp"
|
|
|
|
#include <fstream>
|
|
#include <execution>
|
|
#include <glm/ext/matrix_transform.hpp>
|
|
#include <glm/gtx/euler_angles.hpp>
|
|
#include "util/logger.hpp"
|
|
|
|
|
|
std::error_code assets::threedtk_pose_loader::prefetch(
|
|
path_id_lookups& lookups
|
|
) {
|
|
return {};
|
|
}
|
|
|
|
std::error_code assets::threedtk_pose_loader::load(
|
|
path_id_lookups& lookups,
|
|
data_stores& stores,
|
|
bool pedantic
|
|
) {
|
|
m_path_buffer.clear();
|
|
lookups.poses.by_extension(".pose", m_path_buffer);
|
|
|
|
std::for_each(
|
|
std::execution::parallel_unsequenced_policy{},
|
|
m_path_buffer.begin(),
|
|
m_path_buffer.end(),
|
|
parser_context{
|
|
lookups,
|
|
stores
|
|
}
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
assets::threedtk_pose_loader::parser_context::parser_context(
|
|
path_id_lookups& m_id_lookups,
|
|
data_stores& m_stores
|
|
) :
|
|
m_id_lookups{ &m_id_lookups },
|
|
m_stores{ &m_stores }
|
|
{
|
|
m_line_buffer.reserve(64);
|
|
}
|
|
|
|
void assets::threedtk_pose_loader::parser_context::operator()(lookup_type::const_pointer entry) noexcept
|
|
{
|
|
const auto& [ filename, id ] = *entry;
|
|
|
|
if (const auto res = parse_file(filename, m_line_buffer))
|
|
{
|
|
m_stores->poses.insert(id, res.value());
|
|
}
|
|
else
|
|
{
|
|
const auto error = res.error();
|
|
ztu::logger::error(
|
|
"Error while parsing 3dtk pose file %: [%] %",
|
|
filename,
|
|
error.category().name(),
|
|
error.message()
|
|
);
|
|
}
|
|
}
|
|
|
|
ztu::result<assets::pose_data> assets::threedtk_pose_loader::parse_file(
|
|
const std::filesystem::path& filename,
|
|
std::string& line_buffer
|
|
) {
|
|
|
|
auto in = std::ifstream{ filename };
|
|
if (not in.is_open())
|
|
{
|
|
return std::unexpected{ std::make_error_code(std::errc::no_such_file_or_directory) };
|
|
}
|
|
|
|
std::array<glm::vec3, 2> transform_vecs{};
|
|
|
|
for (std::size_t row{}; row != 2; ++row) {
|
|
|
|
std::getline(in, line_buffer);
|
|
|
|
auto it = line_buffer.cbegin().base();
|
|
auto end = line_buffer.cend().base();
|
|
|
|
for (glm::vec3::length_type col{}; col != 3; ++col) {
|
|
|
|
const auto [ ptr, ec ] = std::from_chars(
|
|
it, end,
|
|
transform_vecs[row][col],
|
|
std::chars_format::general
|
|
);
|
|
|
|
if (ec != std::errc{}) {
|
|
return std::unexpected{ std::make_error_code(ec) };
|
|
}
|
|
|
|
it = ptr + 1; // skip space in between components
|
|
}
|
|
}
|
|
|
|
const auto& translation = transform_vecs[0];
|
|
auto& angles = transform_vecs[1];
|
|
angles *= static_cast<float>(M_PI / 180.0);
|
|
|
|
return (
|
|
glm::translate(glm::identity<glm::mat4>(), translation) *
|
|
glm::eulerAngleXYZ(angles[0], angles[1], angles[2])
|
|
);
|
|
}
|