mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-21 00:59:13 +00:00
Implement CVertexMorphEffect & CSkinnedModelWithAvgNormals (prev. CMorphableSkinnedModel)
This commit is contained in:
@@ -1,15 +1,46 @@
|
||||
#include "Runtime/Graphics/CVertexMorphEffect.hpp"
|
||||
|
||||
#include "Runtime/Character/CSkinRules.hpp"
|
||||
#include "Runtime/Graphics/CSkinnedModel.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
|
||||
CVertexMorphEffect::CVertexMorphEffect(const zeus::CUnitVector3f& v1, const zeus::CVector3f& v2, float diagExtent,
|
||||
float f2, CRandom16& random)
|
||||
: x0_(v1), x20_diagExtent(diagExtent), x24_random(random) {}
|
||||
CVertexMorphEffect::CVertexMorphEffect(const zeus::CUnitVector3f& dir, const zeus::CVector3f& pos, float duration,
|
||||
float diagExtent, CRandom16& random)
|
||||
: x0_dir(dir), xc_pos(pos), x18_duration(duration), x20_diagExtent(diagExtent), x24_random(random) {}
|
||||
|
||||
void CVertexMorphEffect::MorphVertices(SSkinningWorkspace& workspace, TConstVectorRef magnitudes,
|
||||
const TLockedToken<CSkinRules>& skinRules, const CPoseAsTransforms& pose) const {
|
||||
void CVertexMorphEffect::MorphVertices(SSkinningWorkspace& workspace, TConstVectorRef averagedNormals,
|
||||
TLockedToken<CSkinRules>& skinRules, const CPoseAsTransforms& pose,
|
||||
u32 vertexCount) {
|
||||
if (x28_indices.empty()) {
|
||||
std::vector<zeus::CVector3f> normalsOut;
|
||||
normalsOut.reserve(vertexCount);
|
||||
skinRules->BuildNormals(averagedNormals, &normalsOut);
|
||||
for (int i = 0; i < vertexCount; ++i) {
|
||||
float dist = normalsOut[i].dot(x0_dir);
|
||||
if (dist > 0.5f) {
|
||||
x28_indices.emplace_back(i);
|
||||
const auto vert = workspace.m_vertexWorkspace[i];
|
||||
const auto length = vert.x() + vert.y() + vert.z();
|
||||
x38_floats.emplace_back((length - std::trunc(length)) * (dist - 0.5f));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < x28_indices.size(); ++i) {
|
||||
const auto scale = x1c_elapsed / x18_duration;
|
||||
workspace.m_vertexWorkspace[x28_indices[i]] += scale * x20_diagExtent * x38_floats[i] * x0_dir;
|
||||
}
|
||||
}
|
||||
|
||||
void CVertexMorphEffect::Reset(const zeus::CVector3f& dir, const zeus::CVector3f& pos, float duration) {
|
||||
x0_dir = dir;
|
||||
xc_pos = pos;
|
||||
x18_duration = duration;
|
||||
x1c_elapsed = 0.f;
|
||||
x28_indices.clear();
|
||||
x38_floats.clear();
|
||||
}
|
||||
|
||||
void CVertexMorphEffect::Update(float dt) { x1c_elapsed = std::min(x1c_elapsed + dt, x18_duration); }
|
||||
|
||||
} // namespace metaforce
|
||||
|
||||
Reference in New Issue
Block a user