128 lines
2.6 KiB
C++
128 lines
2.6 KiB
C++
#include "dl_model_data.h"
|
|
|
|
#include "vk/dl_vk.h"
|
|
|
|
namespace dl
|
|
{
|
|
|
|
dl::Matrix4 ModelNode::Runtime::GetMatrixLocal()
|
|
{
|
|
if (_bNeedUpdateMatrixLocal)
|
|
{
|
|
_matLocal = _trans2Parent.GetMatrix();
|
|
}
|
|
return _matLocal;
|
|
}
|
|
|
|
dl::Matrix4 ModelNode::Runtime::GetMatrixWorld(ModelNode* node)
|
|
{
|
|
if (_bNeedUpdateMatrixWorld)
|
|
{
|
|
Matrix4 mat = GetMatrixLocal();
|
|
ModelNode* p = node;
|
|
while (p)
|
|
{
|
|
mat = p->_rt.GetMatrixLocal() * mat;
|
|
p = p->_parent;
|
|
}
|
|
_matWorld = mat;
|
|
_bNeedUpdateMatrixWorld = false;
|
|
return mat;
|
|
}
|
|
else
|
|
{
|
|
return _matWorld;
|
|
}
|
|
}
|
|
|
|
void ModelNode::Update()
|
|
{
|
|
_rt._bNeedUpdateMatrixWorld = true;
|
|
if (_mesh)
|
|
{
|
|
ModelMesh::Runtime& rt_mesh = _mesh->_rt;
|
|
Matrix4 mat = GetMatrixWorld();
|
|
if (_skin)
|
|
{
|
|
rt_mesh._mat = mat;
|
|
// Update join matrices
|
|
Matrix4 mat_mesh_inv = Mat::GetInverse(mat);
|
|
|
|
size_t num_joint = std::min(_skin->_allJoint.size(), NUM_MAX_JOINT);
|
|
rt_mesh._allMatJoint.resize(num_joint);
|
|
for (size_t i = 0; i < num_joint; ++i)
|
|
{
|
|
ModelNode* node_joint = _skin->_allJoint[i];
|
|
Matrix4 mat_joint = node_joint->GetMatrixWorld() * _skin->_allOffsetMatrix[i];
|
|
mat_joint = mat_mesh_inv * mat_joint;
|
|
rt_mesh._allMatJoint[i] = mat_joint;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rt_mesh._allMatJoint.resize(1);
|
|
rt_mesh._allMatJoint[0] = mat;
|
|
}
|
|
}
|
|
|
|
for (ModelNode* node : _allChild)
|
|
{
|
|
node->Update();
|
|
}
|
|
}
|
|
|
|
void ModelData::Update()
|
|
{
|
|
if (_allAnimation.empty())
|
|
{
|
|
log_warn("模型没有动画!");
|
|
return;
|
|
}
|
|
ModelAnimation& ani = _allAnimation[_rt._curAni];
|
|
|
|
bool updated = false;
|
|
for (ModelAnimationChannel& channel : ani._allChannel)
|
|
{
|
|
ModelAnimationSampler& sampler = ani._allSampler[channel.samplerIndex];
|
|
if (sampler.inputs.size() > sampler.outputsVec4.size())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
float time = _rt._t;
|
|
for (size_t i = 0; i < sampler.inputs.size() - 1; i++)
|
|
{
|
|
if (time >= sampler.inputs[i]
|
|
&& time <= sampler.inputs[i + 1])
|
|
{
|
|
float u = std::max(0.0f, time - sampler.inputs[i])
|
|
/ (sampler.inputs[i + 1] - sampler.inputs[i]);
|
|
if (u <= 1.0f)
|
|
{
|
|
switch (channel.path)
|
|
{
|
|
case ModelAnimationChannel::PathType::TRANSLATION:
|
|
sampler.translate(i, time, channel.node);
|
|
break;
|
|
case ModelAnimationChannel::PathType::SCALE:
|
|
sampler.scale(i, time, channel.node);
|
|
break;
|
|
case ModelAnimationChannel::PathType::ROTATION:
|
|
sampler.rotate(i, time, channel.node);
|
|
break;
|
|
}
|
|
updated = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (updated)
|
|
{
|
|
for (ModelNode* node : _allNode)
|
|
{
|
|
node->Update();
|
|
}
|
|
}
|
|
}
|
|
|
|
} |