95 lines
2.5 KiB
C++
95 lines
2.5 KiB
C++
#include "components/TrailComponent.hpp"
|
|
|
|
#include "Entity.hpp"
|
|
#include "components/TransformComponent.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
void TrailComponent::Setup() {
|
|
points.clear();
|
|
elapsed = 0.0f;
|
|
lastSampleAt = 0.0f;
|
|
|
|
auto transform = entity->GetComponent<TransformComponent>();
|
|
if (!transform) {
|
|
return;
|
|
}
|
|
|
|
points.push_back({transform->get().x, transform->get().y, elapsed});
|
|
}
|
|
|
|
void TrailComponent::Update(float dt) {
|
|
elapsed += dt;
|
|
|
|
auto transform = entity->GetComponent<TransformComponent>();
|
|
if (!transform) {
|
|
return;
|
|
}
|
|
|
|
while (!points.empty() && (elapsed - points.front().createdAt) > pointLifetime) {
|
|
points.pop_front();
|
|
}
|
|
|
|
const float x = transform->get().x;
|
|
const float y = transform->get().y;
|
|
if (points.empty()) {
|
|
points.push_back({x, y, elapsed});
|
|
lastSampleAt = elapsed;
|
|
return;
|
|
}
|
|
|
|
const Point &last = points.back();
|
|
const float dx = x - last.x;
|
|
const float dy = y - last.y;
|
|
|
|
// check if we've moved far enough from the last point or if enough time has passed to warrant a
|
|
// new sample, for smoother trails when the probe is moving slowly
|
|
const bool movedEnough = (dx * dx + dy * dy) >= (sampleDistance * sampleDistance);
|
|
const bool waitedEnough = (elapsed - lastSampleAt) >= sampleInterval;
|
|
if (movedEnough || waitedEnough) {
|
|
points.push_back({x, y, elapsed});
|
|
lastSampleAt = elapsed;
|
|
} else {
|
|
points.back().x = x;
|
|
points.back().y = y;
|
|
points.back().createdAt = elapsed;
|
|
}
|
|
|
|
if (points.size() > maxPoints) {
|
|
while (points.size() > maxPoints) {
|
|
points.pop_front();
|
|
}
|
|
}
|
|
|
|
Draw();
|
|
}
|
|
|
|
void TrailComponent::Cleanup() {
|
|
points.clear();
|
|
elapsed = 0.0f;
|
|
lastSampleAt = 0.0f;
|
|
}
|
|
|
|
void TrailComponent::Draw() const {
|
|
if (points.size() < 2 || pointLifetime <= 0.0f) {
|
|
return;
|
|
}
|
|
|
|
for (size_t i = 1; i < points.size(); ++i) {
|
|
const Point &a = points[i - 1];
|
|
const Point &b = points[i];
|
|
|
|
const float ageA = elapsed - a.createdAt;
|
|
const float ageB = elapsed - b.createdAt;
|
|
const float lifeNormA = std::clamp(1.0f - (ageA / pointLifetime), 0.0f, 1.0f);
|
|
const float lifeNormB = std::clamp(1.0f - (ageB / pointLifetime), 0.0f, 1.0f);
|
|
const float lifeNorm = 0.5f * (lifeNormA + lifeNormB);
|
|
|
|
Color c = color;
|
|
c.a = (unsigned char)((float)(color.a) * lifeNorm);
|
|
|
|
DrawLineEx({a.x, a.y}, {b.x, b.y}, lineWidth, c);
|
|
}
|
|
}
|