From 4892848c3bec126e23c5ce4de5e4136737a33b08 Mon Sep 17 00:00:00 2001 From: rexim Date: Thu, 31 Oct 2019 03:04:02 +0700 Subject: [PATCH] Make navigation actually usable --- src/boomer.nim | 17 +++++++++-------- src/config.nim | 2 -- src/la.nim | 39 +++++++++++++-------------------------- src/navigation.nim | 22 +++++++++++++--------- src/vert.glsl | 5 +++-- 5 files changed, 38 insertions(+), 47 deletions(-) diff --git a/src/boomer.nim b/src/boomer.nim index dcd5263..ca71edc 100644 --- a/src/boomer.nim +++ b/src/boomer.nim @@ -71,7 +71,8 @@ proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint) = glUseProgram(shader) - glUniformMatrix4fv(glGetUniformLocation(shader, "transform".cstring), 1, false, camera.matrix.caddr) + glUniform2f(glGetUniformLocation(shader, "cameraPos".cstring), camera.position[0], camera.position[1]) + glUniform1f(glGetUniformLocation(shader, "cameraScale".cstring), camera.scale) glBindVertexArray(vao) glDrawElements(GL_TRIANGLES, count = 6, GL_UNSIGNED_INT, indices = nil) @@ -248,7 +249,7 @@ proc main() = var quitting = false - camera = Camera(scale: 1.0, matrix: mat4f(1)) + camera = Camera(scale: 1.0) mouse: Mouse while not quitting: @@ -263,13 +264,13 @@ proc main() = discard of MotionNotify: - mouse.curr = vec2(xev.xmotion.x.float32 / screenshot.width.float32 * 2.0'f32 - 1.0'f32, - xev.xmotion.y.float32 / screenshot.height.float32 * 2.0'f32 - 1.0'f32) + mouse.curr = vec2(xev.xmotion.x.float32, + xev.xmotion.y.float32) if mouse.drag: - let mouseDelta = mouse.prev - mouse.curr - camera.position += mouseDelta - camera.velocity = mouseDelta * config.dragVelocityFactor + let delta = world(mouse.prev, screenshot, camera) - world(mouse.curr, screenshot, camera) + camera.position += delta + camera.velocity = delta * config.dragVelocityFactor mouse.prev = mouse.curr of ClientMessage: @@ -316,7 +317,7 @@ proc main() = else: discard - camera.update(config, 1.0 / config.fps.float, mouse) + camera.update(config, 1.0 / config.fps.float, mouse, screenshot) screenshot.draw(camera, shaderProgram, vao, texture) diff --git a/src/config.nim b/src/config.nim index 57ab867..c8c9dc7 100644 --- a/src/config.nim +++ b/src/config.nim @@ -5,7 +5,6 @@ type Config* = object dragVelocityFactor*: float dragFriction*: float scaleFriction*: float - scalePanning*: float fps*: int const defaultConfig* = Config( @@ -13,7 +12,6 @@ const defaultConfig* = Config( dragVelocityFactor: 10.0, dragFriction: 1.0, scaleFriction: 10.0, - scalePanning: 0.05, fps: 60 ) diff --git a/src/la.nim b/src/la.nim index 0acabcd..b843fbf 100644 --- a/src/la.nim +++ b/src/la.nim @@ -1,18 +1,23 @@ import math type Vec2f* = tuple[x: float32, y: float32] -type Mat4f* = array[0 .. 15, float32] proc vec2*(x: float32, y: float32): Vec2f = (x, y) -proc caddr*(a: var Mat4f): ptr float32 = - addr a[0] - proc `*`*(a: Vec2f, s: float32): Vec2f = - (a.x * s, a.y * s) + vec2(a.x * s, a.y * s) + +proc `*`*(a: Vec2f, b: Vec2f): Vec2f = + vec2(a.x * b.x, a.y * b.y) + +proc `/`*(a: Vec2f, b: Vec2f): Vec2f = + vec2(a.x / b.x, a.y / b.y) proc `-`*(a: Vec2f, b: Vec2f): Vec2f = - (a.x - b.x, a.y - b.y) + vec2(a.x - b.x, a.y - b.y) + +proc `+`*(a: Vec2f, b: Vec2f): Vec2f = + vec2(a.x + b.x, a.y + b.y) proc `+=`*(a: var Vec2f, b: Vec2f) = a.x += b.x @@ -28,24 +33,6 @@ proc length*(a: Vec2f): float32 = proc normalize*(a: Vec2f): Vec2f = let b = a.length if b == 0.0'f32: - return (0.0'f32, 0.0'f32) + return vec2(0.0'f32, 0.0'f32) else: - return (a.x / b, a.y / b) - -proc mat4f*(x: float32): Mat4f = - [x, 0.0'f32, 0.0'f32, 0.0'f32, - 0.0'f32, x, 0.0'f32, 0.0'f32, - 0.0'f32, 0.0'f32, x, 0.0'f32, - 0.0'f32, 0.0'f32, 0.0'f32, x] - -proc translate*(mat: Mat4f, x: float32, y: float32, z: float32): Mat4f = - result = mat - result[12] += x - result[13] += y - result[14] += z - -proc scale*(mat: Mat4f, s: float32): Mat4f = - result = mat - result[0 * 4 + 0] *= s - result[1 * 4 + 1] *= s - result[2 * 4 + 2] *= s + return vec2(a.x / b, a.y / b) diff --git a/src/navigation.nim b/src/navigation.nim index c3d3c41..cba27d7 100644 --- a/src/navigation.nim +++ b/src/navigation.nim @@ -1,6 +1,7 @@ import math import config import la +import image type Mouse* = object curr*: Vec2f @@ -10,19 +11,22 @@ type Mouse* = object type Camera* = object position*: Vec2f velocity*: Vec2f - scale*: float + scale*: float32 deltaScale*: float - matrix*: Mat4f -proc update*(camera: var Camera, config: Config, dt: float, mouse: Mouse) = +proc world*(point: Vec2f, image: Image, camera: Camera): Vec2f = + let f = (camera.position + vec2(1.0f32, 1.0f32)) / vec2(2.0f32, 2.0f32) + let ps = vec2(image.width.float32 * camera.scale, image.height.float32 * camera.scale) * f + let ms = vec2(point.x.float32, point.y.float32) + ps + return vec2(ms.x / (image.width.float32 * camera.scale) * 2.0f32 - 1.0f32, + ms.y / (image.height.float32 * camera.scale) * 2.0f32 - 1.0f32) + +proc update*(camera: var Camera, config: Config, dt: float, mouse: Mouse, image: Image) = if abs(camera.deltaScale) > 0.5: - camera.scale = max(camera.scale + camera.deltaScale * dt, 1.0) - if camera.scale > 1.0: - camera.position += mouse.curr * (camera.deltaScale / camera.scale * config.scalePanning) - camera.deltaScale -= sgn(camera.deltaScale).float * config.scaleFriction * dt + # TODO: camera position adjustment doesn't work anymore + camera.scale = max(camera.scale + camera.delta_scale * dt, 1.0) + camera.delta_scale -= sgn(camera.delta_scale).float * config.scale_friction * dt if not mouse.drag and (camera.velocity.length > 0.01): camera.position += camera.velocity * dt camera.velocity -= camera.velocity.normalize * (config.dragFriction * dt) - - camera.matrix = mat4f(1).translate(-camera.position.x, camera.position.y, 0).scale(camera.scale) diff --git a/src/vert.glsl b/src/vert.glsl index 33dc952..3e558db 100644 --- a/src/vert.glsl +++ b/src/vert.glsl @@ -2,9 +2,10 @@ in vec3 aPos; in vec2 aTexCoord; out vec2 texcoord; -uniform mat4 transform; +uniform vec2 cameraPos; +uniform float cameraScale; void main() { - gl_Position = transform * vec4(aPos, 1.0f); + gl_Position = vec4((aPos.x - cameraPos.x) * cameraScale, (aPos.y + cameraPos.y) * cameraScale, 0.0, 1.0); texcoord = aTexCoord; }