Decompile 4 functions in Source/Contents/Models/ModelAnimation.cpp, Source/Contents/Models/ModelAnimation.h, ...
Batch #14054 by Yommy: 4 byte-identical, 0 confirmed by peer review. - fn_01725 LegacyScaleTrack::Sample: byte-identical - fn_17465 C3dNodeV1::C3dNodeV1: byte-identical (already on main) - fn_17466 C3dNodeV2::C3dNodeV2: byte-identical (already on main) - fn_17507 C3dNodeV1::Animate: byte-identical Merged automatically: every function is byte-identical to the original.
This commit is contained in:
parent
e779c460b1
commit
be2cf07140
4 changed files with 94 additions and 51 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include "Contents/Models/ModelAnimation.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
namespace {
|
||||
__declspec(noinline) ModelRotationKey MatrixQuaternion(const matrix& matrix);
|
||||
|
|
@ -24,11 +25,12 @@ namespace {
|
|||
|
||||
// OFFSET: 0x00540370
|
||||
// FUNCTION: fn_01721
|
||||
void SampleLegacyPosition(const std::vector<ModelPositionKey>& keys, int frame, matrix& output) {
|
||||
void LegacyPositionTrack::Sample(int frame, matrix& output) const {
|
||||
const std::vector<ModelPositionKey>& keys = *this;
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
output.Identity();
|
||||
std::memcpy(output.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -53,11 +55,12 @@ void SampleLegacyPosition(const std::vector<ModelPositionKey>& keys, int frame,
|
|||
|
||||
// OFFSET: 0x00540670
|
||||
// FUNCTION: fn_01723
|
||||
void SampleLegacyRotation(const std::vector<ModelRotationKey>& keys, int frame, matrix& output) {
|
||||
void LegacyRotationTrack::Sample(int frame, matrix& output) const {
|
||||
const std::vector<ModelRotationKey>& keys = *this;
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
output.Identity();
|
||||
std::memcpy(output.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +85,7 @@ void SampleLegacyRotation(const std::vector<ModelRotationKey>& keys, int frame,
|
|||
const auto& b = keys[next];
|
||||
|
||||
if (a.rotation[3] == 1.0f && b.rotation[3] == 1.0f) {
|
||||
output.Identity();
|
||||
std::memcpy(output.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -94,11 +97,12 @@ void SampleLegacyRotation(const std::vector<ModelRotationKey>& keys, int frame,
|
|||
|
||||
// OFFSET: 0x00540BF0
|
||||
// FUNCTION: fn_01725
|
||||
void SampleLegacyScale(const std::vector<ModelScaleKey>& keys, int, matrix& output) {
|
||||
void LegacyScaleTrack::Sample(int, matrix& output) const {
|
||||
const std::vector<ModelScaleKey>& keys = *this;
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
output.Identity();
|
||||
std::memcpy(output.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
} else if (count == 1) {
|
||||
output.SetScale(keys[0].scale[0], keys[0].scale[1], keys[0].scale[2]);
|
||||
}
|
||||
|
|
@ -106,11 +110,12 @@ void SampleLegacyScale(const std::vector<ModelScaleKey>& keys, int, matrix& outp
|
|||
|
||||
// OFFSET: 0x00540C60
|
||||
// FUNCTION: fn_01726
|
||||
void SampleModelScale(const std::vector<ModelRotationKey>& keys, float frame, matrix& output) {
|
||||
void ModelScaleTrack::Sample(float frame, matrix& output) const {
|
||||
const std::vector<ModelRotationKey>& keys = *this;
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
output.Identity();
|
||||
std::memcpy(output.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +132,7 @@ void SampleModelScale(const std::vector<ModelRotationKey>& keys, float frame, ma
|
|||
}
|
||||
|
||||
matrix scale;
|
||||
scale.Identity();
|
||||
std::memcpy(scale.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
ModelRotationKey first{0, {1, 1, 1, 1}};
|
||||
ModelRotationKey second{0, {1, 1, 1, 1}};
|
||||
|
||||
|
|
@ -152,7 +157,8 @@ void SampleModelScale(const std::vector<ModelRotationKey>& keys, float frame, ma
|
|||
|
||||
// OFFSET: 0x005404A0
|
||||
// FUNCTION: fn_01722
|
||||
void SampleModelPosition(const std::vector<ModelRotationKey>& keys, float frame, const matrix& base, matrix& output) {
|
||||
void ModelPositionTrack::Sample(float frame, const matrix& base, matrix& output) const {
|
||||
const std::vector<ModelRotationKey>& keys = *this;
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
|
|
@ -176,13 +182,18 @@ void SampleModelPosition(const std::vector<ModelRotationKey>& keys, float frame,
|
|||
return;
|
||||
}
|
||||
|
||||
ModelRotationKey first;
|
||||
ModelRotationKey second;
|
||||
ModelPositionKey first;
|
||||
ModelPositionKey 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];
|
||||
if (next == 0) {
|
||||
first = ModelPositionKey{0, {base.values[9], base.values[10], base.values[11]}};
|
||||
} else {
|
||||
std::memcpy(&first, &keys[next - 1], sizeof(first));
|
||||
}
|
||||
|
||||
std::memcpy(&second, &keys[next], sizeof(second));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -190,16 +201,17 @@ void SampleModelPosition(const std::vector<ModelRotationKey>& keys, float frame,
|
|||
const float amount = (frame - static_cast<float>(first.frame)) / static_cast<float>((second.frame - first.frame));
|
||||
const float previous = 1.0f - amount;
|
||||
|
||||
output.values[9] = first.rotation[0] * previous + second.rotation[0] * amount;
|
||||
output.values[10] = first.rotation[1] * previous + second.rotation[1] * amount;
|
||||
output.values[11] = first.rotation[2] * previous + second.rotation[2] * amount;
|
||||
output.values[9] = first.position[0] * previous + second.position[0] * amount;
|
||||
output.values[10] = first.position[1] * previous + second.position[1] * amount;
|
||||
output.values[11] = first.position[2] * previous + second.position[2] * amount;
|
||||
}
|
||||
|
||||
// OFFSET: 0x005407A0
|
||||
// FUNCTION: fn_01724
|
||||
void SampleModelRotation(const std::vector<ModelRotationKey>& keys, float frame, const matrix& base, matrix& output) {
|
||||
void ModelRotationTrack::Sample(float frame, const matrix& base, matrix& output) const {
|
||||
const std::vector<ModelRotationKey>& keys = *this;
|
||||
matrix rotation;
|
||||
rotation.Identity();
|
||||
std::memcpy(rotation.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
const unsigned count = keys.size();
|
||||
|
||||
if (count == 0) {
|
||||
|
|
@ -239,21 +251,23 @@ void SampleModelRotation(const std::vector<ModelRotationKey>& keys, float frame,
|
|||
float firstWeight;
|
||||
float secondWeight;
|
||||
|
||||
if (!(dot > -0.95f)) {
|
||||
if (dot > -0.95f) {
|
||||
if (dot <= 0.95f) {
|
||||
const float angle = static_cast<float>(std::acos(static_cast<double>(dot)));
|
||||
const float denominator = ClientSin(angle);
|
||||
firstWeight = ClientSin((1.0f - amount) * angle) / denominator;
|
||||
secondWeight = ClientSin(angle * amount) / denominator;
|
||||
} else {
|
||||
firstWeight = 1.0f - amount;
|
||||
secondWeight = amount;
|
||||
}
|
||||
} else {
|
||||
b.rotation[0] = -a.rotation[1];
|
||||
b.rotation[1] = a.rotation[0];
|
||||
b.rotation[2] = -a.rotation[3];
|
||||
b.rotation[3] = a.rotation[2];
|
||||
firstWeight = ClientSin((0.5f - amount) * 3.141592f);
|
||||
secondWeight = ClientSin(amount * 3.141592f);
|
||||
} else if (dot > 0.95f) {
|
||||
firstWeight = 1.0f - amount;
|
||||
secondWeight = amount;
|
||||
} else {
|
||||
const float angle = static_cast<float>(std::acos(static_cast<double>(dot)));
|
||||
const float denominator = ClientSin(angle);
|
||||
firstWeight = ClientSin((1.0f - amount) * angle) / denominator;
|
||||
secondWeight = ClientSin(angle * amount) / denominator;
|
||||
}
|
||||
|
||||
ModelRotationKey result{0, {}};
|
||||
|
|
|
|||
|
|
@ -6,12 +6,41 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
void SampleLegacyPosition(const std::vector<ModelPositionKey>& keys, int frame, matrix& output);
|
||||
void SampleLegacyRotation(const std::vector<ModelRotationKey>& keys, int frame, matrix& output);
|
||||
void SampleLegacyScale(const std::vector<ModelScaleKey>& keys, int frame, matrix& output);
|
||||
void SampleModelScale(const std::vector<ModelRotationKey>& keys, float frame, matrix& output);
|
||||
void SampleModelPosition(const std::vector<ModelRotationKey>& keys, float frame, const matrix& base, matrix& output);
|
||||
void SampleModelRotation(const std::vector<ModelRotationKey>& keys, float frame, const matrix& base, matrix& output);
|
||||
class LegacyPositionTrack : public std::vector<ModelPositionKey> {
|
||||
public:
|
||||
using std::vector<ModelPositionKey>::operator=;
|
||||
void Sample(int frame, matrix& output) const;
|
||||
};
|
||||
|
||||
class LegacyRotationTrack : public std::vector<ModelRotationKey> {
|
||||
public:
|
||||
using std::vector<ModelRotationKey>::operator=;
|
||||
void Sample(int frame, matrix& output) const;
|
||||
};
|
||||
|
||||
class LegacyScaleTrack : public std::vector<ModelScaleKey> {
|
||||
public:
|
||||
using std::vector<ModelScaleKey>::operator=;
|
||||
void Sample(int frame, matrix& output) const;
|
||||
};
|
||||
|
||||
class ModelScaleTrack : public std::vector<ModelRotationKey> {
|
||||
public:
|
||||
using std::vector<ModelRotationKey>::operator=;
|
||||
void Sample(float frame, matrix& output) const;
|
||||
};
|
||||
|
||||
class ModelPositionTrack : public std::vector<ModelRotationKey> {
|
||||
public:
|
||||
using std::vector<ModelRotationKey>::operator=;
|
||||
void Sample(float frame, const matrix& base, matrix& output) const;
|
||||
};
|
||||
|
||||
class ModelRotationTrack : public std::vector<ModelRotationKey> {
|
||||
public:
|
||||
using std::vector<ModelRotationKey>::operator=;
|
||||
void Sample(float frame, const matrix& base, matrix& output) const;
|
||||
};
|
||||
void QuaternionMatrix(const ModelRotationKey& key, matrix& output);
|
||||
void InterpolateModelRotation(float amount, const ModelRotationKey& first, const ModelRotationKey& second, int spins, ModelRotationKey& output);
|
||||
|
||||
|
|
|
|||
|
|
@ -127,12 +127,12 @@ void C3dNodeV1::Animate(double frame) {
|
|||
matrix position;
|
||||
matrix scale;
|
||||
matrix rotation;
|
||||
position.Identity();
|
||||
scale.Identity();
|
||||
rotation.Identity();
|
||||
SampleLegacyPosition(this->positionKeys, selected, position);
|
||||
SampleLegacyRotation(this->rotationKeys, selected, rotation);
|
||||
SampleLegacyScale(this->scaleKeys, selected, scale);
|
||||
std::memcpy(position.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
std::memcpy(scale.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
std::memcpy(rotation.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
this->positionKeys.Sample(selected, position);
|
||||
this->rotationKeys.Sample(selected, rotation);
|
||||
this->scaleKeys.Sample(selected, scale);
|
||||
matrix combined;
|
||||
combined.Compose(scale, rotation);
|
||||
this->transform.Compose(combined, position);
|
||||
|
|
@ -145,11 +145,11 @@ void C3dNodeV1::Animate(double frame) {
|
|||
// OFFSET: 0x00AB9210
|
||||
// FUNCTION: fn_17508
|
||||
void C3dNodeV2::Animate(double frame) {
|
||||
this->transform.Identity();
|
||||
std::memcpy(this->transform.values, g_identityMatrix, sizeof(g_identityMatrix));
|
||||
const float selected = static_cast<float>(frame);
|
||||
SampleModelScale(this->scaleKeys, selected, this->transform);
|
||||
SampleModelRotation(this->rotationKeys, selected, this->localTransform, this->transform);
|
||||
SampleModelPosition(this->positionKeys, selected, this->localTransform, this->transform);
|
||||
this->scaleKeys.Sample(selected, this->transform);
|
||||
this->rotationKeys.Sample(selected, this->localTransform, this->transform);
|
||||
this->positionKeys.Sample(selected, this->localTransform, this->transform);
|
||||
this->textureTransforms.clear();
|
||||
|
||||
for (auto it = this->textureKeys.begin(); it != this->textureKeys.end(); ++it) {
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@ public:
|
|||
void Animate(double frame) override;
|
||||
void Draw(const float* matrix, unsigned char reversed, bool clip, unsigned char commandMode) override;
|
||||
|
||||
/* 008C */ std::vector<ModelScaleKey> scaleKeys;
|
||||
/* 0098 */ std::vector<ModelRotationKey> rotationKeys;
|
||||
/* 00A4 */ std::vector<ModelPositionKey> positionKeys;
|
||||
/* 008C */ LegacyScaleTrack scaleKeys;
|
||||
/* 0098 */ LegacyRotationTrack rotationKeys;
|
||||
/* 00A4 */ LegacyPositionTrack positionKeys;
|
||||
};
|
||||
|
||||
class C3dNodeV2 : public C3dNode {
|
||||
|
|
@ -66,9 +66,9 @@ public:
|
|||
|
||||
/* 008C */ matrix resourceTransform;
|
||||
/* 00BC */ matrix localTransform;
|
||||
/* 00EC */ std::vector<ModelRotationKey> scaleKeys;
|
||||
/* 00F8 */ std::vector<ModelRotationKey> rotationKeys;
|
||||
/* 0104 */ std::vector<ModelRotationKey> positionKeys;
|
||||
/* 00EC */ ModelScaleTrack scaleKeys;
|
||||
/* 00F8 */ ModelRotationTrack rotationKeys;
|
||||
/* 0104 */ ModelPositionTrack positionKeys;
|
||||
/* 0110 */ std::map<int, ModelTextureChannels> textureKeys;
|
||||
/* 0118 */ std::map<int, ModelTextureTransform> textureTransforms;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue