From 84885f6be392c8ad37661e4c18f0de76839c967f Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 22 Mar 2024 11:00:56 -0400 Subject: [PATCH] WIP CreateROI --- LEGO1/lego/legoomni/include/legocharacters.h | 3 +- .../src/common/legocharactermanager.cpp | 111 ++++++++++++++++-- LEGO1/lego/sources/roi/legolod.cpp | 68 +++++++---- LEGO1/lego/sources/roi/legolod.h | 5 +- LEGO1/realtime/orientableroi.h | 2 + 5 files changed, 154 insertions(+), 35 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocharacters.h b/LEGO1/lego/legoomni/include/legocharacters.h index ea89f10e..101ced3f 100644 --- a/LEGO1/lego/legoomni/include/legocharacters.h +++ b/LEGO1/lego/legoomni/include/legocharacters.h @@ -5,6 +5,7 @@ #include "mxtypes.h" class LegoActor; +class LegoROI; // SIZE 0x108 struct LegoCharacterData { @@ -19,7 +20,7 @@ struct LegoCharacterData { }; char* m_name; // 0x00 - void* m_unk0x04; // 0x04 + LegoROI* m_roi; // 0x04 LegoActor* m_actor; // 0x08 MxS32 m_unk0x0c; // 0x0c MxS32 m_unk0x10; // 0x10 diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index 240477bd..be13f690 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -5,7 +5,10 @@ #include "legogamestate.h" #include "legovideomanager.h" #include "misc.h" +#include "misc/legocontainer.h" #include "mxmisc.h" +#include "realtime/realtime.h" +#include "roi/legolod.h" #include "roi/legoroi.h" DECOMP_SIZE_ASSERT(LegoCharacter, 0x08) @@ -202,25 +205,26 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key) BoundingBox boundingBox; MxMatrix mat; CompoundObject* comp; + MxS32 i, j; Tgl::Renderer* renderer = VideoManager()->GetRenderer(); ViewLODListManager* lodManager = GetViewLODListManager(); LegoTextureContainer* textureContainer = TextureContainer(); - LegoCharacterData* entry = FUN_10084c60(p_key); + LegoCharacterData* characterData = FUN_10084c60(p_key); - if (entry == NULL) { + if (characterData == NULL) { goto done; } if (!strcmpi(p_key, "pep")) { LegoCharacterData* pepper = FUN_10084c60("pepper"); - entry->m_unk0x0c = pepper->m_unk0x0c; - entry->m_unk0x10 = pepper->m_unk0x10; - entry->m_unk0x14 = pepper->m_unk0x14; + characterData->m_unk0x0c = pepper->m_unk0x0c; + characterData->m_unk0x10 = pepper->m_unk0x10; + characterData->m_unk0x14 = pepper->m_unk0x14; - for (MxS32 i = 0; i < _countof(entry->m_parts); i++) { - entry->m_parts[i] = pepper->m_parts[i]; + for (i = 0; i < _countof(characterData->m_parts); i++) { + characterData->m_parts[i] = pepper->m_parts[i]; } } @@ -231,7 +235,6 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key) boundingSphere.Center()[1] = g_characterLODs[0].m_boundingSphere[1]; boundingSphere.Center()[2] = g_characterLODs[0].m_boundingSphere[2]; boundingSphere.Radius() = g_characterLODs[0].m_boundingSphere[3]; - roi->SetBoundingSphere(boundingSphere); boundingBox.Min()[0] = g_characterLODs[0].m_boundingBox[0]; @@ -240,12 +243,102 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key) boundingBox.Max()[0] = g_characterLODs[0].m_boundingBox[3]; boundingBox.Max()[1] = g_characterLODs[0].m_boundingBox[4]; boundingBox.Max()[2] = g_characterLODs[0].m_boundingBox[5]; - roi->SetUnknown0x80(boundingBox); comp = new CompoundObject(); roi->SetComp(comp); + for (j = 0; j < _countof(g_characterLODs) - 1; j++) { + ViewLODList *lodList, *dupLodList; + LegoROI* childROI; + MxU32 lodSize; + const char* parentName; + char lodName[64]; + + // TODO + if (j == 0 || j == 1) { + parentName = characterData->m_parts[j] + .m_unk0x04[characterData->m_parts[j].m_unk0x00[characterData->m_parts[j].m_unk0x08]]; + } + else { + parentName = g_characterLODs[j + 1].m_parentName; + } + + lodList = lodManager->Lookup(parentName); + lodSize = lodList->Size(); + sprintf(lodName, "%s%d", p_key, j); + dupLodList = lodManager->Create(lodName, lodSize); + + for (MxS32 k = 0; k < lodSize; k++) { + dupLodList->PushBack(((LegoLOD*) (*lodList)[k])->Clone(renderer)); + } + + lodList->Release(); + lodList = dupLodList; + + childROI = new LegoROI(renderer, lodList); + lodList->Release(); + + childROI->SetName(g_characterLODs[j + 1].m_name); + childROI->SetParentROI(roi); + + BoundingSphere childBoundingSphere; + + childBoundingSphere.Center()[0] = g_characterLODs[j + 1].m_boundingSphere[0]; + childBoundingSphere.Center()[1] = g_characterLODs[j + 1].m_boundingSphere[1]; + childBoundingSphere.Center()[2] = g_characterLODs[j + 1].m_boundingSphere[2]; + childBoundingSphere.Radius() = g_characterLODs[j + 1].m_boundingSphere[3]; + childROI->SetBoundingSphere(childBoundingSphere); + + BoundingBox childBoundingBox; + childBoundingBox.Min()[0] = g_characterLODs[j + 1].m_boundingBox[0]; + childBoundingBox.Min()[1] = g_characterLODs[j + 1].m_boundingBox[1]; + childBoundingBox.Min()[2] = g_characterLODs[j + 1].m_boundingBox[2]; + childBoundingBox.Max()[0] = g_characterLODs[j + 1].m_boundingBox[3]; + childBoundingBox.Max()[1] = g_characterLODs[j + 1].m_boundingBox[4]; + childBoundingBox.Max()[2] = g_characterLODs[j + 1].m_boundingBox[5]; + childROI->SetUnknown0x80(childBoundingBox); + + CalcLocalTransform( + g_characterLODs[j + 1].m_position, + g_characterLODs[j + 1].m_direction, + g_characterLODs[j + 1].m_up, + mat + ); + childROI->WrappedSetLocalTransform(mat); + + if (g_characterLODs[j + 1].m_flags & LegoCharacterLOD::c_flag1 && + (j != 0 || characterData->m_parts[j].m_unk0x00[characterData->m_parts[j].m_unk0x08] != 0)) { + + LegoTextureInfo* textureInfo = + textureContainer->Get(characterData->m_parts[j].m_unk0x10[characterData->m_parts[j].m_unk0x14]); + + if (textureInfo != NULL) { + childROI->FUN_100a9210(textureInfo); + childROI->FUN_100a9170(1.0F, 1.0F, 1.0F, 0.0F); + } + } + else if (g_characterLODs[j + 1].m_flags & LegoCharacterLOD::c_flag2 || (j == 0 && characterData->m_parts[j].m_unk0x00[characterData->m_parts[j].m_unk0x08] == 0)) { + LegoFloat red, green, blue, alpha; + childROI->FUN_100a9bf0( + characterData->m_parts[j].m_unk0x10[characterData->m_parts[j].m_unk0x14], + red, + green, + blue, + alpha + ); + childROI->FUN_100a9170(red, green, blue, alpha); + } + + comp->push_back(childROI); + } + + CalcLocalTransform(g_characterLODs[0].m_position, g_characterLODs[0].m_direction, g_characterLODs[0].m_up, mat); + roi->WrappedSetLocalTransform(mat); + + characterData->m_roi = roi; + success = TRUE; + done: if (!success && roi != NULL) { delete roi; diff --git a/LEGO1/lego/sources/roi/legolod.cpp b/LEGO1/lego/sources/roi/legolod.cpp index 9536b51a..9a36ec9f 100644 --- a/LEGO1/lego/sources/roi/legolod.cpp +++ b/LEGO1/lego/sources/roi/legolod.cpp @@ -28,7 +28,7 @@ LegoLOD::LegoLOD(Tgl::Renderer* p_renderer) : ViewLOD(p_renderer) GetD3DRM(p_renderer)->CreateMaterial(10.0, &g_unk0x101013d4); } - m_meshes = NULL; + m_melems = NULL; m_numMeshes = 0; m_numVertices = 0; m_numPolys = 0; @@ -38,17 +38,17 @@ LegoLOD::LegoLOD(Tgl::Renderer* p_renderer) : ViewLOD(p_renderer) // FUNCTION: LEGO1 0x100aa450 LegoLOD::~LegoLOD() { - if (m_numMeshes && m_meshes != NULL) { + if (m_numMeshes && m_melems != NULL) { for (LegoU32 i = 0; i < m_numMeshes; i++) { - if (m_meshes[i].m_tglMesh != NULL) { - delete m_meshes[i].m_tglMesh; - m_meshes[i].m_tglMesh = NULL; + if (m_melems[i].m_tglMesh != NULL) { + delete m_melems[i].m_tglMesh; + m_melems[i].m_tglMesh = NULL; } } } - if (m_meshes) { - delete[] m_meshes; + if (m_melems) { + delete[] m_melems; } } @@ -90,8 +90,8 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text SetFlag(c_bit4); - m_meshes = new Mesh[m_numMeshes]; - memset(m_meshes, 0, sizeof(*m_meshes) * m_numMeshes); + m_melems = new Mesh[m_numMeshes]; + memset(m_melems, 0, sizeof(*m_melems) * m_numMeshes); meshUnd1 = m_numMeshes - 1; meshUnd2 = 0; @@ -193,7 +193,7 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text meshUnd2++; } - m_meshes[meshIndex].m_tglMesh = m_meshBuilder->CreateMesh( + m_melems[meshIndex].m_tglMesh = m_meshBuilder->CreateMesh( numPolys & MAXWORD, numVertices & MAXWORD, vertices, @@ -204,11 +204,11 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text shadingModel ); - if (m_meshes[meshIndex].m_tglMesh == NULL) { + if (m_melems[meshIndex].m_tglMesh == NULL) { goto done; } - m_meshes[meshIndex].m_tglMesh->SetShadingModel(shadingModel); + m_melems[meshIndex].m_tglMesh->SetShadingModel(shadingModel); if (textureName != NULL) { if (mesh->GetUnknown0x21()) { @@ -221,9 +221,9 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text goto done; } - m_meshes[meshIndex].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F); - LegoTextureInfo::SetGroupTexture(m_meshes[meshIndex].m_tglMesh, textureInfo); - m_meshes[meshIndex].m_unk0x04 = TRUE; + m_melems[meshIndex].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F); + LegoTextureInfo::SetGroupTexture(m_melems[meshIndex].m_tglMesh, textureInfo); + m_melems[meshIndex].m_unk0x04 = TRUE; } else { LegoFloat red = 1.0F; @@ -241,13 +241,13 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text alpha = mesh->GetAlpha(); } - m_meshes[meshIndex].m_tglMesh->SetColor(red, green, blue, alpha); + m_melems[meshIndex].m_tglMesh->SetColor(red, green, blue, alpha); } if (mesh->GetUnknown0x0d() > 0) { IDirect3DRMMesh* mesh; D3DRMGROUPINDEX index; - GetMeshData(mesh, index, m_meshes[meshIndex].m_tglMesh); + GetMeshData(mesh, index, m_melems[meshIndex].m_tglMesh); mesh->SetGroupMaterial(index, g_unk0x101013d4); } @@ -302,12 +302,34 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text return FAILURE; } +// FUNCTION: LEGO1 0x100aabb0 +LegoLOD* LegoLOD::Clone(Tgl::Renderer* p_renderer) +{ + LegoLOD* dupLod = new LegoLOD(p_renderer); + + dupLod->m_meshBuilder = m_meshBuilder->Clone(); + dupLod->m_melems = new Mesh[m_numMeshes]; + + for (LegoU32 i = 0; i < m_numMeshes; i++) { + dupLod->m_melems[i].m_tglMesh = m_melems[i].m_tglMesh->ShallowClone(dupLod->m_meshBuilder); + dupLod->m_melems[i].m_unk0x04 = m_melems[i].m_unk0x04; + } + + dupLod->m_unk0x08 = m_unk0x08; + dupLod->m_numMeshes = m_numMeshes; + dupLod->m_numVertices = m_numVertices; + dupLod->m_numPolys = m_numPolys; + dupLod->m_unk0x1c = m_unk0x1c; + + return dupLod; +} + // FUNCTION: LEGO1 0x100aacb0 LegoResult LegoLOD::FUN_100aacb0(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha) { for (LegoU32 i = m_unk0x1c; i < m_numMeshes; i++) { - if (!m_meshes[i].m_unk0x04) { - m_meshes[i].m_tglMesh->SetColor(p_red, p_green, p_blue, p_alpha); + if (!m_melems[i].m_unk0x04) { + m_melems[i].m_tglMesh->SetColor(p_red, p_green, p_blue, p_alpha); } } @@ -318,10 +340,10 @@ LegoResult LegoLOD::FUN_100aacb0(LegoFloat p_red, LegoFloat p_green, LegoFloat p LegoResult LegoLOD::FUN_100aad00(LegoTextureInfo* p_textureInfo) { for (LegoU32 i = m_unk0x1c; i < m_numMeshes; i++) { - if (m_meshes[i].m_unk0x04) { - LegoTextureInfo::SetGroupTexture(m_meshes[i].m_tglMesh, p_textureInfo); - m_meshes[i].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F); - m_meshes[i].m_unk0x04 = TRUE; + if (m_melems[i].m_unk0x04) { + LegoTextureInfo::SetGroupTexture(m_melems[i].m_tglMesh, p_textureInfo); + m_melems[i].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F); + m_melems[i].m_unk0x04 = TRUE; } } diff --git a/LEGO1/lego/sources/roi/legolod.h b/LEGO1/lego/sources/roi/legolod.h index 9b1143ef..f454f200 100644 --- a/LEGO1/lego/sources/roi/legolod.h +++ b/LEGO1/lego/sources/roi/legolod.h @@ -27,7 +27,8 @@ class LegoLOD : public ViewLOD { // FUNCTION: LEGO1 0x100aae80 float VTable0x10() override { return 0.0; } // vtable+0x10 - LegoResult Read(Tgl::Renderer*, LegoTextureContainer* p_textureContainer, LegoStorage* p_storage); + LegoResult Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_textureContainer, LegoStorage* p_storage); + LegoLOD* Clone(Tgl::Renderer* p_renderer); LegoResult FUN_100aacb0(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha); LegoResult FUN_100aad00(LegoTextureInfo* p_textureInfo); @@ -37,7 +38,7 @@ class LegoLOD : public ViewLOD { // LegoLOD::`scalar deleting destructor' protected: - Mesh* m_meshes; // 0x0c + Mesh* m_melems; // 0x0c LegoU32 m_numMeshes; // 0x10 LegoU32 m_numVertices; // 0x14 LegoU32 m_numPolys; // 0x18 diff --git a/LEGO1/realtime/orientableroi.h b/LEGO1/realtime/orientableroi.h index beec0ef9..d7b9f998 100644 --- a/LEGO1/realtime/orientableroi.h +++ b/LEGO1/realtime/orientableroi.h @@ -45,6 +45,8 @@ class OrientableROI : public ROI { const float* GetWorldUp() const { return m_local2world[1]; } OrientableROI* GetParentROI() const { return m_parentROI; } + void SetParentROI(OrientableROI* p_parentROI) { m_parentROI = p_parentROI; } + void ToggleUnknown0xd8(BOOL p_enable) { if (p_enable) {