Merge pull request #65 from jameshball/bug-fixes

Various bug fixes
pull/170/head
James H Ball 2023-09-10 12:45:27 +01:00 zatwierdzone przez GitHub
commit 068459812f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
7 zmienionych plików z 116 dodań i 37 usunięć

Wyświetl plik

@ -32,10 +32,23 @@ void VisualiserComponent::paint(juce::Graphics& g) {
auto r = getLocalBounds().toFloat();
auto minDim = juce::jmin(r.getWidth(), r.getHeight());
juce::CriticalSection::ScopedLockType scope(lock);
if (buffer.size() > 0) {
g.setColour(waveformColour);
paintXY(g, r.withSizeKeepingCentre(minDim, minDim));
{
juce::CriticalSection::ScopedLockType scope(lock);
if (buffer.size() > 0) {
g.setColour(waveformColour);
paintXY(g, r.withSizeKeepingCentre(minDim, minDim));
}
}
if (!active) {
// add translucent layer
g.setColour(juce::Colours::black.withAlpha(0.5f));
g.fillRect(getLocalBounds());
// add text
g.setColour(juce::Colours::white);
g.setFont(14.0f);
g.drawFittedText("Paused", getLocalBounds(), juce::Justification::centred, 1);
}
}
@ -51,6 +64,23 @@ void VisualiserComponent::run() {
}
}
void VisualiserComponent::mouseDown(const juce::MouseEvent& event) {
if (event.mods.isLeftButtonDown()) {
active = !active;
if (active) {
startTimerHz(60);
startThread();
} else {
audioProcessor.consumerStop(consumer);
stopTimer();
stopThread(1000);
}
repaint();
} else if (event.mods.isRightButtonDown()) {
// TODO: add menu to control colours and precision
}
}
void VisualiserComponent::paintChannel(juce::Graphics& g, juce::Rectangle<float> area, int channel) {
juce::Path path;

Wyświetl plik

@ -4,7 +4,7 @@
#include "../concurrency/BufferConsumer.h"
#include "../PluginProcessor.h"
class VisualiserComponent : public juce::Component, public juce::Timer, public juce::Thread {
class VisualiserComponent : public juce::Component, public juce::Timer, public juce::Thread, public juce::MouseListener {
public:
VisualiserComponent(int numChannels, OscirenderAudioProcessor& p);
~VisualiserComponent() override;
@ -16,6 +16,7 @@ public:
void paint(juce::Graphics&) override;
void timerCallback() override;
void run() override;
void mouseDown(const juce::MouseEvent& event) override;
private:
juce::CriticalSection lock;
@ -25,6 +26,8 @@ private:
OscirenderAudioProcessor& audioProcessor;
std::vector<float> tempBuffer = std::vector<float>(2 * 4096);
int precision = 4;
std::atomic<bool> active = true;
std::shared_ptr<BufferConsumer> consumer;

Wyświetl plik

@ -35,7 +35,7 @@ public:
{
std::unique_lock<std::mutex> lk(mutex);
not_full.wait(lk, [this]() { return size < content.size() || killed; });
content[head] = std::move(item);
content[(head + size) % content.size()] = std::move(item);
size++;
}
not_empty.notify_one();
@ -47,7 +47,7 @@ public:
if (size == content.size()) {
return false;
}
content[head] = std::move(item);
content[(head + size) % content.size()] = std::move(item);
size++;
}
not_empty.notify_one();

Wyświetl plik

@ -7,9 +7,28 @@ Camera::Camera(double focalLength, double x, double y, double z) : focalLength(f
std::vector<std::unique_ptr<Shape>> Camera::draw(WorldObject& object) {
std::vector<std::unique_ptr<Shape>> shapes;
object.nextFrame();
for (auto& edge : object.edges) {
Vector2 start = project(object.rotateX, object.rotateY, object.rotateZ, edge.x1, edge.y1, edge.z1);
Vector2 end = project(object.rotateX, object.rotateY, object.rotateZ, edge.x2, edge.y2, edge.z2);
for (auto edge : object.edges) {
edge.rotate(object.rotateX, object.rotateY, object.rotateZ);
// very crude frustum culling
double minZ = z + 0.1;
if (edge.z1 < minZ && edge.z2 < minZ) {
continue;
}
if (edge.z1 < minZ) {
double ratio = (minZ - edge.z1) / (edge.z2 - edge.z1);
edge.x1 = edge.x1 + (edge.x2 - edge.x1) * ratio;
edge.y1 = edge.y1 + (edge.y2 - edge.y1) * ratio;
edge.z1 = minZ;
}
if (edge.z2 < minZ) {
double ratio = (minZ - edge.z2) / (edge.z1 - edge.z2);
edge.x2 = edge.x2 + (edge.x1 - edge.x2) * ratio;
edge.y2 = edge.y2 + (edge.y1 - edge.y2) * ratio;
edge.z2 = minZ;
}
Vector2 start = project(edge.x1, edge.y1, edge.z1);
Vector2 end = project(edge.x2, edge.y2, edge.z2);
shapes.push_back(std::make_unique<Line>(start.x, start.y, end.x, end.y));
}
@ -42,10 +61,9 @@ std::vector<Vector2> Camera::sampleVerticesInRender(WorldObject& object) {
for (int i = 0; i < SAMPLE_RENDER_SAMPLES - 1; i++) {
for (size_t j = 0; j < std::min(VERTEX_SAMPLES, object.numVertices); j++) {
double x = object.vs[j * 3];
double y = object.vs[j * 3 + 1];
double z = object.vs[j * 3 + 2];
vertices.push_back(project(object.rotateX, object.rotateY, object.rotateZ, x, y, z));
Vector3D vertex{object.vs[j * 3], object.vs[j * 3 + 1], object.vs[j * 3 + 2]};
vertex.rotate(object.rotateX, object.rotateY, object.rotateZ);
vertices.push_back(project(vertex.x, vertex.y, vertex.z));
}
object.rotateY = object.rotateY + rotation;
object.rotateZ = object.rotateY + rotation;
@ -65,27 +83,9 @@ double Camera::maxVertexValue(std::vector<Vector2>& vertices) {
return max;
}
Vector2 Camera::project(double objRotateX, double objRotateY, double objRotateZ, double x, double y, double z) {
// rotate around x-axis
double cosValue = std::cos(objRotateX);
double sinValue = std::sin(objRotateX);
double y2 = cosValue * y - sinValue * z;
double z2 = sinValue * y + cosValue * z;
// rotate around y-axis
cosValue = std::cos(objRotateY);
sinValue = std::sin(objRotateY);
double x2 = cosValue * x + sinValue * z2;
double z3 = -sinValue * x + cosValue * z2;
// rotate around z-axis
cosValue = cos(objRotateZ);
sinValue = sin(objRotateZ);
double x3 = cosValue * x2 - sinValue * y2;
double y3 = sinValue * x2 + cosValue * y2;
double start = x3 * focalLength / (z3 - this->z) + this->x;
double end = y3 * focalLength / (z3 - this->z) + this->y;
Vector2 Camera::project(double x, double y, double z) {
double start = x * focalLength / (z - this->z) + this->x;
double end = y * focalLength / (z - this->z) + this->y;
return Vector2(start, end);
}

Wyświetl plik

@ -24,5 +24,5 @@ private:
std::vector<Vector2> sampleVerticesInRender(WorldObject& object);
double maxVertexValue(std::vector<Vector2>& vertices);
Vector2 project(double objRotateX, double objRotateY, double objRotateZ, double x, double y, double z);
Vector2 project(double x, double y, double z);
};

Wyświetl plik

@ -1,3 +1,38 @@
#include "Line3D.h"
Line3D::Line3D(double x1, double y1, double z1, double x2, double y2, double z2) : x1(x1), y1(y1), z1(z1), x2(x2), y2(y2), z2(z2) {}
Line3D::Line3D(double x1, double y1, double z1, double x2, double y2, double z2) : x1(x1), y1(y1), z1(z1), x2(x2), y2(y2), z2(z2) {}
void Line3D::rotate(double rotateX, double rotateY, double rotateZ) {
Vector3D vector1(x1, y1, z1);
Vector3D vector2(x2, y2, z2);
vector1.rotate(rotateX, rotateY, rotateZ);
vector2.rotate(rotateX, rotateY, rotateZ);
x1 = vector1.x;
y1 = vector1.y;
z1 = vector1.z;
x2 = vector2.x;
y2 = vector2.y;
z2 = vector2.z;
}
Vector3D::Vector3D(double x, double y, double z) : x(x), y(y), z(z) {}
void Vector3D::rotate(double rotateX, double rotateY, double rotateZ) {
// 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;
z = -sinValue * x + cosValue * z2;
// rotate around z-axis
cosValue = cos(rotateZ);
sinValue = sin(rotateZ);
x = cosValue * x2 - sinValue * y2;
y = sinValue * x2 + cosValue * y2;
}

Wyświetl plik

@ -5,6 +5,17 @@
class Line3D {
public:
Line3D(double, double, double, double, double, double);
void rotate(double, double, double);
double x1, y1, z1, x2, y2, z2;
};
class Vector3D {
public:
Vector3D(double, double, double);
void rotate(double, double, double);
double x, y, z;
};