diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b82c241..be58cb6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,6 +117,7 @@ target_include_directories(realtime PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAKE target_link_libraries(realtime PRIVATE Vec::Vec) add_library(viewmanager STATIC + LEGO1/viewmanager/viewlod.cpp LEGO1/viewmanager/viewlodlist.cpp LEGO1/viewmanager/viewmanager.cpp LEGO1/viewmanager/viewroi.cpp @@ -141,7 +142,7 @@ add_library(roi STATIC register_lego1_target(roi) set_property(TARGET roi PROPERTY ARCHIVE_OUTPUT_NAME "roi$<$:d>") target_include_directories(roi PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAKE_SOURCE_DIR}/LEGO1/lego/sources" "${CMAKE_SOURCE_DIR}/util") -target_link_libraries(roi PRIVATE) +target_link_libraries(roi PRIVATE viewmanager) add_library(anim STATIC LEGO1/lego/sources/anim/legoanim.cpp diff --git a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp index 4faf16e3..de7fbfa6 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp @@ -331,11 +331,11 @@ MxResult LegoWorldPresenter::FUN_10067360(ModelDbPart& p_part, FILE* p_wdbFile) chunk.SetLength(p_part.m_partDataLength); chunk.SetData(buff); - LegoPartPresenter part; - result = part.Read(chunk); + LegoPartPresenter partPresenter; + result = partPresenter.Read(chunk); if (result == SUCCESS) { - part.FUN_1007df20(); + partPresenter.FUN_1007df20(); } delete[] buff; diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index 029826c0..16051cc4 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -1,9 +1,16 @@ #include "legoroi.h" +#include "tgl/d3drm/impl.h" + #include DECOMP_SIZE_ASSERT(LegoROI, 0x108) DECOMP_SIZE_ASSERT(TimeROI, 0x10c) +DECOMP_SIZE_ASSERT(LODObject, 0x04) +DECOMP_SIZE_ASSERT(ViewLOD, 0x0c) +DECOMP_SIZE_ASSERT(LegoLOD, 0x20) + +inline IDirect3DRM2* GetD3DRM(Tgl::Renderer* pRenderer); // SIZE 0x14 typedef struct { @@ -38,6 +45,9 @@ int g_roiConfig = 100; // GLOBAL: LEGO1 0x101013ac ROIHandler g_someHandlerFunction = NULL; +// GLOBAL: LEGO1 0x101013d4 +LPDIRECT3DRMMATERIAL g_unk0x101013d4 = NULL; + // FUNCTION: LEGO1 0x100a81c0 void LegoROI::configureLegoROI(int p_roiConfig) { @@ -99,7 +109,7 @@ LegoResult LegoROI::SetFrame(LegoAnim* p_anim, LegoTime p_time) } // FUNCTION: LEGO1 0x100a9a50 -TimeROI::TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, int p_time) : LegoROI(p_renderer, p_lodList) +TimeROI::TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_time) : LegoROI(p_renderer, p_lodList) { m_time = p_time; } @@ -171,3 +181,28 @@ void LegoROI::UpdateWorldBoundingVolumes() { // TODO } + +// FUNCTION: LEGO1 0x100aa380 +LegoLOD::LegoLOD(Tgl::Renderer* p_renderer) : ViewLOD(p_renderer) +{ + if (g_unk0x101013d4 == NULL) { + GetD3DRM(p_renderer)->CreateMaterial(10.0, &g_unk0x101013d4); + } + + m_unk0x0c = 0; + m_unk0x10 = 0; + m_unk0x14 = 0; + m_numPolys = 0; + m_unk0x1c = 0; +} + +// STUB: LEGO1 0x100aa450 +LegoLOD::~LegoLOD() +{ + // TODO +} + +inline IDirect3DRM2* GetD3DRM(Tgl::Renderer* pRenderer) +{ + return ((TglImpl::RendererImpl*) pRenderer)->ImplementationData(); +} diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index 643713a3..7a9eaf96 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -2,6 +2,7 @@ #define LEGOROI_H #include "misc/legotypes.h" +#include "viewmanager/viewlod.h" #include "viewmanager/viewroi.h" typedef unsigned char (*ROIHandler)(char*, char*, unsigned int); @@ -11,6 +12,31 @@ class LegoTextureContainer; class LegoStorage; class LegoAnim; +// VTABLE: LEGO1 0x100dbf10 +// SIZE 0x20 +class LegoLOD : public ViewLOD { +public: + LegoLOD(Tgl::Renderer*); + ~LegoLOD() override; + + // FUNCTION: LEGO1 0x100aae70 + int NumPolys() const override { return m_numPolys; } // vtable+0x0c + + // FUNCTION: LEGO1 0x100aae80 + float VTable0x10() override { return 0.0; } // vtable+0x10 + + // SYNTHETIC: LEGO1 0x100aa430 + // LegoLOD::`scalar deleting destructor' + +protected: + // TODO: Review 1996 version + undefined4 m_unk0x0c; // 0x0c + undefined4 m_unk0x10; // 0x10 + undefined4 m_unk0x14; // 0x14 + LegoU32 m_numPolys; // 0x18 + undefined4 m_unk0x1c; // 0x1c +}; + // VTABLE: LEGO1 0x100dbe38 // SIZE 0x108 class LegoROI : public ViewROI { @@ -44,7 +70,7 @@ class LegoROI : public ViewROI { ); static unsigned char ColorAliasLookup(char* p_param, float& p_red, float& p_green, float& p_blue, float& p_other); - inline const char* GetName() const { return m_name; } + inline const LegoChar* GetName() const { return m_name; } inline LegoEntity* GetUnknown0x104() { return m_unk0x104; } inline void SetUnknown0x104(LegoEntity* p_unk0x104) { m_unk0x104 = p_unk0x104; } @@ -63,13 +89,13 @@ class LegoROI : public ViewROI { // SIZE 0x10c class TimeROI : public LegoROI { public: - TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, int p_time); + TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_time); // SYNTHETIC: LEGO1 0x100a9ad0 // TimeROI::`scalar deleting destructor' private: - int m_time; // 0x108 + LegoTime m_time; // 0x108 }; #endif // LEGOROI_H diff --git a/LEGO1/realtime/roi.h b/LEGO1/realtime/roi.h index 850a533f..70f335a0 100644 --- a/LEGO1/realtime/roi.h +++ b/LEGO1/realtime/roi.h @@ -45,13 +45,22 @@ class BoundingSphere { * Abstract base class representing a single LOD version of * a geometric object. */ +// VTABLE: LEGO1 0x100dbd90 +// SIZE 0x04 class LODObject { public: // LODObject(); + + // FUNCTION: LEGO1 0x100a6f00 virtual ~LODObject() {} - virtual float Cost(float pixels_covered) const = 0; // vtable+0x04 - virtual float AveragePolyArea() const = 0; // vtable+0x08 - virtual int NVerts() const = 0; // vtable+0x0c + + virtual double AveragePolyArea() const = 0; // vtable+0x04 + virtual int NVerts() const = 0; // vtable+0x08 + virtual int NumPolys() const = 0; // vtable+0x0c + virtual float VTable0x10() = 0; // vtable+0x10 + + // SYNTHETIC: LEGO1 0x100a6f10 + // LODObject::`scalar deleting destructor' }; /* diff --git a/LEGO1/tgl/d3drm/group.cpp b/LEGO1/tgl/d3drm/group.cpp index bc7da727..af9ba1b7 100644 --- a/LEGO1/tgl/d3drm/group.cpp +++ b/LEGO1/tgl/d3drm/group.cpp @@ -79,33 +79,35 @@ Result GroupImpl::SetMaterialMode(MaterialMode mode) } // FUNCTION: LEGO1 0x100a3410 -Result GroupImpl::Add(const Mesh* pMesh) -{ - const MeshImpl* pMeshImpl = static_cast(pMesh); - return ResultVal(m_data->AddVisual(pMeshImpl->ImplementationData()->groupMesh)); -} - -// FUNCTION: LEGO1 0x100a3430 Result GroupImpl::Add(const Group* pGroup) { const GroupImpl* pGroupImpl = static_cast(pGroup); return ResultVal(m_data->AddVisual(pGroupImpl->m_data)); } +// FUNCTION: LEGO1 0x100a3430 +Result GroupImpl::Add(const Mesh* pMesh) +{ + const MeshImpl* pMeshImpl = static_cast(pMesh); + // TODO: Incorrect structure + return ResultVal(m_data->AddVisual((IDirect3DRMMesh*) pMeshImpl->ImplementationData())); +} + // FUNCTION: LEGO1 0x100a3450 +Result GroupImpl::Remove(const Mesh* pMesh) +{ + const MeshImpl* pMeshImpl = static_cast(pMesh); + // TODO: Incorrect structure + return ResultVal(m_data->DeleteVisual((IDirect3DRMMesh*) pMeshImpl->ImplementationData())); +} + +// FUNCTION: LEGO1 0x100a3480 Result GroupImpl::Remove(const Group* pGroup) { const GroupImpl* pGroupImpl = static_cast(pGroup); return ResultVal(m_data->DeleteVisual(pGroupImpl->m_data)); } -// FUNCTION: LEGO1 0x100a3480 -Result GroupImpl::Remove(const Mesh* pMesh) -{ - const MeshImpl* pMeshImpl = static_cast(pMesh); - return ResultVal(m_data->DeleteVisual(pMeshImpl->ImplementationData()->groupMesh)); -} - // STUB: LEGO1 0x100a34b0 Result GroupImpl::RemoveAll() { diff --git a/LEGO1/tgl/d3drm/impl.h b/LEGO1/tgl/d3drm/impl.h index 69caa85e..8b1fe39e 100644 --- a/LEGO1/tgl/d3drm/impl.h +++ b/LEGO1/tgl/d3drm/impl.h @@ -315,12 +315,12 @@ class GroupImpl : public Group { Result SetTexture(const Texture*) override; Result GetTexture(Texture*&) override; Result SetMaterialMode(MaterialMode) override; - Result Add(const Mesh*) override; + Result Add(const Group*) override; // vtable+0x20 - Result Add(const Group*) override; - Result Remove(const Mesh*) override; + Result Add(const Mesh*) override; Result Remove(const Group*) override; + Result Remove(const Mesh*) override; Result RemoveAll() override; // vtable+0x30 diff --git a/LEGO1/tgl/tgl.h b/LEGO1/tgl/tgl.h index 1067f863..a8d89fb5 100644 --- a/LEGO1/tgl/tgl.h +++ b/LEGO1/tgl/tgl.h @@ -294,10 +294,10 @@ class Group : public Object { virtual Result SetTexture(const Texture*) = 0; virtual Result GetTexture(Texture*&) = 0; virtual Result SetMaterialMode(MaterialMode) = 0; - virtual Result Add(const Mesh*) = 0; virtual Result Add(const Group*) = 0; - virtual Result Remove(const Mesh*) = 0; + virtual Result Add(const Mesh*) = 0; virtual Result Remove(const Group*) = 0; + virtual Result Remove(const Mesh*) = 0; virtual Result RemoveAll() = 0; // This is TransformLocalToWorld in the leak, however it seems diff --git a/LEGO1/viewmanager/viewlod.cpp b/LEGO1/viewmanager/viewlod.cpp new file mode 100644 index 00000000..199e4c3a --- /dev/null +++ b/LEGO1/viewmanager/viewlod.cpp @@ -0,0 +1,7 @@ +#include "viewlod.h" + +// FUNCTION: LEGO1 0x100a5e40 +ViewLOD::~ViewLOD() +{ + delete m_meshGroup; +} diff --git a/LEGO1/viewmanager/viewlod.h b/LEGO1/viewmanager/viewlod.h new file mode 100644 index 00000000..569e9a84 --- /dev/null +++ b/LEGO1/viewmanager/viewlod.h @@ -0,0 +1,32 @@ +#include "decomp.h" +#include "realtime/roi.h" +#include "tgl/tgl.h" + +////////////////////////////////////////////////////////////////////////////// +// ViewLOD +// + +// VTABLE: LEGO1 0x100dbd70 +// SIZE 0x0c +class ViewLOD : public LODObject { +public: + ViewLOD(Tgl::Renderer* pRenderer) : m_meshGroup(NULL), m_unk0x08(3) {} + ~ViewLOD() override; + + // FUNCTION: LEGO1 0x100a6f30 + double AveragePolyArea() const override { return 2 * 3.14159 * 10.0 / NumPolys(); } // vtable+0x04 + + // FUNCTION: LEGO1 0x100a6f50 + int NVerts() const override { return NumPolys() * 2; } // vtable+0x08 + + Tgl::Group* GetGeometry() { return m_meshGroup; } + const Tgl::Group* GetGeometry() const { return m_meshGroup; } + + // SYNTHETIC: LEGO1 0x100a6f60 + // ViewLOD::`scalar deleting destructor' + +protected: + // TODO: m_meshGroup unconfirmed (based on 1996) + Tgl::Group* m_meshGroup; // 0x04 + undefined4 m_unk0x08; // 0x08 +}; diff --git a/LEGO1/viewmanager/viewmanager.cpp b/LEGO1/viewmanager/viewmanager.cpp index eb238378..0d8473e8 100644 --- a/LEGO1/viewmanager/viewmanager.cpp +++ b/LEGO1/viewmanager/viewmanager.cpp @@ -1,11 +1,12 @@ #include "viewmanager.h" #include "tgl/d3drm/impl.h" +#include "viewlod.h" DECOMP_SIZE_ASSERT(ViewManager, 0x1bc) -inline undefined4 SetD3DRM(IDirect3DRM2*& d3drm, Tgl::Renderer* pRenderer); -inline undefined4 SetFrame(IDirect3DRMFrame2*& frame, Tgl::Group* scene); +inline undefined4 GetD3DRM(IDirect3DRM2*& d3drm, Tgl::Renderer* pRenderer); +inline undefined4 GetFrame(IDirect3DRMFrame2*& frame, Tgl::Group* scene); // FUNCTION: LEGO1 0x100a5eb0 ViewManager::ViewManager(Tgl::Renderer* pRenderer, Tgl::Group* scene, const OrientableROI* point_of_view) @@ -13,8 +14,8 @@ ViewManager::ViewManager(Tgl::Renderer* pRenderer, Tgl::Group* scene, const Orie { SetPOVSource(point_of_view); unk0x28 = 0.09; - SetD3DRM(d3drm, pRenderer); - SetFrame(frame, scene); + GetD3DRM(d3drm, pRenderer); + GetFrame(frame, scene); width = 0.0; height = 0.0; view_angle = 0.0; @@ -86,10 +87,25 @@ void ViewManager::RemoveAll(ViewROI* p_roi) } } -// STUB: LEGO1 0x100a66a0 +// FUNCTION: LEGO1 0x100a66a0 void ViewManager::FUN_100a66a0(ViewROI* p_roi) { - // TODO + const ViewLOD* lod = (const ViewLOD*) p_roi->GetLOD(p_roi->GetUnknown0xe0()); + + if (lod != NULL) { + const Tgl::Mesh* meshGroup = NULL; + Tgl::Group* roiGeometry = p_roi->GetGeometry(); + + meshGroup = (const Tgl::Mesh*) lod->GetGeometry(); + + if (meshGroup != NULL) { + roiGeometry->Remove(meshGroup); + } + + scene->Remove(roiGeometry); + } + + p_roi->SetUnknown0xe0(-1); } // STUB: LEGO1 0x100a6930 @@ -131,13 +147,13 @@ ViewROI* ViewManager::Pick(Tgl::View* p_view, unsigned long x, unsigned long y) return NULL; } -inline undefined4 SetD3DRM(IDirect3DRM2*& d3drm, Tgl::Renderer* pRenderer) +inline undefined4 GetD3DRM(IDirect3DRM2*& d3drm, Tgl::Renderer* pRenderer) { d3drm = ((TglImpl::RendererImpl*) pRenderer)->ImplementationData(); return 0; } -inline undefined4 SetFrame(IDirect3DRMFrame2*& frame, Tgl::Group* scene) +inline undefined4 GetFrame(IDirect3DRMFrame2*& frame, Tgl::Group* scene) { frame = ((TglImpl::GroupImpl*) scene)->ImplementationData(); return 0; diff --git a/LEGO1/viewmanager/viewroi.cpp b/LEGO1/viewmanager/viewroi.cpp index e304ab03..790ab1b6 100644 --- a/LEGO1/viewmanager/viewroi.cpp +++ b/LEGO1/viewmanager/viewroi.cpp @@ -16,13 +16,13 @@ float ViewROI::IntrinsicImportance() const } // for now // FUNCTION: LEGO1 0x100a9ec0 -const Tgl::Group* ViewROI::GetGeometry() const +Tgl::Group* ViewROI::GetGeometry() { return geometry; } // FUNCTION: LEGO1 0x100a9ed0 -Tgl::Group* ViewROI::GetGeometry() +const Tgl::Group* ViewROI::GetGeometry() const { return geometry; } diff --git a/LEGO1/viewmanager/viewroi.h b/LEGO1/viewmanager/viewroi.h index e11abf26..5a521824 100644 --- a/LEGO1/viewmanager/viewroi.h +++ b/LEGO1/viewmanager/viewroi.h @@ -53,8 +53,8 @@ class ViewROI : public OrientableROI { void VTable0x1c() override; // vtable+0x1c void SetLocalTransform(const Matrix4& p_transform) override; // vtable+0x20 void VTable0x24(const Matrix4& p_transform) override; // vtable+0x24 - virtual const Tgl::Group* GetGeometry() const; // vtable+0x34 virtual Tgl::Group* GetGeometry(); // vtable+0x30 + virtual const Tgl::Group* GetGeometry() const; // vtable+0x34 inline int GetUnknown0xe0() { return m_unk0xe0; } inline void SetUnknown0xe0(int p_unk0xe0) { m_unk0xe0 = p_unk0xe0; }