Changed up how resources import/export files. Added Model codecs.
This commit is contained in:
@@ -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
108
src/io/model/MdlCodec.cpp
Normal 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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user