osci-render/Source/audio/PerspectiveEffect.h

43 wiersze
1.6 KiB
C++

#pragma once
#include <JuceHeader.h>
#include "../obj/Camera.h"
class PerspectiveEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<double>>& values, double sampleRate) override {
auto effectScale = values[0].load();
// Far plane clipping happens at about 1.2 deg for 100 far plane dist
double fovDegrees = juce::jlimit(1.5, 179.0, values[1].load());
double fov = juce::degreesToRadians(fovDegrees);
// Place camera such that field of view is tangent to unit sphere
Vec3 origin = Vec3(0, 0, -1.0f / std::sin(0.5f * (float)fov));
camera.setPosition(origin);
camera.setFov(fov);
Vec3 vec = Vec3(input.x, input.y, input.z);
Vec3 projected = camera.project(vec);
return osci::Point(
(1 - effectScale) * input.x + effectScale * projected.x,
(1 - effectScale) * input.y + effectScale * projected.y,
0
);
}
std::shared_ptr<osci::Effect> build() const override {
auto eff = std::make_shared<osci::Effect>(
std::make_shared<PerspectiveEffect>(),
std::vector<osci::EffectParameter*>{
new osci::EffectParameter("Perspective", "Controls the strength of the 3D perspective projection.", "perspectiveStrength", VERSION_HINT, 1.0, 0.0, 1.0),
new osci::EffectParameter("Field of View", "Controls the camera's field of view in degrees. A lower field of view makes the image look more flat, and a higher field of view makes the image look more 3D.", "perspectiveFov", VERSION_HINT, 50.0, 5.0, 130.0),
}
);
return eff;
}
private:
Camera camera;
};