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