Adjusted workflow.
This commit is contained in:
91
src/io/model/AnimBone.cpp
Normal file
91
src/io/model/AnimBone.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include "ehs/io/model/AnimBone.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
AnimBone::AnimBone()
|
||||
: boneId(0xFF)
|
||||
{
|
||||
}
|
||||
|
||||
AnimBone::AnimBone(const UInt_8 boneId)
|
||||
: boneId(boneId)
|
||||
{
|
||||
}
|
||||
|
||||
AnimBone::AnimBone(const UInt_8 boneId, const UInt_64 size)
|
||||
: boneId(boneId), keyFrames(size)
|
||||
{
|
||||
}
|
||||
|
||||
AnimBone::AnimBone(const UInt_8 boneId, Array<KeyFrame> keyFrames)
|
||||
: boneId(boneId), keyFrames(std::move(keyFrames))
|
||||
{
|
||||
}
|
||||
|
||||
AnimBone::AnimBone(const AnimBone& anim)
|
||||
: boneId(anim.boneId), keyFrames(anim.keyFrames)
|
||||
{
|
||||
}
|
||||
|
||||
AnimBone::AnimBone(AnimBone&& anim) noexcept
|
||||
: boneId(anim.boneId), keyFrames(std::move(anim.keyFrames))
|
||||
{
|
||||
anim.boneId = 0xFF;
|
||||
}
|
||||
|
||||
AnimBone& AnimBone::operator=(AnimBone&& anim) noexcept
|
||||
{
|
||||
if (this == &anim)
|
||||
return *this;
|
||||
|
||||
boneId = anim.boneId;
|
||||
keyFrames = std::move(anim.keyFrames);
|
||||
|
||||
anim.boneId = 0xFF;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
AnimBone& AnimBone::operator=(const AnimBone& anim)
|
||||
{
|
||||
if (this == &anim)
|
||||
return *this;
|
||||
|
||||
boneId = anim.boneId;
|
||||
keyFrames = anim.keyFrames;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
UInt_8 AnimBone::GetBoneId() const
|
||||
{
|
||||
return boneId;
|
||||
}
|
||||
|
||||
Array<KeyFrame> AnimBone::GetKeyFrames() const
|
||||
{
|
||||
return keyFrames;
|
||||
}
|
||||
|
||||
Array<KeyFrame>& AnimBone::GetKeyFrames()
|
||||
{
|
||||
return keyFrames;
|
||||
}
|
||||
|
||||
float AnimBone::GetPrevAndNext(KeyFrame& prev, KeyFrame& next, const float elapsed) const
|
||||
{
|
||||
prev = keyFrames[0];
|
||||
next = keyFrames[0];
|
||||
for (UInt_64 i = 1; i < keyFrames.Size(); ++i)
|
||||
{
|
||||
next = keyFrames[i];
|
||||
if (keyFrames[i].GetTimeStamp() > elapsed)
|
||||
break;
|
||||
prev = keyFrames[i];
|
||||
}
|
||||
|
||||
return (elapsed - prev.GetTimeStamp()) / (next.GetTimeStamp() - prev.GetTimeStamp());
|
||||
}
|
||||
}
|
130
src/io/model/Animation.cpp
Normal file
130
src/io/model/Animation.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#include "ehs/io/model/Animation.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Animation::Animation()
|
||||
: hashId(0), duration(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(Str_8 id, const float duration)
|
||||
: hashId(id.Hash_64()), id(std::move(id)), duration(duration)
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(Str_8 id, const float duration, UInt_64 size)
|
||||
: hashId(id.Hash_64()), id(std::move(id)), duration(duration), animated(size)
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(Str_8 id, const float duration, Array<AnimBone> animated)
|
||||
: hashId(id.Hash_64()), id(std::move(id)), duration(duration), animated(std::move(animated))
|
||||
{
|
||||
}
|
||||
|
||||
Animation::Animation(Animation&& anim) noexcept
|
||||
: hashId(anim.hashId), id(std::move(anim.id)), duration(anim.duration), animated(std::move(anim.animated))
|
||||
{
|
||||
anim.hashId = 0;
|
||||
anim.duration = 0.0f;
|
||||
}
|
||||
|
||||
Animation::Animation(const Animation& anim)
|
||||
: hashId(anim.hashId), id(anim.id), duration(anim.duration), animated(anim.animated)
|
||||
{
|
||||
}
|
||||
|
||||
Animation& Animation::operator=(Animation&& anim) noexcept
|
||||
{
|
||||
if (this == &anim)
|
||||
return *this;
|
||||
|
||||
hashId = anim.hashId;
|
||||
id = std::move(anim.id);
|
||||
duration = anim.duration;
|
||||
animated = std::move(anim.animated);
|
||||
|
||||
anim.hashId = 0;
|
||||
anim.duration = 0.0f;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Animation& Animation::operator=(const Animation& anim)
|
||||
{
|
||||
if (this == &anim)
|
||||
return *this;
|
||||
|
||||
hashId = anim.hashId;
|
||||
id = anim.id;
|
||||
duration = anim.duration;
|
||||
animated = anim.animated;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
UInt_64 Animation::GetHashId() const
|
||||
{
|
||||
return hashId;
|
||||
}
|
||||
|
||||
void Animation::SetId(Str_8 newId)
|
||||
{
|
||||
hashId = newId.Hash_64();
|
||||
id = std::move(newId);
|
||||
}
|
||||
|
||||
Str_8 Animation::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
float Animation::GetDuration() const
|
||||
{
|
||||
return duration;
|
||||
}
|
||||
|
||||
Array<AnimBone> Animation::GetAnimated() const
|
||||
{
|
||||
return animated;
|
||||
}
|
||||
|
||||
Array<AnimBone>& Animation::GetAnimated()
|
||||
{
|
||||
return animated;
|
||||
}
|
||||
|
||||
Array<Mat4_f> Animation::Interpolate(const UInt_64 boneCount, const float elapsed) const
|
||||
{
|
||||
Array<Mat4_f> result(boneCount);
|
||||
for (UInt_64 i = 0; i < result.Size(); ++i)
|
||||
result[i] = Mat4_f::Identity();
|
||||
|
||||
if (elapsed == 0.0f)
|
||||
{
|
||||
for (UInt_64 i = 0; i < animated.Size(); ++i)
|
||||
{
|
||||
Array<KeyFrame> keyFrames = animated[i].GetKeyFrames();
|
||||
if (!keyFrames.Size())
|
||||
continue;
|
||||
|
||||
result[animated[i].GetBoneId()] = keyFrames[0].GetTrans();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UInt_64 i = 0; i < animated.Size(); ++i)
|
||||
{
|
||||
KeyFrame prev;
|
||||
KeyFrame next;
|
||||
float perc = animated[i].GetPrevAndNext(prev, next, elapsed);
|
||||
if (prev.GetNum() == next.GetNum() || perc <= 0.0f)
|
||||
result[animated[i].GetBoneId()] = prev.GetTrans();
|
||||
else
|
||||
result[animated[i].GetBoneId()] = KeyFrame::Interpolate(prev, next, perc);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
240
src/io/model/Bone.cpp
Normal file
240
src/io/model/Bone.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
#include "ehs/io/model/Bone.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Bone::Bone()
|
||||
: hashName(0), id(0), animTrans(Mat4_f::Identity())
|
||||
{
|
||||
}
|
||||
|
||||
Bone::Bone(Str_8 name, const UInt_8 id, const Mat4_f& localBindTrans, const Mat4_f& invBindTrans)
|
||||
: hashName(name.Hash_64()), name(std::move(name)), id(id), animTrans(Mat4_f::Identity()),
|
||||
localBindTrans(localBindTrans), invBindTrans(invBindTrans)
|
||||
{
|
||||
}
|
||||
|
||||
Bone::Bone(Bone&& bone) noexcept
|
||||
: hashName(bone.hashName), name(std::move(bone.name)), id(bone.id), animTrans(bone.animTrans),
|
||||
localBindTrans(bone.localBindTrans), invBindTrans(bone.invBindTrans), children(std::move(bone.children))
|
||||
{
|
||||
bone.hashName = 0;
|
||||
bone.id = 0xFF;
|
||||
bone.animTrans = Mat4_f::Identity();
|
||||
bone.localBindTrans = {};
|
||||
bone.invBindTrans = {};
|
||||
}
|
||||
|
||||
Bone::Bone(const Bone& bone)
|
||||
: hashName(bone.hashName), name(bone.name), id(bone.id), animTrans(bone.animTrans), localBindTrans(bone.localBindTrans),
|
||||
invBindTrans(bone.invBindTrans), children(bone.children)
|
||||
{
|
||||
}
|
||||
|
||||
Bone& Bone::operator=(Bone&& bone) noexcept
|
||||
{
|
||||
if (this == &bone)
|
||||
return *this;
|
||||
|
||||
hashName = bone.hashName;
|
||||
name = std::move(bone.name);
|
||||
id = bone.id;
|
||||
animTrans = bone.animTrans;
|
||||
localBindTrans = bone.localBindTrans;
|
||||
invBindTrans = bone.invBindTrans;
|
||||
children = std::move(bone.children);
|
||||
|
||||
bone.hashName = 0;
|
||||
bone.id = 0;
|
||||
bone.animTrans = Mat4_f::Identity();
|
||||
bone.localBindTrans = {};
|
||||
bone.invBindTrans = {};
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bone& Bone::operator=(const Bone& bone)
|
||||
{
|
||||
if (this == &bone)
|
||||
return *this;
|
||||
|
||||
hashName = bone.hashName;
|
||||
name = bone.name;
|
||||
id = bone.id;
|
||||
animTrans = bone.animTrans;
|
||||
localBindTrans = bone.localBindTrans;
|
||||
invBindTrans = bone.invBindTrans;
|
||||
children = bone.children;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
UInt_64 Bone::GetHashName() const
|
||||
{
|
||||
return hashName;
|
||||
}
|
||||
|
||||
void Bone::SetName(Str_8 newId)
|
||||
{
|
||||
hashName = newId.Hash_64();
|
||||
name = std::move(newId);
|
||||
}
|
||||
|
||||
Str_8 Bone::GetName() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
UInt_8 Bone::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
void Bone::SetAnimTrans(const Mat4_f& newTrans)
|
||||
{
|
||||
animTrans = newTrans;
|
||||
}
|
||||
|
||||
Mat4_f Bone::GetAnimTrans() const
|
||||
{
|
||||
return animTrans;
|
||||
}
|
||||
|
||||
void Bone::GetAnimTransRec(Array<Mat4_f>& output) const
|
||||
{
|
||||
output[id] = animTrans;
|
||||
|
||||
for (UInt_64 i = 0; i < children.Size(); ++i)
|
||||
children[i].GetAnimTransRec(output);
|
||||
}
|
||||
|
||||
Mat4_f Bone::GetLocalBindTrans() const
|
||||
{
|
||||
return localBindTrans;
|
||||
}
|
||||
|
||||
Mat4_f Bone::GetInvBindTrans() const
|
||||
{
|
||||
return invBindTrans;
|
||||
}
|
||||
|
||||
UInt_8 Bone::GetBoneCount() const
|
||||
{
|
||||
UInt_8 count = 1;
|
||||
|
||||
for (UInt_64 i = 0; i < children.Size(); ++i)
|
||||
count += children[i].GetBoneCount();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool Bone::HasBone(const UInt_64 hashName, const UInt_8 id) const
|
||||
{
|
||||
if (this->hashName == hashName && this->id == id)
|
||||
return true;
|
||||
|
||||
bool result = false;
|
||||
|
||||
for (UInt_64 i = 0; i < children.Size(); ++i)
|
||||
result = children[i].HasBone(hashName, id);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Bone::HasBone(const UInt_64 hashName) const
|
||||
{
|
||||
if (this->hashName == hashName)
|
||||
return true;
|
||||
|
||||
bool result = false;
|
||||
|
||||
for (UInt_64 i = 0; i < children.Size(); ++i)
|
||||
result = children[i].HasBone(hashName);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Bone::HasBone(const UInt_8 id) const
|
||||
{
|
||||
if (this->id == id)
|
||||
return true;
|
||||
|
||||
bool result = false;
|
||||
|
||||
for (UInt_64 i = 0; i < children.Size(); ++i)
|
||||
result = children[i].HasBone(id);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Bone::AddBone(Bone child)
|
||||
{
|
||||
if (HasBone(child.hashName, child.id))
|
||||
return false;
|
||||
|
||||
children.Push(std::move(child));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const Bone* Bone::GetBone(const UInt_64 hashName) const
|
||||
{
|
||||
if (this->hashName == hashName)
|
||||
return this;
|
||||
|
||||
const Bone* result = nullptr;
|
||||
|
||||
for (UInt_64 i = 0; i < children.Size(); ++i)
|
||||
result = children[i].GetBone(hashName);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Bone* Bone::GetBone(const UInt_64 hashName)
|
||||
{
|
||||
if (this->hashName == hashName)
|
||||
return this;
|
||||
|
||||
Bone* result = nullptr;
|
||||
|
||||
for (UInt_64 i = 0; i < children.Size(); ++i)
|
||||
result = children[i].GetBone(hashName);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const Bone* Bone::GetBone(const UInt_8 id) const
|
||||
{
|
||||
if (this->id == id)
|
||||
return this;
|
||||
|
||||
const Bone* result = nullptr;
|
||||
|
||||
for (UInt_64 i = 0; i < children.Size(); ++i)
|
||||
result = children[i].GetBone(id);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Bone* Bone::GetBone(const UInt_8 id)
|
||||
{
|
||||
if (this->id == id)
|
||||
return this;
|
||||
|
||||
Bone* result = nullptr;
|
||||
|
||||
for (UInt_64 i = 0; i < children.Size(); ++i)
|
||||
result = children[i].GetBone(id);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const Array<Bone>& Bone::GetChildren() const
|
||||
{
|
||||
return children;
|
||||
}
|
||||
|
||||
Array<Bone>& Bone::GetChildren()
|
||||
{
|
||||
return children;
|
||||
}
|
||||
}
|
102
src/io/model/KeyFrame.cpp
Normal file
102
src/io/model/KeyFrame.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "ehs/io/model/KeyFrame.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
KeyFrame::KeyFrame()
|
||||
: num(0.0f), timeStamp(0.0f), scale(1.0f), trans(Mat4_f::Identity())
|
||||
{
|
||||
}
|
||||
|
||||
KeyFrame::KeyFrame(const float num, const float timeStamp, const Vec3_f& pos, const Quat_f& rot, const Vec3_f& scale)
|
||||
: num(num), timeStamp(timeStamp), pos(pos), rot(rot), scale(scale),
|
||||
trans(Mat4_f::Translate(pos) * rot.ToMatrix() * Mat4_f::Scale(scale))
|
||||
{
|
||||
}
|
||||
|
||||
KeyFrame::KeyFrame(const float num, const float timeStamp)
|
||||
: num(num), timeStamp(timeStamp), scale(1.0f), trans(Mat4_f::Identity())
|
||||
{
|
||||
}
|
||||
|
||||
KeyFrame::KeyFrame(const KeyFrame& kf)
|
||||
: num(kf.num), timeStamp(kf.timeStamp), pos(kf.pos), rot(kf.rot), scale(kf.scale), trans(kf.trans)
|
||||
{
|
||||
}
|
||||
|
||||
KeyFrame& KeyFrame::operator=(const KeyFrame& kf)
|
||||
{
|
||||
if (this == &kf)
|
||||
return *this;
|
||||
|
||||
num = kf.num;
|
||||
timeStamp = kf.timeStamp;
|
||||
pos = kf.pos;
|
||||
rot = kf.rot;
|
||||
scale = kf.scale;
|
||||
trans = kf.trans;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
float KeyFrame::GetNum() const
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
float KeyFrame::GetTimeStamp() const
|
||||
{
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
void KeyFrame::SetPos(const Vec3_f& newPos)
|
||||
{
|
||||
pos = newPos;
|
||||
}
|
||||
|
||||
Vec3_f KeyFrame::GetPos() const
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
void KeyFrame::SetRot(const Quat_f& newRot)
|
||||
{
|
||||
rot = newRot;
|
||||
}
|
||||
|
||||
Quat_f KeyFrame::GetRot() const
|
||||
{
|
||||
return rot;
|
||||
}
|
||||
|
||||
void KeyFrame::SetScale(const Vec3_f& newScale)
|
||||
{
|
||||
scale = newScale;
|
||||
}
|
||||
|
||||
Vec3_f KeyFrame::GetScale() const
|
||||
{
|
||||
return scale;
|
||||
}
|
||||
|
||||
void KeyFrame::CalculateTransform()
|
||||
{
|
||||
trans = Mat4_f::Translate(pos) * rot.ToMatrix() * Mat4_f::Scale(scale);
|
||||
}
|
||||
|
||||
Mat4_f KeyFrame::GetTrans() const
|
||||
{
|
||||
return trans;
|
||||
}
|
||||
|
||||
Mat4_f KeyFrame::Interpolate(const KeyFrame& prev, const KeyFrame& next, const float percentage)
|
||||
{
|
||||
Vec3_f newPos = Vec3_f::Lerp(prev.pos, next.pos, percentage);
|
||||
Quat_f newRot = Quat_f::Slerp(prev.rot, next.rot, percentage).GetNormalized();
|
||||
Vec3_f newScale = Vec3_f::Lerp(prev.scale, next.scale, percentage);
|
||||
Mat4_f newTrans = Mat4_f::Translate(newPos) * newRot.ToMatrix() * Mat4_f::Scale(newScale);
|
||||
|
||||
return newTrans;
|
||||
}
|
||||
}
|
164
src/io/model/Mesh.cpp
Normal file
164
src/io/model/Mesh.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
#include "ehs/io/model/Mesh.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Mesh::Mesh()
|
||||
: hashId(0)
|
||||
{
|
||||
AddType("Mesh");
|
||||
}
|
||||
|
||||
Mesh::Mesh(Str_8 id, Array<Vertex_f> vertices, Array<UInt_32> indices)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), vertices((Array<Vertex_f>&&)vertices),
|
||||
indices((Array<UInt_32>&&)indices)
|
||||
{
|
||||
AddType("Mesh");
|
||||
}
|
||||
|
||||
Mesh::Mesh(Str_8 id, Array<Vertex_f> vertices)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), vertices((Array<Vertex_f>&&)vertices)
|
||||
{
|
||||
AddType("Mesh");
|
||||
}
|
||||
|
||||
Mesh::Mesh(Mesh&& mesh) noexcept
|
||||
: BaseObj((BaseObj&&)mesh), hashId(mesh.hashId), id((Str_8&&)mesh.id), vertices((Array<Vertex_f>&&)mesh.vertices),
|
||||
indices((Array<UInt_32>&&)mesh.indices)
|
||||
{
|
||||
mesh.hashId = 0;
|
||||
}
|
||||
|
||||
Mesh::Mesh(const Mesh& mesh)
|
||||
: BaseObj((BaseObj&&)mesh), hashId(mesh.hashId), id(mesh.id), vertices(mesh.vertices), indices(mesh.indices)
|
||||
{
|
||||
}
|
||||
|
||||
Mesh& Mesh::operator=(Mesh&& mesh) noexcept
|
||||
{
|
||||
if (this == &mesh)
|
||||
return *this;
|
||||
|
||||
BaseObj::operator=((BaseObj&&)mesh);
|
||||
|
||||
hashId = mesh.hashId;
|
||||
id = (Str_8&&)mesh.id;
|
||||
vertices = (Array<Vertex_f>&&)mesh.vertices;
|
||||
indices = (Array<UInt_32>&&)mesh.indices;
|
||||
|
||||
mesh.hashId = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Mesh& Mesh::operator=(const Mesh& mesh)
|
||||
{
|
||||
if (this == &mesh)
|
||||
return *this;
|
||||
|
||||
BaseObj::operator=(mesh);
|
||||
|
||||
hashId = mesh.hashId;
|
||||
id = mesh.id;
|
||||
vertices = mesh.vertices;
|
||||
indices = mesh.indices;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Mesh::Release()
|
||||
{
|
||||
vertices.Clear();
|
||||
indices.Clear();
|
||||
}
|
||||
|
||||
UInt_64 Mesh::GetHashId() const
|
||||
{
|
||||
return hashId;
|
||||
}
|
||||
|
||||
void Mesh::SetId(Str_8 newId)
|
||||
{
|
||||
hashId = newId.Hash_64();
|
||||
id = (Str_8&&)newId;
|
||||
}
|
||||
|
||||
Str_8 Mesh::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
void Mesh::SetVertices(const Array<Vertex_f>& newVertices)
|
||||
{
|
||||
vertices = newVertices;
|
||||
}
|
||||
|
||||
const Array<Vertex_f>& Mesh::GetVertices() const
|
||||
{
|
||||
return vertices;
|
||||
}
|
||||
|
||||
Array<Vertex_f>& Mesh::GetVertices()
|
||||
{
|
||||
return vertices;
|
||||
}
|
||||
|
||||
void Mesh::SetIndices(const Array<UInt_32>& newIndices)
|
||||
{
|
||||
indices = newIndices;
|
||||
}
|
||||
|
||||
bool Mesh::HasIndices() const
|
||||
{
|
||||
return indices.Size();
|
||||
}
|
||||
|
||||
const Array<UInt_32>& Mesh::GetIndices() const
|
||||
{
|
||||
return indices;
|
||||
}
|
||||
|
||||
Array<UInt_32>& Mesh::GetIndices()
|
||||
{
|
||||
return indices;
|
||||
}
|
||||
|
||||
void Mesh::Calculate()
|
||||
{
|
||||
if (indices.Size())
|
||||
for (UInt_64 i = 0; i < indices.Size(); i += 3)
|
||||
Calculate(vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]]);
|
||||
else
|
||||
for (UInt_64 i = 0; i < vertices.Size(); i += 3)
|
||||
Calculate(vertices[i], vertices[i + 1], vertices[i + 2]);
|
||||
}
|
||||
|
||||
void Mesh::Calculate(Vertex_f& vert1, Vertex_f& vert2, Vertex_f& vert3)
|
||||
{
|
||||
Vec3_f edge1 = vert2.pos - vert1.pos;
|
||||
Vec3_f edge2 = vert3.pos - vert1.pos;
|
||||
Vec2_f deltaUV1 = vert2.uv - vert1.uv;
|
||||
Vec2_f deltaUV2 = vert3.uv - vert1.uv;
|
||||
|
||||
float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
|
||||
|
||||
Vec3_f tan(
|
||||
f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x),
|
||||
f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y),
|
||||
f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z)
|
||||
);
|
||||
|
||||
vert1.tan = tan;
|
||||
vert2.tan = tan;
|
||||
vert3.tan = tan;
|
||||
|
||||
Vec3_f bTan(
|
||||
f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x),
|
||||
f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y),
|
||||
f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z)
|
||||
);
|
||||
|
||||
vert1.bTan = bTan;
|
||||
vert2.bTan = bTan;
|
||||
vert3.bTan = bTan;
|
||||
}
|
||||
}
|
275
src/io/model/Model.cpp
Normal file
275
src/io/model/Model.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
#include "ehs/io/model/Model.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
Model::Model()
|
||||
: hashId(0)
|
||||
{
|
||||
AddType("Model");
|
||||
}
|
||||
|
||||
Model::Model(const Str_8& filePath)
|
||||
{
|
||||
AddType("Model");
|
||||
|
||||
File file(filePath, Mode::READ, Disposition::OPEN);
|
||||
|
||||
hashId = file.GetName().Hash_64();
|
||||
id = file.GetName();
|
||||
|
||||
if (file.GetExtension() == "ehm")
|
||||
{
|
||||
FromEHM(file);
|
||||
}
|
||||
}
|
||||
|
||||
Model::Model(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");
|
||||
}
|
||||
|
||||
Model::Model(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");
|
||||
}
|
||||
|
||||
Model::Model(Str_8 id, Array<Mesh> meshes)
|
||||
: hashId(id.Hash_64()), id((Str_8&&)id), meshes((Array<Mesh>&&)meshes)
|
||||
{
|
||||
AddType("Model");
|
||||
}
|
||||
|
||||
Model::Model(Model&& 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
|
||||
{
|
||||
if (this == &model)
|
||||
return *this;
|
||||
|
||||
BaseObj::operator=((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.hashId = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Model::Release()
|
||||
{
|
||||
meshes.Clear();
|
||||
skeleton = {};
|
||||
animations.Clear();
|
||||
}
|
||||
|
||||
UInt_64 Model::GetHashId() const
|
||||
{
|
||||
return hashId;
|
||||
}
|
||||
|
||||
void Model::SetId(Str_8 newId)
|
||||
{
|
||||
hashId = newId.Hash_64();
|
||||
id = (Str_8&&)newId;
|
||||
}
|
||||
|
||||
Str_8 Model::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
const Array<Mesh>& Model::GetMeshes() const
|
||||
{
|
||||
return meshes;
|
||||
}
|
||||
|
||||
Array<Mesh>& Model::GetMeshes()
|
||||
{
|
||||
return meshes;
|
||||
}
|
||||
|
||||
Mesh* Model::GetMesh(const UInt_64 inHashId)
|
||||
{
|
||||
for (UInt_64 i = 0; i < meshes.Size(); ++i)
|
||||
if (meshes[i].GetHashId() == inHashId)
|
||||
return &meshes[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Mesh* Model::GetMesh(const Str_8& inId)
|
||||
{
|
||||
return GetMesh(inId.Hash_64());
|
||||
}
|
||||
|
||||
const Bone& Model::GetSkeleton() const
|
||||
{
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
Bone& Model::GetSkeleton()
|
||||
{
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
Animation* Model::GetAnimation(const UInt_64 inHashId)
|
||||
{
|
||||
for (UInt_64 i = 0; i < animations.Size(); ++i)
|
||||
if (animations[i].GetHashId() == inHashId)
|
||||
return &animations[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Array<Animation>& Model::GetAnimations() const
|
||||
{
|
||||
return animations;
|
||||
}
|
||||
|
||||
Array<Animation>& Model::GetAnimations()
|
||||
{
|
||||
return animations;
|
||||
}
|
||||
|
||||
void Model::Calculate()
|
||||
{
|
||||
for (UInt_64 i = 0; i < meshes.Size(); ++i)
|
||||
meshes[i].Calculate();
|
||||
}
|
||||
|
||||
void Model::Export(const Str_8& filePath, const ModelEncoding encoding)
|
||||
{
|
||||
File file(filePath, Mode::WRITE, Disposition::OPEN_PERSISTENT);
|
||||
|
||||
switch (encoding)
|
||||
{
|
||||
case ModelEncoding::EHM:
|
||||
{
|
||||
ToEHM(file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Model::ToEHM(File& file)
|
||||
{
|
||||
Serializer<UInt_64> data(Endianness::LE);
|
||||
data.WriteVersion({1, 0, 0});
|
||||
data.Write<UInt_64>(meshes.Size());
|
||||
|
||||
for (UInt_64 i = 0; i < meshes.Size(); ++i)
|
||||
{
|
||||
data.WriteStr(meshes[i].GetId());
|
||||
|
||||
Array<Vertex_f> vertices = meshes[i].GetVertices();
|
||||
|
||||
data.Write<UInt_64>(vertices.Size());
|
||||
|
||||
for (UInt_64 v = 0; v < vertices.Size(); ++v)
|
||||
{
|
||||
data.WriteVec3(vertices[v].pos);
|
||||
data.WriteVec3(vertices[v].normal);
|
||||
data.WriteVec2(vertices[v].uv);
|
||||
}
|
||||
}
|
||||
|
||||
file.WriteSerializer_64(data);
|
||||
file.Truncate(data.Size());
|
||||
}
|
||||
|
||||
void Model::FromEHM(File& file)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
meshes.Resize(data.Read<UInt_64>());
|
||||
for (UInt_64 i = 0; i < meshes.Size(); ++i)
|
||||
{
|
||||
meshes[i].SetId(data.ReadStr<Char_8, UInt_64>());
|
||||
|
||||
Array<Vertex_f>& vertices = meshes[i].GetVertices();
|
||||
vertices.Resize(data.Read<UInt_64>());
|
||||
|
||||
for (UInt_64 v = 0; v < vertices.Size(); ++v)
|
||||
{
|
||||
vertices[v].pos = data.ReadVec3<float>();
|
||||
vertices[v].normal = data.ReadVec3<float>();
|
||||
vertices[v].uv = data.ReadVec2<float>();
|
||||
vertices[v].bones = data.ReadVec4<UInt_8>();
|
||||
vertices[v].weights = data.ReadVec4<float>();
|
||||
}
|
||||
|
||||
meshes[i].SetIndices(data.ReadArray<UInt_32, UInt_64>());
|
||||
|
||||
UInt_8 boneCount = data.Read<UInt_8>();
|
||||
for (UInt_8 b = 0; b < boneCount; ++b)
|
||||
{
|
||||
Str_8 name = data.ReadStr<Char_8, UInt_64>();
|
||||
UInt_8 parentId = data.Read<UInt_8>();
|
||||
Mat4_f localBindTrans = data.ReadMat4<float>();
|
||||
Mat4_f invBindTrans = data.ReadMat4<float>();
|
||||
if (b == 0)
|
||||
{
|
||||
skeleton = {name, b, localBindTrans, invBindTrans};
|
||||
}
|
||||
else
|
||||
{
|
||||
Bone* parent = skeleton.GetBone(parentId);
|
||||
if (!parent)
|
||||
{
|
||||
EHS_LOG_INT("Error", 0, "Invalid bone order.");
|
||||
return;
|
||||
}
|
||||
|
||||
parent->AddBone({name, b, localBindTrans, invBindTrans});
|
||||
}
|
||||
}
|
||||
|
||||
animations = Array<Animation>(data.Read<UInt_64>());
|
||||
for (UInt_64 a = 0; a < animations.Size(); ++a)
|
||||
{
|
||||
Str_8 animId = data.ReadStr<Char_8, UInt_64>();
|
||||
float duration = data.Read<float>();
|
||||
|
||||
animations[a] = Animation(animId, duration, data.Read<UInt_8>());
|
||||
Array<AnimBone>& animated = animations[a].GetAnimated();
|
||||
for (UInt_8 ba = 0; ba < (UInt_8)animated.Size(); ++ba)
|
||||
{
|
||||
UInt_8 boneId = data.Read<UInt_8>();
|
||||
|
||||
animated[ba] = AnimBone(boneId, data.Read<UInt_64>());
|
||||
Array<KeyFrame>& keyFrames = animated[ba].GetKeyFrames();
|
||||
for (UInt_64 kf = 0; kf < keyFrames.Size(); ++kf)
|
||||
{
|
||||
float num = data.Read<float>();
|
||||
float timeStamp = data.Read<float>();
|
||||
Vec3_f pos = data.ReadVec3<float>();
|
||||
Quat_f rot = data.ReadQuat<float>();
|
||||
Vec3_f scale = data.ReadVec3<float>();
|
||||
|
||||
keyFrames[kf] = KeyFrame(num, timeStamp, pos, rot, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
src/io/model/PropertyChange.cpp
Normal file
14
src/io/model/PropertyChange.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "ehs/io/model/PropertyChange.h"
|
||||
|
||||
namespace ehs
|
||||
{
|
||||
PropertyChange::PropertyChange()
|
||||
: type(ChangeType::INVALID), value(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyChange::PropertyChange(const ChangeType type, const float value)
|
||||
: type(type), value(value)
|
||||
{
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user