From bf498dca2c333bd66775005571ef915cf27c3ee8 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Wed, 14 Jan 2026 18:45:49 +0100 Subject: Got physics working again --- examples/particles_gpu/particles_gpu.cpp | 15 ++++--- lib/core/c++/particle/particle.hpp | 75 ++++++++++++++++++-------------- lib/core/tests/particles.cpp | 12 +++-- 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/examples/particles_gpu/particles_gpu.cpp b/examples/particles_gpu/particles_gpu.cpp index dfd5af3..abbc192 100644 --- a/examples/particles_gpu/particles_gpu.cpp +++ b/examples/particles_gpu/particles_gpu.cpp @@ -42,12 +42,15 @@ saw::error_or lbm_main(int argc, char** argv){ } } + saw::data> time_step; + time_step.at({}).set(0.05f); + for(saw::data dt{0u}; dt < saw::data{32ul}; ++dt){ // Do Verlet Step for(saw::data i{0u}; i < particles.size(); ++i){ auto& part_i = particles.at(i); - verlet_step_lambda(part_i,{0.05f}); + verlet_step_lambda(part_i,time_step); auto& body_i = part_i.template get<"rigid_body">(); auto& acc_i = body_i.template get<"acceleration">(); @@ -70,23 +73,23 @@ saw::error_or lbm_main(int argc, char** argv){ auto& pos_j = body_j.template get<"position">(); auto& pos_old_j = body_j.template get<"position_old">(); - auto res = broadphase_collision_distance(part_i, part_j); + auto res = broadphase_collision_distance_squared(part_i, part_j); if(res.first){ //std::cout<<"Collision"< +struct rotation_type_helper; + +template +struct rotation_type_helper { + using Schema = Scalar; +}; + +template +struct rotation_type_helper { + using Schema = Vector; +}; +} + template using ParticleRigidBody = Struct< Member, "position">, Member, "position_old">, - Member, - Member, + Member::Schema, "rotation">, + Member::Schema, "rotation_old">, Member, "acceleration">, - Member + Member::Schema, "rotational_acceleration"> >; template @@ -44,8 +59,8 @@ saw::data, sch::ParticleCollisionSpheroid> create_spheroid saw::data> rot_pos_p, saw::data> rot_vel_p, saw::data> rot_acc_p, - saw::data rad_p, - saw::data density_p + saw::data> rad_p, + saw::data> density_p ){ saw::data> part; @@ -70,54 +85,48 @@ saw::data, sch::ParticleCollisionSpheroid> create_spheroid } template -constexpr auto verlet_step_lambda = [](saw::data>& particle, saw::data time_step_delta){ - auto& body = particle.template get<"rigid_body">(); +constexpr auto verlet_step_lambda = [](saw::data>& particle, saw::data> time_step_delta){ + auto& body = particle.template get<"rigid_body">(); - auto& pos = body.template get<"position">(); - auto& pos_old = body.template get<"position_old">(); + auto& pos = body.template get<"position">(); + auto& pos_old = body.template get<"position_old">(); - auto& rot = body.template get<"rotation">(); - auto& acc = body.template get<"acceleration">(); + auto& rot = body.template get<"rotation">(); + auto& acc = body.template get<"acceleration">(); - auto tsd_squared = time_step_delta * time_step_delta; + auto tsd_squared = time_step_delta * time_step_delta; - saw::data> pos_new; - // Actual step - for(uint64_t i = 0u; i < D; ++i){ - pos_new.at({{i}}) = saw::data{2.0} * pos.at({{i}}) - pos_old.at({{i}}) + acc.at({{i}}) * tsd_squared; - } + saw::data> pos_new; + // Actual step + saw::data> two; + two.at({}).set(2.0); + pos_new = pos * two - pos_old + acc * tsd_squared; - pos_old = pos; - pos = pos_new; + pos_old = pos; + pos = pos_new; }; template -constexpr auto handle_collision = [](saw::data>& left, saw::data>& right, saw::data> unit_pos_rel, saw::data> vel_rel) +constexpr auto handle_collision = [](saw::data>& left, saw::data>& right, saw::data> unit_pos_rel, saw::data> vel_rel, saw::data> d_t) { auto& rb_l = left.template get<"rigid_body">(); auto& pos_l = rb_l.template get<"position">(); auto& pos_old_l = rb_l.template get<"position_old">(); - auto vel_l = pos_l - pos_old_l; auto& mass_l = left.template get<"mass">(); + auto vel_l = (pos_l-pos_old_l)/d_t; auto& rb_r = right.template get<"rigid_body">(); auto& pos_r = rb_r.template get<"position">(); auto& pos_old_r = rb_r.template get<"position_old">(); - auto vel_r = pos_r - pos_old_r; auto& mass_r = left.template get<"mass">(); + auto vel_r = (pos_r-pos_old_r)/d_t; - /** - * E to 0 - */ - - constexpr saw::data> elasticity{0u}; - constexpr saw::data> one{1.0}; - - saw::data> j = (e - one) / ((one / mass_l) + (one / mass_r)); - - vel_l = vel_l + vel_rel * j; - vel_r = vel_r - vel_rel * j; + auto vel_pos_rel_dot = saw::math::dot(unit_pos_rel,vel_rel); + if( vel_pos_rel_dot.at({{0u}}).get() < 0.0 ){ + pos_l = pos_l + vel_rel * unit_pos_rel * d_t; + pos_r = pos_r - vel_rel * unit_pos_rel * d_t; + } }; diff --git a/lib/core/tests/particles.cpp b/lib/core/tests/particles.cpp index 366c2a2..b2581f7 100644 --- a/lib/core/tests/particles.cpp +++ b/lib/core/tests/particles.cpp @@ -22,7 +22,9 @@ SAW_TEST("Verlet step 2D - Planar"){ acc.at({{0}}).set({1.0}); - lbm::verlet_step_lambda(particle,{0.5}); + saw::data> dt; + dt.at({}).set(0.5); + lbm::verlet_step_lambda(particle,dt); SAW_EXPECT(pos.at({{0}}).get() == 0.25, std::string{"Incorrect Pos X: "} + std::to_string(pos.at({{0}}).get())); SAW_EXPECT(pos.at({{1}}).get() == 0.0, std::string{"Incorrect Pos Y: "} + std::to_string(pos.at({{1}}).get())); @@ -130,11 +132,13 @@ SAW_TEST("Moving particles 2D"){ pos_old = pos; acc.at({{0u}}) = -0.1; } - + + saw::data> dt; + dt.at({}).set(0.5); bool has_collided = false; for(uint64_t i = 0u; i < 32u; ++i){ - lbm::verlet_step_lambda(part_a,{0.5}); - lbm::verlet_step_lambda(part_b,{0.5}); + lbm::verlet_step_lambda(part_a,dt); + lbm::verlet_step_lambda(part_b,dt); has_collided = lbm::broadphase_collision_check(part_a,part_b); if(has_collided){ -- cgit v1.2.3