Files
dl_old/dl/render/dl_model_data.cpp
T
2024-08-31 11:25:02 +08:00

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();
}
}
}
}