2024-03-26 13:51:52 -04:00
|
|
|
#include "legowegedge.h"
|
|
|
|
|
2024-12-22 13:47:39 -05:00
|
|
|
#include "legounkown100db7f4.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
2024-03-26 13:51:52 -04:00
|
|
|
DECOMP_SIZE_ASSERT(LegoWEGEdge, 0x54)
|
2025-01-17 20:33:27 -05:00
|
|
|
DECOMP_SIZE_ASSERT(PathWithTrigger, 0x0c)
|
2024-03-26 13:51:52 -04:00
|
|
|
|
|
|
|
// FUNCTION: LEGO1 0x1009a730
|
2024-12-22 13:47:39 -05:00
|
|
|
// FUNCTION: BETA10 0x101830ec
|
2024-03-26 13:51:52 -04:00
|
|
|
LegoWEGEdge::LegoWEGEdge()
|
|
|
|
{
|
|
|
|
m_unk0x0d = 0;
|
|
|
|
m_name = NULL;
|
|
|
|
m_unk0x14.Clear();
|
|
|
|
m_edgeNormals = NULL;
|
2024-05-12 15:30:34 -04:00
|
|
|
m_flags = 0;
|
2024-12-22 13:47:39 -05:00
|
|
|
m_numTriggers = 0;
|
2024-05-22 14:09:06 -04:00
|
|
|
m_pathTrigger = NULL;
|
2024-03-26 13:51:52 -04:00
|
|
|
m_unk0x50 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FUNCTION: LEGO1 0x1009a800
|
|
|
|
LegoWEGEdge::~LegoWEGEdge()
|
|
|
|
{
|
|
|
|
if (m_edges) {
|
|
|
|
delete[] m_edges;
|
|
|
|
m_edges = NULL;
|
|
|
|
}
|
|
|
|
if (m_name) {
|
|
|
|
delete[] m_name;
|
|
|
|
}
|
|
|
|
if (m_edgeNormals) {
|
|
|
|
delete[] m_edgeNormals;
|
|
|
|
}
|
2024-05-22 14:09:06 -04:00
|
|
|
if (m_pathTrigger) {
|
|
|
|
delete m_pathTrigger;
|
2024-03-26 13:51:52 -04:00
|
|
|
}
|
|
|
|
if (m_unk0x50) {
|
|
|
|
delete m_unk0x50;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-22 13:47:39 -05:00
|
|
|
// FUNCTION: LEGO1 0x1009a8c0
|
|
|
|
// FUNCTION: BETA10 0x101832f7
|
|
|
|
LegoS32 LegoWEGEdge::VTable0x04()
|
2024-03-26 13:51:52 -04:00
|
|
|
{
|
2024-12-22 13:47:39 -05:00
|
|
|
LegoS32 result = 0;
|
|
|
|
m_unk0x30.Clear();
|
|
|
|
LegoWEEdge::VTable0x04();
|
|
|
|
|
|
|
|
assert(m_numEdges > 1);
|
|
|
|
|
|
|
|
Vector3* local20;
|
|
|
|
if (IsEqual(m_edges[0]->m_faceA)) {
|
|
|
|
local20 = m_edges[0]->m_pointB;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
assert(IsEqual(m_edges[0]->m_faceB));
|
|
|
|
local20 = m_edges[0]->m_pointA;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector3 *local1c, *local14;
|
|
|
|
if (IsEqual(m_edges[1]->m_faceA)) {
|
|
|
|
local1c = m_edges[1]->m_pointB;
|
|
|
|
local14 = m_edges[1]->m_pointA;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
assert(IsEqual(m_edges[1]->m_faceB));
|
|
|
|
local1c = m_edges[1]->m_pointA;
|
|
|
|
local14 = m_edges[1]->m_pointB;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = FUN_1009aea0();
|
|
|
|
if (result != 0) {
|
|
|
|
result = -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(m_edgeNormals == NULL);
|
|
|
|
m_edgeNormals = new Mx4DPointFloat[m_numEdges];
|
|
|
|
assert(m_edgeNormals);
|
|
|
|
|
|
|
|
LegoUnknown100db7f4* edge;
|
|
|
|
LegoS32 i;
|
|
|
|
|
|
|
|
for (i = 0; i < m_numEdges; i++) {
|
|
|
|
edge = m_edges[i];
|
|
|
|
m_unk0x30 += *edge->m_pointA;
|
|
|
|
m_unk0x30 += *edge->m_pointB;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_unk0x30 /= m_numEdges * 2;
|
|
|
|
m_unk0x44 = 0.0f;
|
|
|
|
|
|
|
|
for (i = 0; i < m_numEdges; i++) {
|
|
|
|
Mx3DPointFloat local44;
|
|
|
|
edge = m_edges[i];
|
|
|
|
|
|
|
|
local44 = *edge->m_pointA;
|
|
|
|
local44 -= m_unk0x30;
|
|
|
|
float length = local44.LenSquared();
|
|
|
|
|
|
|
|
if (m_unk0x44 < length) {
|
|
|
|
m_unk0x44 = length;
|
|
|
|
}
|
|
|
|
|
|
|
|
local44 = *edge->m_pointB;
|
|
|
|
local44 -= m_unk0x30;
|
|
|
|
length = local44.LenSquared();
|
|
|
|
|
|
|
|
if (m_unk0x44 < length) {
|
|
|
|
m_unk0x44 = length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_unk0x44 = sqrt((double) m_unk0x44);
|
|
|
|
|
|
|
|
for (i = 0; i < m_numEdges; i++) {
|
|
|
|
edge = m_edges[i];
|
|
|
|
Vector3& local5c = edge->m_unk0x28;
|
|
|
|
|
|
|
|
if (edge->m_unk0x3c == 0) {
|
|
|
|
local5c = *m_edges[i]->m_pointB;
|
|
|
|
local5c -= *m_edges[i]->m_pointA;
|
|
|
|
edge->m_unk0x3c = local5c.LenSquared();
|
|
|
|
|
|
|
|
if (edge->m_unk0x3c <= 0.0f) {
|
|
|
|
assert(0);
|
|
|
|
if (result == 0) {
|
|
|
|
result = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
edge->m_unk0x3c = sqrt((double) edge->m_unk0x3c);
|
|
|
|
local5c /= edge->m_unk0x3c;
|
|
|
|
}
|
|
|
|
|
|
|
|
Mx3DPointFloat local58;
|
|
|
|
Vector3 local64(&m_edgeNormals[i][0]);
|
|
|
|
edge->FUN_1002ddc0(*this, local58);
|
2024-12-24 16:21:26 -05:00
|
|
|
local64.EqualsCross(local58, m_unk0x14);
|
2024-12-22 13:47:39 -05:00
|
|
|
|
2024-12-24 16:21:26 -05:00
|
|
|
m_edgeNormals[i][3] = -local64.Dot(*m_edges[i]->m_pointA, local64);
|
|
|
|
if (m_edgeNormals[i][3] + m_unk0x30.Dot(m_unk0x30, local64) < 0.0f) {
|
2024-12-22 13:47:39 -05:00
|
|
|
m_edgeNormals[i] *= -1.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (edge->GetFaceA() != NULL && edge->GetFaceB() != NULL) {
|
|
|
|
edge->SetFlags(LegoUnknown100db7f4::c_bit1 | LegoUnknown100db7f4::c_bit2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_numTriggers > 0) {
|
|
|
|
Vector3* vTrig1 = m_edges[0]->CCWVertex(*this);
|
|
|
|
Vector3* vTrig2 = m_edges[1]->CCWVertex(*this);
|
|
|
|
assert(vTrig1 && vTrig2);
|
|
|
|
|
|
|
|
m_unk0x50 = new Mx3DPointFloat();
|
|
|
|
*m_unk0x50 = *vTrig2;
|
|
|
|
*m_unk0x50 -= *vTrig1;
|
|
|
|
|
|
|
|
if (m_unk0x50->Unitize() < 0) {
|
|
|
|
assert(0);
|
|
|
|
delete m_unk0x50;
|
|
|
|
m_unk0x50 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetNumEdges() == 4) {
|
|
|
|
float local98 = 0.0f;
|
|
|
|
Mx3DPointFloat localb8(*m_edges[0]->CWVertex(*this));
|
|
|
|
Mx3DPointFloat local80(*m_edges[2]->CCWVertex(*this));
|
|
|
|
Mx3DPointFloat local94(*vTrig2);
|
|
|
|
|
|
|
|
local94 -= *vTrig1;
|
|
|
|
float local9c = sqrt(local94.LenSquared());
|
|
|
|
|
|
|
|
localb8 -= *vTrig1;
|
|
|
|
local80 -= *vTrig1;
|
|
|
|
|
2024-12-24 16:21:26 -05:00
|
|
|
float locala4 = localb8.Dot(*m_unk0x50, localb8);
|
2024-12-22 13:47:39 -05:00
|
|
|
if (local98 < locala4) {
|
|
|
|
local98 = locala4;
|
|
|
|
}
|
|
|
|
|
2024-12-24 16:21:26 -05:00
|
|
|
locala4 = local80.Dot(*m_unk0x50, local80);
|
2024-12-22 13:47:39 -05:00
|
|
|
if (locala4 < local9c) {
|
|
|
|
local9c = locala4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (local9c < local98) {
|
|
|
|
result = -3;
|
|
|
|
}
|
|
|
|
if (local9c - local98 < 0.0025) {
|
|
|
|
result = -4;
|
|
|
|
}
|
|
|
|
|
|
|
|
local98 += 0.001;
|
|
|
|
local9c -= 0.001;
|
|
|
|
|
|
|
|
for (LegoS32 j = 0; j < m_numTriggers; j++) {
|
|
|
|
if (m_pathTrigger[j].m_unk0x08 < local98) {
|
|
|
|
m_pathTrigger[j].m_unk0x08 = local98;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_pathTrigger[j].m_unk0x08 > local9c) {
|
|
|
|
m_pathTrigger[j].m_unk0x08 = local9c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
result = -5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FUNCTION: LEGO1 0x1009aea0
|
|
|
|
// FUNCTION: BETA10 0x10183e2a
|
|
|
|
LegoS32 LegoWEGEdge::FUN_1009aea0()
|
|
|
|
{
|
|
|
|
LegoU32 localc = FALSE;
|
|
|
|
Mx3DPointFloat local24;
|
|
|
|
|
|
|
|
if (m_numEdges < 3) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector3** local8 = new Vector3*[m_numEdges];
|
|
|
|
LegoS32 i;
|
|
|
|
|
|
|
|
for (i = 0; i < m_numEdges; i++) {
|
|
|
|
local8[i] = m_edges[i]->CWVertex(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 2; i < m_numEdges; i++) {
|
|
|
|
Mx3DPointFloat local3c;
|
|
|
|
Mx3DPointFloat local50;
|
|
|
|
float local28 = 0.0f;
|
|
|
|
|
|
|
|
local3c = *local8[i];
|
|
|
|
local3c -= *local8[i - 1];
|
|
|
|
local50 = *local8[i - 2];
|
|
|
|
local50 -= *local8[i - 1];
|
|
|
|
|
2024-12-24 16:21:26 -05:00
|
|
|
local24.EqualsCross(local50, local3c);
|
2024-12-22 13:47:39 -05:00
|
|
|
local28 = local24.LenSquared();
|
|
|
|
|
|
|
|
if (local28 < 0.00001f) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
float local58 = sqrt((double) local28);
|
|
|
|
local24 /= local58;
|
|
|
|
|
|
|
|
if (localc) {
|
2024-12-24 16:21:26 -05:00
|
|
|
float local54 = local24.Dot(m_unk0x14, local24);
|
2024-12-22 13:47:39 -05:00
|
|
|
if (local54 < 0.98) {
|
|
|
|
delete[] local8;
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_unk0x14[0] = local24[0];
|
|
|
|
m_unk0x14[1] = local24[1];
|
|
|
|
m_unk0x14[2] = local24[2];
|
2024-12-24 16:21:26 -05:00
|
|
|
m_unk0x14[3] = -local8[i]->Dot(*local8[i], local24);
|
2024-12-22 13:47:39 -05:00
|
|
|
localc = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (local8 != NULL) {
|
|
|
|
delete[] local8;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!localc) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2024-03-26 13:51:52 -04:00
|
|
|
}
|