feat: tweak sim params and better detect when wobble is done

This commit is contained in:
Matias 2025-07-16 13:32:12 +02:00
parent 92438a9bce
commit 1059a997f3
No known key found for this signature in database
GPG Key ID: ED35A6AC65A06B69

View File

@ -1,6 +1,7 @@
#include "globals.hpp"
#include <GLES3/gl32.h>
#include <cmath>
#include <hyprgraphics/color/Color.hpp>
// version.hpp will be generated by meson
#include "version.hpp"
@ -46,8 +47,10 @@ class CBindOwnFramebufferPassElement final: public IPassElement {
m_pFramebuffer->bind();
g_pHyprOpenGL->m_renderData.currentFB = m_pFramebuffer;
// TODO: this is not working
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0));
GLCALL(glClearColor(0, 0, 0, 0));
GLCALL(glClear(GL_COLOR_BUFFER_BIT));
g_pHyprRenderer->damageMonitor(g_pHyprOpenGL->m_renderData.pMonitor.lock());
}
bool needsLiveBlur() override {
@ -70,16 +73,6 @@ class CBindOwnFramebufferPassElement final: public IPassElement {
CFramebuffer* m_pFramebuffer;
};
float map_value_in_range(
float value,
float inMin,
float inMax,
float outMin = 0.0,
float outMax = 1.0
) {
return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
}
class CWobblyWindow {
struct SParticle {
Vector2D position;
@ -91,7 +84,7 @@ class CWobblyWindow {
public:
// static wobble parameters
static inline float s_springStrength = 500.f;
static inline float s_dampingStrength = 8.f;
static inline float s_dampingStrength = 12.f;
static inline float s_drag = 0.4f;
std::vector<SParticle> m_particles;
@ -112,7 +105,7 @@ class CWobblyWindow {
bool step(Time::steady_tp time) {
const auto usec =
std::chrono::duration_cast<std::chrono::microseconds>(time - m_lastTime).count();
const float dt = usec * 0.000001f;
const float dt = std::min(0.016f, usec * 0.000001f);
m_lastTime = time;
Vector2D totalVel {};
@ -122,21 +115,22 @@ class CWobblyWindow {
auto&& particlePositon = particle.position;
auto&& targetPosition = m_targetPositions[i];
auto&& directionToTarget = targetPosition - particlePositon;
const Vector2D directionToTarget = targetPosition - particlePositon;
if (m_grabPosition.has_value()) {
auto&& distanceToDragPosition = m_grabPosition.value().distance(particlePositon);
auto&& dragStrength = std::clamp((float)distanceToDragPosition, 0.f, 1.f);
const float distanceToDragPosition =
m_grabPosition.value().distance(particlePositon);
const float dragStrength = std::clamp(distanceToDragPosition, 0.f, 1.f);
particle.position += m_windowMovement * dragStrength;
}
auto&& springForce =
const Vector2D springForce =
directionToTarget * s_springStrength - particle.velocity * s_dampingStrength;
particle.velocity += springForce * dt;
// Apply drag
auto&& dragForceVector = (particle.velocity * particle.velocity) * -s_drag;
const Vector2D dragForceVector = (particle.velocity * particle.velocity) * -s_drag;
// * Area
auto dir = particle.velocity;
@ -151,7 +145,12 @@ class CWobblyWindow {
totalVel += particle.velocity;
}
return totalVel.distanceSq(Vector2D {}) < 0.1f;
const bool shouldEnd =
m_windowMovement.size() == 0 and totalVel.size() / m_particles.size() < .001f;
m_windowMovement = Vector2D {};
return shouldEnd;
}
};
@ -223,6 +222,8 @@ class CRenderWobblyWindowPassElement final: public IPassElement {
if (g_wobblyWindows.contains(m_pWindow)) {
auto&& wobble = g_wobblyWindows[m_pWindow];
// 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);
@ -232,7 +233,19 @@ class CRenderWobblyWindowPassElement final: public IPassElement {
}
GLCALL(glBindBuffer(GL_ARRAY_BUFFER, g_VBO));
GLCALL(glBufferSubData(GL_ARRAY_BUFFER, 0, verts.size() * sizeof(float), verts.data()));
GLCALL(
glBufferSubData(GL_ARRAY_BUFFER, 0, verts.size() * sizeof(float), verts.data())
);
}
} else {
// restore default verts
GLCALL(glBindBuffer(GL_ARRAY_BUFFER, g_VBO));
GLCALL(glBufferSubData(
GL_ARRAY_BUFFER,
0,
g_baseVerts.size() * sizeof(float),
g_baseVerts.data()
));
}
GLCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_EBO));
@ -305,7 +318,7 @@ void hkRenderWindow(
const auto windowBox = pWindow->getFullWindowBoundingBox();
const auto windowSize = Vector2D {windowBox.width, windowBox.height};
if (g_pInputManager->m_currentlyDraggedWindow == pWindow) {
if (windowSize.size() != 0 and g_pInputManager->m_currentlyDraggedWindow == pWindow) {
if (not wobble.m_grabPosition.has_value()) {
auto&& mousePos = g_pInputManager->getMouseCoordsInternal();
wobble.m_grabPosition = (mousePos - pos) / windowSize;
@ -367,9 +380,9 @@ void hkRenderWindow(
);
if (shouldWobble) {
const bool shouldStop = g_wobblyWindows[pWindow].step(time);
if (shouldStop)
g_wobblyWindows.erase(pWindow);
std::erase_if(g_wobblyWindows, [&](auto&& wobble) {
return g_wobblyWindows[pWindow].step(time);
});
pRenderer->m_renderPass.add(
makeUnique<CRenderWobblyWindowPassElement>(pOldFramebuffer, pWindow)