Files
dl_old/dl/render/dl_model_data.cpp
T
2026-04-13 20:50:46 +08:00

215 lines
5.2 KiB
C++

#include "dl_model_data.h"
#ifndef DL_DISABLE_RENDER
#include "vk/dl_vk.h"
namespace dl
{
dl::Matrix4 ModelNodeRt::GetMatrixLocal()
{
if (_bNeedUpdateMatrixLocal)
{
_matLocal = _trans2Parent.GetMatrix();
}
return _matLocal;
}
dl::Matrix4 ModelNodeRt::GetMatrixWorld()
{
if (_bNeedUpdateMatrixWorld)
{
Matrix4 mat = GetMatrixLocal();
ModelNodeRt* p = this;
while (p)
{
mat = p->GetMatrixLocal() * mat;
auto parent = p->_node->GetParent();
if(!parent)
break;
p = parent->GetValue();
}
_matWorld = mat;
_bNeedUpdateMatrixWorld = false;
return mat;
}
else
{
return _matWorld;
}
}
void ModelNodeRt::Update(const std::vector<ModelSkin*>& all_skin)
{
_bNeedUpdateMatrixWorld = true;
Matrix4 mat = GetMatrixWorld();
if (_indexSkin != -1)
{
ModelSkin* skin = all_skin[_indexSkin];
Matrix4 mat_mesh_inv = Mat::GetInverse(mat);
Matrix4 mat_joint = GetMatrixWorld() * skin->_allOffsetMatrix[_index];
_mat = mat_mesh_inv * mat_joint;
}
else
_mat = mat;
}
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;
q1[0] = outputsVec4[index][0];
q1[1] = outputsVec4[index][1];
q1[2] = outputsVec4[index][2];
q1[3] = outputsVec4[index][3];
Position4 q2;
q2[0] = outputsVec4[index + 1][0];
q2[1] = outputsVec4[index + 1][1];
q2[2] = outputsVec4[index + 1][2];
q2[3] = outputsVec4[index + 1][3];
node->_trans2Parent._r = Math::Normalize(Math::Slerp(q1, q2, u));
break;
}
case ModelAnimationSampler::InterpolationType::STEP:
{
Position4 q1;
q1[0] = outputsVec4[index][0];
q1[1] = outputsVec4[index][1];
q1[2] = outputsVec4[index][2];
q1[3] = outputsVec4[index][3];
node->_trans2Parent._r = q1;
break;
}
case ModelAnimationSampler::InterpolationType::CUBICSPLINE:
{
Position4 rot = cubicSplineInterpolation(index, time, 4);
Position4 q;
q[0] = rot[0];
q[1] = rot[1];
q[2] = rot[2];
q[3] = rot[3];
node->_trans2Parent._r = Math::Normalize(dl::as_const(q));
break;
}
}
}
}
#endif