Files
dl_old/dl/render/dl_model_data.cpp
T

209 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "dl_model_data.h"
#ifndef DL_DISABLE_RENDER
#include "vk/dl_vk.h"
#include "dl_graphics.h"
namespace dl
{
dl::Matrix4 ModelNodeRt::GetMatrixLocal()
{
if (true || _bNeedUpdateMatrixLocal)
{
_matLocal = _trans2Parent.GetMatrix();
}
return _matLocal;
}
dl::Matrix4 ModelNodeRt::GetMatrixWorld(ModelAnimationInstance* instance)
{
if (_bNeedUpdateMatrixWorld)
{
Matrix4 mat = GetMatrixLocal();
ModelNodeRt* parent = instance->GetNode(_indexParent);
while (parent)
{
mat = parent->GetMatrixLocal() * mat;
parent = instance->GetNode(parent->_indexParent);
}
_matWorld = mat;
_bNeedUpdateMatrixWorld = false;
return _matWorld;
}
else
{
return _matWorld;
}
}
void ModelNodeRt::Update(const std::vector<ModelSkin>& all_skin,
ModelAnimationInstance* instance)
{
_bNeedUpdateMatrixWorld = true;
Matrix4 mat = GetMatrixWorld(instance);
if (_indexSkin != -1)
{
Matrix4 mat_inv = Mat::GetInverse(mat);
const ModelSkin& skin = all_skin[_indexSkin];
// 处理所有影响的节点
size_t num_joint = std::min(skin._allJoint.size(), NUM_MAX_BONE);
for (size_t i = 0; i < num_joint; ++i)
{
int index = skin._allJoint[i];
ModelNodeRt* node_joint = instance->GetNode(index);
Matrix4 mat_joint =
mat_inv * node_joint->GetMatrixWorld(instance) * skin._allOffsetMatrix[i];
instance->_finalTrans[i] = mat_joint;
}
}
// Offset Matrix = 骨骼在绑定姿势下的世界矩阵的逆矩阵
// 1.模型空间(T-pose) -> 骨骼空间
// 2.骨骼空间 -> 世界空间
}
BoundingBox::BoundingBox()
{
}
BoundingBox::BoundingBox(Position3 imin, Position3 imax):
min{imin},
max{imax}
{
}
BoundingBox BoundingBox::getAABB(Matrix4 m)
{
Position3 min = toShorter(m[3]);
Position3 max = min;
Position3 v0, v1;
Position3 right = toShorter(m[0]);
v0 = right * this->min[0];
v1 = right * this->max[0];
min += Each::Min(v0, v1);
max += Each::Max(v0, v1);
Position3 up = toShorter(m[1]);
v0 = up * this->min[1];
v1 = up * this->max[1];
min += Each::Min(v0, v1);
max += Each::Max(v0, v1);
Position3 back = toShorter(m[2]);
v0 = back * this->min[2];
v1 = back * this->max[2];
min += Each::Min(v0, v1);
max += Each::Max(v0, v1);
return BoundingBox(min, max);
}
dl::Position4 ModelAnimationSampler::cubicSplineInterpolation(size_t index, float time, uint32_t stride) const
{
float delta = inputs[index + 1] - inputs[index];
float t = (time - inputs[index]) / delta;
const size_t current = index * stride * 3;
const size_t next = (index + 1) * stride * 3;
const size_t A = 0;
const size_t V = stride * 1;
const size_t B = stride * 2;
float t2 = powf(t, 2);
float t3 = powf(t, 3);
Position4 pt{};
for (uint32_t i = 0; i < stride; i++) {
float p0 = outputs[current + i + V]; // starting point at t = 0
float m0 = delta * outputs[current + i + A]; // scaled starting tangent at t = 0
float p1 = outputs[next + i + V]; // ending point at t = 1
float m1 = delta * outputs[next + i + B]; // scaled ending tangent at t = 1
pt[i] = ((2.f * t3 - 3.f * t2 + 1.f) * p0) + ((t3 - 2.f * t2 + t) * m0) + ((-2.f * t3 + 3.f * t2) * p1) + ((t3 - t2) * m0);
}
return pt;
}
void ModelAnimationSampler::translate(size_t index, float time, ModelNodeRt* node) const
{
switch (interpolation)
{
case ModelAnimationSampler::InterpolationType::LINEAR:
{
float u = std::max(0.0f, time - inputs[index]) / (inputs[index + 1] - inputs[index]);
node->_trans2Parent._t = toShorter(
Each::Lerp(outputsVec4[index], outputsVec4[index + 1], u));
break;
}
case ModelAnimationSampler::InterpolationType::STEP:
{
node->_trans2Parent._t = toShorter(outputsVec4[index]);
break;
}
case ModelAnimationSampler::InterpolationType::CUBICSPLINE:
{
node->_trans2Parent._t = toShorter(cubicSplineInterpolation(index, time, 3));
break;
}
}
}
void ModelAnimationSampler::scale(size_t index, float time, ModelNodeRt* node) const
{
switch (interpolation)
{
case ModelAnimationSampler::InterpolationType::LINEAR:
{
float u = std::max(0.0f, time - inputs[index]) / (inputs[index + 1] - inputs[index]);
node->_trans2Parent._s = toShorter(
Each::Lerp(outputsVec4[index], outputsVec4[index + 1], u));
break;
}
case ModelAnimationSampler::InterpolationType::STEP:
{
node->_trans2Parent._s = toShorter(outputsVec4[index]);
break;
}
case ModelAnimationSampler::InterpolationType::CUBICSPLINE:
{
node->_trans2Parent._s = toShorter(cubicSplineInterpolation(index, time, 3));
break;
}
}
}
void ModelAnimationSampler::rotate(size_t index, float time, ModelNodeRt* node) const
{
switch (interpolation)
{
case ModelAnimationSampler::InterpolationType::LINEAR:
{
float u = std::max(0.0f, time - inputs[index]) / (inputs[index + 1] - inputs[index]);
Position4 q1 = outputsVec4[index];
Position4 q2 = outputsVec4[index + 1];
node->_trans2Parent._r = Math::Normalize(Math::Slerp(q1, q2, u));
break;
}
case ModelAnimationSampler::InterpolationType::STEP:
{
Position4 q1 = outputsVec4[index];
node->_trans2Parent._r = q1;
break;
}
case ModelAnimationSampler::InterpolationType::CUBICSPLINE:
{
Position4 rot = cubicSplineInterpolation(index, time, 4);
Position4 q = rot;
node->_trans2Parent._r = Math::Normalize(dl::as_const(q));
break;
}
}
}
}
#endif