#include "wobblywindow.h" #include "globals.h" #include "renderpasses.h" CWobblyWindow::CWobblyWindow() { auto&& verts = CRenderWobblyWindowPassElement::s_baseVerts; m_particles.reserve(verts.size() / 2); m_targetPositions.reserve(verts.size() / 2); for (unsigned int i {}; i < verts.size(); i += 2) { m_particles.push_back(SParticle {Vector2D {verts[i], verts[i + 1]}, {}}); m_targetPositions.push_back(Vector2D {verts[i], verts[i + 1]}); } } bool CWobblyWindow::step(Time::steady_tp time) { const auto usec = std::chrono::duration_cast(time - m_lastTime).count(); const float dt = std::min(0.016f, usec * 0.000001f); m_lastTime = time; Vector2D totalVel {}; for (unsigned int i {}; i < m_particles.size(); i++) { auto&& particle = m_particles[i]; auto&& particlePositon = particle.position; auto&& targetPosition = m_targetPositions[i]; const Vector2D directionToTarget = targetPosition - particlePositon; if (m_grabPosition.has_value()) { const float distanceToDragPosition = m_grabPosition.value().distance(particlePositon); const float dragStrength = std::clamp(distanceToDragPosition, 0.f, 1.f); particle.position += m_windowMovement * dragStrength; } const Vector2D springForce = directionToTarget * s_springStrength - particle.velocity * s_dampingStrength; particle.velocity += springForce * dt; // Apply drag const Vector2D dragForceVector = (particle.velocity * particle.velocity) * -s_drag; // * Area auto dir = particle.velocity; float magnitude = dir.normalize(); if (magnitude != 0) particle.velocity += (dragForceVector * dir) * dt; // Apply velocity particle.position += particle.velocity * dt; totalVel += particle.velocity; } const bool shouldEnd = m_windowMovement.size() == 0 and totalVel.size() / m_particles.size() < .001f; // std::println( // "Top left: {}, totalVel: {}", // m_particles[0].position, // totalVel.size() / m_particles.size() // ); m_windowMovement = Vector2D {}; return shouldEnd; }