holesome/src/game/camera/tracking_view.cpp

144 lines
3.4 KiB
C++
Raw Normal View History

2023-05-23 23:38:37 +02:00
#include "tracking_view.h"
#include "../../utilities/vector_utils.hpp"
2023-05-09 20:50:50 +02:00
TrackingView::TrackingView(float freeMoveRadius, float dynamicFollowRadius) : freeMoveRadius(freeMoveRadius),
dynamicFollowRadius(dynamicFollowRadius),
view(nullptr),
hasViewChanged(false)
{
trackables = std::vector<ITrackable *>();
marker = new CircleObject(2, sf::Color::Yellow);
2023-05-24 14:00:51 +02:00
Game::getInstance()->registerView(this);
}
2023-05-23 23:38:37 +02:00
TrackingView::~TrackingView()
2023-05-09 20:50:50 +02:00
{
2023-05-10 11:03:14 +02:00
delete view;
delete marker;
2023-05-09 20:50:50 +02:00
}
2023-05-24 14:00:51 +02:00
void TrackingView::lateUpdate()
2023-05-09 20:50:50 +02:00
{
// Initialize if necessary
2023-05-10 11:03:14 +02:00
if (view == nullptr)
{
2023-05-24 14:00:51 +02:00
initializeView();
2023-05-10 11:03:14 +02:00
}
processTrackableStates();
2023-05-10 11:03:14 +02:00
// Update size
// TODO: Update size based on distance of tracked objects
2023-05-24 14:00:51 +02:00
setSize(Game::getInstance()->window->getSize());
2023-05-09 20:50:50 +02:00
if (!trackables.empty())
{
followTarget();
}
// Update window if necessary
if (hasViewChanged)
2023-05-09 20:50:50 +02:00
{
2023-05-24 14:00:51 +02:00
Game::getInstance()->window->setView(*this->view);
hasViewChanged = false;
2023-05-09 20:50:50 +02:00
}
2023-05-10 11:03:14 +02:00
}
2023-05-24 14:00:51 +02:00
void TrackingView::initializeView()
2023-05-10 11:03:14 +02:00
{
2023-05-24 14:00:51 +02:00
auto size = Game::getInstance()->window->getView().getSize();
view = new sf::View({0, 0}, size);
2023-05-09 20:50:50 +02:00
}
2023-05-23 23:38:37 +02:00
void TrackingView::setSize(sf::Vector2u windowSize)
{
// TODO: Maybe listen to resize events instead of checking every frame?
// Is different?
if (view->getSize().x == windowSize.x && view->getSize().y == windowSize.y)
{
// Nothing to do
return;
}
sf::Vector2f viewSize = sf::Vector2f(windowSize.x, windowSize.y);
view->setSize(viewSize);
hasViewChanged = true;
}
2023-05-23 23:38:37 +02:00
sf::Vector2f TrackingView::getSize() const
{
return view->getSize();
}
2023-05-23 23:38:37 +02:00
sf::Vector2f TrackingView::getCenter() const
{
return view->getCenter();
}
2023-05-23 23:38:37 +02:00
void TrackingView::followTarget()
{
auto trackingPoint = getCollectiveTrackingPoint();
marker->coordinates.set(IsometricCoordinates(trackingPoint));
2023-05-24 14:00:51 +02:00
moveCenter(trackingPoint - getCenter());
return;
// if (isTargetInArea(freeMoveArea))
// {
// // Nothing to do
// return;
// }
// performHardFollow();
// if (isTargetInArea(dynamicFollowArea))
// {
// // Slowly push target back into free area
// performDynamicFollow();
// } else
// {
// // Hard follow
// performHardFollow();
// }
}
void TrackingView::moveCenter(sf::Vector2<float> delta)
{
view->move(delta);
hasViewChanged = true;
}
void TrackingView::draw(sf::RenderWindow *window) const
{
marker->draw(window);
}
void TrackingView::addTrackable(ITrackable *trackable)
{
trackables.push_back(trackable);
}
sf::Vector2f TrackingView::getCollectiveTrackingPoint() const
{
sf::Vector2f collectiveTrackingPoint = {0, 0};
for (auto trackable : trackables)
{
if (trackable->getTrackableState() != TrackableState::TRACKING)
{
continue;
}
collectiveTrackingPoint += trackable->getTrackablePosition();
}
return collectiveTrackingPoint / (float) trackables.size();
}
void TrackingView::processTrackableStates()
{
// Remove trackables that have ended tracking
std::remove_if(trackables.begin(), trackables.end(), [](ITrackable *trackable)
{
return trackable->getTrackableState() == TrackableState::END_TRACKING;
});
}