mirror of
https://git.allpurposem.at/mat/WiggleWobble.git
synced 2025-12-23 13:01:28 +01:00
feat: tweak sim params and better detect when wobble is done
This commit is contained in:
parent
92438a9bce
commit
1059a997f3
77
src/main.cpp
77
src/main.cpp
@ -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,16 +222,30 @@ class CRenderWobblyWindowPassElement final: public IPassElement {
|
||||
if (g_wobblyWindows.contains(m_pWindow)) {
|
||||
auto&& wobble = g_wobblyWindows[m_pWindow];
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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, 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(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));
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user