mirror of
https://git.allpurposem.at/mat/WiggleWobble.git
synced 2025-12-23 13:01:28 +01:00
perf: avoid useless copy of particle positions in renderpass
This commit is contained in:
parent
4885426233
commit
e0475aa880
@ -17,7 +17,9 @@ class CWobblyWindow {
|
||||
static inline float s_dampingStrength = 12.f;
|
||||
static inline float s_drag = 0.4f;
|
||||
|
||||
std::vector<SParticle> m_particles;
|
||||
std::vector<float> m_particlePositions;
|
||||
std::vector<Vector2D> m_particleVelocities;
|
||||
|
||||
std::vector<Vector2D> m_targetPositions;
|
||||
std::optional<Vector2D> m_grabPosition {std::nullopt};
|
||||
Vector2D m_windowMovement;
|
||||
@ -25,5 +27,7 @@ class CWobblyWindow {
|
||||
CWobblyWindow();
|
||||
|
||||
bool step(Time::steady_tp time);
|
||||
|
||||
void applyMovement(const Vector2D& movement);
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -73,10 +73,7 @@ void hkRenderWindow(
|
||||
wobble.m_grabPosition = std::nullopt;
|
||||
}
|
||||
|
||||
wobble.m_windowMovement = (pos - g_windowPositions[pWindow]) / windowSize;
|
||||
for (auto&& particle : wobble.m_particles) {
|
||||
particle.position -= wobble.m_windowMovement;
|
||||
}
|
||||
wobble.applyMovement((pos - g_windowPositions[pWindow]) / windowSize);
|
||||
|
||||
// update last pos
|
||||
g_windowPositions[pWindow] = pos;
|
||||
|
||||
@ -165,16 +165,13 @@ void CRenderWobblyWindowPassElement::draw(const CRegion& damage) {
|
||||
// TODO: these should never be nan
|
||||
// if (not std::isnan(wobble.m_particles[0].position.x)) {
|
||||
|
||||
// TODO: we need the particle positions in their own vec, to avoid this copy
|
||||
std::vector<float> verts;
|
||||
verts.reserve(vertsPerRow * vertsPerRow * 2);
|
||||
for (auto&& particle : wobble.m_particles) {
|
||||
verts.push_back(particle.position.x);
|
||||
verts.push_back(particle.position.y);
|
||||
}
|
||||
|
||||
GLCALL(glBindBuffer(GL_ARRAY_BUFFER, s_VBO));
|
||||
GLCALL(glBufferSubData(GL_ARRAY_BUFFER, 0, verts.size() * sizeof(float), verts.data()));
|
||||
GLCALL(glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
0,
|
||||
wobble.m_particlePositions.size() * sizeof(float),
|
||||
wobble.m_particlePositions.data()
|
||||
));
|
||||
// }
|
||||
} else {
|
||||
// restore default verts
|
||||
|
||||
@ -5,11 +5,15 @@
|
||||
|
||||
CWobblyWindow::CWobblyWindow() {
|
||||
auto&& verts = CRenderWobblyWindowPassElement::s_baseVerts;
|
||||
m_particles.reserve(verts.size() / 2);
|
||||
m_targetPositions.reserve(verts.size() / 2);
|
||||
|
||||
// copy directly
|
||||
m_particlePositions = verts;
|
||||
|
||||
// init empty
|
||||
m_particleVelocities.resize(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]});
|
||||
}
|
||||
}
|
||||
@ -22,42 +26,44 @@ bool CWobblyWindow::step(Time::steady_tp time) {
|
||||
|
||||
Vector2D totalVel {};
|
||||
|
||||
for (unsigned int i {}; i < m_particles.size(); i++) {
|
||||
auto&& particle = m_particles[i];
|
||||
auto&& particlePositon = particle.position;
|
||||
for (unsigned int i {}; i < m_particlePositions.size() / 2; i++) {
|
||||
// TODO: avoid float -> double promotion
|
||||
const auto& pos = Vector2D {m_particlePositions[i * 2], m_particlePositions[i * 2 + 1]};
|
||||
auto&& vel = m_particleVelocities[i];
|
||||
auto&& targetPosition = m_targetPositions[i];
|
||||
|
||||
const Vector2D directionToTarget = targetPosition - particlePositon;
|
||||
const Vector2D directionToTarget = targetPosition - pos;
|
||||
|
||||
if (m_grabPosition.has_value()) {
|
||||
const float distanceToDragPosition = m_grabPosition.value().distance(particlePositon);
|
||||
const float distanceToDragPosition = m_grabPosition.value().distance(pos);
|
||||
const float dragStrength = std::clamp(distanceToDragPosition, 0.f, 1.f);
|
||||
|
||||
particle.position += m_windowMovement * dragStrength;
|
||||
m_particlePositions[i * 2] += m_windowMovement.x * dragStrength;
|
||||
m_particlePositions[i * 2 + 1] += m_windowMovement.y * dragStrength;
|
||||
}
|
||||
|
||||
const Vector2D springForce =
|
||||
directionToTarget * s_springStrength - particle.velocity * s_dampingStrength;
|
||||
particle.velocity += springForce * dt;
|
||||
const Vector2D springForce = directionToTarget * s_springStrength - vel * s_dampingStrength;
|
||||
vel += springForce * dt;
|
||||
|
||||
// Apply drag
|
||||
const Vector2D dragForceVector = (particle.velocity * particle.velocity) * -s_drag;
|
||||
const Vector2D dragForceVector = (vel * vel) * -s_drag;
|
||||
|
||||
// * Area
|
||||
auto dir = particle.velocity;
|
||||
auto dir = vel;
|
||||
float magnitude = dir.normalize();
|
||||
|
||||
if (magnitude != 0)
|
||||
particle.velocity += (dragForceVector * dir) * dt;
|
||||
vel += (dragForceVector * dir) * dt;
|
||||
|
||||
// Apply velocity
|
||||
particle.position += particle.velocity * dt;
|
||||
m_particlePositions[i * 2] += vel.x * dt;
|
||||
m_particlePositions[i * 2 + 1] += vel.y * dt;
|
||||
|
||||
totalVel += particle.velocity;
|
||||
totalVel += vel;
|
||||
}
|
||||
|
||||
const bool shouldEnd =
|
||||
m_windowMovement.size() == 0 and totalVel.size() / m_particles.size() < .001f;
|
||||
const bool shouldEnd = m_windowMovement.size() == 0
|
||||
and totalVel.size() / (m_particlePositions.size() / 2.f) < .001f;
|
||||
|
||||
// std::println(
|
||||
// "Top left: {}, totalVel: {}",
|
||||
@ -68,3 +74,12 @@ bool CWobblyWindow::step(Time::steady_tp time) {
|
||||
|
||||
return shouldEnd;
|
||||
}
|
||||
|
||||
void CWobblyWindow::applyMovement(const Vector2D& movement) {
|
||||
m_windowMovement = movement;
|
||||
|
||||
for (unsigned int i = 0; i < m_particlePositions.size() / 2; i++) {
|
||||
m_particlePositions[i * 2] -= movement.x;
|
||||
m_particlePositions[i * 2 + 1] -= movement.y;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user