Get Frustum Culling half-working

pull/218/head
James Ball 2024-01-21 22:22:03 +00:00
rodzic 379109be0d
commit e83f3f769e
7 zmienionych plików z 120 dodań i 3 usunięć

Wyświetl plik

@ -65,9 +65,14 @@ Point PerspectiveEffect::apply(int index, Point input, const std::vector<double>
double x3 = cosValue * x2 - sinValue * y2;
double y3 = sinValue * x2 + cosValue * y2;
Point p = Point(x3, y3, z3);
Frustum frustum = Frustum(focalLength, 1.0, 0.1, 1000);
frustum.clipToFrustum(p);
return Point(
(1 - effectScale) * input.x + effectScale * (x3 * focalLength / (z3 - depth)),
(1 - effectScale) * input.y + effectScale * (y3 * focalLength / (z3 - depth)),
(1 - effectScale) * input.x + effectScale * (p.x * focalLength / p.z),
(1 - effectScale) * input.y + effectScale * (p.y * focalLength / p.z),
0
);
}

Wyświetl plik

@ -3,6 +3,7 @@
#include "../shape/Point.h"
#include "../audio/Effect.h"
#include "../lua/LuaParser.h"
#include "../obj/Frustum.h"
class PerspectiveEffect : public EffectApplication {
public:

Wyświetl plik

@ -0,0 +1,46 @@
// FROM https://cgvr.cs.uni-bremen.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/index.html
#include "Frustum.h"
void Frustum::setCameraInternals(float focalLength, float ratio, float nearDistance, float farDistance) {
// store the information
this->ratio = ratio;
this->nearDistance = nearDistance;
this->farDistance = farDistance;
// compute width and height of the near section
float fov = 2 * std::atan(1 / (focalLength * 2));
origin = Point(0, 0, -focalLength);
tang = (float) std::tan(fov * 0.5);
height = nearDistance * tang;
width = height * ratio;
}
void Frustum::clipToFrustum(Point &p) {
float pcz, pcx, pcy, aux;
// compute vector from camera position to p
Point v = p - origin;
// compute and test the Z coordinate
Point negZ = -Z;
pcz = v.innerProduct(Z);
pcz = juce::jlimit(nearDistance, farDistance, pcz);
// compute and test the Y coordinate
pcy = v.innerProduct(Y);
aux = pcz * tang;
pcy = juce::jlimit(-aux, aux, pcy);
// compute and test the X coordinate
pcx = v.innerProduct(X);
aux = aux * ratio;
pcx = juce::jlimit(-aux, aux, pcx);
// calculate the clipped point using the referential coordinates
Point x = X * pcx;
Point y = Y * pcy;
Point z = Z * pcz;
p = x + y + z;
}

Wyświetl plik

@ -0,0 +1,25 @@
// FROM https://cgvr.cs.uni-bremen.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/index.html
#pragma once
#include <JuceHeader.h>
#include "../shape/Point.h"
class Frustum {
public:
float ratio, nearDistance, farDistance, width, height, tang;
Point origin = Point(0, 0, 0);
Point X = Point(1, 0, 0);
Point Y = Point(0, 1, 0);
Point Z = Point(0, 0, 1);
Frustum(float fov, float ratio, float nearDistance, float farDistance) {
setCameraInternals(fov, ratio, nearDistance, farDistance);
}
~Frustum() {};
void setCameraInternals(float fov, float ratio, float nearD, float farD);
void clipToFrustum(Point &p);
};

Wyświetl plik

@ -32,6 +32,17 @@ void Point::rotate(double rotateX, double rotateY, double rotateZ) {
y = sinValue * x2 + cosValue * y2;
}
void Point::normalize() {
double mag = magnitude();
x /= mag;
y /= mag;
z /= mag;
}
double Point::innerProduct(Point& other) {
return x * other.x + y * other.y + z * other.z;
}
void Point::scale(double x, double y, double z) {
this->x *= x;
this->y *= y;
@ -49,7 +60,7 @@ double Point::length() {
}
double Point::magnitude() {
return sqrt(x * x * x + y * y * y + z * z * z);
return sqrt(x * x + y * y + z * z);
}
std::unique_ptr<Shape> Point::clone() {
@ -66,3 +77,23 @@ Point& Point::operator=(const Point& other) {
z = other.z;
return *this;
}
Point Point::operator+(const Point& other) {
return Point(x + other.x, y + other.y, z + other.z);
}
Point Point::operator-(const Point& other) {
return Point(x - other.x, y - other.y, z - other.z);
}
Point Point::operator-() {
return Point(-x, -y, -z);
}
Point Point::operator*(const Point& other) {
return Point(x * other.x, y * other.y, z * other.z);
}
Point Point::operator*(double scalar) {
return Point(x * scalar, y * scalar, z * scalar);
}

Wyświetl plik

@ -20,9 +20,16 @@ public:
std::string type() override;
void rotate(double rotateX, double rotateY, double rotateZ);
void normalize();
double innerProduct(Point& other);
// copy assignment operator
Point& operator=(const Point& other);
Point operator+(const Point& other);
Point operator-(const Point& other);
Point operator-();
Point operator*(const Point& other);
Point operator*(double scalar);
double x, y, z;

Wyświetl plik

@ -393,6 +393,8 @@
file="Source/MidiComponent.cpp"/>
<FILE id="GJqoJa" name="MidiComponent.h" compile="0" resource="0" file="Source/MidiComponent.h"/>
<GROUP id="{E6ED85A9-3843-825F-EF48-BCF81E38F8AD}" name="obj">
<FILE id="T6iC8q" name="Frustum.cpp" compile="1" resource="0" file="Source/obj/Frustum.cpp"/>
<FILE id="ky5ZfA" name="Frustum.h" compile="0" resource="0" file="Source/obj/Frustum.h"/>
<FILE id="Yfpzzn" name="ObjectServer.cpp" compile="1" resource="0"
file="Source/obj/ObjectServer.cpp"/>
<FILE id="CqYgqM" name="ObjectServer.h" compile="0" resource="0" file="Source/obj/ObjectServer.h"/>