pull/307/head
James H Ball 2025-08-16 20:03:08 +01:00
commit 8fa4034789
23 zmienionych plików z 156 dodań i 219 usunięć

Wyświetl plik

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16 16H8.9L11 13.9L7 10L9.8 7.2L13.9 11.1L16 8.9V16M5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21M5 5H19V19H5V5Z" /></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19.59,7L12,14.59L6.41,9H11V7H3V15H5V10.41L12,17.41L21,8.41" /></svg>

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 236 B

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 138 B

Wyświetl plik

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.41,19.31L16.59,22.5L18,21.07L14.83,17.9M15.54,11.53H15.53L12,15.07L8.47,11.53H8.46V11.53C7.56,10.63 7,9.38 7,8A5,5 0 0,1 12,3A5,5 0 0,1 17,8C17,9.38 16.44,10.63 15.54,11.53M16.9,13C18.2,11.73 19,9.96 19,8A7,7 0 0,0 12,1A7,7 0 0,0 5,8C5,9.96 5.81,11.73 7.1,13V13L10.59,16.5L6,21.07L7.41,22.5L16.9,13Z" /></svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 382 B

Wyświetl plik

@ -112,6 +112,9 @@ CommonPluginEditor::~CommonPluginEditor() {
}
bool CommonPluginEditor::keyPressed(const juce::KeyPress& key) {
// If we're not accepting special keys, end early
if (!audioProcessor.getAcceptsKeys()) return false;
if (key.getModifiers().isCommandDown() && key.getModifiers().isShiftDown() && key.getKeyCode() == 'S') {
saveProjectAs();
} else if (key.getModifiers().isCommandDown() && key.getKeyCode() == 'S') {

Wyświetl plik

@ -16,6 +16,7 @@ CommonAudioProcessor::CommonAudioProcessor(const BusesProperties& busesPropertie
: AudioProcessor(busesProperties)
#endif
{
if (!applicationFolder.exists()) {
applicationFolder.createDirectory();
}

Wyświetl plik

@ -153,6 +153,12 @@ public:
#else
"ffmpeg";
#endif
void setAcceptsKeys(bool shouldAcceptKeys) {
setGlobalValue("acceptsAllKeys", shouldAcceptKeys);
}
bool getAcceptsKeys() {
return getGlobalBoolValue("acceptsAllKeys", juce::JUCEApplicationBase::isStandaloneApp());
}
protected:

Wyświetl plik

@ -11,10 +11,13 @@
#include "PluginEditor.h"
#include "audio/BitCrushEffect.h"
#include "audio/BulgeEffect.h"
#include "audio/TwistEffect.h"
#include "audio/DistortEffect.h"
#include "audio/KaleidoscopeEffect.h"
#include "audio/MultiplexEffect.h"
#include "audio/SmoothEffect.h"
#include "audio/WobbleEffect.h"
#include "audio/DashedLineEffect.h"
#include "audio/VectorCancellingEffect.h"
#include "audio/ScaleEffect.h"
#include "audio/RotateEffect.h"
@ -34,41 +37,28 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() : CommonAudioProcessor(Buse
// locking isn't necessary here because we are in the constructor
toggleableEffects.push_back(BitCrushEffect().build());
toggleableEffects.push_back(BulgeEffect().build());
toggleableEffects.push_back(MultiplexEffect().build());
toggleableEffects.push_back(KaleidoscopeEffect().build());
toggleableEffects.push_back(BounceEffect().build());
toggleableEffects.push_back(VectorCancellingEffect().build());
{
auto scaleEffect = ScaleEffectApp().build();
booleanParameters.push_back(scaleEffect->linked);
toggleableEffects.push_back(scaleEffect);
}
{
auto distortEffect = DistortEffect().build();
booleanParameters.push_back(distortEffect->linked);
toggleableEffects.push_back(distortEffect);
}
toggleableEffects.push_back(RippleEffectApp().build());
toggleableEffects.push_back(RotateEffectApp().build());
toggleableEffects.push_back(TranslateEffectApp().build());
toggleableEffects.push_back(SwirlEffectApp().build());
toggleableEffects.push_back(SmoothEffect().build());
{
auto wobble = std::make_shared<osci::Effect>(
wobbleEffect,
std::vector<osci::EffectParameter*>{
new osci::EffectParameter("Wobble Amount", "Adds a sine wave of the prominent frequency in the audio currently playing. The sine wave's frequency is slightly offset to create a subtle 'wobble' in the image. Increasing the slider increases the strength of the wobble.", "wobble", VERSION_HINT, 0.3, 0.0, 1.0),
new osci::EffectParameter("Wobble Phase", "Controls the phase of the wobble.", "wobblePhase", VERSION_HINT, 0.0, -1.0, 1.0, 0.0001f, osci::LfoType::Sawtooth, 1.0f),
});
wobble->setName("Wobble");
wobble->setIcon(BinaryData::wobble_svg);
toggleableEffects.push_back(wobble);
}
toggleableEffects.push_back(WobbleEffect(*this).build());
toggleableEffects.push_back(DelayEffect().build());
toggleableEffects.push_back(DashedLineEffect().build());
toggleableEffects.push_back(DashedLineEffect(*this).build());
toggleableEffects.push_back(TwistEffect().build());
auto scaleEffect = ScaleEffectApp().build();
booleanParameters.push_back(scaleEffect->linked);
toggleableEffects.push_back(scaleEffect);
auto distortEffect = DistortEffect().build();
booleanParameters.push_back(distortEffect->linked);
toggleableEffects.push_back(distortEffect);
custom->setIcon(BinaryData::lua_svg);
toggleableEffects.push_back(custom);

Wyświetl plik

@ -16,14 +16,12 @@
#include "UGen/Env.h"
#include "UGen/ugen_JuceEnvelopeComponent.h"
#include "audio/CustomEffect.h"
#include "audio/DashedLineEffect.h"
#include "audio/DelayEffect.h"
#include "audio/PerspectiveEffect.h"
#include "audio/PublicSynthesiser.h"
#include "audio/SampleRateManager.h"
#include "audio/ShapeSound.h"
#include "audio/ShapeVoice.h"
#include "audio/WobbleEffect.h"
#include "obj/ObjectServer.h"
#if (JUCE_MAC || JUCE_WINDOWS) && OSCI_PREMIUM
@ -90,8 +88,6 @@ public:
std::shared_ptr<DelayEffect> delayEffect = std::make_shared<DelayEffect>();
std::shared_ptr<DashedLineEffect> dashedLineEffect = std::make_shared<DashedLineEffect>();
std::function<void(int, juce::String, juce::String)> errorCallback = [this](int lineNum, juce::String fileName, juce::String error) { notifyErrorListeners(lineNum, fileName, error); };
std::shared_ptr<CustomEffect> customEffect = std::make_shared<CustomEffect>(errorCallback, luaValues);
std::shared_ptr<osci::Effect> custom = std::make_shared<osci::Effect>(
@ -103,7 +99,7 @@ public:
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("Focal Length", "Controls the focal length of the 3D perspective effect. A higher focal length makes the image look more flat, and a lower focal length makes the image look more 3D.", "perspectiveFocalLength", VERSION_HINT, 2.0, 0.0, 10.0),
new osci::EffectParameter("FOV", "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),
});
osci::BooleanParameter* midiEnabled = new osci::BooleanParameter("MIDI Enabled", "midiEnabled", VERSION_HINT, false, "Enable MIDI input for the synth. If disabled, the synth will play a constant tone, as controlled by the frequency slider.");
@ -172,8 +168,6 @@ public:
std::atomic<double> animationFrame = 0.f;
std::shared_ptr<WobbleEffect> wobbleEffect = std::make_shared<WobbleEffect>(*this);
const double FONT_SIZE = 1.0f;
juce::Font font = juce::Font(juce::Font::getDefaultSansSerifFontName(), FONT_SIZE, juce::Font::plain);

Wyświetl plik

@ -1,118 +1,4 @@
#include <JuceHeader.h>
#include "obj/Camera.h"
#include "mathter/Common/Approx.hpp"
class FrustumTest : public juce::UnitTest {
public:
FrustumTest() : juce::UnitTest("Frustum Culling") {}
void runTest() override {
double focalLength = 1;
Camera camera;
camera.setFocalLength(focalLength);
Vec3 position = Vec3(0, 0, -focalLength);
camera.setPosition(position);
Frustum frustum = camera.getFrustum();
beginTest("Focal Plane Frustum In-Bounds");
// Focal plane is at z = 0
Vec3 vecs[] = {
Vec3(0, 0, 0), Vec3(0, 0, 0),
Vec3(1, 1, 0), Vec3(1, 1, 0),
Vec3(-1, -1, 0), Vec3(-1, -1, 0),
Vec3(1, -1, 0), Vec3(1, -1, 0),
Vec3(-1, 1, 0), Vec3(-1, 1, 0),
Vec3(0.5, 0.5, 0), Vec3(0.5, 0.5, 0),
};
testFrustumClippedEqualsExpected(vecs, camera, 6);
beginTest("Focal Plane Frustum Out-Of-Bounds");
// Focal plane is at z = 0
Vec3 vecs2[] = {
Vec3(1.1, 1.1, 0), Vec3(1, 1, 0),
Vec3(-1.1, -1.1, 0), Vec3(-1, -1, 0),
Vec3(1.1, -1.1, 0), Vec3(1, -1, 0),
Vec3(-1.1, 1.1, 0), Vec3(-1, 1, 0),
Vec3(1.1, 0.5, 0), Vec3(1, 0.5, 0),
Vec3(-1.1, 0.5, 0), Vec3(-1, 0.5, 0),
Vec3(0.5, -1.1, 0), Vec3(0.5, -1, 0),
Vec3(0.5, 1.1, 0), Vec3(0.5, 1, 0),
Vec3(10, 10, 0), Vec3(1, 1, 0),
Vec3(-10, -10, 0), Vec3(-1, -1, 0),
Vec3(10, -10, 0), Vec3(1, -1, 0),
Vec3(-10, 10, 0), Vec3(-1, 1, 0),
};
testFrustumClippedEqualsExpected(vecs2, camera, 12);
beginTest("Behind Camera Out-Of-Bounds");
double minZWorldCoords = -focalLength + camera.getFrustum().nearDistance;
Vec3 vecs3[] = {
Vec3(0, 0, -focalLength), Vec3(0, 0, minZWorldCoords),
Vec3(0, 0, -100), Vec3(0, 0, minZWorldCoords),
Vec3(0.5, 0.5, -focalLength), Vec3(0.1, 0.1, minZWorldCoords),
Vec3(10, -10, -focalLength), Vec3(0.1, -0.1, minZWorldCoords),
Vec3(-0.5, 0.5, -100), Vec3(-0.1, 0.1, minZWorldCoords),
Vec3(-10, 10, -100), Vec3(-0.1, 0.1, minZWorldCoords),
};
testFrustumClippedEqualsExpected(vecs3, camera, 6);
beginTest("3D Point Out-Of-Bounds");
Vec3 vecs4[] = {
Vec3(1, 1, -0.1),
Vec3(-1, -1, -0.1),
Vec3(1, -1, -0.1),
Vec3(-1, 1, -0.1),
Vec3(0.5, 0.5, minZWorldCoords),
};
testFrustumClipOccurs(vecs4, camera, 5);
}
Vec3 project(Vec3& p, double focalLength) {
return Vec3(
p.x * focalLength / p.z,
p.y * focalLength / p.z,
0
);
}
juce::String vec3ToString(Vec3& p) {
return "(" + juce::String(p.x) + ", " + juce::String(p.y) + ", " + juce::String(p.z) + ")";
}
juce::String errorMessage(Vec3& actual, Vec3& expected) {
return "Expected: " + vec3ToString(expected) + ", Actual: " + vec3ToString(actual);
}
void testFrustumClippedEqualsExpected(Vec3 vecs[], Camera& camera, int length) {
for (int i = 0; i < length; i++) {
Vec3 p = vecs[2 * i];
p = camera.toCameraSpace(p);
camera.getFrustum().clipToFrustum(p);
p = camera.toWorldSpace(p);
expect(mathter::AlmostEqual(p, vecs[2 * i + 1]), errorMessage(p, vecs[2 * i + 1]));
}
}
void testFrustumClipOccurs(Vec3 vecs[], Camera& camera, int length) {
for (int i = 0; i < length; i++) {
Vec3 p = vecs[i];
p = camera.toCameraSpace(p);
camera.getFrustum().clipToFrustum(p);
p = camera.toWorldSpace(p);
expect(!mathter::AlmostEqual(p, vecs[i]), errorMessage(p, vecs[i]));
}
}
};
class ProducerThread : public juce::Thread {
public:
@ -183,7 +69,6 @@ public:
}
};
static FrustumTest frustumTest;
static BufferConsumerTest bufferConsumerTest;
int main(int argc, char* argv[]) {

Wyświetl plik

@ -44,7 +44,7 @@ public:
std::vector<osci::EffectParameter*>{
new osci::EffectParameter("Bounce Size", "Size (scale) of the bouncing object.", "bounceSize", VERSION_HINT, 0.3, 0.05, 1.0),
new osci::EffectParameter("Bounce Speed", "Speed of motion.", "bounceSpeed", VERSION_HINT, 5.0, 0.0, 10.0),
new osci::EffectParameter("Bounce Angle", "Direction of travel (0..1 -> 0..360°).", "bounceAngle", VERSION_HINT, 0.16, 0.0, 1.0),
new osci::EffectParameter("Bounce Angle", juce::String(juce::CharPointer_UTF8("Direction of travel (0..1 -> 0..360°).")), "bounceAngle", VERSION_HINT, 0.16, 0.0, 1.0),
}
);
eff->setName("Bounce");

Wyświetl plik

@ -1,36 +1,54 @@
#pragma once
#include <JuceHeader.h>
#include "../PluginProcessor.h"
class DashedLineEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point vector, const std::vector<std::atomic<double>>& values, double sampleRate) override {
// dash length in seconds
double dashLength = values[0] / 400;
int dashLengthSamples = (int)(dashLength * sampleRate);
dashLengthSamples = juce::jmin(dashLengthSamples, MAX_BUFFER);
if (dashIndex >= dashLengthSamples) {
dashIndex = 0;
bufferIndex = 0;
DashedLineEffect(OscirenderAudioProcessor& p) : audioProcessor(p) {}
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<double>>& values, double sampleRate) override {
// if only 2 parameters are provided, this is being used as a 'trace effect'
// where the dash count is 1.
double dashCount = 1.0;
int i = 0;
if (values.size() > 2) {
dashCount = juce::jmax(1.0, values[i++].load()); // Dashes per cycle
}
buffer[bufferIndex] = vector;
double dashCoverage = juce::jlimit(0.0, 1.0, values[i++].load());
double dashOffset = values[i++];
double dashLengthSamples = (sampleRate / audioProcessor.frequency) / dashCount;
double dashPhase = framePhase * dashCount - dashOffset;
dashPhase = dashPhase - std::floor(dashPhase); // Wrap
buffer[bufferIndex] = input;
// Linear interpolation works much better than nearest for this
double samplePos = bufferIndex - dashLengthSamples * dashPhase * (1 - dashCoverage);
samplePos = samplePos - buffer.size() * std::floor(samplePos / buffer.size()); // Wrap to [0, size]
int lowIndex = (int)std::floor(samplePos) % buffer.size();
int highIndex = (lowIndex + 1) % buffer.size();
double mixFactor = samplePos - std::floor(samplePos); // Fractional part
osci::Point output = (1 - mixFactor) * buffer[lowIndex] + mixFactor * buffer[highIndex];
bufferIndex++;
vector = buffer[dashIndex];
if (index % 2 == 0) {
dashIndex++;
if (bufferIndex >= buffer.size()) {
bufferIndex = 0;
}
return vector;
framePhase += audioProcessor.frequency / sampleRate;
framePhase = framePhase - std::floor(framePhase);
return output;
}
std::shared_ptr<osci::Effect> build() const override {
auto eff = std::make_shared<osci::Effect>(
std::make_shared<DashedLineEffect>(),
std::make_shared<DashedLineEffect>(audioProcessor),
std::vector<osci::EffectParameter*>{
new osci::EffectParameter("Dash Length", "Controls the length of the dashed line.", "dashLength", VERSION_HINT, 0.3, 0.0, 1.0),
new osci::EffectParameter("Dash Count", "Controls the number of dashed lines in the drawing.", "dashCount", VERSION_HINT, 16.0, 1.0, 32.0),
new osci::EffectParameter("Dash Width", "Controls how much each dash unit is drawn.", "dashWidth", VERSION_HINT, 0.5, 0.0, 1.0),
new osci::EffectParameter("Dash Offset", "Offsets the location of the dashed lines.", "dashOffset", VERSION_HINT, 0.0, 0.0, 1.0, 0.0001f, osci::LfoType::Sawtooth, 1.0f),
}
);
eff->setName("Dash");
@ -39,8 +57,9 @@ public:
}
private:
OscirenderAudioProcessor &audioProcessor;
const static int MAX_BUFFER = 192000;
std::vector<osci::Point> buffer = std::vector<osci::Point>(MAX_BUFFER);
int dashIndex = 0;
int bufferIndex = 0;
double framePhase = 0.0; // [0, 1]
};

Wyświetl plik

@ -6,11 +6,14 @@ 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();
auto focalLength = juce::jmax(values[1].load(), 0.001);
// 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);
Vec3 origin = Vec3(0, 0, -focalLength);
// 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.setFocalLength(focalLength);
camera.setFov(fov);
Vec3 vec = Vec3(input.x, input.y, input.z);
Vec3 projected = camera.project(vec);
@ -34,6 +37,6 @@ public:
}
private:
Camera camera;
};

Wyświetl plik

@ -11,7 +11,7 @@ public:
weight *= 0.95;
double strength = 10;
weight = std::log(strength * weight + 1) / std::log(strength + 1);
// TODO: This doesn't consider the sample rate!
weight = std::pow(weight, 48000 / sampleRate);
avg = weight * avg + (1 - weight) * input;
return avg;
@ -29,5 +29,5 @@ public:
private:
osci::Point avg;
juce::String idPrefix;
float smoothingDefault = 0.75f;
float smoothingDefault = 0.5f;
};

Wyświetl plik

@ -0,0 +1,22 @@
#pragma once
#include <JuceHeader.h>
#include <numbers>
class TwistEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<double>> &values, double sampleRate) override {
double twistStrength = values[0] * 4 * std::numbers::pi;
double twistTheta = twistStrength * input.y;
input.rotate(0.0, twistTheta, 0.0);
return input;
}
std::shared_ptr<osci::Effect> build() const override {
auto eff = std::make_shared<osci::Effect>(
std::make_shared<TwistEffect>(),
new osci::EffectParameter("Twist", "Twists the image in a corkscrew pattern.", "twist", VERSION_HINT, 0.5, 0.0, 1.0, 0.0001, osci::LfoType::Sine, 0.5)
);
eff->setIcon(BinaryData::twist_svg);
return eff;
}
};

Wyświetl plik

@ -1,14 +0,0 @@
#include "WobbleEffect.h"
#include "../PluginProcessor.h"
WobbleEffect::WobbleEffect(OscirenderAudioProcessor& p) : audioProcessor(p) {}
WobbleEffect::~WobbleEffect() {}
osci::Point WobbleEffect::apply(int index, osci::Point input, const std::vector<std::atomic<double>>& values, double sampleRate) {
double wobblePhase = values[1] * std::numbers::pi;
double theta = nextPhase(audioProcessor.frequency, sampleRate) + wobblePhase;
double delta = 0.5 * values[0] * std::sin(theta);
return input + delta;
}

Wyświetl plik

@ -1,18 +1,29 @@
#pragma once
#include <JuceHeader.h>
#include "../PluginProcessor.h"
class OscirenderAudioProcessor;
class WobbleEffect : public osci::EffectApplication {
public:
WobbleEffect(OscirenderAudioProcessor& p);
~WobbleEffect();
WobbleEffect(OscirenderAudioProcessor &p) : audioProcessor(p) {}
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<double>>& values, double sampleRate) override;
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<double>>& values, double sampleRate) override {
double wobblePhase = values[1] * std::numbers::pi;
double theta = nextPhase(audioProcessor.frequency, sampleRate) + wobblePhase;
double delta = 0.5 * values[0] * std::sin(theta);
return input + delta;
}
std::shared_ptr<osci::Effect> build() const override {
// Cannot build without processor reference; caller should construct explicitly and wrap in osci::Effect with parameters.
jassertfalse;
return nullptr;
auto wobble = std::make_shared<osci::Effect>(
std::make_shared<WobbleEffect>(audioProcessor),
std::vector<osci::EffectParameter*>{
new osci::EffectParameter("Wobble Amount", "Adds a sine wave of the prominent frequency in the audio currently playing. The sine wave's frequency is slightly offset to create a subtle 'wobble' in the image. Increasing the slider increases the strength of the wobble.", "wobble", VERSION_HINT, 0.3, 0.0, 1.0),
new osci::EffectParameter("Wobble Phase", "Controls the phase of the wobble.", "wobblePhase", VERSION_HINT, 0.0, -1.0, 1.0, 0.0001f, osci::LfoType::Sawtooth, 1.0f),
});
wobble->setName("Wobble");
wobble->setIcon(BinaryData::wobble_svg);
return wobble;
}
private:

Wyświetl plik

@ -102,7 +102,13 @@ void OsciMainMenuBarModel::resetMenuItems() {
audioProcessor.clearPreviewEffect();
}
resetMenuItems(); // update tick state
}, [this] { return audioProcessor.getGlobalBoolValue("previewEffectOnHover", true); });
}, [this] { return audioProcessor.getGlobalBoolValue("previewEffectOnHover", true);
});
addToggleMenuItem(interfaceMenuIndex, "Listen for Special Keys", [this] {
audioProcessor.setAcceptsKeys(! audioProcessor.getAcceptsKeys());
resetMenuItems();
}, [this] { return audioProcessor.getAcceptsKeys(); });
}
#if (JUCE_MAC || JUCE_WINDOWS) && OSCI_PREMIUM

Wyświetl plik

@ -4,6 +4,10 @@
#include "../SosciPluginProcessor.h"
SosciMainMenuBarModel::SosciMainMenuBarModel(SosciPluginEditor& e, SosciAudioProcessor& p) : editor(e), processor(p) {
resetMenuItems();
}
void SosciMainMenuBarModel::resetMenuItems() {
addTopLevelMenu("File");
addTopLevelMenu("About");
addTopLevelMenu("Video");
@ -105,4 +109,11 @@ SosciMainMenuBarModel::SosciMainMenuBarModel(SosciPluginEditor& e, SosciAudioPro
if (editor.processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone) {
addMenuItem(3, "Settings...", [&]() { editor.openAudioSettings(); });
}
// Interface menu index depends on whether Audio menu exists
int interfaceMenuIndex = (editor.processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone) ? 4 : 3;
addToggleMenuItem(interfaceMenuIndex, "Listen for Special Keys", [this] {
processor.setAcceptsKeys(! processor.getAcceptsKeys());
resetMenuItems();
}, [this] { return processor.getAcceptsKeys(); });
}

Wyświetl plik

@ -1,6 +1,6 @@
#include "Camera.h"
Camera::Camera() : frustum(1, 1, 0.1, 100) {
Camera::Camera() : frustum(1, 1, 0.001, 100) {
viewMatrix = mathter::Identity();
}
@ -18,8 +18,8 @@ Vec3 Camera::toWorldSpace(Vec3& point) {
return mathter::Inverse(viewMatrix) * point;
}
void Camera::setFocalLength(double focalLength) {
frustum.setCameraInternals(focalLength, frustum.ratio, frustum.nearDistance, frustum.farDistance);
void Camera::setFov(double fov) {
frustum.setCameraInternals(fov, frustum.ratio, frustum.nearDistance, frustum.farDistance);
}
Vec3 Camera::project(Vec3& pWorld) {
@ -27,10 +27,10 @@ Vec3 Camera::project(Vec3& pWorld) {
frustum.clipToFrustum(p);
double start = p.x * frustum.focalLength / p.z;
double end = p.y * frustum.focalLength / p.z;
float x = p.x * frustum.focalLength / p.z;
float y = p.y * frustum.focalLength / p.z;
return Vec3(start, end, 0);
return Vec3(x, y, 0);
}
Frustum Camera::getFrustum() {

Wyświetl plik

@ -12,7 +12,7 @@ public:
void setPosition(Vec3& position);
Vec3 toCameraSpace(Vec3& point);
Vec3 toWorldSpace(Vec3& point);
void setFocalLength(double focalLength);
void setFov(double fov);
Vec3 project(Vec3& p);
Frustum getFrustum();
private:

Wyświetl plik

@ -2,16 +2,16 @@
#include "Frustum.h"
void Frustum::setCameraInternals(float focalLength, float ratio, float nearDistance, float farDistance) {
void Frustum::setCameraInternals(float fov, float ratio, float nearDistance, float farDistance) {
// store the information
this->focalLength = focalLength;
this->fov = fov;
this->ratio = ratio;
this->nearDistance = nearDistance;
this->farDistance = farDistance;
// compute width and height of the near section
float fov = 2 * std::atan(1 / focalLength);
tang = (float) std::tan(fov * 0.5);
tang = std::tan(fov * 0.5f);
focalLength = 1.0f / tang;
height = nearDistance * tang;
width = height * ratio;
}

Wyświetl plik

@ -9,16 +9,13 @@ using Vec3 = mathter::Vector<float, 3, false>;
class Frustum {
public:
float ratio, nearDistance, farDistance, width, height, tang, focalLength;
float ratio, nearDistance, farDistance, width, height, tang, fov, focalLength;
Frustum(float focalLength, float ratio, float nearDistance, float farDistance) {
setCameraInternals(focalLength, ratio, nearDistance, farDistance);
Frustum(float fov, float ratio, float nearDistance, float farDistance) {
setCameraInternals(fov, ratio, nearDistance, farDistance);
}
~Frustum() {};
void setCameraInternals(float focalLength, float ratio, float nearD, float farD);
void setCameraInternals(float fov, float ratio, float nearD, float farD);
void clipToFrustum(Vec3 &p);
float getFocalLength() {
return focalLength;
}
};

Wyświetl plik

@ -254,6 +254,9 @@ void VisualiserComponent::mouseDown(const juce::MouseEvent &event) {
}
bool VisualiserComponent::keyPressed(const juce::KeyPress &key) {
// If we're not accepting special keys, end early
if (!audioProcessor.getAcceptsKeys()) return false;
if (key.isKeyCode(juce::KeyPress::escapeKey)) {
if (fullScreenCallback) {
fullScreenCallback(FullScreenMode::MAIN_COMPONENT);

Wyświetl plik

@ -88,6 +88,7 @@
<FILE id="rFYmV8" name="timer.svg" compile="0" resource="1" file="Resources/svg/timer.svg"/>
<FILE id="ESR7bv" name="trace.svg" compile="0" resource="1" file="Resources/svg/trace.svg"/>
<FILE id="ID1vTS" name="translate.svg" compile="0" resource="1" file="Resources/svg/translate.svg"/>
<FILE id="Sw4WWb" name="twist.svg" compile="0" resource="1" file="Resources/svg/twist.svg"/>
<FILE id="praXUY" name="vector-cancelling.svg" compile="0" resource="1"
file="Resources/svg/vector-cancelling.svg"/>
<FILE id="qC6QiP" name="volume.svg" compile="0" resource="1" file="Resources/svg/volume.svg"/>
@ -134,10 +135,9 @@
<FILE id="yiIupB" name="SwirlEffect.h" compile="0" resource="0" file="Source/audio/SwirlEffect.h"/>
<FILE id="qZkeZC" name="TranslateEffect.h" compile="0" resource="0"
file="Source/audio/TranslateEffect.h"/>
<FILE id="RsHWPN" name="TwistEffect.h" compile="0" resource="0" file="Source/audio/TwistEffect.h"/>
<FILE id="Be21D0" name="VectorCancellingEffect.h" compile="0" resource="0"
file="Source/audio/VectorCancellingEffect.h"/>
<FILE id="VHRytO" name="WobbleEffect.cpp" compile="1" resource="0"
file="Source/audio/WobbleEffect.cpp"/>
<FILE id="sgdTlo" name="WobbleEffect.h" compile="0" resource="0" file="Source/audio/WobbleEffect.h"/>
</GROUP>
<GROUP id="{2A41BAF3-5E83-B018-5668-39D89ABFA00C}" name="chinese_postman">
@ -814,14 +814,13 @@
microphonePermissionNeeded="1" frameworkSearchPaths="/Library/Frameworks"
extraCustomFrameworks="/Library/Frameworks/Syphon.framework"
hardenedRuntime="1" hardenedRuntimeOptions="com.apple.security.cs.disable-library-validation,com.apple.security.device.audio-input"
iosDevelopmentTeamID="D86A3M3H2L">
userNotes="D86A3M3H2L">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug" targetName="osci-render" customXcodeFlags="LD_RUNPATH_SEARCH_PATHS = '/Library/Frameworks',OTHER_CODE_SIGN_FLAGS = --timestamp --force --deep"
codeSigningIdentity="Developer ID Application: James Ball (D86A3M3H2L)"/>
<CONFIGURATION name="Release" targetName="osci-render" customXcodeFlags="LD_RUNPATH_SEARCH_PATHS = '/Library/Frameworks',CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO,OTHER_CODE_SIGN_FLAGS = --timestamp --force --deep"
codeSigningIdentity="Developer ID Application: James Ball (D86A3M3H2L)"/>
<CONFIGURATION name="Release (Development)" targetName="osci-render" customXcodeFlags="LD_RUNPATH_SEARCH_PATHS = '/Library/Frameworks',OTHER_CODE_SIGN_FLAGS = --timestamp --force --deep"
codeSigningIdentity="Developer ID Application: James Ball (D86A3M3H2L)"/>
<CONFIGURATION name="Release (Development)" targetName="osci-render" customXcodeFlags="LD_RUNPATH_SEARCH_PATHS = '/Library/Frameworks',OTHER_CODE_SIGN_FLAGS = --timestamp --force --deep"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path="../../../JUCE/modules"/>