cs381/as6/components/TrailComponent.cpp

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);
}
}