physics: add particle force generator

This commit is contained in:
Zack Buhman 2025-07-17 15:40:16 -05:00
parent be38080bd6
commit 0c245870b8
5 changed files with 128 additions and 1 deletions

View File

@ -0,0 +1,34 @@
template <typename T, int max_length>
struct fixed_length_list
{
T values[max_length];
int length;
fixed_length_list()
: length(0)
{}
void add(const T& value)
{
for (int i = 0; i < length; i++) {
if (values[i] == value)
return;
}
values[length] = value;
length += 1;
}
void remove(const T& value)
{
for (int i = 0; i < length; i++) {
if (values[i] == value) {
for (int k = i + 1; k < length;) {
values[i++] = values[k++];
}
length -= 1;
break;
}
}
}
};

View File

@ -18,6 +18,9 @@ namespace physics {
// drag
velocity *= damping;
// clear forces
force_accum = vec3(0, 0, 0);
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "math/float_types.hpp"
#include "math/math.hpp"
namespace physics {
@ -14,6 +15,16 @@ namespace physics {
vec3 force_accum;
void integrate(float duration);
};
inline void add_force(const vec3& force)
{
force_accum += force;
}
inline float get_mass() const
{
float sqrt_mass = 1.0f / sqrt<float>(inverse_mass);
return sqrt_mass * sqrt_mass;
}
};
}

View File

@ -0,0 +1,32 @@
#include "physics/particle_force_generator.hpp"
namespace physics {
void particle_force_registry::add(particle * particle, particle_force_generator * force_generator)
{
registrations.add({particle, force_generator});
}
void particle_force_registry::update_forces(float duration)
{
for (int i = 0; i < registrations.length; i++) {
const particle_force_entry& entry = registrations.values[i];
entry.force_generator->update_force(entry.particle, duration);
}
}
void particle_gravity::update_force(particle * particle, float duration)
{
particle->add_force(gravity * particle->get_mass());
}
void particle_drag::update_force(particle * particle, float duration)
{
vec3 force = particle->velocity;
float drag_coeff = magnitude(force);
drag_coeff = k1 * drag_coeff + k2 * drag_coeff * drag_coeff;
particle->add_force(normalize(force) * drag_coeff);
}
}

View File

@ -0,0 +1,47 @@
#pragma once
#include "physics/particle.hpp"
#include "lib/fixed_length_list.hpp"
namespace physics {
struct particle_force_generator
{
virtual void update_force(particle * particle, float duration) = 0;
};
struct particle_force_entry
{
physics::particle * particle;
particle_force_generator * force_generator;
bool operator==(const particle_force_entry&) const = default;
};
struct particle_force_registry
{
fixed_length_list<particle_force_entry, 64> registrations;
void add(particle * particle, particle_force_generator * force_generator);
void update_forces(float duration);
};
struct particle_gravity : particle_force_generator
{
vec3 gravity;
particle_gravity(const vec3& gravity)
: gravity(gravity)
{}
void update_force(particle * particle, float duration) override;
};
struct particle_drag : particle_force_generator
{
float k1;
float k2;
void update_force(particle * particle, float duration) override;
};
}