Implement LegoCharacterManager::CreateROI (#709)

* WIP

* Create globals

* Add Read

* Name Init

* Add LegoCharacter init data

* Add define for NULL

* Use MxS8

* Add LegoCharacterLOD

* WIP CreateROI

* Fix

* WIP

* Match

* Match

* Match, implement Find

* Fix MeshBuilder

* Fix

* space
This commit is contained in:
Christian Semmler 2024-03-22 13:40:19 -04:00 committed by GitHub
parent 8cffa7cf8c
commit 68bb20f04f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 1617 additions and 109 deletions

View file

@ -317,6 +317,7 @@ add_library(lego1 SHARED
LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp
LEGO1/lego/legoomni/src/common/legobackgroundcolor.cpp
LEGO1/lego/legoomni/src/common/legocharactermanager.cpp
LEGO1/lego/legoomni/src/common/legocharacters.cpp
LEGO1/lego/legoomni/src/common/legofullscreenmovie.cpp
LEGO1/lego/legoomni/src/common/legogamestate.cpp
LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp

View file

@ -31,50 +31,27 @@ struct LegoCharacter {
MxU32 m_refCount; // 0x04
};
typedef map<const char*, LegoCharacter*, LegoCharacterComparator> LegoCharacterMap;
struct LegoCharacterData;
struct LegoSaveDataEntry3 {
char* m_name;
void* m_unk0x04;
LegoActor* m_actor;
MxS32 m_savePart1;
MxS32 m_savePart2;
MxU8 m_savePart3;
undefined4 m_unk0x18[6];
MxU8 m_frameOffsetInDwords; // 0x30
MxS32* m_pFrameData;
MxU8 m_currentFrame;
undefined4 m_unk0x3c[2];
MxU8 m_savePart5; // 0x44
undefined4 m_unk0x48[5];
MxU8 m_savePart6; // 0x5c
undefined4 m_unk0x60[11];
MxU8 m_savePart7; // 0x8c
undefined4 m_unk0x90[5];
MxU8 m_savePart8; // 0xa4
undefined4 m_unk0xa8[17];
MxU8 m_savePart9; // 0xec
undefined4 m_unk0xf0[5];
MxU8 m_savePart10; // 0x104
};
typedef map<const char*, LegoCharacter*, LegoCharacterComparator> LegoCharacterMap;
// SIZE 0x08
class LegoCharacterManager {
public:
LegoCharacterManager();
MxResult WriteSaveData3(LegoStorage* p_storage);
MxResult ReadSaveData3(LegoStorage* p_storage);
MxResult Write(LegoStorage* p_storage);
MxResult Read(LegoStorage* p_storage);
LegoROI* GetROI(const char* p_key, MxBool p_createEntity);
void InitSaveData();
void Init();
static void SetCustomizeAnimFile(const char* p_value);
static MxBool FUN_10084c00(const LegoChar*);
void FUN_100832a0();
void FUN_10083db0(LegoROI* p_roi);
void FUN_10083f10(LegoROI* p_roi);
LegoSaveDataEntry3* FUN_10084c60(const char* p_key);
LegoCharacterData* Find(const char* p_key);
MxBool FUN_10084ec0(LegoROI* p_roi);
MxU32 FUN_10085140(LegoROI*, MxBool);
LegoROI* FUN_10085210(const LegoChar*, LegoChar*, undefined);
@ -92,6 +69,12 @@ class LegoCharacterManager {
};
// clang-format off
// TEMPLATE: LEGO1 0x1001a690
// list<ROI *,allocator<ROI *> >::_Buynode
// TEMPLATE: LEGO1 0x10035790
// _Construct
// TEMPLATE: LEGO1 0x10082b90
// _Tree<char const *,pair<char const * const,LegoCharacter *>,map<char const *,LegoCharacter *,LegoCharacterComparator,allocator<LegoCharacter *> >::_Kfn,LegoCharacterComparator,allocator<LegoCharacter *> >::~_Tree<char const *,pair<char const * const,LegoCharacter *>,map<char const *,LegoCharacter *,LegoCharacterComparator,allocator<LegoCharacter *> >::_Kfn,LegoCharacterComparator,allocator<LegoCharacter *> >

View file

@ -0,0 +1,51 @@
#ifndef LEGOCHARACTERS_H
#define LEGOCHARACTERS_H
#include "decomp.h"
#include "mxtypes.h"
class LegoActor;
class LegoROI;
// SIZE 0x108
struct LegoCharacterData {
// SIZE 0x18
struct Part {
MxU8* m_unk0x00; // 0x00
const char** m_unk0x04; // 0x04
MxU8 m_unk0x08; // 0x08
MxU8* m_unk0x0c; // 0x0c
const char** m_unk0x10; // 0x10
MxU8 m_unk0x14; // 0x14
};
char* m_name; // 0x00
LegoROI* m_roi; // 0x04
LegoActor* m_actor; // 0x08
MxS32 m_unk0x0c; // 0x0c
MxS32 m_unk0x10; // 0x10
MxU8 m_unk0x14; // 0x14
Part m_parts[10]; // 0x18
};
// SIZE 0x58
struct LegoCharacterLOD {
enum {
c_flag1 = 0x01,
c_flag2 = 0x02
};
const char* m_name; // 0x00
const char* m_parentName; // 0x04
MxU32 m_flags; // 0x08
float m_boundingSphere[4]; // 0x0c
float m_boundingBox[6]; // 0x1c
float m_position[3]; // 0x34
float m_direction[3]; // 0x40
float m_up[3]; // 0x4c
};
extern LegoCharacterData g_characterDataInit[66];
extern LegoCharacterLOD g_characterLODs[11];
#endif // LEGOCHARACTERS_H

View file

@ -1,40 +1,40 @@
#include "legocharactermanager.h"
#include "legoanimactor.h"
#include "legocharacters.h"
#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)
DECOMP_SIZE_ASSERT(LegoCharacterManager, 0x08)
DECOMP_SIZE_ASSERT(LegoSaveDataEntry3, 0x108)
// GLOBAL: LEGO1 0x100f80c0
LegoSaveDataEntry3 g_saveDataInit[66]; // TODO: add data
// GLOBAL: LEGO1 0x100fc4e4
char* LegoCharacterManager::g_customizeAnimFile = NULL;
// GLOBAL: LEGO1 0x10104f20
LegoSaveDataEntry3 g_saveData3[66];
LegoCharacterData g_characterData[66];
// FUNCTION: LEGO1 0x10082a20
LegoCharacterManager::LegoCharacterManager()
{
m_characters = new LegoCharacterMap();
InitSaveData();
Init();
m_customizeAnimFile = new CustomizeAnimFileVariable("CUSTOMIZE_ANIM_FILE");
VariableTable()->SetVariable(m_customizeAnimFile);
}
// FUNCTION: LEGO1 0x10083270
void LegoCharacterManager::InitSaveData()
void LegoCharacterManager::Init()
{
for (MxS32 i = 0; i < 66; i++) {
g_saveData3[i] = g_saveDataInit[i];
for (MxS32 i = 0; i < _countof(g_characterData); i++) {
g_characterData[i] = g_characterDataInit[i];
}
}
@ -45,59 +45,95 @@ void LegoCharacterManager::FUN_100832a0()
}
// FUNCTION: LEGO1 0x10083310
MxResult LegoCharacterManager::WriteSaveData3(LegoStorage* p_storage)
MxResult LegoCharacterManager::Write(LegoStorage* p_storage)
{
MxResult result = FAILURE;
// This should probably be a for loop but I can't figure out how to
// make it match as a for loop.
LegoSaveDataEntry3* entry = g_saveData3;
const LegoSaveDataEntry3* end = &g_saveData3[66];
for (MxS32 i = 0; i < _countof(g_characterData) - 1; i++) {
LegoCharacterData* data = &g_characterData[i];
while (TRUE) {
if (p_storage->Write(&entry->m_savePart1, 4) != SUCCESS) {
break;
if (p_storage->Write(&data->m_unk0x0c, sizeof(data->m_unk0x0c)) != SUCCESS) {
goto done;
}
if (p_storage->Write(&entry->m_savePart2, 4) != SUCCESS) {
break;
if (p_storage->Write(&data->m_unk0x10, sizeof(data->m_unk0x10)) != SUCCESS) {
goto done;
}
if (p_storage->Write(&entry->m_savePart3, 1) != SUCCESS) {
break;
if (p_storage->Write(&data->m_unk0x14, sizeof(data->m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Write(&entry->m_currentFrame, 1) != SUCCESS) {
break;
if (p_storage->Write(&data->m_parts[1].m_unk0x08, sizeof(data->m_parts[1].m_unk0x08)) != SUCCESS) {
goto done;
}
if (p_storage->Write(&entry->m_savePart5, 1) != SUCCESS) {
break;
if (p_storage->Write(&data->m_parts[1].m_unk0x14, sizeof(data->m_parts[1].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Write(&entry->m_savePart6, 1) != SUCCESS) {
break;
if (p_storage->Write(&data->m_parts[2].m_unk0x14, sizeof(data->m_parts[2].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Write(&entry->m_savePart7, 1) != SUCCESS) {
break;
if (p_storage->Write(&data->m_parts[4].m_unk0x14, sizeof(data->m_parts[4].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Write(&entry->m_savePart8, 1) != SUCCESS) {
break;
if (p_storage->Write(&data->m_parts[5].m_unk0x14, sizeof(data->m_parts[5].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Write(&entry->m_savePart9, 1) != SUCCESS) {
break;
if (p_storage->Write(&data->m_parts[8].m_unk0x14, sizeof(data->m_parts[8].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Write(&entry->m_savePart10, 1) != SUCCESS) {
break;
}
if (++entry >= end) {
result = SUCCESS;
break;
if (p_storage->Write(&data->m_parts[9].m_unk0x14, sizeof(data->m_parts[9].m_unk0x14)) != SUCCESS) {
goto done;
}
}
result = SUCCESS;
done:
return result;
}
// STUB: LEGO1 0x100833f0
MxResult LegoCharacterManager::ReadSaveData3(LegoStorage* p_storage)
// FUNCTION: LEGO1 0x100833f0
MxResult LegoCharacterManager::Read(LegoStorage* p_storage)
{
return SUCCESS;
MxResult result = FAILURE;
for (MxS32 i = 0; i < _countof(g_characterData) - 1; i++) {
LegoCharacterData* data = &g_characterData[i];
if (p_storage->Read(&data->m_unk0x0c, sizeof(data->m_unk0x0c)) != SUCCESS) {
goto done;
}
if (p_storage->Read(&data->m_unk0x10, sizeof(data->m_unk0x10)) != SUCCESS) {
goto done;
}
if (p_storage->Read(&data->m_unk0x14, sizeof(data->m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Read(&data->m_parts[1].m_unk0x08, sizeof(data->m_parts[1].m_unk0x08)) != SUCCESS) {
goto done;
}
if (p_storage->Read(&data->m_parts[1].m_unk0x14, sizeof(data->m_parts[1].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Read(&data->m_parts[2].m_unk0x14, sizeof(data->m_parts[2].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Read(&data->m_parts[4].m_unk0x14, sizeof(data->m_parts[4].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Read(&data->m_parts[5].m_unk0x14, sizeof(data->m_parts[5].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Read(&data->m_parts[8].m_unk0x14, sizeof(data->m_parts[8].m_unk0x14)) != SUCCESS) {
goto done;
}
if (p_storage->Read(&data->m_parts[9].m_unk0x14, sizeof(data->m_parts[9].m_unk0x14)) != SUCCESS) {
goto done;
}
}
result = SUCCESS;
done:
return result;
}
// FUNCTION: LEGO1 0x10083500
@ -139,7 +175,7 @@ LegoROI* LegoCharacterManager::GetROI(const char* p_key, MxBool p_createEntity)
actor->SetROI(character->m_roi, FALSE, FALSE);
actor->FUN_100114e0(0);
actor->SetFlag(LegoActor::c_bit2);
FUN_10084c60(p_key)->m_actor = actor;
Find(p_key)->m_actor = actor;
}
return character->m_roi;
@ -160,10 +196,153 @@ void LegoCharacterManager::FUN_10083f10(LegoROI* p_roi)
// TODO
}
// STUB: LEGO1 0x10084030
// FUNCTION: LEGO1 0x10084030
LegoROI* LegoCharacterManager::CreateROI(const char* p_key)
{
return NULL;
MxBool success = FALSE;
LegoROI* roi = NULL;
BoundingSphere boundingSphere;
BoundingBox boundingBox;
MxMatrix mat;
CompoundObject* comp;
MxS32 i, j;
Tgl::Renderer* renderer = VideoManager()->GetRenderer();
ViewLODListManager* lodManager = GetViewLODListManager();
LegoTextureContainer* textureContainer = TextureContainer();
LegoCharacterData* characterData = Find(p_key);
if (characterData == NULL) {
goto done;
}
if (!strcmpi(p_key, "pep")) {
LegoCharacterData* pepper = Find("pepper");
characterData->m_unk0x0c = pepper->m_unk0x0c;
characterData->m_unk0x10 = pepper->m_unk0x10;
characterData->m_unk0x14 = pepper->m_unk0x14;
for (i = 0; i < _countof(characterData->m_parts); i++) {
characterData->m_parts[i] = pepper->m_parts[i];
}
}
roi = new LegoROI(renderer);
roi->SetName(p_key);
boundingSphere.Center()[0] = g_characterLODs[0].m_boundingSphere[0];
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];
boundingBox.Min()[1] = g_characterLODs[0].m_boundingBox[1];
boundingBox.Min()[2] = g_characterLODs[0].m_boundingBox[2];
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 (i = 0; i < _countof(g_characterLODs) - 1; i++) {
ViewLODList *lodList, *dupLodList;
LegoROI* childROI;
MxS32 lodSize;
const char* parentName;
char lodName[64];
LegoCharacterData::Part& part = characterData->m_parts[i];
if (i == 0 || i == 1) {
parentName = part.m_unk0x04[part.m_unk0x00[part.m_unk0x08]];
}
else {
parentName = g_characterLODs[i + 1].m_parentName;
}
lodList = lodManager->Lookup(parentName);
lodSize = lodList->Size();
sprintf(lodName, "%s%d", p_key, i);
dupLodList = lodManager->Create(lodName, lodSize);
for (j = 0; j < lodSize; j++) {
dupLodList->PushBack(((LegoLOD*) (*lodList)[j])->Clone(renderer));
}
lodList->Release();
lodList = dupLodList;
childROI = new LegoROI(renderer, lodList);
lodList->Release();
childROI->SetName(g_characterLODs[i + 1].m_name);
childROI->SetParentROI(roi);
BoundingSphere childBoundingSphere;
childBoundingSphere.Center()[0] = g_characterLODs[i + 1].m_boundingSphere[0];
childBoundingSphere.Center()[1] = g_characterLODs[i + 1].m_boundingSphere[1];
childBoundingSphere.Center()[2] = g_characterLODs[i + 1].m_boundingSphere[2];
childBoundingSphere.Radius() = g_characterLODs[i + 1].m_boundingSphere[3];
childROI->SetBoundingSphere(childBoundingSphere);
BoundingBox childBoundingBox;
childBoundingBox.Min()[0] = g_characterLODs[i + 1].m_boundingBox[0];
childBoundingBox.Min()[1] = g_characterLODs[i + 1].m_boundingBox[1];
childBoundingBox.Min()[2] = g_characterLODs[i + 1].m_boundingBox[2];
childBoundingBox.Max()[0] = g_characterLODs[i + 1].m_boundingBox[3];
childBoundingBox.Max()[1] = g_characterLODs[i + 1].m_boundingBox[4];
childBoundingBox.Max()[2] = g_characterLODs[i + 1].m_boundingBox[5];
childROI->SetUnknown0x80(childBoundingBox);
CalcLocalTransform(
Mx3DPointFloat(g_characterLODs[i + 1].m_position),
Mx3DPointFloat(g_characterLODs[i + 1].m_direction),
Mx3DPointFloat(g_characterLODs[i + 1].m_up),
mat
);
childROI->WrappedSetLocalTransform(mat);
if (g_characterLODs[i + 1].m_flags & LegoCharacterLOD::c_flag1 &&
(i != 0 || part.m_unk0x00[part.m_unk0x08] != 0)) {
LegoTextureInfo* textureInfo = textureContainer->Get(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]]);
if (textureInfo != NULL) {
childROI->FUN_100a9210(textureInfo);
childROI->FUN_100a9170(1.0F, 1.0F, 1.0F, 0.0F);
}
}
else if (g_characterLODs[i + 1].m_flags & LegoCharacterLOD::c_flag2 || (i == 0 && part.m_unk0x00[part.m_unk0x08] == 0)) {
LegoFloat red, green, blue, alpha;
childROI->FUN_100a9bf0(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]], red, green, blue, alpha);
childROI->FUN_100a9170(red, green, blue, alpha);
}
comp->push_back(childROI);
}
CalcLocalTransform(
Mx3DPointFloat(g_characterLODs[0].m_position),
Mx3DPointFloat(g_characterLODs[0].m_direction),
Mx3DPointFloat(g_characterLODs[0].m_up),
mat
);
roi->WrappedSetLocalTransform(mat);
characterData->m_roi = roi;
success = TRUE;
done:
if (!success && roi != NULL) {
delete roi;
roi = NULL;
}
return roi;
}
// STUB: LEGO1 0x10084c00
@ -173,9 +352,21 @@ MxBool LegoCharacterManager::FUN_10084c00(const LegoChar*)
return FALSE;
}
// STUB: LEGO1 0x10084c60
LegoSaveDataEntry3* LegoCharacterManager::FUN_10084c60(const char* p_key)
// FUNCTION: LEGO1 0x10084c60
LegoCharacterData* LegoCharacterManager::Find(const char* p_key)
{
MxU32 i;
for (i = 0; i < _countof(g_characterData) - 1; i++) {
if (!strcmpi(g_characterData[i].m_name, p_key)) {
break;
}
}
if (i < _countof(g_characterData)) {
return &g_characterData[i];
}
return NULL;
}

File diff suppressed because it is too large Load diff

View file

@ -235,7 +235,7 @@ MxResult LegoGameState::Save(MxULong p_slot)
}
WriteEndOfVariables(&fileStorage);
CharacterManager()->WriteSaveData3(&fileStorage);
CharacterManager()->Write(&fileStorage);
PlantManager()->Save(&fileStorage);
result = BuildingManager()->Save(&fileStorage);
@ -334,7 +334,7 @@ MxResult LegoGameState::Load(MxULong p_slot)
SetLightPosition(atoi(lightPosition));
}
if (CharacterManager()->ReadSaveData3(&fileStorage) == FAILURE) {
if (CharacterManager()->Read(&fileStorage) == FAILURE) {
goto done;
}
if (PlantManager()->Load(&fileStorage) == FAILURE) {
@ -1057,7 +1057,7 @@ void LegoGameState::Init()
SetLightPosition(2);
PlantManager()->Init();
BuildingManager()->Init();
CharacterManager()->InitSaveData();
CharacterManager()->Init();
AnimationManager()->FUN_1005ee80(TRUE);
SetColors();
RemoveActor();

View file

@ -128,7 +128,7 @@ Mx3DPointFloat LegoCameraController::GetWorldUp()
{
if (m_lego3DView && m_lego3DView->GetPointOfView()) {
Mx3DPointFloat vec;
vec = Vector3(m_lego3DView->GetPointOfView()->GetWorldUp());
vec = m_lego3DView->GetPointOfView()->GetWorldUp();
return Mx3DPointFloat(vec[0], vec[1], vec[2]);
}
else {
@ -141,7 +141,7 @@ Mx3DPointFloat LegoCameraController::GetWorldLocation()
{
if (m_lego3DView && m_lego3DView->GetPointOfView()) {
Mx3DPointFloat vec;
vec = Vector3(m_lego3DView->GetPointOfView()->GetWorldPosition());
vec = m_lego3DView->GetPointOfView()->GetWorldPosition();
return Mx3DPointFloat(vec[0], vec[1] - m_entityOffsetUp, vec[2]);
}
else {
@ -154,7 +154,7 @@ Mx3DPointFloat LegoCameraController::GetWorldDirection()
{
if (m_lego3DView && m_lego3DView->GetPointOfView()) {
Mx3DPointFloat vec;
vec = Vector3(m_lego3DView->GetPointOfView()->GetWorldDirection());
vec = m_lego3DView->GetPointOfView()->GetWorldDirection();
return Mx3DPointFloat(vec[0], vec[1], vec[2]);
}
else {

View file

@ -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;
}
}

View file

@ -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

View file

@ -553,6 +553,23 @@ void LegoROI::FUN_100a9d30(ROIHandler p_func)
g_unk0x101013ac = p_func;
}
// FUNCTION: LEGO1 0x100a9d40
void LegoROI::SetName(const LegoChar* p_name)
{
if (m_name != NULL) {
delete[] m_name;
}
if (p_name != NULL) {
m_name = new LegoChar[strlen(p_name) + 1];
strcpy(m_name, p_name);
strlwr(m_name);
}
else {
m_name = NULL;
}
}
// FUNCTION: LEGO1 0x100a9e10
void LegoROI::SetDisplayBB(int p_displayBB)
{

View file

@ -34,6 +34,7 @@ class LegoROI : public ViewROI {
LegoResult SetFrame(LegoAnim* p_anim, LegoTime p_time);
LegoResult FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult FUN_100a9210(LegoTextureInfo* p_textureInfo);
void SetName(const LegoChar* p_name);
float IntrinsicImportance() const override; // vtable+0x04
void UpdateWorldBoundingVolumes() override; // vtable+0x18
@ -58,6 +59,9 @@ class LegoROI : public ViewROI {
inline LegoEntity* GetEntity() { return m_entity; }
inline void SetEntity(LegoEntity* p_entity) { m_entity = p_entity; }
inline void SetComp(CompoundObject* p_comp) { comp = p_comp; }
inline void SetBoundingSphere(const BoundingSphere& p_sphere) { m_sphere = m_world_bounding_sphere = p_sphere; }
inline void SetUnknown0x80(const BoundingBox& p_unk0x80) { m_unk0x80 = p_unk0x80; }
// SYNTHETIC: LEGO1 0x100a82b0
// LegoROI::`scalar deleting destructor'

View file

@ -20,7 +20,7 @@ class Mx3DPointFloat : public Vector3 {
// FUNCTION: LEGO1 0x100343a0
inline Mx3DPointFloat(const Mx3DPointFloat& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); }
inline Mx3DPointFloat(const float* p_other) : Vector3(m_elements) { EqualsImpl((float*) p_other); }
inline Mx3DPointFloat(const Vector3& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); }
// SYNTHETIC: LEGO1 0x1001d170
// Mx3DPointFloat::Mx3DPointFloat

View file

@ -52,6 +52,10 @@ typedef MxU8 MxBool;
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#define TWOCC(a, b) (((a) << 0) | ((b) << 8))
#define FOURCC(a, b, c, d) (((a) << 0) | ((b) << 8) | ((c) << 16) | ((d) << 24))

View file

@ -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) {

View file

@ -178,7 +178,7 @@ Result MeshBuilderImpl::GetBoundingBox(float min[3], float max[3])
MeshBuilder* MeshBuilderImpl::Clone()
{
MeshBuilderImpl* mesh = new MeshBuilderImpl();
int ret = m_data->Clone(0, IID_IDirect3DRMMeshBuilder, (void**) &mesh->m_data);
int ret = m_data->Clone(0, IID_IDirect3DRMMesh, (void**) &mesh->m_data);
if (ret < 0) {
delete mesh;
mesh = NULL;