Changed up how resources import/export files. Added Model codecs.

This commit is contained in:
2024-02-20 22:47:52 -08:00
parent 54012df3a1
commit 93f881cf03
20 changed files with 998 additions and 882 deletions

View File

@@ -1,54 +1,102 @@
#include "ehs/io/model/Model.h"
#include "ehs/io/mdl/Mdl.h"
namespace ehs
{
Model::Model()
: hashId(0)
Array<MdlCodec> Mdl::codecs;
bool Mdl::HasCodec(const UInt_64 hashExt)
{
AddType("Model");
for (UInt_64 i = 0; i < codecs.Size(); ++i)
if (codecs[i].GetHashExt() == hashExt)
return true;
return false;
}
Model::Model(const Str_8& filePath)
bool Mdl::HasCodec(const Str_8& ext)
{
AddType("Model");
return HasCodec(ext.Hash_64());
}
bool Mdl::AddCodec(MdlCodec codec)
{
if (HasCodec(codec.GetHashExt()))
return false;
codecs.Push(std::move(codec));
return true;
}
const MdlCodec* Mdl::GetCodec(const UInt_64 hashExt)
{
for (UInt_64 i = 0; i < codecs.Size(); ++i)
if (codecs[i].GetHashExt() == hashExt)
return &codecs[i];
return nullptr;
}
const MdlCodec* Mdl::GetCodec(const Str_8& ext)
{
return GetCodec(ext.Hash_64());
}
Mdl::Mdl()
: hashId(0)
{
AddType("Mdl");
}
Mdl::Mdl(const Str_8& filePath)
{
AddType("Mdl");
File file(filePath, Mode::READ, Disposition::OPEN);
Str_8 ext = file.GetExtension();
hashId = file.GetName().Hash_64();
id = file.GetName();
if (file.GetExtension() == "ehm")
const MdlCodec* codec = GetCodec(ext);
if (!codec)
{
FromEHM(file);
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
return;
}
Serializer<UInt_64> data = file.ReadSerializer_64(codec->GetEndianness(), file.Size());
file.Release();
codec->Decode(data, this);
}
Model::Model(Str_8 id, Array<Mesh> meshes, Bone skeleton, Array<Animation> animations)
Mdl::Mdl(Str_8 id, Array<Mesh> meshes, Bone skeleton, Array<Animation> animations)
: hashId(id.Hash_64()), id((Str_8&&)id), meshes((Array<Mesh>&&)meshes), skeleton((Bone&&)skeleton),
animations((Array<Animation>&&)animations)
{
AddType("Model");
AddType("Mdl");
}
Model::Model(Str_8 id, Array<Mesh> meshes, Bone skeleton)
Mdl::Mdl(Str_8 id, Array<Mesh> meshes, Bone skeleton)
: hashId(id.Hash_64()), id((Str_8&&)id), meshes((Array<Mesh>&&)meshes), skeleton((Bone&&)skeleton)
{
AddType("Model");
AddType("Mdl");
}
Model::Model(Str_8 id, Array<Mesh> meshes)
Mdl::Mdl(Str_8 id, Array<Mesh> meshes)
: hashId(id.Hash_64()), id((Str_8&&)id), meshes((Array<Mesh>&&)meshes)
{
AddType("Model");
AddType("Mdl");
}
Model::Model(Model&& model) noexcept
Mdl::Mdl(Mdl&& model) noexcept
: BaseObj((BaseObj&&)model), hashId(model.hashId), id((Str_8&&)model.id), meshes((Array<Mesh>&&)model.meshes),
skeleton((Bone&&)model.skeleton), animations((Array<Animation>&&)model.animations)
{
}
Model& Model::operator=(Model&& model) noexcept
Mdl& Mdl::operator=(Mdl&& model) noexcept
{
if (this == &model)
return *this;
@@ -66,40 +114,40 @@ namespace ehs
return *this;
}
void Model::Release()
void Mdl::Release()
{
meshes.Clear();
skeleton = {};
animations.Clear();
}
UInt_64 Model::GetHashId() const
UInt_64 Mdl::GetHashId() const
{
return hashId;
}
void Model::SetId(Str_8 newId)
void Mdl::SetId(Str_8 newId)
{
hashId = newId.Hash_64();
id = (Str_8&&)newId;
}
Str_8 Model::GetId() const
Str_8 Mdl::GetId() const
{
return id;
}
const Array<Mesh>& Model::GetMeshes() const
const Array<Mesh>& Mdl::GetMeshes() const
{
return meshes;
}
Array<Mesh>& Model::GetMeshes()
Array<Mesh>& Mdl::GetMeshes()
{
return meshes;
}
Mesh* Model::GetMesh(const UInt_64 inHashId)
Mesh* Mdl::GetMesh(const UInt_64 inHashId)
{
for (UInt_64 i = 0; i < meshes.Size(); ++i)
if (meshes[i].GetHashId() == inHashId)
@@ -108,22 +156,22 @@ namespace ehs
return nullptr;
}
Mesh* Model::GetMesh(const Str_8& inId)
Mesh* Mdl::GetMesh(const Str_8& inId)
{
return GetMesh(inId.Hash_64());
}
const Bone& Model::GetSkeleton() const
const Bone& Mdl::GetSkeleton() const
{
return skeleton;
}
Bone& Model::GetSkeleton()
Bone& Mdl::GetSkeleton()
{
return skeleton;
}
Animation* Model::GetAnimation(const UInt_64 inHashId)
Animation* Mdl::GetAnimation(const UInt_64 inHashId)
{
for (UInt_64 i = 0; i < animations.Size(); ++i)
if (animations[i].GetHashId() == inHashId)
@@ -132,39 +180,47 @@ namespace ehs
return nullptr;
}
const Array<Animation>& Model::GetAnimations() const
const Array<Animation>& Mdl::GetAnimations() const
{
return animations;
}
Array<Animation>& Model::GetAnimations()
Array<Animation>& Mdl::GetAnimations()
{
return animations;
}
void Model::Calculate()
void Mdl::Calculate()
{
for (UInt_64 i = 0; i < meshes.Size(); ++i)
meshes[i].Calculate();
}
void Model::Export(const Str_8& filePath, const ModelEncoding encoding)
bool Mdl::Export(const Str_8& filePath) const
{
File file(filePath, Mode::WRITE, Disposition::OPEN_PERSISTENT);
Str_8 ext = File::ParseExt_8(filePath);
switch (encoding)
const MdlCodec* codec = GetCodec(ext);
if (!codec)
{
case ModelEncoding::EHM:
{
ToEHM(file);
break;
}
EHS_LOG_INT("Error", 0, "Codec not found for file extension, \"" + ext + "\".");
return false;
}
Serializer<UInt_64> result;
if (!codec->Encode(result, this))
return false;
File file(filePath, Mode::WRITE, Disposition::CREATE_PERSISTENT);
file.WriteSerializer_64(result);
return true;
}
void Model::ToEHM(File& file)
bool EncodeEHM(const MdlCodec* const codec, Serializer<UInt_64>& data, const Mdl* const mdl)
{
Serializer<UInt_64> data(Endianness::LE);
const Array<Mesh>& meshes = mdl->GetMeshes();
data.WriteVersion({1, 0, 0});
data.Write<UInt_64>(meshes.Size());
@@ -184,24 +240,23 @@ namespace ehs
}
}
file.WriteSerializer_64(data);
file.Truncate(data.Size());
return true;
}
void Model::FromEHM(File& file)
bool DecodeEHM(const MdlCodec* const codec, Serializer<UInt_64>& data, Mdl* const mdl)
{
Serializer<UInt_64> data = file.ReadSerializer_64(Endianness::LE, file.Size());
Version ver = data.ReadVersion();
if (ver != Version(1, 0, 0))
{
EHS_LOG_INT("Error", 0, "Cannot decode EHM file version " + Str_8::FromNum(ver.major) + "." +
Str_8::FromNum(ver.minor) + "." + Str_8::FromNum(ver.patch) +
", must be version 0.0.0.");
return;
return false;
}
Array<Mesh>& meshes = mdl->GetMeshes();
meshes.Resize(data.Read<UInt_64>());
for (UInt_64 i = 0; i < meshes.Size(); ++i)
{
meshes[i].SetId(data.ReadStr<Char_8, UInt_64>());
@@ -220,6 +275,7 @@ namespace ehs
meshes[i].SetIndices(data.ReadArray<UInt_32, UInt_64>());
Bone& skeleton = mdl->GetSkeleton();
UInt_8 boneCount = data.Read<UInt_8>();
for (UInt_8 b = 0; b < boneCount; ++b)
{
@@ -237,14 +293,16 @@ namespace ehs
if (!parent)
{
EHS_LOG_INT("Error", 0, "Invalid bone order.");
return;
return false;
}
parent->AddBone({name, b, localBindTrans, invBindTrans});
}
}
animations = Array<Animation>(data.Read<UInt_64>());
Array<Animation>& animations = mdl->GetAnimations();
animations.Resize(data.Read<UInt_64>());
for (UInt_64 a = 0; a < animations.Size(); ++a)
{
Str_8 animId = data.ReadStr<Char_8, UInt_64>();
@@ -271,5 +329,7 @@ namespace ehs
}
}
}
return true;
}
}

108
src/io/model/MdlCodec.cpp Normal file
View File

@@ -0,0 +1,108 @@
#include "ehs/io/mdl/MdlCodec.h"
namespace ehs
{
MdlCodec::MdlCodec()
: hashExt(0), endianness(Endianness::LE), encoder(nullptr), decoder(nullptr)
{
}
MdlCodec::MdlCodec(Str_8 id, Str_8 ext, const Endianness end, EnocdeMdlCb encoder, DecodeMdlCb decoder)
: id(std::move(id)), hashExt(ext.Hash_64()), ext(std::move(ext)), endianness(end), encoder(encoder),
decoder(decoder)
{
}
MdlCodec::MdlCodec(MdlCodec&& codec) noexcept
: id(std::move(codec.id)), hashExt(codec.hashExt), ext(std::move(codec.ext)), endianness(codec.endianness),
encoder(codec.encoder), decoder(codec.decoder)
{
codec.hashExt = 0;
codec.endianness = Endianness::LE;
codec.encoder = nullptr;
codec.decoder = nullptr;
}
MdlCodec::MdlCodec(const MdlCodec& codec)
: id(codec.id), hashExt(codec.hashExt), ext(codec.ext), endianness(codec.endianness), encoder(codec.encoder),
decoder(codec.decoder)
{
}
MdlCodec& MdlCodec::operator=(MdlCodec&& codec) noexcept
{
if (this == &codec)
return *this;
id = std::move(codec.id);
hashExt = codec.hashExt;
ext = std::move(codec.ext);
endianness = codec.endianness;
encoder = codec.encoder;
decoder = codec.decoder;
codec.hashExt = 0;
codec.endianness = Endianness::LE;
codec.encoder = nullptr;
codec.decoder = nullptr;
return *this;
}
MdlCodec& MdlCodec::operator=(const MdlCodec& codec)
{
if (this == &codec)
return *this;
id = codec.id;
hashExt = codec.hashExt;
ext = codec.ext;
endianness = codec.endianness;
encoder = codec.encoder;
decoder = codec.decoder;
return *this;
}
Str_8 MdlCodec::GetId() const
{
return id;
}
UInt_64 MdlCodec::GetHashExt() const
{
return hashExt;
}
Str_8 MdlCodec::GetExt() const
{
return ext;
}
Endianness MdlCodec::GetEndianness() const
{
return endianness;
}
bool MdlCodec::Encode(Serializer<UInt_64>& out, const Mdl* in) const
{
if (!encoder)
{
EHS_LOG_INT("Error", 0, "Encoding is not supported for the " + id + " format.");
return false;
}
return encoder(this, out, in);
}
bool MdlCodec::Decode(Serializer<UInt_64>& in, Mdl* out) const
{
if (!decoder)
{
EHS_LOG_INT("Error", 0, "Decoding is not supported for the " + id + " format.");
return false;
}
return decoder(this, in, out);
}
}