Files
dl_old/dl/render/dl_model_object.cpp
T

194 lines
3.9 KiB
C++

#include "dl_model_loader.h" // Android dl_concept.h 宏名字冲突需要前置
#ifndef DL_DISABLE_RENDER
#include "io/dl_log.h"
#include "render/dl_model.h"
#include "render/dl_model_object.h"
namespace dl
{
std::vector<ModelObject*> ModelObject::Create(std::string_view path_name, std::string_view res_name)
{
std::vector<ModelObject*> ret = g_modelLoader->Load(path_name, res_name);
if (ret.empty())
{
log_err("模型加载失败:{}", path_name);
return {};
}
return ret;
}
void ModelObject::Load(std::string_view path_name)
{
StreamInput s;
if (!s.LoadFromFile(path_name, true))
{
log_warn("文件加载失败:{}", path_name );
return;
}
{
s.ReadSize(&_treeNode);
for (size_t i = 0; i < _treeNode.size(); ++i)
_treeNode[i].Load(s);
}
s.Read(&_treeNodeParent);
s.Read(&_allVertex);
s.Read(&_allVertexBone);
s.Read(&_allIndex);
{
s.ReadSize(&_allMaterial);
for (size_t i = 0; i < _allMaterial.size(); ++i)
_allMaterial[i].Load(s);
}
{
s.ReadSize(&_allAnimation);
for (size_t i = 0; i < _allAnimation.size(); ++i)
_allAnimation[i].Load(s);
}
{
s.ReadSize(&_allSkin);
for (size_t i = 0; i < _allSkin.size(); ++i)
_allSkin[i].Load(s);
}
s.Read(&_allSub);
}
void ModelObject::SaveToFile(std::string_view path_name)
{
StreamOutput s;
{
s.WriteSize(&_treeNode);
for (size_t i = 0; i < _treeNode.size(); ++i)
_treeNode[i].Save(s);
}
s.Write(&_treeNodeParent);
s.Write(&_allVertex);
s.Write(&_allVertexBone);
s.Write(&_allIndex);
{
s.WriteSize(&_allMaterial);
for (size_t i = 0; i < _allMaterial.size(); ++i)
_allMaterial[i].Save(s);
}
{
s.WriteSize(&_allAnimation);
for (size_t i = 0; i < _allAnimation.size(); ++i)
_allAnimation[i].Save(s);
}
{
s.WriteSize(&_allSkin);
for (size_t i = 0; i < _allSkin.size(); ++i)
_allSkin[i].Save(s);
}
s.Write(&_allSub);
s.Save(path_name, true);
}
void ModelAnimationInstance::Update(FloatTime dt)
{
if (_indexAni >= _model->_allAnimation.size())
{
log_warn("动画下标越界!");
return;
}
_t += dt;
const ModelAnimation& ani = _model->_allAnimation[_indexAni];
if (_t > ani.end)
{
_t = 0;
}
// 动画插值(操作动画控制的节点)
bool updated = false;
for (const ModelAnimationChannel& channel : ani._allChannel)
{
ModelNodeRt* node = GetNode(channel.indexNode);
const ModelAnimationSampler& sampler = ani._allSampler[channel.samplerIndex];
if (sampler.inputs.size() > sampler.outputsVec4.size())
{
continue;
}
float time = _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, node);
break;
case ModelAnimationChannel::PathType::SCALE:
sampler.scale(i, time, node);
break;
case ModelAnimationChannel::PathType::ROTATION:
sampler.rotate(i, time, node);
break;
}
updated = true;
}
}
}
}
// 节点树更新
if (updated)
{
UpdateNode();
}
}
void ModelAnimationInstance::Set(size_t i, float t)
{
if (i >= _model->_allAnimation.size())
{
log_warn("动画下标越界:{}/{}", i, _model->_allAnimation.size());
return;
}
_indexAni = i;
_t = t;
}
void ModelAnimationInstance::Set(std::string_view name, float t)
{
for (size_t i = 0; i < _model->_allAnimation.size(); ++i)
{
if (_model->_allAnimation[i]._name == name)
{
_indexAni = i;
_t = t;
return;
}
}
log_warn("未找到动画名:{}", name);
}
std::string ModelAnimationInstance::Get()
{
return _model->_allAnimation[_indexAni]._name;
}
void ModelAnimationInstance::UpdateNode()
{
for (size_t i = 0; i < _treeNode.size(); ++i)
{
ModelNodeRt& node = _treeNode[i];
node.Update(_model->_allSkin, this);
}
}
}
#endif