cs381/as6/components/GravityReceiverComponent.cpp

84 lines
2.5 KiB
C++

#include "components/GravityReceiverComponent.hpp"
#include "Entity.hpp"
#include "components/GravityWellComponent.hpp"
#include "components/NullZoneComponent.hpp"
#include "components/PhysicsComponent.hpp"
#include "components/TransformComponent.hpp"
#include <algorithm>
#include <cmath>
void GravityReceiverComponent::Setup() {}
void GravityReceiverComponent::Update(float dt) {
if (!context || !context->probeEntity || entity != context->probeEntity) {
return;
}
auto myTransform = entity->GetComponent<TransformComponent>();
auto physics = entity->GetComponent<PhysicsComponent>();
if (!myTransform || !physics) {
return;
}
inVoid = false;
if (context->entities) {
for (auto &other : *context->entities) {
if (!other || other.get() == entity) {
continue;
}
auto zone = other->GetComponent<NullZoneComponent>();
auto zoneTransform = other->GetComponent<TransformComponent>();
if (!zone || !zoneTransform) {
continue;
}
const float left = zoneTransform->get().x;
const float right = left + zone->get().width;
if (myTransform->get().x >= left && myTransform->get().x <= right) {
inVoid = true;
break;
}
}
}
if (inVoid) {
// inside a null zone, the probe floats freely until it exits
return;
}
if (!context->entities) {
return;
}
for (auto &other : *context->entities) {
if (!other || other.get() == entity) {
continue;
}
auto wellTransform = other->GetComponent<TransformComponent>();
auto wellGravity = other->GetComponent<GravityWellComponent>();
if (!wellTransform || !wellGravity || !wellGravity->get().active) {
continue;
}
const float dx = wellTransform->get().x - myTransform->get().x;
const float dy = wellTransform->get().y - myTransform->get().y;
const float dist = std::sqrt(dx * dx + dy * dy);
if (dist <= 0.0001f) {
continue;
}
const float clampedDist = std::max(dist, wellGravity->get().minDist);
const float force = wellGravity->get().mass / (clampedDist * clampedDist);
const float nx = dx / dist;
const float ny = dy / dist;
physics->get().vx += nx * force * dt;
physics->get().vy += ny * force * dt;
}
}
void GravityReceiverComponent::Cleanup() {}