Clear unknowns in LegoAnimScene (#1649)

This commit is contained in:
Fabian Neundorf
2025-07-22 19:45:50 +02:00
committed by GitHub
parent 36f6d963dc
commit ed33541a2e
4 changed files with 142 additions and 129 deletions

View File

@@ -337,7 +337,7 @@ void LegoRaceCar::KickCamera(float p_param)
transformationMatrix.SetIdentity(); transformationMatrix.SetIdentity();
// Possible bug in the original code: The first argument is not initialized // Possible bug in the original code: The first argument is not initialized
a->GetAnimTreePtr()->GetCamAnim()->FUN_1009f490(deltaTime, transformationMatrix); a->GetAnimTreePtr()->GetCamAnim()->CalculateCameraTransform(deltaTime, transformationMatrix);
if (r->GetCameraController()) { if (r->GetCameraController()) {
r->GetCameraController()->TransformPointOfView(transformationMatrix, 0); r->GetCameraController()->TransformPointOfView(transformationMatrix, 0);

View File

@@ -938,7 +938,7 @@ void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p
if (p_anim->GetCamAnim() != NULL) { if (p_anim->GetCamAnim() != NULL) {
MxMatrix transform(mat); MxMatrix transform(mat);
p_anim->GetCamAnim()->FUN_1009f490(p_time, transform); p_anim->GetCamAnim()->CalculateCameraTransform(p_time, transform);
if (m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { if (m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) {
m_currentWorld->GetCameraController()->TransformPointOfView(transform, FALSE); m_currentWorld->GetCameraController()->TransformPointOfView(transform, FALSE);

View File

@@ -10,20 +10,20 @@ DECOMP_SIZE_ASSERT(LegoTranslationKey, 0x14)
DECOMP_SIZE_ASSERT(LegoRotationKey, 0x18) DECOMP_SIZE_ASSERT(LegoRotationKey, 0x18)
DECOMP_SIZE_ASSERT(LegoScaleKey, 0x14) DECOMP_SIZE_ASSERT(LegoScaleKey, 0x14)
DECOMP_SIZE_ASSERT(LegoMorphKey, 0x0c) DECOMP_SIZE_ASSERT(LegoMorphKey, 0x0c)
DECOMP_SIZE_ASSERT(LegoUnknownKey, 0x0c) DECOMP_SIZE_ASSERT(LegoRotationZKey, 0x0c)
DECOMP_SIZE_ASSERT(LegoAnimNodeData, 0x34) DECOMP_SIZE_ASSERT(LegoAnimNodeData, 0x34)
DECOMP_SIZE_ASSERT(LegoAnimActorEntry, 0x08) DECOMP_SIZE_ASSERT(LegoAnimActorEntry, 0x08)
DECOMP_SIZE_ASSERT(LegoAnimScene, 0x24) DECOMP_SIZE_ASSERT(LegoAnimScene, 0x24)
DECOMP_SIZE_ASSERT(LegoAnim, 0x18) DECOMP_SIZE_ASSERT(LegoAnim, 0x18)
// FUNCTION: LEGO1 0x1009f000 // FUNCTION: LEGO1 0x1009f000
LegoUnknownKey::LegoUnknownKey() LegoRotationZKey::LegoRotationZKey()
{ {
m_z = 0.0f; m_z = 0.0f;
} }
// FUNCTION: LEGO1 0x1009f020 // FUNCTION: LEGO1 0x1009f020
LegoResult LegoUnknownKey::Read(LegoStorage* p_storage) LegoResult LegoRotationZKey::Read(LegoStorage* p_storage)
{ {
LegoResult result; LegoResult result;
@@ -40,7 +40,7 @@ LegoResult LegoUnknownKey::Read(LegoStorage* p_storage)
// FUNCTION: LEGO1 0x1009f060 // FUNCTION: LEGO1 0x1009f060
// FUNCTION: BETA10 0x1018133f // FUNCTION: BETA10 0x1018133f
LegoResult LegoUnknownKey::Write(LegoStorage* p_storage) LegoResult LegoRotationZKey::Write(LegoStorage* p_storage)
{ {
LegoResult result; LegoResult result;
@@ -58,33 +58,33 @@ LegoResult LegoUnknownKey::Write(LegoStorage* p_storage)
// FUNCTION: LEGO1 0x1009f0a0 // FUNCTION: LEGO1 0x1009f0a0
LegoAnimScene::LegoAnimScene() LegoAnimScene::LegoAnimScene()
{ {
m_unk0x00 = 0; m_translationKeysCount = 0;
m_unk0x04 = NULL; m_translationKeys = NULL;
m_unk0x08 = 0; m_targetKeysCount = 0;
m_unk0x0c = NULL; m_targetKeys = NULL;
m_unk0x10 = 0; m_rotationKeysCount = 0;
m_unk0x14 = NULL; m_rotationKeys = NULL;
m_unk0x18 = 0; m_targetIndex = 0;
m_unk0x1c = 0; m_translationIndex = 0;
m_unk0x20 = 0; m_rotationIndex = 0;
} }
// FUNCTION: LEGO1 0x1009f0d0 // FUNCTION: LEGO1 0x1009f0d0
LegoAnimScene::~LegoAnimScene() LegoAnimScene::~LegoAnimScene()
{ {
if (m_unk0x04 != NULL) { if (m_translationKeys != NULL) {
delete[] m_unk0x04; delete[] m_translationKeys;
m_unk0x04 = NULL; m_translationKeys = NULL;
} }
if (m_unk0x0c != NULL) { if (m_targetKeys != NULL) {
delete[] m_unk0x0c; delete[] m_targetKeys;
m_unk0x0c = NULL; m_targetKeys = NULL;
} }
if (m_unk0x14 != NULL) { if (m_rotationKeys != NULL) {
delete[] m_unk0x14; delete[] m_rotationKeys;
m_unk0x14 = NULL; m_rotationKeys = NULL;
} }
} }
@@ -95,34 +95,34 @@ LegoResult LegoAnimScene::Write(LegoStorage* p_storage)
LegoResult result; LegoResult result;
LegoS32 i; LegoS32 i;
if ((result = p_storage->Write(&m_unk0x00, sizeof(LegoU16))) != SUCCESS) { if ((result = p_storage->Write(&m_translationKeysCount, sizeof(LegoU16))) != SUCCESS) {
return result; return result;
} }
if (m_unk0x00 != 0) { if (m_translationKeysCount != 0) {
for (i = 0; i < m_unk0x00; i++) { for (i = 0; i < m_translationKeysCount; i++) {
if ((result = m_unk0x04[i].Write(p_storage)) != SUCCESS) { if ((result = m_translationKeys[i].Write(p_storage)) != SUCCESS) {
return result; return result;
} }
} }
} }
if ((result = p_storage->Write(&m_unk0x08, sizeof(LegoU16))) != SUCCESS) { if ((result = p_storage->Write(&m_targetKeysCount, sizeof(LegoU16))) != SUCCESS) {
return result; return result;
} }
if (m_unk0x08 != 0) { if (m_targetKeysCount != 0) {
for (i = 0; i < m_unk0x08; i++) { for (i = 0; i < m_targetKeysCount; i++) {
if ((result = m_unk0x0c[i].Write(p_storage)) != SUCCESS) { if ((result = m_targetKeys[i].Write(p_storage)) != SUCCESS) {
return result; return result;
} }
} }
} }
if ((result = p_storage->Write(&m_unk0x10, sizeof(LegoU16))) != SUCCESS) { if ((result = p_storage->Write(&m_rotationKeysCount, sizeof(LegoU16))) != SUCCESS) {
return result; return result;
} }
if (m_unk0x10 != 0) { if (m_rotationKeysCount != 0) {
for (i = 0; i < m_unk0x10; i++) { for (i = 0; i < m_rotationKeysCount; i++) {
if ((result = m_unk0x14[i].Write(p_storage)) != SUCCESS) { if ((result = m_rotationKeys[i].Write(p_storage)) != SUCCESS) {
return result; return result;
} }
} }
@@ -137,37 +137,37 @@ LegoResult LegoAnimScene::Read(LegoStorage* p_storage)
LegoResult result; LegoResult result;
LegoS32 i; LegoS32 i;
if ((result = p_storage->Read(&m_unk0x00, sizeof(LegoU16))) != SUCCESS) { if ((result = p_storage->Read(&m_translationKeysCount, sizeof(LegoU16))) != SUCCESS) {
return result; return result;
} }
if (m_unk0x00 != 0) { if (m_translationKeysCount != 0) {
m_unk0x04 = new LegoTranslationKey[m_unk0x00]; m_translationKeys = new LegoTranslationKey[m_translationKeysCount];
for (i = 0; i < m_unk0x00; i++) { for (i = 0; i < m_translationKeysCount; i++) {
if ((result = m_unk0x04[i].Read(p_storage)) != SUCCESS) { if ((result = m_translationKeys[i].Read(p_storage)) != SUCCESS) {
goto done; goto done;
} }
} }
} }
if ((result = p_storage->Read(&m_unk0x08, sizeof(LegoU16))) != SUCCESS) { if ((result = p_storage->Read(&m_targetKeysCount, sizeof(LegoU16))) != SUCCESS) {
return result; return result;
} }
if (m_unk0x08 != 0) { if (m_targetKeysCount != 0) {
m_unk0x0c = new LegoTranslationKey[m_unk0x08]; m_targetKeys = new LegoTranslationKey[m_targetKeysCount];
for (i = 0; i < m_unk0x08; i++) { for (i = 0; i < m_targetKeysCount; i++) {
if ((result = m_unk0x0c[i].Read(p_storage)) != SUCCESS) { if ((result = m_targetKeys[i].Read(p_storage)) != SUCCESS) {
goto done; goto done;
} }
} }
} }
if ((result = p_storage->Read(&m_unk0x10, sizeof(LegoU16))) != SUCCESS) { if ((result = p_storage->Read(&m_rotationKeysCount, sizeof(LegoU16))) != SUCCESS) {
return result; return result;
} }
if (m_unk0x10 != 0) { if (m_rotationKeysCount != 0) {
m_unk0x14 = new LegoUnknownKey[m_unk0x10]; m_rotationKeys = new LegoRotationZKey[m_rotationKeysCount];
for (i = 0; i < m_unk0x10; i++) { for (i = 0; i < m_rotationKeysCount; i++) {
if ((result = m_unk0x14[i].Read(p_storage)) != SUCCESS) { if ((result = m_rotationKeys[i].Read(p_storage)) != SUCCESS) {
goto done; goto done;
} }
} }
@@ -176,22 +176,22 @@ LegoResult LegoAnimScene::Read(LegoStorage* p_storage)
return SUCCESS; return SUCCESS;
done: done:
if (m_unk0x04 != NULL) { if (m_translationKeys != NULL) {
delete[] m_unk0x04; delete[] m_translationKeys;
m_unk0x00 = 0; m_translationKeysCount = 0;
m_unk0x04 = NULL; m_translationKeys = NULL;
} }
if (m_unk0x0c != NULL) { if (m_targetKeys != NULL) {
delete[] m_unk0x0c; delete[] m_targetKeys;
m_unk0x08 = 0; m_targetKeysCount = 0;
m_unk0x0c = NULL; m_targetKeys = NULL;
} }
if (m_unk0x14 != NULL) { if (m_rotationKeys != NULL) {
delete[] m_unk0x14; delete[] m_rotationKeys;
m_unk0x10 = 0; m_rotationKeysCount = 0;
m_unk0x14 = NULL; m_rotationKeys = NULL;
} }
return result; return result;
@@ -199,82 +199,95 @@ done:
// FUNCTION: LEGO1 0x1009f490 // FUNCTION: LEGO1 0x1009f490
// FUNCTION: BETA10 0x10181a83 // FUNCTION: BETA10 0x10181a83
LegoResult LegoAnimScene::FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix) LegoResult LegoAnimScene::CalculateCameraTransform(LegoFloat p_time, Matrix4& p_matrix)
{ {
MxMatrix localb0; MxMatrix tempMatrix;
MxMatrix local4c; MxMatrix original;
Vector3 local5c(localb0[0]); Vector3 column0(tempMatrix[0]);
Vector3 local68(localb0[1]); Vector3 column1(tempMatrix[1]);
Vector3 local54(localb0[2]); Vector3 column2(tempMatrix[2]);
Vector3 localb8(localb0[3]); Vector3 column3(tempMatrix[3]);
Mx3DPointFloat localcc; Mx3DPointFloat tempTranslation;
localb0.SetIdentity(); tempMatrix.SetIdentity();
LegoU32 local60; LegoU32 translationIndex;
if (m_unk0x08 != 0) { if (m_targetKeysCount != 0) {
local60 = GetUnknown0x18(); translationIndex = GetTargetIndex();
LegoAnimNodeData::GetTranslation(m_unk0x08, m_unk0x0c, p_time, localb0, local60); LegoAnimNodeData::GetTranslation(m_targetKeysCount, m_targetKeys, p_time, tempMatrix, translationIndex);
SetUnknown0x18(local60); SetTargetIndex(translationIndex);
localcc = localb8; tempTranslation = column3;
localb8.Clear(); column3.Clear();
} }
if (m_unk0x00 != 0) { if (m_translationKeysCount != 0) {
local60 = GetUnknown0x1c(); translationIndex = GetTranslationIndex();
LegoAnimNodeData::GetTranslation(m_unk0x00, m_unk0x04, p_time, localb0, local60); LegoAnimNodeData::GetTranslation(
SetUnknown0x1c(local60); m_translationKeysCount,
m_translationKeys,
p_time,
tempMatrix,
translationIndex
);
SetTranslationIndex(translationIndex);
} }
local54 = localcc; column2 = tempTranslation;
local54 -= localb8; column2 -= column3;
if (local54.Unitize() == 0) { if (column2.Unitize() == 0) {
local5c.EqualsCross(local68, local54); column0.EqualsCross(column1, column2);
if (local5c.Unitize() == 0) { if (column0.Unitize() == 0) {
local68.EqualsCross(local54, local5c); column1.EqualsCross(column2, column0);
localcc = p_matrix[3]; tempTranslation = p_matrix[3];
localcc += localb0[3]; tempTranslation += tempMatrix[3];
p_matrix[3][0] = p_matrix[3][1] = p_matrix[3][2] = localb0[3][0] = localb0[3][1] = localb0[3][2] = 0; p_matrix[3][0] = p_matrix[3][1] = p_matrix[3][2] = tempMatrix[3][0] = tempMatrix[3][1] = tempMatrix[3][2] =
0;
if (m_unk0x10 != 0) { if (m_rotationKeysCount != 0) {
LegoU32 locald0 = -1; LegoU32 old_index = -1;
LegoU32 locald8; LegoU32 i;
locald0 = GetUnknown0x20(); old_index = GetRotationIndex();
LegoU32 localdc = LegoU32 count = LegoAnimNodeData::FindKeys(
LegoAnimNodeData::FindKeys(p_time, m_unk0x10, m_unk0x14, sizeof(*m_unk0x14), locald8, locald0); p_time,
m_rotationKeysCount,
m_rotationKeys,
sizeof(*m_rotationKeys),
i,
old_index
);
SetUnknown0x20(locald0); SetRotationIndex(old_index);
switch (localdc) { switch (count) {
case 1: case 1:
p_matrix.RotateZ(m_unk0x14[locald8].GetZ()); p_matrix.RotateZ(m_rotationKeys[i].GetZ());
break; break;
case 2: case 2:
// Seems to be unused // Seems to be unused
LegoFloat z = LegoAnimNodeData::Interpolate( LegoFloat z = LegoAnimNodeData::Interpolate(
p_time, p_time,
m_unk0x14[locald8], m_rotationKeys[i],
m_unk0x14[locald8].GetZ(), m_rotationKeys[i].GetZ(),
m_unk0x14[locald8 + 1], m_rotationKeys[i + 1],
m_unk0x14[locald8 + 1].GetZ() m_rotationKeys[i + 1].GetZ()
); );
p_matrix.RotateZ(m_unk0x14[locald8].GetZ()); p_matrix.RotateZ(m_rotationKeys[i].GetZ());
break; break;
} }
} }
local4c = p_matrix; original = p_matrix;
p_matrix.Product(local4c.GetData(), localb0.GetData()); p_matrix.Product(original.GetData(), tempMatrix.GetData());
p_matrix[3][0] = localcc[0]; p_matrix[3][0] = tempTranslation[0];
p_matrix[3][1] = localcc[1]; p_matrix[3][1] = tempTranslation[1];
p_matrix[3][2] = localcc[2]; p_matrix[3][2] = tempTranslation[2];
} }
} }

View File

@@ -137,9 +137,9 @@ protected:
}; };
// SIZE 0x0c // SIZE 0x0c
class LegoUnknownKey : public LegoAnimKey { class LegoRotationZKey : public LegoAnimKey {
public: public:
LegoUnknownKey(); LegoRotationZKey();
LegoResult Read(LegoStorage* p_storage); LegoResult Read(LegoStorage* p_storage);
LegoResult Write(LegoStorage* p_storage); LegoResult Write(LegoStorage* p_storage);
@@ -309,26 +309,26 @@ public:
~LegoAnimScene(); ~LegoAnimScene();
LegoResult Read(LegoStorage* p_storage); LegoResult Read(LegoStorage* p_storage);
LegoResult Write(LegoStorage* p_storage); LegoResult Write(LegoStorage* p_storage);
LegoResult FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix); LegoResult CalculateCameraTransform(LegoFloat p_time, Matrix4& p_matrix);
LegoU32 GetUnknown0x18() { return m_unk0x18; } LegoU32 GetTargetIndex() { return m_targetIndex; }
LegoU32 GetUnknown0x1c() { return m_unk0x1c; } LegoU32 GetTranslationIndex() { return m_translationIndex; }
LegoU32 GetUnknown0x20() { return m_unk0x20; } LegoU32 GetRotationIndex() { return m_rotationIndex; }
void SetUnknown0x18(LegoU32 p_unk0x18) { m_unk0x18 = p_unk0x18; } void SetTargetIndex(LegoU32 p_targetIndex) { m_targetIndex = p_targetIndex; }
void SetUnknown0x1c(LegoU32 p_unk0x1c) { m_unk0x1c = p_unk0x1c; } void SetTranslationIndex(LegoU32 p_translationIndex) { m_translationIndex = p_translationIndex; }
void SetUnknown0x20(LegoU32 p_unk0x20) { m_unk0x20 = p_unk0x20; } void SetRotationIndex(LegoU32 p_rotationIndex) { m_rotationIndex = p_rotationIndex; }
private: private:
LegoU16 m_unk0x00; // 0x00 LegoU16 m_translationKeysCount; // 0x00
LegoTranslationKey* m_unk0x04; // 0x04 LegoTranslationKey* m_translationKeys; // 0x04
LegoU16 m_unk0x08; // 0x08 LegoU16 m_targetKeysCount; // 0x08
LegoTranslationKey* m_unk0x0c; // 0x0c LegoTranslationKey* m_targetKeys; // 0x0c
LegoU16 m_unk0x10; // 0x10 LegoU16 m_rotationKeysCount; // 0x10
LegoUnknownKey* m_unk0x14; // 0x14 LegoRotationZKey* m_rotationKeys; // 0x14
LegoU32 m_unk0x18; // 0x18 LegoU32 m_targetIndex; // 0x18
LegoU32 m_unk0x1c; // 0x1c LegoU32 m_translationIndex; // 0x1c
LegoU32 m_unk0x20; // 0x20 LegoU32 m_rotationIndex; // 0x20
}; };
// VTABLE: LEGO1 0x100db8d8 // VTABLE: LEGO1 0x100db8d8