From b8d9e36baf889f93aff5761f49fa7eb30874d283 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Thu, 17 Jun 2021 23:27:31 +0200 Subject: Reimplement camera controller --- tangle/LLBM/volumetric.h | 22 +++++++------- tangle/util/camera.h | 62 ++++++++++++++++++++++++---------------- tangle/util/volumetric_example.h | 8 ++++-- 3 files changed, 52 insertions(+), 40 deletions(-) (limited to 'tangle') diff --git a/tangle/LLBM/volumetric.h b/tangle/LLBM/volumetric.h index 312d0e8..5e5a18a 100644 --- a/tangle/LLBM/volumetric.h +++ b/tangle/LLBM/volumetric.h @@ -9,11 +9,7 @@ __device__ float2 getNormalizedScreenPos(float w, float h, float x, float y) { ); } -__device__ float3 getEyeRayDir(float2 screen_pos, float3 eye_pos, float3 eye_target) { - const float3 forward = normalize(eye_target - eye_pos); - const float3 right = normalize(cross(make_float3(0.f, 0.f, -1.f), forward)); - const float3 up = normalize(cross(forward, right)); - +__device__ float3 getEyeRayDir(float2 screen_pos, float3 forward, float3 right, float3 up) { return normalize(screen_pos.x*right + screen_pos.y*up + 4*forward); } @@ -43,8 +39,10 @@ struct VolumetricRenderConfig { float brightness = 1; float3 background = make_float3(22.f / 255.f); - float3 eye_pos; - float3 eye_dir; + float3 camera_position; + float3 camera_forward; + float3 camera_right; + float3 camera_up; cudaSurfaceObject_t canvas; uint2 canvas_size; @@ -74,7 +72,7 @@ __global__ void raymarch( } const float2 screen_pos = getNormalizedScreenPos(config.canvas_size.x, config.canvas_size.y, x, y); - const float3 ray_dir = getEyeRayDir(screen_pos, config.eye_pos, config.eye_pos + config.eye_dir); + const float3 ray_dir = getEyeRayDir(screen_pos, config.camera_forward, config.camera_right, config.camera_up); float3 r = make_float3(0); float a = 0; @@ -82,13 +80,13 @@ __global__ void raymarch( float tmin = 0; float tmax = 4000; - if (aabb(config.eye_pos, ray_dir, config.cuboid, tmin, tmax)) { + if (aabb(config.camera_position, ray_dir, config.cuboid, tmin, tmax)) { float volume_dist = tmax - tmin; - float3 geometry_pos = config.eye_pos + tmin*ray_dir; + float3 geometry_pos = config.camera_position + tmin*ray_dir; float geometry_dist = approximateDistance(geometry, geometry_pos, ray_dir, 0, volume_dist); geometry_pos += geometry_dist * ray_dir; - float jitter = config.align_slices_to_view * (floor(fabs(dot(config.eye_dir, tmin*ray_dir)) / config.delta) * config.delta - tmin) + float jitter = config.align_slices_to_view * (floor(fabs(dot(config.camera_forward, tmin*ray_dir)) / config.delta) * config.delta - tmin) + config.apply_noise * config.delta * noiseFromTexture(config.noise, threadIdx.x, threadIdx.y); tmin += jitter; @@ -96,7 +94,7 @@ __global__ void raymarch( geometry_dist -= jitter; if (volume_dist > config.delta) { - float3 sample_pos = config.eye_pos + tmin * ray_dir; + float3 sample_pos = config.camera_position + tmin * ray_dir; unsigned n_samples = floor(geometry_dist / config.delta); for (unsigned i=0; i < n_samples; ++i) { sample_pos += config.delta * ray_dir; diff --git a/tangle/util/camera.h b/tangle/util/camera.h index 0a793d3..2b2c9ef 100644 --- a/tangle/util/camera.h +++ b/tangle/util/camera.h @@ -1,23 +1,28 @@ #include #include "SFML/Window/Event.hpp" +#include +#include +#include +#include + class Camera { private: - float _distance; - float _phi; - float _psi; + glm::quat _rotation; + glm::mat3 _matrix; float3 _target; - float3 _eye; - float3 _direction; + float3 _position; + float3 _forward; + float3 _right; + float3 _up; + float _distance; bool _dragging; bool _moving; float2 _lastMouse; public: - Camera(float3 target, float distance, float phi, float psi): + Camera(float3 target, float distance): _distance(distance), - _phi(phi), - _psi(psi), _target(target), _dragging(false), _moving(false) { @@ -25,8 +30,14 @@ public: } void update() { - _eye = _target + make_float3(_distance*sin(_psi)*cos(_phi), _distance*sin(_psi)*sin(_phi), _distance*cos(_psi)); - _direction = normalize(_target - _eye); + glm::vec3 position = _matrix * glm::vec3(0, _distance, 0); + _position = _target + make_float3(position[0], position[1], position[2]); + _forward = normalize(_target - _position); + + glm::vec3 right = _matrix * glm::vec4(-1, 0, 0, 0); + _right = make_float3(right[0], right[1], right[2]); + glm::vec3 up = _matrix * glm::vec4(glm::cross(glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0)), 0); + _up = make_float3(up[0], up[1], up[2]); } void handle(sf::Event& event) { @@ -55,32 +66,33 @@ public: float2 mouse = make_float2(event.mouseMove.x, event.mouseMove.y); float2 delta = mouse - _lastMouse; _lastMouse = mouse; - _phi += 0.4*delta.x * 2*M_PI/360; - if (delta.y > 0 && _psi <= M_PI-2*M_PI/60) { - _psi += 0.4*delta.y * M_PI/180; - } else if (delta.y < 0 && _psi >= 2*M_PI/60) { - _psi += 0.4*delta.y * M_PI/180; - } + + glm::quat rotation_z = glm::conjugate(_rotation) * glm::vec3(0,0,0.01*delta.x); + glm::quat rotation_x = glm::conjugate(_rotation) * glm::vec3(0.01*delta.y,0,0); + + _matrix = _matrix * glm::mat3_cast(_rotation * glm::cross(rotation_x, rotation_z)); } if (_moving) { float2 mouse = make_float2(event.mouseMove.x, event.mouseMove.y); float2 delta = mouse - _lastMouse; _lastMouse = mouse; - float3 forward = normalize(_target - _eye); - float3 right = normalize(cross(make_float3(0.f, 0.f, -1.f), forward)); - float3 up = cross(right, forward); - _target += 0.4*right*delta.x - 0.4*up*delta.y; + _target += 0.4*_right*delta.x + 0.4*_up*delta.y; } break; } update(); } - float3 getDirection() const { - return _direction; + float3 getPosition() const { + return _position; } - - float3 getEyePosition() const { - return _eye; + float3 getForward() const { + return _forward; + } + float3 getRight() const { + return _right; + } + float3 getUp() const { + return _up; } }; diff --git a/tangle/util/volumetric_example.h b/tangle/util/volumetric_example.h index da5e4c4..cbcb2d2 100644 --- a/tangle/util/volumetric_example.h +++ b/tangle/util/volumetric_example.h @@ -24,7 +24,7 @@ int _samples_per_second = 30; public: VolumetricExample(descriptor::CuboidD<3> cuboid): RenderWindow("LiterateLB"), - _camera(make_float3(cuboid.nX/2,cuboid.nY/2,cuboid.nZ/2), cuboid.nX, M_PI/2, M_PI/2), + _camera(make_float3(cuboid.nX/2,cuboid.nY/2,cuboid.nZ/2), cuboid.nX), _config(cuboid), _palette(_config.palette), _noise(_config.noise) @@ -103,8 +103,10 @@ void run(TIMESTEP step) { }, [&](sf::Event& event) { _camera.handle(event); - _config.eye_pos = _camera.getEyePosition(); - _config.eye_dir = _camera.getDirection(); + _config.camera_position = _camera.getPosition(); + _config.camera_forward = _camera.getForward(); + _config.camera_right = _camera.getRight(); + _config.camera_up = _camera.getUp(); _config.canvas_size = make_uint2(this->getRenderView().width, this->getRenderView().height); } ); -- cgit v1.2.3