diff options
| author | MegaMech <MegaMech@users.noreply.github.com> | 2025-12-13 17:28:44 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-13 17:28:44 -0700 |
| commit | 7bc8d6f4be2bc22f7f4815d3c5eac691c4b92c0f (patch) | |
| tree | ea7bed88faf5f3bb0788c698fd0252d3f624548a /src/engine | |
| parent | 4e51b7d5b6a9b89deb5ef135deec0ee5f0087e7c (diff) | |
Refactor Field-of-view into the Camera Struct (#590)
* Fix finishline for toads turnpike in extra
* Fixed trash bin in extra
* Refactor fov
* Update scene.json
* Allow setting fog
* impl fog save & load
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/actors/FallingRock.cpp | 2 | ||||
| -rw-r--r-- | src/engine/actors/MarioSign.cpp | 2 | ||||
| -rw-r--r-- | src/engine/actors/Text.cpp | 2 | ||||
| -rw-r--r-- | src/engine/actors/Tree.cpp | 2 | ||||
| -rw-r--r-- | src/engine/actors/WarioSign.cpp | 2 | ||||
| -rw-r--r-- | src/engine/cameras/FreeCamera.cpp | 2 | ||||
| -rw-r--r-- | src/engine/cameras/GameCamera.cpp | 2 | ||||
| -rw-r--r-- | src/engine/cameras/TourCamera.cpp | 2 | ||||
| -rw-r--r-- | src/engine/editor/EditorMath.cpp | 2 | ||||
| -rw-r--r-- | src/engine/editor/SceneManager.cpp | 58 | ||||
| -rw-r--r-- | src/engine/editor/SceneManager.h | 2 | ||||
| -rw-r--r-- | src/engine/objects/TrashBin.cpp | 13 | ||||
| -rw-r--r-- | src/engine/tracks/BansheeBoardwalk.cpp | 2 | ||||
| -rw-r--r-- | src/engine/tracks/ChocoMountain.cpp | 4 | ||||
| -rw-r--r-- | src/engine/tracks/ToadsTurnpike.cpp | 2 | ||||
| -rw-r--r-- | src/engine/tracks/Track.cpp | 14 |
16 files changed, 91 insertions, 22 deletions
diff --git a/src/engine/actors/FallingRock.cpp b/src/engine/actors/FallingRock.cpp index fb0c47280..d32b65c9d 100644 --- a/src/engine/actors/FallingRock.cpp +++ b/src/engine/actors/FallingRock.cpp @@ -157,7 +157,7 @@ void AFallingRock::Draw(Camera* camera) { return; } - height = is_within_render_distance(camera->pos, Pos, camera->rot[1], 400.0f, gCameraFOV[camera - camera1], + height = is_within_render_distance(camera->pos, Pos, camera->rot[1], 400.0f, camera->fieldOfView, 4000000.0f); if (CVarGetInteger("gNoCulling", 0) == 1) { diff --git a/src/engine/actors/MarioSign.cpp b/src/engine/actors/MarioSign.cpp index c8d9188ff..7722b7de5 100644 --- a/src/engine/actors/MarioSign.cpp +++ b/src/engine/actors/MarioSign.cpp @@ -68,7 +68,7 @@ void AMarioSign::Draw(Camera *camera) { return; } - unk = is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 16000000.0f); + unk = is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, camera->fieldOfView, 16000000.0f); if (CVarGetInteger("gNoCulling", 0) == 1) { unk = MAX(unk, 0.0f); } diff --git a/src/engine/actors/Text.cpp b/src/engine/actors/Text.cpp index 0a5b204e6..9e6423239 100644 --- a/src/engine/actors/Text.cpp +++ b/src/engine/actors/Text.cpp @@ -182,7 +182,7 @@ void AText::Draw(Camera* camera) { } f32 distance = is_within_render_distance(camera->pos, (float*)&Pos[0], camera->rot[1], Close, - gCameraFOV[camera - camera1], Far); + camera->fieldOfView, Far); if (distance == -1.0f) { Dist = DistanceProps::TOO_FAR; diff --git a/src/engine/actors/Tree.cpp b/src/engine/actors/Tree.cpp index 480fdf980..cd732c1e4 100644 --- a/src/engine/actors/Tree.cpp +++ b/src/engine/actors/Tree.cpp @@ -38,7 +38,7 @@ void ATree::Draw(Camera* camera) { return; } - dist = is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, gCameraFOV[camera - camera1], + dist = is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, camera->fieldOfView, DrawDistance); if (CVarGetInteger("gNoCulling", 0) == 1) { diff --git a/src/engine/actors/WarioSign.cpp b/src/engine/actors/WarioSign.cpp index aca8084eb..cd7813f04 100644 --- a/src/engine/actors/WarioSign.cpp +++ b/src/engine/actors/WarioSign.cpp @@ -48,7 +48,7 @@ void AWarioSign::Tick() { void AWarioSign::Draw(Camera *camera) { Mat4 sp38; f32 unk = - is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, gCameraFOV[camera - camera1], 16000000.0f); + is_within_render_distance(camera->pos, Pos, camera->rot[1], 0, camera->fieldOfView, 16000000.0f); if (CVarGetInteger("gNoCulling", 0) == 1) { unk = MAX(unk, 0.0f); diff --git a/src/engine/cameras/FreeCamera.cpp b/src/engine/cameras/FreeCamera.cpp index 887f97611..71a0f9079 100644 --- a/src/engine/cameras/FreeCamera.cpp +++ b/src/engine/cameras/FreeCamera.cpp @@ -56,7 +56,7 @@ void FreeCamera::SetViewProjection() { // Perspective (camera movement) FrameInterpolation_RecordOpenChild("freecam_persp", FrameInterpolation_GetCameraEpoch()); - guPerspective(&PerspectiveMatrix, &perspNorm, 40, gScreenAspect, + guPerspective(&PerspectiveMatrix, &perspNorm, _camera->fieldOfView, gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, &PerspectiveMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); diff --git a/src/engine/cameras/GameCamera.cpp b/src/engine/cameras/GameCamera.cpp index fd02dbd98..73dd9953a 100644 --- a/src/engine/cameras/GameCamera.cpp +++ b/src/engine/cameras/GameCamera.cpp @@ -88,7 +88,7 @@ void GameCamera::SetViewProjection() { (FrameInterpolation_GetCameraEpoch() | ((_camera->cameraId << 8)))); // Calculate camera perspective (camera movement/location) - guPerspective(&PerspectiveMatrix, &perspNorm, gCameraFOV[_camera->cameraId], gScreenAspect, + guPerspective(&PerspectiveMatrix, &perspNorm, _camera->fieldOfView, gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, &PerspectiveMatrix, diff --git a/src/engine/cameras/TourCamera.cpp b/src/engine/cameras/TourCamera.cpp index 3e25e77bd..ff50481bf 100644 --- a/src/engine/cameras/TourCamera.cpp +++ b/src/engine/cameras/TourCamera.cpp @@ -196,7 +196,7 @@ void TourCamera::SetViewProjection() { // Perspective (camera movement) FrameInterpolation_RecordOpenChild("tourcam_persp", FrameInterpolation_GetCameraEpoch()); - guPerspective(&PerspectiveMatrix, &perspNorm, 40, gScreenAspect, + guPerspective(&PerspectiveMatrix, &perspNorm, _camera->fieldOfView, gScreenAspect, CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); gSPPerspNormalize(gDisplayListHead++, perspNorm); gSPMatrix(gDisplayListHead++, &PerspectiveMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); diff --git a/src/engine/editor/EditorMath.cpp b/src/engine/editor/EditorMath.cpp index 620aa2b48..02932a5a7 100644 --- a/src/engine/editor/EditorMath.cpp +++ b/src/engine/editor/EditorMath.cpp @@ -62,7 +62,7 @@ FVector ScreenRayTrace() { Mat4 perspMtx; u16 perspNorm; - guPerspectiveF(perspMtx, &perspNorm, 40, OTRGetAspectRatio(), CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); + guPerspectiveF(perspMtx, &perspNorm, camera->fieldOfView, OTRGetAspectRatio(), CM_GetProps()->NearPersp, CM_GetProps()->FarPersp, 1.0f); Mat4 inversePerspMtx; if (InverseMatrix((float*)&perspMtx, (float*)&inversePerspMtx) != 2) { diff --git a/src/engine/editor/SceneManager.cpp b/src/engine/editor/SceneManager.cpp index 135079a57..b8e3d93e0 100644 --- a/src/engine/editor/SceneManager.cpp +++ b/src/engine/editor/SceneManager.cpp @@ -29,6 +29,8 @@ extern "C" { #include "actors.h" #include "actor_types.h" #include "code_80005FD0.h" +#include "code_800029B0.h" +#include "render_courses.h" } namespace Editor { @@ -56,6 +58,10 @@ namespace Editor { data["Tour"] = tour; } + nlohmann::json fog; + SaveFog(fog); + data["Fog"] = fog; + if (nullptr == track->Archive) { SPDLOG_INFO("[SceneManager] [SaveLevel] Track archive nullptr"); return; @@ -297,6 +303,19 @@ namespace Editor { } } + void SaveFog(nlohmann::json& fog) { + if (bFog) { + fog["EnableFog"] = bFog; + fog["Colour"]["R"] = gFogColour.r; + fog["Colour"]["G"] = gFogColour.g; + fog["Colour"]["B"] = gFogColour.b; + fog["Colour"]["A"] = gFogColour.a; + + fog["Min"] = gFogMin; + fog["Max"] = gFogMax; + } + } + void LoadProps(Track* track, nlohmann::json& data) { if (!data.contains("Props") || !data["Props"].is_object()) { SPDLOG_INFO("Track is missing props data. Is the scene.json file corrupt?"); @@ -415,4 +434,43 @@ namespace Editor { } } } + + void LoadFog(nlohmann::json& data) { + if (!data.contains("Fog") || !data["Fog"].is_object()) { + SPDLOG_INFO(" This track does not contain fog"); + return; + } + + nlohmann::json& fog = data["Fog"]; + + bFog = fog.value("Enabled", false); + + if (!bFog) return; + + // Load color + if (fog.contains("Colour") && fog["Colour"].is_object()) { + nlohmann::json& c = fog["Colour"]; + gFogColour.r = c.value("R", 255); + gFogColour.g = c.value("G", 255); + gFogColour.b = c.value("B", 255); + gFogColour.a = c.value("A", 255); + } + + // Load min/max with safety clamps + int minVal = fog.value("Min", 0); + int maxVal = fog.value("Max", 500); + + // Ensure min < max + if (minVal >= maxVal) { + minVal = maxVal - 1; + } + + // Clamp to valid ranges + minVal = std::clamp(minVal, 0, 999); + maxVal = std::clamp(maxVal, 1, 1000); + + gFogMin = static_cast<int16_t>(minVal); + gFogMax = static_cast<int16_t>(maxVal); + + } } diff --git a/src/engine/editor/SceneManager.h b/src/engine/editor/SceneManager.h index 48b52a1e2..551d79e32 100644 --- a/src/engine/editor/SceneManager.h +++ b/src/engine/editor/SceneManager.h @@ -17,6 +17,7 @@ namespace Editor { void SaveActors(nlohmann::json& actorList); void SaveStaticMeshActors(nlohmann::json& actorList); void SaveTour(Track* track, nlohmann::json& tour); + void SaveFog(nlohmann::json& fog); void LoadProps(Track* track, nlohmann::json& data); void LoadPaths(Track* track, const std::string& trackPath); @@ -24,6 +25,7 @@ namespace Editor { void LoadActors(Track* track, nlohmann::json& data); void LoadStaticMeshActors(Track* track, nlohmann::json& data); void LoadTour(Track* track, nlohmann::json& data); + void LoadFog(nlohmann::json& data); void SpawnActors(std::vector<std::pair<std::string, SpawnParams>> spawnList); diff --git a/src/engine/objects/TrashBin.cpp b/src/engine/objects/TrashBin.cpp index 954b9491a..b483a7549 100644 --- a/src/engine/objects/TrashBin.cpp +++ b/src/engine/objects/TrashBin.cpp @@ -19,14 +19,13 @@ extern "C" { #include "audio/external.h" } -#define DEGREES_FLOAT_TO_SHORT(Degrees) ((s16)((Degrees) * (0x8000 / 180.0f))) - OTrashBin::OTrashBin(const SpawnParams& params) : OObject(params) { Name = "Trash Bin"; ResourceName = "mk:trash_bin"; _pos = params.Location.value_or(FVector(0, 0, 0)); + _pos.x *= xOrientation; _rot = params.Rotation.value_or(IRotator(0, 0, 0)); - _scale = params.Scale.value_or(FVector(0, 0, 0)).y; // Only y + _scale = params.Scale.value_or(FVector(0, 0, 0)).y; _bhv = static_cast<Behaviour>(params.Behaviour.value_or(0)); find_unused_obj_index(&_objectIndex); @@ -86,9 +85,9 @@ void OTrashBin::init_bb_trash_bin(s32 objectIndex) { gObjectList[objectIndex].unk_04C = 0; gObjectList[objectIndex].unk_084[7] = 0; set_obj_orientation(objectIndex, 0U, 0U, 0U); - gObjectList[objectIndex].orientation[0] = DEGREES_FLOAT_TO_SHORT(_rot.pitch); - gObjectList[objectIndex].orientation[1] = DEGREES_FLOAT_TO_SHORT(_rot.yaw); - gObjectList[objectIndex].orientation[2] = DEGREES_FLOAT_TO_SHORT(_rot.roll); + gObjectList[objectIndex].orientation[0] = _rot.pitch; + gObjectList[objectIndex].orientation[1] = _rot.yaw; + gObjectList[objectIndex].orientation[2] = _rot.roll; gObjectList[objectIndex].pos[0] = _pos.x; if (_drawBin) { // Position the lid on-top of the box. @@ -105,8 +104,6 @@ void OTrashBin::init_bb_trash_bin(s32 objectIndex) { object_next_state(objectIndex); } -#undef DEGREES_FLOAT_TO_SHORT - void OTrashBin::func_8007E00C(s32 objectIndex) { switch (gObjectList[objectIndex].state) { case 1: diff --git a/src/engine/tracks/BansheeBoardwalk.cpp b/src/engine/tracks/BansheeBoardwalk.cpp index 54dc2ac8b..337dc14cd 100644 --- a/src/engine/tracks/BansheeBoardwalk.cpp +++ b/src/engine/tracks/BansheeBoardwalk.cpp @@ -166,7 +166,7 @@ void BansheeBoardwalk::BeginPlay() { } if (gIsMirrorMode) { - SpawnActor<OTrashBin>(FVector(1765.0f, 45.0f, 195.0f), IRotator(0, 180, 0), 1.0f, bhv); + SpawnActor<OTrashBin>(FVector(-1765.0f, 45.0f, 195.0f), IRotator(0, 180, 0), 1.0f, bhv); } else { SpawnActor<OTrashBin>(FVector(-1765.0f, 45.0f, 70.0f), IRotator(0, 0, 0), 1.0f, bhv); } diff --git a/src/engine/tracks/ChocoMountain.cpp b/src/engine/tracks/ChocoMountain.cpp index dc369c9a5..aa8e4666e 100644 --- a/src/engine/tracks/ChocoMountain.cpp +++ b/src/engine/tracks/ChocoMountain.cpp @@ -132,8 +132,8 @@ void ChocoMountain::Load() { gFogColour.g = 255; gFogColour.b = 255; gFogColour.a = 255; - gFogMin = 0x3E3; - gFogMax = 0x3E8; + gFogMin = 995; + gFogMax = 1000; D_802B87D4 = 0x71C; D_802B87D0 = 0xE38; diff --git a/src/engine/tracks/ToadsTurnpike.cpp b/src/engine/tracks/ToadsTurnpike.cpp index ea675e301..4a4c9bbcb 100644 --- a/src/engine/tracks/ToadsTurnpike.cpp +++ b/src/engine/tracks/ToadsTurnpike.cpp @@ -103,7 +103,7 @@ ToadsTurnpike::ToadsTurnpike() { Props.CloudList = gToadsTurnpikeRainbowRoadStars; FVector finish; - finish.x = (gIsMirrorMode != 0) ? 100 + 138.0f : 100 - 138.0f; + finish.x = -38.0f * xOrientation; finish.y = (f32) (0 - 15); finish.z = 16; diff --git a/src/engine/tracks/Track.cpp b/src/engine/tracks/Track.cpp index ae6477c59..3f898754e 100644 --- a/src/engine/tracks/Track.cpp +++ b/src/engine/tracks/Track.cpp @@ -623,6 +623,19 @@ void Track::Waypoints(Player* player, int8_t playerId) { void Track::Draw(ScreenContext* arg0) { gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + + if (bFog) { + gDPSetCycleType(gDisplayListHead++, G_CYC_2CYCLE); + gDPSetRenderMode(gDisplayListHead++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); + gSPSetGeometryMode(gDisplayListHead++, G_FOG); + + gDPSetFogColor(gDisplayListHead++, gFogColour.r, gFogColour.g, gFogColour.b, gFogColour.a); + gSPFogPosition(gDisplayListHead++, gFogMin, gFogMax); + gDPPipeSync(gDisplayListHead++); + } else { + gSPClearGeometryMode(gDisplayListHead++, G_FOG); + } + set_track_light_direction(D_800DC610, D_802B87D4, 0, 1); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); gSPSetGeometryMode(gDisplayListHead++, G_SHADING_SMOOTH); @@ -630,7 +643,6 @@ void Track::Draw(ScreenContext* arg0) { if (func_80290C20(arg0->camera) == 1) { gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2); - // d_course_big_donut_packed_dl_DE8 } const TrackInfo* info = gTrackRegistry.GetInfo(ResourceName); |
