2023-07-21 16:42:29 +00:00
|
|
|
#include "PerspectiveEffect.h"
|
|
|
|
#include <numbers>
|
2023-09-09 10:22:14 +00:00
|
|
|
#include "../MathUtil.h"
|
2024-02-11 22:06:35 +00:00
|
|
|
#include "../obj/Camera.h"
|
2023-07-21 16:42:29 +00:00
|
|
|
|
2024-01-07 19:48:02 +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
|
|
|
|
2024-01-07 19:48:02 +00:00
|
|
|
PerspectiveEffect::~PerspectiveEffect() {}
|
2023-12-20 23:30:20 +00:00
|
|
|
|
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];
|
2024-01-17 01:26:07 +00:00
|
|
|
auto focalLength = juce::jmax(values[1], 0.001);
|
2024-02-11 22:06:35 +00:00
|
|
|
auto depth = values[2];
|
2024-01-07 19:48:02 +00:00
|
|
|
auto rotateSpeed = linearSpeedToActualSpeed(values[3]);
|
2023-07-22 14:07:11 +00:00
|
|
|
double baseRotateX, baseRotateY, baseRotateZ;
|
|
|
|
if (fixedRotateX->getBoolValue()) {
|
|
|
|
baseRotateX = 0;
|
2024-01-07 19:48:02 +00:00
|
|
|
currentRotateX = values[4] * std::numbers::pi;
|
2023-07-22 14:07:11 +00:00
|
|
|
} else {
|
2024-01-07 19:48:02 +00:00
|
|
|
baseRotateX = values[4] * std::numbers::pi;
|
2023-07-22 14:07:11 +00:00
|
|
|
}
|
|
|
|
if (fixedRotateY->getBoolValue()) {
|
|
|
|
baseRotateY = 0;
|
2024-01-07 19:48:02 +00:00
|
|
|
currentRotateY = values[5] * std::numbers::pi;
|
2023-07-22 14:07:11 +00:00
|
|
|
} else {
|
2024-01-07 19:48:02 +00:00
|
|
|
baseRotateY = values[5] * std::numbers::pi;
|
2023-07-22 14:07:11 +00:00
|
|
|
}
|
|
|
|
if (fixedRotateZ->getBoolValue()) {
|
|
|
|
baseRotateZ = 0;
|
2024-01-07 19:48:02 +00:00
|
|
|
currentRotateZ = values[6] * std::numbers::pi;
|
2023-07-22 14:07:11 +00:00
|
|
|
} else {
|
2024-01-07 19:48:02 +00:00
|
|
|
baseRotateZ = values[6] * std::numbers::pi;
|
2023-07-22 14:07:11 +00:00
|
|
|
}
|
2023-07-21 16:42:29 +00:00
|
|
|
|
2023-09-09 10:22:14 +00:00
|
|
|
currentRotateX = MathUtil::wrapAngle(currentRotateX + baseRotateX * rotateSpeed);
|
|
|
|
currentRotateY = MathUtil::wrapAngle(currentRotateY + baseRotateY * rotateSpeed);
|
|
|
|
currentRotateZ = MathUtil::wrapAngle(currentRotateZ + baseRotateZ * rotateSpeed);
|
2023-07-21 19:04:10 +00:00
|
|
|
|
2023-07-21 16:42:29 +00:00
|
|
|
auto x = input.x;
|
|
|
|
auto y = input.y;
|
2024-01-07 19:48:02 +00:00
|
|
|
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);
|
|
|
|
|
2024-02-11 22:06:35 +00:00
|
|
|
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
|
|
|
|
2024-02-11 22:06:35 +00:00
|
|
|
Vec3 projected = camera.project(vec);
|
2024-02-11 18:56:46 +00:00
|
|
|
|
2024-01-07 16:17:20 +00:00
|
|
|
return Point(
|
2024-02-11 22:06:35 +00:00
|
|
|
(1 - effectScale) * input.x + effectScale * projected.x,
|
|
|
|
(1 - effectScale) * input.y + effectScale * projected.y,
|
2024-01-07 19:48:02 +00:00
|
|
|
0
|
2023-07-21 16:42:29 +00:00
|
|
|
);
|
|
|
|
}
|
2023-07-22 21:00:59 +00:00
|
|
|
|
2024-01-07 19:48:02 +00:00
|
|
|
void PerspectiveEffect::resetRotation() {
|
|
|
|
currentRotateX = 0;
|
|
|
|
currentRotateY = 0;
|
|
|
|
currentRotateZ = 0;
|
2023-07-22 21:00:59 +00:00
|
|
|
}
|