osci-render/Source/audio/PerspectiveEffect.cpp

90 wiersze
2.8 KiB
C++
Czysty Zwykły widok Historia

2023-07-21 16:42:29 +00:00
#include "PerspectiveEffect.h"
#include <numbers>
#include "../MathUtil.h"
#include "../obj/Camera.h"
2023-07-21 16:42:29 +00:00
PerspectiveEffect::PerspectiveEffect(int versionHint) {
2023-09-01 18:52:36 +00:00
fixedRotateX = new BooleanParameter("Perspective Fixed Rotate X", "perspectiveFixedRotateX", versionHint, false);
fixedRotateY = new BooleanParameter("Perspective Fixed Rotate Y", "perspectiveFixedRotateY", versionHint, false);
fixedRotateZ = new BooleanParameter("Perspective Fixed Rotate Z", "perspectiveFixedRotateZ", versionHint, false);
}
2023-07-21 16:42:29 +00:00
PerspectiveEffect::~PerspectiveEffect() {}
2024-01-07 16:17:20 +00:00
Point PerspectiveEffect::apply(int index, Point input, const std::vector<double>& values, double sampleRate) {
2023-07-21 16:42:29 +00:00
auto effectScale = values[0];
auto focalLength = juce::jmax(values[1], 0.001);
auto depth = values[2];
auto rotateSpeed = linearSpeedToActualSpeed(values[3]);
double baseRotateX, baseRotateY, baseRotateZ;
if (fixedRotateX->getBoolValue()) {
baseRotateX = 0;
currentRotateX = values[4] * std::numbers::pi;
} else {
baseRotateX = values[4] * std::numbers::pi;
}
if (fixedRotateY->getBoolValue()) {
baseRotateY = 0;
currentRotateY = values[5] * std::numbers::pi;
} else {
baseRotateY = values[5] * std::numbers::pi;
}
if (fixedRotateZ->getBoolValue()) {
baseRotateZ = 0;
currentRotateZ = values[6] * std::numbers::pi;
} else {
baseRotateZ = values[6] * std::numbers::pi;
}
2023-07-21 16:42:29 +00:00
currentRotateX = MathUtil::wrapAngle(currentRotateX + baseRotateX * rotateSpeed);
currentRotateY = MathUtil::wrapAngle(currentRotateY + baseRotateY * rotateSpeed);
currentRotateZ = MathUtil::wrapAngle(currentRotateZ + baseRotateZ * rotateSpeed);
2023-07-21 16:42:29 +00:00
auto x = input.x;
auto y = input.y;
auto z = input.z;
2023-07-21 16:42:29 +00:00
auto rotateX = baseRotateX + currentRotateX;
auto rotateY = baseRotateY + currentRotateY;
auto rotateZ = baseRotateZ + currentRotateZ;
// rotate around x-axis
double cosValue = std::cos(rotateX);
double sinValue = std::sin(rotateX);
double y2 = cosValue * y - sinValue * z;
double z2 = sinValue * y + cosValue * z;
// rotate around y-axis
cosValue = std::cos(rotateY);
sinValue = std::sin(rotateY);
double x2 = cosValue * x + sinValue * z2;
double z3 = -sinValue * x + cosValue * z2;
// rotate around z-axis
cosValue = cos(rotateZ);
sinValue = sin(rotateZ);
double x3 = cosValue * x2 - sinValue * y2;
double y3 = sinValue * x2 + cosValue * y2;
2024-01-21 22:22:03 +00:00
Point p = Point(x3, y3, z3);
Vec3 origin = Vec3(0, 0, -focalLength - depth);
camera.setPosition(origin);
camera.setFocalLength(focalLength);
Vec3 vec = Vec3(p.x, p.y, p.z);
2024-01-21 22:22:03 +00:00
Vec3 projected = camera.project(vec);
2024-01-07 16:17:20 +00:00
return Point(
(1 - effectScale) * input.x + effectScale * projected.x,
(1 - effectScale) * input.y + effectScale * projected.y,
0
2023-07-21 16:42:29 +00:00
);
}
void PerspectiveEffect::resetRotation() {
currentRotateX = 0;
currentRotateY = 0;
currentRotateZ = 0;
}