From 1f2b1cb037a202cafe25167c071a2615341dafdb Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Sun, 24 Feb 2019 14:07:16 +0100 Subject: Further abstract mouse handling --- src/main.cc | 42 ++++++++++++++++++++--------------- src/shader/code/interact.glsl | 51 +++++++++++++++++++------------------------ 2 files changed, 47 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/main.cc b/src/main.cc index aa2456e..99e9a73 100644 --- a/src/main.cc +++ b/src/main.cc @@ -108,13 +108,17 @@ int renderWindow() { auto pause_key = window.getKeyWatcher(GLFW_KEY_SPACE); + int prevMouseState = 0; + float prevLatticeMouseX; + float prevLatticeMouseY; + + int currMouseState = 0; + float currLatticeMouseX; + float currLatticeMouseY; + auto tick_buffers = { lattice_a->getBuffer(), lattice_b->getBuffer(), fluid->getBuffer() }; auto tock_buffers = { lattice_b->getBuffer(), lattice_a->getBuffer(), fluid->getBuffer() }; - int prevLatticeMouseState = 0; - int prevLatticeMouseX = 0; - int prevLatticeMouseY = 0; - window.render([&](bool window_size_changed) { if ( pause_key.wasClicked() ) { update_lattice = !update_lattice; @@ -139,24 +143,28 @@ int renderWindow() { tick = true; } - /// Handle mouse-based interaction - const auto m = window.getMouse(); + /// Update mouse projection + { + const auto m = window.getMouse(); - if ( std::get<0>(m) != 0 || prevLatticeMouseState != 0 ) { - auto guard = interact_shader->use(); + prevMouseState = currMouseState; + prevLatticeMouseX = currLatticeMouseX; + prevLatticeMouseY = currLatticeMouseY; - interact_shader->setUniform("prevMouseState", prevLatticeMouseState); - interact_shader->setUniform("prevMousePos", prevLatticeMouseX, prevLatticeMouseY); + currMouseState = std::get<0>(m); + currLatticeMouseX = float(std::get<1>(m)) / window.getWidth() * world_width + nX/2; + currLatticeMouseY = float(std::get<2>(m)) / window.getHeight() * world_height + nY/2; + } - const float latticeMouseX = float(std::get<1>(m)) / window.getWidth() * world_width + nX/2; - const float latticeMouseY = float(std::get<2>(m)) / window.getHeight() * world_height + nY/2; + /// Handle mouse-based interaction + if ( currMouseState != 0 || prevMouseState != 0 ) { + auto guard = interact_shader->use(); - interact_shader->setUniform("currMouseState", std::get<0>(m)); - interact_shader->setUniform("currMousePos", latticeMouseX, latticeMouseY); + interact_shader->setUniform("influxRequested", currMouseState == 1); + interact_shader->setUniform("wallRequested", currMouseState == 2); - prevLatticeMouseState = std::get<0>(m); - prevLatticeMouseX = latticeMouseX; - prevLatticeMouseY = latticeMouseY; + interact_shader->setUniform("startOfLine", prevLatticeMouseX, prevLatticeMouseY); + interact_shader->setUniform("endOfLine", currLatticeMouseX, currLatticeMouseY); interact_shader->dispatch(nX, nY); } diff --git a/src/shader/code/interact.glsl b/src/shader/code/interact.glsl index a65d96a..cb69333 100644 --- a/src/shader/code/interact.glsl +++ b/src/shader/code/interact.glsl @@ -10,10 +10,11 @@ uniform uint nY; /// External influence -uniform int prevMouseState; -uniform vec2 prevMousePos; -uniform int currMouseState; -uniform vec2 currMousePos; +uniform bool influxRequested; +uniform bool wallRequested; + +uniform vec2 startOfLine; +uniform vec2 endOfLine; /// Vector utilities @@ -37,6 +38,14 @@ float distanceToLineSegment(vec2 a, vec2 b, vec2 p) { return norm(pa - ab * (dot(ab, pa) / dot(ab, ab))); } +bool isNearLine(uint x, uint y, float eps) { + if ( startOfLine == endOfLine ) { + return norm(vec2(x,y) - endOfLine) < eps; + } else { + return distanceToLineSegment(startOfLine, endOfLine, vec2(x,y)) < eps; + } +} + /// Array indexing uint indexOfFluidVertex(uint x, uint y) { @@ -74,24 +83,6 @@ void disableWallInterior(uint x, uint y) { } } -/// Determine external influence - -bool isNearMouse(uint x, uint y, float eps) { - if ( prevMouseState == currMouseState ) { - return distanceToLineSegment(prevMousePos, currMousePos, vec2(x,y)) < eps; - } else { - return norm(vec2(x,y) - currMousePos) < eps; - } -} - -bool isInfluxRequestedAt(uint x, uint y) { - return currMouseState == 1 && isNearMouse(x, y, 3); -} - -bool isWallRequestedAt(uint x, uint y) { - return currMouseState == 2 && isNearMouse(x, y, 3); -} - /// Actual interaction kernel void main() { @@ -105,13 +96,15 @@ void main() { const int material = getMaterial(x,y); if ( material == 1 ) { - if ( isInfluxRequestedAt(x,y) ) { - setMaterial(x,y,4); - return; - } - if ( isWallRequestedAt(x,y) ) { - setMaterial(x,y,3); - return; + if ( isNearLine(x, y, 3) ) { + if ( influxRequested ) { + setMaterial(x,y,4); + return; + } + if ( wallRequested ) { + setMaterial(x,y,3); + return; + } } } -- cgit v1.2.3