#include #include "entities/world.hpp" #include "word_anim_system.hpp" #include "utils/config.hpp" namespace Nimbin { static constexpr double ANIM_ADD_DUR = 0.20; static double smoothstep(double t) { t = std::clamp(t, 0., 1.); return t * t * (3. - 2. * t); } static double lerp_d(double a, double b, double t) { return a + (b - a) * t; } void WordAnimSystem::update(DynArray& anims_add, DynArray& anims_drop, CarriedLine& carried, DynArray& words, double dt) { double floor_y = World::get_FloorY(); for (WordAnim_Add& anim : anims_add) { if (anim.complete) continue; anim.t += dt / ANIM_ADD_DUR; if (anim.t >= 1.0) { anim.complete = true; anim.word->pos = anim.target_pos; anim.word->yaw = static_cast(anim.yaw_target); anim.word->pitch = static_cast(anim.pitch_target); carried.push(std::move(anim.word)); } else { double s = smoothstep(anim.t); anim.word->pos = { lerp_d(anim.start_pos.x, anim.target_pos.x, s), lerp_d(anim.start_pos.y, anim.target_pos.y, s), lerp_d(anim.start_pos.z, anim.target_pos.z, s) }; anim.word->yaw = static_cast(lerp_d(anim.yaw_start, anim.yaw_target, s)); anim.word->pitch = static_cast(lerp_d(anim.pitch_start, anim.pitch_target, s)); } } anims_add.erase( std::remove_if(anims_add.begin(), anims_add.end(), [](const WordAnim_Add& a) { return a.complete; }), anims_add.end()); for (WordAnim_Drop& drop : anims_drop) { if (drop.complete) continue; drop.word->body.vel.y -= Config::Physics::proj_grav * dt; drop.word->pos.x += drop.word->body.vel.x * dt; drop.word->pos.y += drop.word->body.vel.y * dt; drop.word->pos.z += drop.word->body.vel.z * dt; const double bottom = drop.word->pos.y - drop.word->shape.half_extents.y; if (bottom <= floor_y) { drop.complete = true; drop.word->pos.y = floor_y + drop.word->shape.half_extents.y; drop.word->body.vel.x *= 0.1; drop.word->body.vel.z *= 0.1; drop.word->body.vel.y = 0.0; drop.word->body.mode = PhysicsMode::Dynamic; if (drop.word->type == ObjectType::Text) drop.word->set_Look(Config::Color::keep, Text::Token::depth_floor); words.push_back(std::move(drop.word)); } } anims_drop.erase( std::remove_if(anims_drop.begin(), anims_drop.end(), [](const WordAnim_Drop& d) { return d.complete; }), anims_drop.end()); } } // namespace Nimbin