2023-05-23 23:38:37 +02:00
|
|
|
#include "tracking_view.h"
|
2023-05-14 22:23:25 +02:00
|
|
|
#include "../../utilities/vector_utils.hpp"
|
2023-05-09 20:50:50 +02:00
|
|
|
|
2023-05-24 01:15:05 +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-24 01:15:05 +02:00
|
|
|
}
|
|
|
|
|
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;
|
2023-05-14 22:23:25 +02:00
|
|
|
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
|
|
|
{
|
2023-05-10 11:30:11 +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
|
|
|
}
|
|
|
|
|
2023-05-24 01:15:05 +02:00
|
|
|
processTrackableStates();
|
|
|
|
|
2023-05-10 11:03:14 +02:00
|
|
|
// Update size
|
2023-05-24 01:15:05 +02:00
|
|
|
// 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
|
|
|
|
2023-05-24 01:15:05 +02:00
|
|
|
if (!trackables.empty())
|
2023-05-14 22:23:25 +02:00
|
|
|
{
|
|
|
|
followTarget();
|
|
|
|
}
|
2023-05-10 11:30:11 +02:00
|
|
|
|
|
|
|
// 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);
|
2023-05-10 11:30:11 +02:00
|
|
|
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();
|
2023-05-14 22:23:25 +02:00
|
|
|
view = new sf::View({0, 0}, size);
|
2023-05-09 20:50:50 +02:00
|
|
|
}
|
2023-05-10 11:30:11 +02:00
|
|
|
|
2023-05-23 23:38:37 +02:00
|
|
|
void TrackingView::setSize(sf::Vector2u windowSize)
|
2023-05-10 11:30:11 +02:00
|
|
|
{
|
2023-05-14 22:23:25 +02:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2023-05-10 11:30:11 +02:00
|
|
|
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
|
2023-05-10 11:30:11 +02:00
|
|
|
{
|
2023-05-14 22:23:25 +02:00
|
|
|
return view->getSize();
|
|
|
|
}
|
|
|
|
|
2023-05-23 23:38:37 +02:00
|
|
|
sf::Vector2f TrackingView::getCenter() const
|
2023-05-14 22:23:25 +02:00
|
|
|
{
|
|
|
|
return view->getCenter();
|
|
|
|
}
|
|
|
|
|
2023-05-23 23:38:37 +02:00
|
|
|
void TrackingView::followTarget()
|
2023-05-14 22:23:25 +02:00
|
|
|
{
|
2023-05-24 01:15:05 +02:00
|
|
|
auto trackingPoint = getCollectiveTrackingPoint();
|
|
|
|
marker->coordinates.set(IsometricCoordinates(trackingPoint));
|
2023-05-24 14:00:51 +02:00
|
|
|
moveCenter(trackingPoint - getCenter());
|
2023-05-14 22:23:25 +02:00
|
|
|
return;
|
|
|
|
|
2023-05-24 01:15:05 +02:00
|
|
|
// if (isTargetInArea(freeMoveArea))
|
|
|
|
// {
|
|
|
|
// // Nothing to do
|
|
|
|
// return;
|
|
|
|
// }
|
2023-05-10 11:30:11 +02:00
|
|
|
|
2023-05-14 22:23:25 +02:00
|
|
|
// performHardFollow();
|
|
|
|
// if (isTargetInArea(dynamicFollowArea))
|
|
|
|
// {
|
|
|
|
// // Slowly push target back into free area
|
|
|
|
// performDynamicFollow();
|
|
|
|
// } else
|
|
|
|
// {
|
|
|
|
// // Hard follow
|
|
|
|
// performHardFollow();
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
2023-05-24 01:15:05 +02:00
|
|
|
void TrackingView::moveCenter(sf::Vector2<float> delta)
|
2023-05-14 22:23:25 +02:00
|
|
|
{
|
2023-05-24 01:15:05 +02:00
|
|
|
view->move(delta);
|
|
|
|
hasViewChanged = true;
|
2023-05-14 22:23:25 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 01:15:05 +02:00
|
|
|
void TrackingView::draw(sf::RenderWindow *window) const
|
2023-05-14 22:23:25 +02:00
|
|
|
{
|
2023-05-24 01:15:05 +02:00
|
|
|
marker->draw(window);
|
2023-05-14 22:23:25 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 01:15:05 +02:00
|
|
|
void TrackingView::addTrackable(ITrackable *trackable)
|
2023-05-14 22:23:25 +02:00
|
|
|
{
|
2023-05-24 01:15:05 +02:00
|
|
|
trackables.push_back(trackable);
|
2023-05-14 22:23:25 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 01:15:05 +02:00
|
|
|
sf::Vector2f TrackingView::getCollectiveTrackingPoint() const
|
2023-05-14 22:23:25 +02:00
|
|
|
{
|
2023-05-24 14:29:08 +02:00
|
|
|
sf::Vector2f minPoint = trackables[0]->getTrackablePosition();
|
|
|
|
sf::Vector2f maxPoint = minPoint;
|
2023-05-14 22:23:25 +02:00
|
|
|
|
2023-05-24 14:29:08 +02:00
|
|
|
// Find min and max point coordinates for x and y axis over all trackables
|
2023-05-24 01:15:05 +02:00
|
|
|
for (auto trackable : trackables)
|
|
|
|
{
|
2023-05-24 14:29:08 +02:00
|
|
|
auto trackableCoordinates = trackable->getTrackablePosition();
|
|
|
|
auto trackableSize = trackable->getTrackableSize();
|
|
|
|
|
|
|
|
auto minPointX = trackableCoordinates.x - trackableSize.x / 2.f;
|
|
|
|
auto maxPointX = trackableCoordinates.x + trackableSize.x / 2.f;
|
|
|
|
auto minPointY = trackableCoordinates.y - trackableSize.y / 2.f;
|
|
|
|
auto maxPointY = trackableCoordinates.y + trackableSize.y / 2.f;
|
|
|
|
|
|
|
|
if (minPointX < minPoint.x)
|
2023-05-24 01:15:05 +02:00
|
|
|
{
|
2023-05-24 14:29:08 +02:00
|
|
|
minPoint.x = minPointX;
|
|
|
|
}
|
|
|
|
if (maxPointX > maxPoint.x)
|
|
|
|
{
|
|
|
|
maxPoint.x = maxPointX;
|
|
|
|
}
|
|
|
|
if (minPointY < minPoint.y)
|
|
|
|
{
|
|
|
|
minPoint.y = minPointY;
|
|
|
|
}
|
|
|
|
if (maxPointY > maxPoint.y)
|
|
|
|
{
|
|
|
|
maxPoint.y = maxPointY;
|
2023-05-24 01:15:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-24 14:29:08 +02:00
|
|
|
return minPoint + (maxPoint - minPoint) / 2.f;
|
2023-05-14 22:23:25 +02:00
|
|
|
}
|
|
|
|
|
2023-05-24 01:15:05 +02:00
|
|
|
void TrackingView::processTrackableStates()
|
2023-05-14 22:23:25 +02:00
|
|
|
{
|
2023-05-24 01:15:05 +02:00
|
|
|
// Remove trackables that have ended tracking
|
|
|
|
std::remove_if(trackables.begin(), trackables.end(), [](ITrackable *trackable)
|
|
|
|
{
|
|
|
|
return trackable->getTrackableState() == TrackableState::END_TRACKING;
|
|
|
|
});
|
2023-05-14 22:23:25 +02:00
|
|
|
}
|