Refactor Matrix4::ToQuaternion()

This commit is contained in:
jonschz 2024-05-01 15:50:36 +02:00
parent cd39e71597
commit a42bae146f

View File

@ -151,48 +151,45 @@ class Matrix4 {
float (*m_data)[4]; float (*m_data)[4];
}; };
// Not close, Ghidra struggles understinging this method so it will have to // FUNCTION: LEGO1 0x10002550
// be manually worked out. Included since I at least figured out what it was
// doing with rotateIndex and what overall operation it's trying to do.
// STUB: LEGO1 0x10002550
inline void Matrix4::ToQuaternion(Vector4& p_outQuat) inline void Matrix4::ToQuaternion(Vector4& p_outQuat)
{ {
/* float trace = m_data[0][0] + m_data[1][1] + m_data[2][2];
float trace = m_data[0] + m_data[5] + m_data[10];
if (trace > 0) { if (trace > 0) {
trace = sqrt(trace + 1.0); trace = sqrt(trace + 1.0);
p_outQuat->GetData()[3] = trace * 0.5f; p_outQuat[3] = trace * 0.5f;
p_outQuat->GetData()[0] = (m_data[9] - m_data[6]) * trace; trace = 0.5f / trace;
p_outQuat->GetData()[1] = (m_data[2] - m_data[8]) * trace; p_outQuat[0] = (m_data[2][1] - m_data[1][2]) * trace;
p_outQuat->GetData()[2] = (m_data[4] - m_data[1]) * trace; p_outQuat[1] = (m_data[0][2] - m_data[2][0]) * trace;
p_outQuat[2] = (m_data[1][0] - m_data[0][1]) * trace;
return; return;
} }
// ~GLOBAL: LEGO1 0x100d4090 // GLOBAL: LEGO1 0x100d4090
static int rotateIndex[] = {1, 2, 0}; static int rotateIndex[] = {1, 2, 0};
// Largest element along the trace // Largest element along the trace
int largest = m_data[0] < m_data[5]; int largest = 0;
if (*Element(largest, largest) < m_data[10]) if (m_data[0][0] < m_data[1][1])
largest = 1;
if (*Element(largest, largest) < m_data[2][2])
largest = 2; largest = 2;
int next = rotateIndex[largest]; int next = rotateIndex[largest];
int nextNext = rotateIndex[next]; int nextNext = rotateIndex[next];
float valueA = *Element(nextNext, nextNext);
float valueB = *Element(next, next);
float valueC = *Element(largest, largest);
// Above is somewhat decomped, below is pure speculation since the automatic trace = *Element(nextNext, nextNext);
// decomp becomes very garbled. trace += *Element(next, next);
float traceValue = sqrt(valueA - valueB - valueC + 1.0); trace = *Element(largest, largest) - trace;
trace += 1.0f;
trace = sqrt(trace);
p_outQuat->GetData()[largest] = traceValue * 0.5f; p_outQuat[largest] = trace * 0.5f;
traceValue = 0.5f / traceValue; trace = 0.5f / trace;
p_outQuat->GetData()[3] = (m_data[next + 4 * nextNext] - m_data[nextNext + 4 * next]) * traceValue; p_outQuat[3] = (*Element(nextNext, next) - *Element(next, nextNext)) * trace;
p_outQuat->GetData()[next] = (m_data[next + 4 * largest] + m_data[largest + 4 * next]) * traceValue; p_outQuat[next] = (*Element(largest, next) + *Element(next, largest)) * trace;
p_outQuat->GetData()[nextNext] = (m_data[nextNext + 4 * largest] + m_data[largest + 4 * nextNext]) * traceValue; p_outQuat[nextNext] = (*Element(largest, nextNext) + *Element(nextNext, largest)) * trace;
*/
} }
// FUNCTION: LEGO1 0x10002710 // FUNCTION: LEGO1 0x10002710