mirror of
https://git.allpurposem.at/mat/WiggleWobble.git
synced 2025-12-23 13:01:28 +01:00
71 lines
2.2 KiB
C++
71 lines
2.2 KiB
C++
#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<std::chrono::microseconds>(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;
|
|
}
|