mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-21 14:53:02 +01:00
Don't tween entities that are not visible on screen or when zoomed out
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
|
||||
#include "../entity/Guest.h"
|
||||
#include "../entity/Staff.h"
|
||||
#include "../interface/Viewport.h"
|
||||
#include "../interface/Window.h"
|
||||
#include "../ride/Vehicle.h"
|
||||
#include "EntityList.h"
|
||||
#include "EntityRegistry.h"
|
||||
@@ -17,25 +19,79 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
void EntityTweener::AddEntity(EntityBase* entity)
|
||||
namespace OpenRCT2
|
||||
{
|
||||
static inline ViewportList GetUnzoomedViewports() noexcept
|
||||
{
|
||||
ViewportList viewports;
|
||||
WindowVisitEach([&](WindowBase* w) {
|
||||
if (auto* vp = WindowGetViewport(w); vp != nullptr)
|
||||
{
|
||||
if (!vp->isVisible)
|
||||
{
|
||||
// Ignore viewports that are not visible.
|
||||
return;
|
||||
}
|
||||
if (vp->zoom > ZoomLevel{ 0 })
|
||||
{
|
||||
// Ignore viewports that are zoomed out, interpolation wouldn't have much of an effect
|
||||
// due to the loss of detail.
|
||||
return;
|
||||
}
|
||||
viewports.push_back(vp);
|
||||
}
|
||||
});
|
||||
return viewports;
|
||||
}
|
||||
|
||||
static inline bool IsEntityVisible(const ViewportList& vpList, const EntityBase* entity) noexcept
|
||||
{
|
||||
const auto worldLoc = entity->GetLocation();
|
||||
|
||||
for (const auto* vp : vpList)
|
||||
{
|
||||
const auto screenPos = Translate3DTo2DWithZ(vp->rotation, worldLoc);
|
||||
if (vp->Contains(screenPos))
|
||||
{
|
||||
// Entity is visible in at least one viewport, tween.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void EntityTweener::AddEntity(const ViewportList& vpList, EntityBase* entity)
|
||||
{
|
||||
if (!IsEntityVisible(vpList, entity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entities.push_back(entity);
|
||||
PrePos.emplace_back(entity->GetLocation());
|
||||
}
|
||||
|
||||
void EntityTweener::PopulateEntities()
|
||||
{
|
||||
const auto vpList = GetUnzoomedViewports();
|
||||
if (vpList.empty())
|
||||
{
|
||||
// No viewports that fit the criteria, bail.
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto ent : EntityList<Guest>())
|
||||
{
|
||||
AddEntity(ent);
|
||||
AddEntity(vpList, ent);
|
||||
}
|
||||
for (auto ent : EntityList<Staff>())
|
||||
{
|
||||
AddEntity(ent);
|
||||
AddEntity(vpList, ent);
|
||||
}
|
||||
for (auto ent : EntityList<Vehicle>())
|
||||
{
|
||||
AddEntity(ent);
|
||||
AddEntity(vpList, ent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,3 +184,5 @@ EntityTweener& EntityTweener::Get()
|
||||
{
|
||||
return tweener;
|
||||
}
|
||||
|
||||
} // namespace OpenRCT2
|
||||
|
||||
@@ -9,10 +9,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../interface/Window.h"
|
||||
#include "EntityBase.h"
|
||||
|
||||
#include <sfl/static_vector.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenRCT2
|
||||
{
|
||||
struct Viewport;
|
||||
|
||||
// TODO: Move this to somewhere else, currently filters also by zoom.
|
||||
using ViewportList = sfl::static_vector<Viewport*, kWindowLimitMax>;
|
||||
|
||||
class EntityTweener
|
||||
{
|
||||
std::vector<EntityBase*> Entities;
|
||||
@@ -21,7 +30,7 @@ class EntityTweener
|
||||
|
||||
private:
|
||||
void PopulateEntities();
|
||||
void AddEntity(EntityBase* entity);
|
||||
void AddEntity(const ViewportList& vp, EntityBase* entity);
|
||||
|
||||
public:
|
||||
static EntityTweener& Get();
|
||||
@@ -33,3 +42,5 @@ public:
|
||||
void Restore();
|
||||
void Reset();
|
||||
};
|
||||
|
||||
} // namespace OpenRCT2
|
||||
|
||||
Reference in New Issue
Block a user