Decompile 3 functions in Source/Contents/Models/ModelAnimation.cpp, Source/Contents/Models/ModelAnimation.h, ...
Batch #12238 by Yommy: 0 byte-identical, 3 confirmed by peer review. - fn_01721 SampleLegacyPosition: logic confirmed by peer review - fn_01722 SampleModelPosition: logic confirmed by peer review - fn_01723 SampleLegacyRotation: logic confirmed by peer review Peer-reviewed-by: KWDev, Toshiro, cremane Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
This commit is contained in:
parent
e78cdd3cee
commit
dd95a31022
2 changed files with 113 additions and 69 deletions
|
|
@ -24,51 +24,60 @@ namespace {
|
|||
|
||||
// OFFSET: 0x00540370
|
||||
// FUNCTION: fn_01721
|
||||
void SampleLegacyPosition(std::span<const ModelPositionKey> keys, int frame, matrix& output) {
|
||||
if (keys.empty()) {
|
||||
void SampleLegacyPosition(const std::vector<ModelPositionKey>& keys, int frame, matrix& output) {
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
output.Identity();
|
||||
} else if (keys.size() == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
output.MakeTranslate(keys[0].position[0], keys[0].position[1], keys[0].position[2]);
|
||||
} else {
|
||||
unsigned next = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
while (keys[next].frame <= frame) {
|
||||
if (++next >= keys.size()) {
|
||||
return;
|
||||
}
|
||||
for (unsigned next = 1; next < count; ++next) {
|
||||
if (keys[next].frame > frame) {
|
||||
const auto& a = keys[next - 1];
|
||||
const auto& b = keys[next];
|
||||
const float amount = static_cast<float>((frame - a.frame)) / static_cast<float>((b.frame - a.frame));
|
||||
const float previous = static_cast<float>(1.0 - static_cast<double>(amount));
|
||||
output.MakeTranslate(
|
||||
previous * a.position[0] + amount * b.position[0], previous * a.position[1] + amount * b.position[1], previous * a.position[2] + amount * b.position[2]
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& a = keys[next - 1];
|
||||
const auto& b = keys[next];
|
||||
const float amount = static_cast<float>((frame - a.frame)) / static_cast<float>((b.frame - a.frame));
|
||||
const float previous = static_cast<float>(1.0 - static_cast<double>(amount));
|
||||
output.MakeTranslate(
|
||||
previous * a.position[0] + amount * b.position[0], previous * a.position[1] + amount * b.position[1], previous * a.position[2] + amount * b.position[2]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00540670
|
||||
// FUNCTION: fn_01723
|
||||
void SampleLegacyRotation(std::span<const ModelRotationKey> keys, int frame, matrix& output) {
|
||||
if (keys.empty()) {
|
||||
void SampleLegacyRotation(const std::vector<ModelRotationKey>& keys, int frame, matrix& output) {
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
output.Identity();
|
||||
return;
|
||||
}
|
||||
|
||||
if (keys.size() == 1) {
|
||||
if (count == 1) {
|
||||
QuaternionMatrix(keys[0], output);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned next = 1;
|
||||
|
||||
while (keys[next].frame <= frame) {
|
||||
if (++next >= keys.size()) {
|
||||
return;
|
||||
for (; next < count; ++next) {
|
||||
if (keys[next].frame > frame) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (next >= count) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& a = keys[next - 1];
|
||||
const auto& b = keys[next];
|
||||
|
||||
|
|
@ -85,74 +94,99 @@ void SampleLegacyRotation(std::span<const ModelRotationKey> keys, int frame, mat
|
|||
|
||||
// OFFSET: 0x00540BF0
|
||||
// FUNCTION: fn_01725
|
||||
void SampleLegacyScale(std::span<const ModelScaleKey> keys, int, matrix& output) {
|
||||
if (keys.empty()) {
|
||||
void SampleLegacyScale(const std::vector<ModelScaleKey>& keys, int, matrix& output) {
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
output.Identity();
|
||||
} else if (keys.size() == 1) {
|
||||
} else if (count == 1) {
|
||||
output.SetScale(keys[0].scale[0], keys[0].scale[1], keys[0].scale[2]);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00540C60
|
||||
// FUNCTION: fn_01726
|
||||
void SampleModelScale(std::span<const ModelRotationKey> keys, float frame, matrix& output) {
|
||||
if (keys.empty()) {
|
||||
void SampleModelScale(const std::vector<ModelRotationKey>& keys, float frame, matrix& output) {
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
output.Identity();
|
||||
return;
|
||||
}
|
||||
|
||||
if (keys.size() == 1 || frame >= static_cast<float>(keys.back().frame)) {
|
||||
const auto& key = keys.size() == 1 ? keys[0] : keys.back();
|
||||
output.SetScale(key.rotation[0], key.rotation[1], key.rotation[2]);
|
||||
if (count == 1) {
|
||||
output.SetScale(keys[0].rotation[0], keys[0].rotation[1], keys[0].rotation[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned next = 0;
|
||||
const auto& last = keys[count - 1];
|
||||
|
||||
while (!(static_cast<float>(keys[next].frame) > frame)) {
|
||||
if (++next >= keys.size()) {
|
||||
output.SetScale(1, 1, 1);
|
||||
return;
|
||||
if (frame >= static_cast<float>(last.frame)) {
|
||||
output.SetScale(last.rotation[0], last.rotation[1], last.rotation[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
matrix scale;
|
||||
scale.Identity();
|
||||
ModelRotationKey first{0, {1, 1, 1, 1}};
|
||||
ModelRotationKey second{0, {1, 1, 1, 1}};
|
||||
|
||||
for (unsigned next = 0; next < count; ++next) {
|
||||
if (static_cast<float>(keys[next].frame) > frame) {
|
||||
if (next != 0) {
|
||||
first = keys[next - 1];
|
||||
}
|
||||
|
||||
second = keys[next];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const ModelRotationKey first = next ? keys[next - 1] : ModelRotationKey{0, {1, 1, 1, 1}};
|
||||
const auto& second = keys[next];
|
||||
const float amount = second.frame != first.frame ? (frame - static_cast<float>(first.frame)) / static_cast<float>((second.frame - first.frame)) : 0.0f;
|
||||
output.SetScale(
|
||||
scale.SetScale(
|
||||
(1.0f - amount) * first.rotation[0] + second.rotation[0] * amount, (1.0f - amount) * first.rotation[1] + second.rotation[1] * amount,
|
||||
first.rotation[2] * (1.0f - amount) + second.rotation[2] * amount
|
||||
);
|
||||
output = scale;
|
||||
}
|
||||
|
||||
// OFFSET: 0x005404A0
|
||||
// FUNCTION: fn_01722
|
||||
void SampleModelPosition(std::span<const ModelRotationKey> keys, float frame, const matrix& base, matrix& output) {
|
||||
if (keys.empty()) {
|
||||
void SampleModelPosition(const std::vector<ModelRotationKey>& keys, float frame, const matrix& base, matrix& output) {
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
output.values[9] = base.values[9];
|
||||
output.values[10] = base.values[10];
|
||||
output.values[11] = base.values[11];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (keys.size() == 1 || !(frame < static_cast<float>(keys.back().frame))) {
|
||||
const auto& key = keys.size() == 1 ? keys[0] : keys.back();
|
||||
output.values[9] = key.rotation[0];
|
||||
output.values[10] = key.rotation[1];
|
||||
output.values[11] = key.rotation[2];
|
||||
|
||||
if (count == 1) {
|
||||
output.values[9] = keys[0].rotation[0];
|
||||
output.values[10] = keys[0].rotation[1];
|
||||
output.values[11] = keys[0].rotation[2];
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned next = 0;
|
||||
|
||||
while (!(static_cast<float>(keys[next].frame) > frame)) {
|
||||
++next;
|
||||
if (frame >= static_cast<float>(keys[count - 1].frame)) {
|
||||
output.values[9] = keys[keys.size() - 1].rotation[0];
|
||||
output.values[10] = keys[keys.size() - 1].rotation[1];
|
||||
output.values[11] = keys[keys.size() - 1].rotation[2];
|
||||
return;
|
||||
}
|
||||
|
||||
ModelRotationKey first;
|
||||
ModelRotationKey second;
|
||||
|
||||
for (unsigned next = 0; next < count; ++next) {
|
||||
if (static_cast<float>(keys[next].frame) > frame) {
|
||||
first = next ? keys[next - 1] : ModelRotationKey{0, {base.values[9], base.values[10], base.values[11], 0}};
|
||||
second = keys[next];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const ModelRotationKey first = next ? keys[next - 1] : ModelRotationKey{0, {base.values[9], base.values[10], base.values[11], 0}};
|
||||
const auto& second = keys[next];
|
||||
const float amount = (frame - static_cast<float>(first.frame)) / static_cast<float>((second.frame - first.frame));
|
||||
const float previous = 1.0f - amount;
|
||||
|
||||
|
|
@ -163,24 +197,34 @@ void SampleModelPosition(std::span<const ModelRotationKey> keys, float frame, co
|
|||
|
||||
// OFFSET: 0x005407A0
|
||||
// FUNCTION: fn_01724
|
||||
void SampleModelRotation(std::span<const ModelRotationKey> keys, float frame, const matrix& base, matrix& output) {
|
||||
void SampleModelRotation(const std::vector<ModelRotationKey>& keys, float frame, const matrix& base, matrix& output) {
|
||||
matrix rotation;
|
||||
rotation.Identity();
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (keys.empty()) {
|
||||
if (count == 0) {
|
||||
rotation = base;
|
||||
} else if (keys.size() == 1 || frame >= static_cast<float>(keys.back().frame)) {
|
||||
QuaternionMatrix(keys.size() == 1 ? keys[0] : keys.back(), rotation);
|
||||
} else if (count == 1) {
|
||||
QuaternionMatrix(keys[0], rotation);
|
||||
} else if (frame >= static_cast<float>(keys[count - 1].frame)) {
|
||||
QuaternionMatrix(keys[count - 1], rotation);
|
||||
} else {
|
||||
unsigned next = 0;
|
||||
ModelRotationKey a{0, {0, 0, 0, 1}};
|
||||
ModelRotationKey b{0, {0, 0, 0, 1}};
|
||||
|
||||
while (!(static_cast<float>(keys[next].frame) > frame)) {
|
||||
if (++next >= keys.size()) {
|
||||
for (unsigned next = 0; next < count; ++next) {
|
||||
if (static_cast<float>(keys[next].frame) > frame) {
|
||||
if (next == 0) {
|
||||
a = MatrixQuaternion(base);
|
||||
} else {
|
||||
a = keys[next - 1];
|
||||
}
|
||||
|
||||
b = keys[next];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ModelRotationKey a = next < keys.size() ? (next ? keys[next - 1] : MatrixQuaternion(base)) : ModelRotationKey{0, {0, 0, 0, 1}};
|
||||
ModelRotationKey b = next < keys.size() ? keys[next] : ModelRotationKey{0, {0, 0, 0, 1}};
|
||||
const float amount = b.frame != a.frame ? (frame - static_cast<float>(a.frame)) / static_cast<float>((b.frame - a.frame)) : 0.0f;
|
||||
float dot = ((b.rotation[0] * a.rotation[0] + b.rotation[1] * a.rotation[1]) + b.rotation[2] * a.rotation[2]) + b.rotation[3] * a.rotation[3];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue