kopia lustrzana https://github.com/jameshball/osci-render
Super basic 3D object line culling
rodzic
eece1b1dae
commit
a047888382
|
@ -65,16 +65,20 @@ void VisualiserComponent::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualiserComponent::mouseDown(const juce::MouseEvent& event) {
|
void VisualiserComponent::mouseDown(const juce::MouseEvent& event) {
|
||||||
active = !active;
|
if (event.mods.isLeftButtonDown()) {
|
||||||
if (active) {
|
active = !active;
|
||||||
startTimerHz(60);
|
if (active) {
|
||||||
startThread();
|
startTimerHz(60);
|
||||||
} else {
|
startThread();
|
||||||
audioProcessor.consumerStop(consumer);
|
} else {
|
||||||
stopTimer();
|
audioProcessor.consumerStop(consumer);
|
||||||
stopThread(1000);
|
stopTimer();
|
||||||
|
stopThread(1000);
|
||||||
|
}
|
||||||
|
repaint();
|
||||||
|
} else if (event.mods.isRightButtonDown()) {
|
||||||
|
// TODO: add menu to control colours and precision
|
||||||
}
|
}
|
||||||
repaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualiserComponent::paintChannel(juce::Graphics& g, juce::Rectangle<float> area, int channel) {
|
void VisualiserComponent::paintChannel(juce::Graphics& g, juce::Rectangle<float> area, int channel) {
|
||||||
|
|
|
@ -7,16 +7,15 @@ 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>> Camera::draw(WorldObject& object) {
|
||||||
std::vector<std::unique_ptr<Shape>> shapes;
|
std::vector<std::unique_ptr<Shape>> shapes;
|
||||||
object.nextFrame();
|
object.nextFrame();
|
||||||
Line3D* prevLine = nullptr;
|
for (auto edge : object.edges) {
|
||||||
Vector2 prevVertex;
|
edge.rotate(object.rotateX, object.rotateY, object.rotateZ);
|
||||||
for (auto& edge : object.edges) {
|
// very crude frustum culling
|
||||||
Vector2 start;
|
if (edge.z1 < z || edge.z2 < z) {
|
||||||
if (prevLine != nullptr && prevLine->x2 == edge.x1 && prevLine->y2 == edge.y1 && prevLine->z2 == edge.z1) {
|
continue;
|
||||||
start = prevVertex;
|
|
||||||
} else {
|
|
||||||
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);
|
|
||||||
|
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));
|
shapes.push_back(std::make_unique<Line>(start.x, start.y, end.x, end.y));
|
||||||
}
|
}
|
||||||
|
@ -49,10 +48,9 @@ std::vector<Vector2> Camera::sampleVerticesInRender(WorldObject& object) {
|
||||||
|
|
||||||
for (int i = 0; i < SAMPLE_RENDER_SAMPLES - 1; i++) {
|
for (int i = 0; i < SAMPLE_RENDER_SAMPLES - 1; i++) {
|
||||||
for (size_t j = 0; j < std::min(VERTEX_SAMPLES, object.numVertices); j++) {
|
for (size_t j = 0; j < std::min(VERTEX_SAMPLES, object.numVertices); j++) {
|
||||||
double x = object.vs[j * 3];
|
Vector3D vertex{object.vs[j * 3], object.vs[j * 3 + 1], object.vs[j * 3 + 2]};
|
||||||
double y = object.vs[j * 3 + 1];
|
vertex.rotate(object.rotateX, object.rotateY, object.rotateZ);
|
||||||
double z = object.vs[j * 3 + 2];
|
vertices.push_back(project(vertex.x, vertex.y, vertex.z));
|
||||||
vertices.push_back(project(object.rotateX, object.rotateY, object.rotateZ, x, y, z));
|
|
||||||
}
|
}
|
||||||
object.rotateY = object.rotateY + rotation;
|
object.rotateY = object.rotateY + rotation;
|
||||||
object.rotateZ = object.rotateY + rotation;
|
object.rotateZ = object.rotateY + rotation;
|
||||||
|
@ -72,27 +70,9 @@ double Camera::maxVertexValue(std::vector<Vector2>& vertices) {
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 Camera::project(double objRotateX, double objRotateY, double objRotateZ, double x, double y, double z) {
|
Vector2 Camera::project(double x, double y, double z) {
|
||||||
// rotate around x-axis
|
double start = x * focalLength / (z - this->z) + this->x;
|
||||||
double cosValue = std::cos(objRotateX);
|
double end = y * focalLength / (z - this->z) + this->y;
|
||||||
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;
|
|
||||||
|
|
||||||
return Vector2(start, end);
|
return Vector2(start, end);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,5 +24,5 @@ private:
|
||||||
|
|
||||||
std::vector<Vector2> sampleVerticesInRender(WorldObject& object);
|
std::vector<Vector2> sampleVerticesInRender(WorldObject& object);
|
||||||
double maxVertexValue(std::vector<Vector2>& vertices);
|
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);
|
||||||
};
|
};
|
|
@ -1,3 +1,38 @@
|
||||||
#include "Line3D.h"
|
#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;
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,17 @@
|
||||||
class Line3D {
|
class Line3D {
|
||||||
public:
|
public:
|
||||||
Line3D(double, double, double, double, double, double);
|
Line3D(double, double, double, double, double, double);
|
||||||
|
|
||||||
|
void rotate(double, double, double);
|
||||||
|
|
||||||
double x1, y1, z1, x2, y2, z2;
|
double x1, y1, z1, x2, y2, z2;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Vector3D {
|
||||||
|
public:
|
||||||
|
Vector3D(double, double, double);
|
||||||
|
|
||||||
|
void rotate(double, double, double);
|
||||||
|
|
||||||
|
double x, y, z;
|
||||||
};
|
};
|
Ładowanie…
Reference in New Issue