libeuropa/util: Add some structs for mesh/math stuff

This commit is contained in:
Lily Tsuru 2025-01-20 01:36:36 -05:00
parent 263cfd2cf4
commit badda50a87
2 changed files with 103 additions and 0 deletions

View file

@ -0,0 +1,40 @@
//
// EuropaTools
//
// (C) 2021-2025 modeco80 <lily.modeco80@protonmail.ch>
//
// SPDX-License-Identifier: MIT
//
// Math types which are used by mesh I/O code.
// These are not general purpose and are only meant to be
// binary compatible.
#pragma once
namespace europa::structs {
#ifdef _MSC_VER
#pragma pack(push, 1)
#endif
struct [[gnu::packed]] Vec3f {
float x;
float y;
float z;
};
struct [[gnu::packed]] Uvf {
float u;
float v;
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif
static_assert(sizeof(Vec3f) == 0xc, "Vec3f size is incorrect");
static_assert(sizeof(Uvf) == 0x8, "Uvf size is incorrect");
}

View file

@ -0,0 +1,63 @@
#pragma once
#include <vector>
namespace europa::util {
template <class To, class From>
struct IntoImpl {
constexpr static To DoInto(const From& from) {
// The default implentation assumes that the To type has a constructor which
// can initalize it from a value of From const&.
return To(from);
}
};
/// Into() support for vectors of items.
template <class To, class From>
struct IntoImpl<std::vector<To>, std::vector<From>> {
constexpr static std::vector<To> DoInto(const std::vector<From>& from) {
// FIXME: Ranges could make this less stupid
auto vec = std::vector<To> {};
vec.resize(from.size());
// Feed into existing Into() implementation
for(auto const& item : from)
vec.push_back(Into(item));
return vec;
}
};
/// Allows a type to be converted.
/// A user is allowed to supply conversions out-of-band.
template <class To, class From>
constexpr To Into(const From& from) {
return IntoImpl<To, From>::DoInto(from);
}
/// Helper macro to hide away the annoying boilerplate of
/// implementing the IntoImpl struct used for implementing conversion
#define EUROPA_BEGIN_INTO_CONVERSION(To, From) \
template <> \
struct ::europa::util::IntoImpl<To, From> { \
static To DoInto([[maybe_unused]] const From& from)
#define EUROPA_END_INTO_CONVERSION }
#if 0
// An example of specializing Into().
// This is a bit iffy, but works.
struct Frob {};
EUROPA_BEGIN_INTO_CONVERSION(int, Frob) {
return 42;
} EUROPA_END_INTO_CONVERSION;
auto a() {
Frob f{};
int i = Into<int>(f);
}
#endif
} // namespace europa::util