Skip to content
Snippets Groups Projects
Verified Commit b2bcd613 authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Implemented abstract interpolation functions into framework

parent 1217cc07
No related branches found
No related tags found
1 merge request!53Resolve "Kamera - Kamerafahrt mit Interpolation"
...@@ -54,6 +54,8 @@ set(vkcv_sources ...@@ -54,6 +54,8 @@ set(vkcv_sources
${vkcv_include}/vkcv/PipelineConfig.hpp ${vkcv_include}/vkcv/PipelineConfig.hpp
${vkcv_source}/vkcv/PipelineConfig.cpp ${vkcv_source}/vkcv/PipelineConfig.cpp
${vkcv_include}/vkcv/Interpolation.hpp
${vkcv_include}/vkcv/Logger.hpp ${vkcv_include}/vkcv/Logger.hpp
${vkcv_include}/vkcv/ShaderStage.hpp ${vkcv_include}/vkcv/ShaderStage.hpp
......
#pragma once
/**
* @authors Tobias Frisch
* @file vkcv/Interpolation.hpp
* @brief Structure for interpolation
*/
#include <algorithm>
#include <cmath>
#include <functional>
#include <vector>
namespace vkcv {
template<typename V, typename T = double>
struct interpolation_function {
typedef std::function<V(const V&, const V&, T)> type;
};
template<typename V, typename T = double>
struct interpolation_state {
T time;
V value;
bool operator<(const interpolation_state& other) const {
return time < other.time;
}
};
template<typename V, typename T = double>
struct interpolation {
private:
typename interpolation_function<V, T>::type m_function;
std::vector< interpolation_state<V, T> > m_states;
public:
interpolation(const typename interpolation_function<V, T>::type& function)
: m_function(function), m_states() {}
interpolation(const interpolation& other) = default;
interpolation(interpolation&& other) noexcept = default;
~interpolation() = default;
interpolation& operator=(const interpolation& other) = default;
interpolation& operator=(interpolation&& other) noexcept = default;
void clear() {
m_states.clear();
}
void add(T time, const V& value) {
interpolation_state<V, T> state;
state.time = time;
state.value = value;
m_states.insert(
std::lower_bound(m_states.begin(), m_states.end(), state),
state
);
}
V operator()(T time) const {
interpolation_state<V, T> state;
state.time = time;
auto end = std::lower_bound(m_states.begin(), m_states.end(), state);
auto start = end != m_states.begin()? (end - 1) : m_states.begin();
if (end == m_states.end()) {
end = start;
}
const T ratio = (time - (*start).time) / ((*end).time - (*start).time);
return m_function(
(*start).value,
(*end).value,
std::clamp<T>(
ratio,
static_cast<T>(0),
static_cast<T>(1)
)
);
}
};
template<typename V, typename T = double>
interpolation<V, T> linearInterpolation() {
return interpolation<V, T>([](const V& start, const V& end, T ratio) {
return start * (static_cast<T>(1) - ratio) + end * ratio;
});
}
template<typename V, typename T = double>
interpolation<V, T> cubicInterpolation() {
return interpolation<V, T>([](const V& start, const V& end, T ratio) {
const T r0 = (static_cast<T>(1) - ratio) * (static_cast<T>(1) - ratio);
const T r1 = ratio * ratio;
return (
start * r0 +
start * r0 * ratio * static_cast<T>(2) +
end * r1 * (static_cast<T>(1) - ratio) * static_cast<T>(2) +
end * r1
);
});
}
template<typename V, typename T = double>
interpolation<V, T> cosInterpolation() {
return interpolation<V, T>([](const V& start, const V& end, T ratio) {
const T cos_ratio = (static_cast<T>(1) - std::cos(
ratio * static_cast<T>(M_PI)
)) / static_cast<T>(2);
return start * (static_cast<T>(1) - cos_ratio) + end * cos_ratio;
});
}
}
\ No newline at end of file
...@@ -18,8 +18,6 @@ set(vkcv_camera_sources ...@@ -18,8 +18,6 @@ set(vkcv_camera_sources
${vkcv_camera_source}/vkcv/camera/PilotCameraController.cpp ${vkcv_camera_source}/vkcv/camera/PilotCameraController.cpp
${vkcv_camera_include}/vkcv/camera/TrackballCameraController.hpp ${vkcv_camera_include}/vkcv/camera/TrackballCameraController.hpp
${vkcv_camera_source}/vkcv/camera/TrackballCameraController.cpp ${vkcv_camera_source}/vkcv/camera/TrackballCameraController.cpp
${vkcv_camera_include}/vkcv/camera/InterpolationLinear.hpp
${vkcv_camera_source}/vkcv/camera/InterpolationLinear.cpp
) )
# adding source files to the project # adding source files to the project
......
#include <glm/glm.hpp>
#include <GLFW/glfw3.h>
#include <vkcv/camera/Camera.hpp>
#include <vector>
namespace vkcv::camera {
class InterpolationLinear{
private:
Camera& m_camera;
double m_timeSinceStart;
std::vector<glm::vec3> m_positions;
public:
InterpolationLinear(Camera &camera);
/**
* @brief Add position vector to be approached. The positions are approached in the order in which they where added.
*
* @param pos
*/
void addPosition(const glm::vec3& pos);
/**
* @brief Set the Camera object
*
* @param camera
*/
void setCamera(Camera camera);
/**
* @brief Resets timer
*
*/
void resetTimer();
/**
* @brief Updates the camera with the interpolated position values
*
*/
void updateCamera();
};
}
\ No newline at end of file
#include "vkcv/camera/InterpolationLinear.hpp"
#include <vkcv/Logger.hpp>
#include <iostream>
namespace vkcv::camera {
InterpolationLinear::InterpolationLinear(Camera &camera)
: m_camera(camera) {
resetTimer();
}
void InterpolationLinear::resetTimer() {
m_timeSinceStart = glfwGetTime();
}
void InterpolationLinear::addPosition(const glm::vec3& pos) {
m_positions.push_back(pos);
}
glm::vec3 interpolate(glm::vec3 posA, glm::vec3 posB, double time, double duration) {
glm::vec3 posDiff = posB - posA;
glm::vec3 posInterp = posA + (posDiff * static_cast<float>(time / duration));
return posInterp;
}
void InterpolationLinear::updateCamera() {
if (m_positions.size() < 2) {
vkcv_log(LogLevel::ERROR, "At least 2 positions needed for interpolation.");
return;
}
double t = glfwGetTime() - m_timeSinceStart;
double segmentDuration = 2.0;
int numberOfSegments = m_positions.size()-1;
double totalDuration = numberOfSegments * segmentDuration;
double modt = fmod(t, totalDuration);
int currentSegment = static_cast<int>((modt / totalDuration) * numberOfSegments);
glm::vec3 posInterp = interpolate(m_positions[currentSegment], m_positions[currentSegment+1], fmod(modt, segmentDuration), segmentDuration);
// const glm::vec3 front = m_camera.getFront();
// const glm::vec3 up = m_camera.getUp();
// m_camera.lookAt(posInterp, front+posInterp, up);
m_camera.setPosition(posInterp); // always look at center
}
}
\ No newline at end of file
#include <iostream> #include <iostream>
#include <vkcv/Core.hpp> #include <vkcv/Core.hpp>
#include <vkcv/Image.hpp> #include <vkcv/Image.hpp>
#include <vkcv/Interpolation.hpp>
#include <vkcv/Pass.hpp> #include <vkcv/Pass.hpp>
#include <vkcv/Sampler.hpp> #include <vkcv/Sampler.hpp>
#include <vkcv/camera/CameraManager.hpp> #include <vkcv/camera/CameraManager.hpp>
#include <vkcv/camera/InterpolationLinear.hpp>
#include <chrono>
#include <vkcv/asset/asset_loader.hpp> #include <vkcv/asset/asset_loader.hpp>
#include <vkcv/shader/GLSLCompiler.hpp> #include <vkcv/shader/GLSLCompiler.hpp>
...@@ -115,14 +114,14 @@ int main(int argc, const char** argv) { ...@@ -115,14 +114,14 @@ int main(int argc, const char** argv) {
cameraManager.getCamera(camHandle1).setPosition(glm::vec3(0, 0, -3)); cameraManager.getCamera(camHandle1).setPosition(glm::vec3(0, 0, -3));
cameraManager.getCamera(camHandle2).setPosition(glm::vec3(0, 0, -3)); cameraManager.getCamera(camHandle2).setPosition(glm::vec3(0, 0, -3));
vkcv::camera::InterpolationLinear interp (cameraManager.getCamera(camHandle0)); auto interp = vkcv::linearInterpolation<glm::vec3, float>();
interp.addPosition(glm::vec3(5,5,-5)); interp.add( 0.0f, glm::vec3(+5, +5, -5));
interp.addPosition(glm::vec3(0,5,-5)); interp.add( 2.0f, glm::vec3(+0, +5, -5));
interp.addPosition(glm::vec3(0,-3,-3)); interp.add( 4.0f, glm::vec3(+0, -3, -3));
interp.addPosition(glm::vec3(3,0,-6)); interp.add( 6.0f, glm::vec3(+3, +0, -6));
interp.addPosition(glm::vec3(5,5,5)); interp.add( 8.0f, glm::vec3(+5, +5, +5));
interp.addPosition(glm::vec3(5,5,-5)); interp.add(10.0f, glm::vec3(+5, +5, -5));
core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt, core.run([&](const vkcv::WindowHandle &windowHandle, double t, double dt,
uint32_t swapchainWidth, uint32_t swapchainHeight) { uint32_t swapchainWidth, uint32_t swapchainHeight) {
...@@ -139,7 +138,9 @@ int main(int argc, const char** argv) { ...@@ -139,7 +138,9 @@ int main(int argc, const char** argv) {
} }
cameraManager.update(dt); cameraManager.update(dt);
interp.updateCamera(); cameraManager.getCamera(camHandle0).setPosition(
interp(static_cast<float>(std::fmod<double>(t, 10.0)))
);
glm::mat4 mvp = cameraManager.getActiveCamera().getMVP(); glm::mat4 mvp = cameraManager.getActiveCamera().getMVP();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment