From d92963982abcc583ac8806e0b2729201c5dc4af7 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Tue, 19 Mar 2024 14:24:53 -0400 Subject: [PATCH] Implement ViewManager::FUN_100a6dc0 (#697) * Update viewmanager.cpp * Fix function --------- Co-authored-by: Christian Semmler --- LEGO1/viewmanager/viewmanager.cpp | 20 ++++++++++++++------ LEGO1/viewmanager/viewmanager.h | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/LEGO1/viewmanager/viewmanager.cpp b/LEGO1/viewmanager/viewmanager.cpp index 2ed3b448..31302284 100644 --- a/LEGO1/viewmanager/viewmanager.cpp +++ b/LEGO1/viewmanager/viewmanager.cpp @@ -2,6 +2,7 @@ #include "mxdirectx/mxstopwatch.h" #include "tgl/d3drm/impl.h" +#include "vec.h" #include "viewlod.h" DECOMP_SIZE_ASSERT(ViewManager, 0x1bc) @@ -192,7 +193,7 @@ inline void ViewManager::FUN_100a66f0(ViewROI* p_roi, int p_und) if (p_und == -1) { if (p_roi->GetWorldBoundingSphere().Radius() > 0.001F) { - float und = FUN_100a6dc0(p_roi->GetWorldBoundingSphere()); + float und = ProjectedSize(p_roi->GetWorldBoundingSphere()); if (und < seconds_allowed * g_unk0x1010105c) { if (p_roi->GetUnknown0xe0() == -2) { @@ -268,7 +269,7 @@ inline int ViewManager::Unknown() } else { float fVar7 = tan(view_angle / 2.0F); - unk0x2c = view_angle * view_angle * 4.0F; + view_area_at_one = view_angle * view_angle * 4.0F; float fVar1 = front * fVar7; float fVar2 = (width / height) * fVar1; @@ -433,11 +434,18 @@ void ViewManager::SetPOVSource(const OrientableROI* point_of_view) } } -// STUB: LEGO1 0x100a6dc0 -float ViewManager::FUN_100a6dc0(const BoundingSphere& p_bounding_sphere) +// FUNCTION: LEGO1 0x100a6dc0 +float ViewManager::ProjectedSize(const BoundingSphere& p_bounding_sphere) { - // TODO - return 0.0F; + // The algorithm projects the radius of bounding sphere onto the perpendicular + // plane one unit in front of the camera. That value is simply the ratio of the + // radius to the distance from the camera to the sphere center. The projected size + // is then the ratio of the area of that projected circle to the view surface area + // at Z == 1.0. + // + float sphere_projected_area = 3.14159265359 * (p_bounding_sphere.Radius() * p_bounding_sphere.Radius()); + float square_dist_to_sphere = DISTSQRD3(p_bounding_sphere.Center(), pov[3]); + return sphere_projected_area / view_area_at_one / square_dist_to_sphere; } // STUB: LEGO1 0x100a6e00 diff --git a/LEGO1/viewmanager/viewmanager.h b/LEGO1/viewmanager/viewmanager.h index 69aaeebd..8a7e50d0 100644 --- a/LEGO1/viewmanager/viewmanager.h +++ b/LEGO1/viewmanager/viewmanager.h @@ -26,7 +26,7 @@ class ViewManager { void FUN_100a65b0(ViewROI* p_roi, int p_und); void FUN_100a66a0(ViewROI* p_roi); void SetPOVSource(const OrientableROI* point_of_view); - float FUN_100a6dc0(const BoundingSphere& p_bounding_sphere); + float ProjectedSize(const BoundingSphere& p_bounding_sphere); ViewROI* Pick(Tgl::View* p_view, unsigned long x, unsigned long y); void SetResolution(int width, int height); void SetFrustrum(float fov, float front, float back); @@ -50,7 +50,7 @@ class ViewManager { RealtimeView rt_view; // 0x14 ROIList visible_rois; // 0x18 float unk0x28; // 0x28 - float unk0x2c; // 0x2c + float view_area_at_one; // 0x2c unsigned int flags; // 0x30 float width; // 0x34 float height; // 0x38