work on raytracing
This commit is contained in:
26
geo/Plane3.h
Normal file
26
geo/Plane3.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef PLANE3_H
|
||||
#define PLANE3_H
|
||||
|
||||
#include "Point3.h"
|
||||
|
||||
class Plane3 {
|
||||
|
||||
private:
|
||||
|
||||
Point3 p1;
|
||||
Point3 p2;
|
||||
Point3 p3;
|
||||
Point3 p4;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
Plane3(Point3 p1, Point3 p2, Point3 p3, Point3 p4) : p1(p1), p2(p2), p3(p3), p4(p4) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // PLANE3_H
|
||||
@@ -116,8 +116,8 @@ private:
|
||||
|
||||
};
|
||||
|
||||
inline bool dot(const Point3& p1, const Point3& p2) {
|
||||
return p1.x*p2.x + p1.y*p2.y + p1.z*p2.z;
|
||||
inline float dot(const Point3& p1, const Point3& p2) {
|
||||
return (p1.x*p2.x) + (p1.y*p2.y) + (p1.z*p2.z);
|
||||
}
|
||||
|
||||
inline Point3 cross(const Point3& a, const Point3& b) {
|
||||
|
||||
28
geo/Ray3.h
Normal file
28
geo/Ray3.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef RAY3_H
|
||||
#define RAY3_H
|
||||
|
||||
#include "Point3.h"
|
||||
|
||||
struct Ray3 {
|
||||
|
||||
/** starting point */
|
||||
Point3 start;
|
||||
|
||||
/** ray's direction */
|
||||
Point3 dir;
|
||||
|
||||
public:
|
||||
|
||||
/** empty */
|
||||
Ray3() : start(), dir() {
|
||||
;
|
||||
}
|
||||
|
||||
/** ctor */
|
||||
Ray3(Point3 start, Point3 dir) : start(start), dir(dir) {
|
||||
;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // RAY3_H
|
||||
128
geo/Sphere3.h
Normal file
128
geo/Sphere3.h
Normal file
@@ -0,0 +1,128 @@
|
||||
#ifndef SPHERE3_H
|
||||
#define SPHERE3_H
|
||||
|
||||
#include "Point3.h"
|
||||
#include "Ray3.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
struct Sphere3 {
|
||||
|
||||
Point3 center;
|
||||
|
||||
float radius;
|
||||
|
||||
/** empty ctor */
|
||||
Sphere3() : center(), radius(0) {;}
|
||||
|
||||
/** ctor */
|
||||
Sphere3(const Point3 center, const float radius) : center(center), radius(radius) {;}
|
||||
|
||||
/** create a sphere that fully contains the given point-set */
|
||||
static Sphere3 around(const std::vector<Point3>& lst) {
|
||||
|
||||
// NOT OPTIMAL but fast
|
||||
Point3 sum(0,0,0);
|
||||
for (const Point3 p : lst) {sum += p;}
|
||||
const Point3 center = sum / lst.size();
|
||||
float radius = 0;
|
||||
for (const Point3 p : lst) {
|
||||
const float dist = center.getDistance(p);
|
||||
if (dist > radius) {radius = dist;}
|
||||
}
|
||||
return Sphere3(center, radius);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static Sphere3 join(const Sphere3& a, const Sphere3& b) {
|
||||
|
||||
if (a.contains(b)) {return a;}
|
||||
if (b.contains(a)) {return b;}
|
||||
|
||||
Point3 newCen = (a.center + b.center) / 2;
|
||||
float newRad = (a.center.getDistance(b.center) + std::max(a.radius, b.radius) * 2) / 2;
|
||||
return Sphere3(newCen, newRad);
|
||||
}
|
||||
|
||||
/** does this sphere contain the given sphere? */
|
||||
bool contains(const Sphere3& o) const {
|
||||
return (o.center.getDistance(this->center) + o.radius) < this->radius;
|
||||
}
|
||||
|
||||
/** does the sphere contain the given point? */
|
||||
bool contains(const Point3& p) const {
|
||||
return center.getDistance(p) <= radius;
|
||||
}
|
||||
|
||||
bool intersects(const Ray3& ray) const {
|
||||
|
||||
if (contains(ray.start)) {return true;}
|
||||
|
||||
/*
|
||||
// https://stackoverflow.com/questions/6533856/ray-sphere-intersection
|
||||
|
||||
const float xA = ray.start.x;
|
||||
const float yA = ray.start.y;
|
||||
const float zA = ray.start.z;
|
||||
|
||||
const float xB = (ray.start + ray.dir).x;
|
||||
const float yB = (ray.start + ray.dir).y;
|
||||
const float zB = (ray.start + ray.dir).z;
|
||||
|
||||
const float xC = center.x;
|
||||
const float yC = center.y;
|
||||
const float zC = center.z;
|
||||
|
||||
const float a = (xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)+(zB-zA)*(zB-zA);
|
||||
const float b = 2*((xB-xA)*(xA-xC)+(yB-yA)*(yA-yC)+(zB-zA)*(zA-zC));
|
||||
const float c = (xA-xC)*(xA-xC)+(yA-yC)*(yA-yC)+(zA-zC)*(zA-zC)-(radius*radius);
|
||||
|
||||
const float delta = (b*b) - (4*a*c);
|
||||
|
||||
// intersection?
|
||||
return delta >= 0;
|
||||
*/
|
||||
|
||||
|
||||
// http://www.ccs.neu.edu/home/fell/CSU540/programs/RayTracingFormulas.htm
|
||||
|
||||
const double x0 = ray.start.x;
|
||||
const double y0 = ray.start.y;
|
||||
const double z0 = ray.start.z;
|
||||
|
||||
const double cx = center.x;
|
||||
const double cy = center.y;
|
||||
const double cz = center.z;
|
||||
|
||||
const double dx = ray.dir.x;
|
||||
const double dy = ray.dir.y;
|
||||
const double dz = ray.dir.z;
|
||||
|
||||
const double a = dx*dx + dy*dy + dz*dz;
|
||||
const double b = 2*dx*(x0-cx) + 2*dy*(y0-cy) + 2*dz*(z0-cz);
|
||||
const double c = cx*cx + cy*cy + cz*cz + x0*x0 + y0*y0 + z0*z0 + -2*(cx*x0 + cy*y0 + cz*z0) - radius*radius;
|
||||
|
||||
const double discriminant = (b*b) - (4*a*c);
|
||||
return discriminant >= 0;
|
||||
|
||||
|
||||
/*
|
||||
// http://www.pixelnerve.com/v/2009/02/08/ray-sphere-intersection/
|
||||
const float a = ray.dir.length();
|
||||
//if (a == 0.0) return 0;
|
||||
const float b = 2.0f * ( dot(ray.start, ray.dir) - dot(ray.dir, center)) ;
|
||||
const Point3 tempDiff = center - ray.start;
|
||||
const float c = tempDiff.length() - (radius*radius);
|
||||
const float disc = b * b - 4 * a * c;
|
||||
return disc >= 0.0f;
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // SPHERE3_H
|
||||
0
geo/TestSphere3.cpp
Normal file
0
geo/TestSphere3.cpp
Normal file
118
geo/Triangle3.h
Normal file
118
geo/Triangle3.h
Normal file
@@ -0,0 +1,118 @@
|
||||
#ifndef TRIANGLE3_H
|
||||
#define TRIANGLE3_H
|
||||
|
||||
#include "Point3.h"
|
||||
#include "Ray3.h"
|
||||
|
||||
struct Triangle3 {
|
||||
|
||||
Point3 p1;
|
||||
Point3 p2;
|
||||
Point3 p3;
|
||||
|
||||
public:
|
||||
|
||||
/** empty ctor */
|
||||
Triangle3() : p1(), p2(), p3() {;}
|
||||
|
||||
/** ctor */
|
||||
Triangle3(Point3 p1, Point3 p2, Point3 p3) : p1(p1), p2(p2), p3(p3) {;}
|
||||
|
||||
|
||||
// Point3 cross(Point3 b, Point3 c) const {
|
||||
// return Point3(
|
||||
// b.y*c.z - c.y*b.z,
|
||||
// b.z*c.x - c.z*b.x,
|
||||
// b.x*c.y - c.x*b.y
|
||||
// );
|
||||
// }
|
||||
|
||||
// float dot(Point3 b, Point3 c) const {
|
||||
// return b.x*c.x + b.y*c.y + b.z*c.z;
|
||||
// }
|
||||
|
||||
Triangle3 operator - (const Point3 o) const {
|
||||
return Triangle3(p1-o, p2-o, p3-o);
|
||||
}
|
||||
|
||||
Point3 getNormal() const {
|
||||
return cross( p2-p1, p3-p1 ).normalized();
|
||||
}
|
||||
|
||||
|
||||
// http://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/
|
||||
bool intersects(Ray3 ray, Point3& pos) const {
|
||||
|
||||
const Point3 e1 = p2-p1;
|
||||
const Point3 e2 = p3-p1;
|
||||
|
||||
const Point3 h = cross(ray.dir, e2);
|
||||
const float a = dot(e1, h);
|
||||
|
||||
if (a > -0.00001 && a < 0.00001) {return false;}
|
||||
|
||||
const float f = 1/a;
|
||||
|
||||
const Point3 s = ray.start - p1;
|
||||
const float u = f * dot(s,h);
|
||||
|
||||
if (u < 0.0 || u > 1.0) {return false;}
|
||||
|
||||
const Point3 q = cross(s, e1);
|
||||
const float v = f * dot(ray.dir, q);
|
||||
|
||||
if (v < 0.0 || u + v > 1.0) {return false;}
|
||||
const float t = f * dot(e2,q);
|
||||
|
||||
|
||||
if (t > 0.00001) {
|
||||
pos = ray.start + (ray.dir * t);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
int rayIntersectsTriangle(float *p, float *d,
|
||||
float *v0, float *v1, float *v2) {
|
||||
|
||||
float e1[3],e2[3],h[3],s[3],q[3];
|
||||
float a,f,u,v;
|
||||
|
||||
//crossProduct(h,d,e2);
|
||||
a = innerProduct(e1,h);
|
||||
|
||||
if (a > -0.00001 && a < 0.00001)
|
||||
return(false);
|
||||
|
||||
f = 1/a;
|
||||
vector(s,p,v0);
|
||||
u = f * (innerProduct(s,h));
|
||||
|
||||
if (u < 0.0 || u > 1.0)
|
||||
return(false);
|
||||
|
||||
crossProduct(q,s,e1);
|
||||
v = f * innerProduct(d,q);
|
||||
|
||||
if (v < 0.0 || u + v > 1.0)
|
||||
return(false);
|
||||
|
||||
// at this stage we can compute t to find out where
|
||||
// the intersection point is on the line
|
||||
t = f * innerProduct(e2,q);
|
||||
|
||||
if (t > 0.00001) // ray intersection
|
||||
return(true);
|
||||
|
||||
else // this means that there is a line intersection
|
||||
// but not a ray intersection
|
||||
return (false);
|
||||
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
#endif // TRIANGLE3_H
|
||||
21
geo/volume/BVH.h
Normal file
21
geo/volume/BVH.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef BOUNDINGVOLUMEHIERARCHY_H
|
||||
#define BOUNDINGVOLUMEHIERARCHY_H
|
||||
|
||||
#include "BoundingVolume.h"
|
||||
#include "BoundingVolumeAABB.h"
|
||||
#include "BoundingVolumeSphere.h"
|
||||
|
||||
class BVH {
|
||||
|
||||
public:
|
||||
|
||||
/** add a new volume to the tree */
|
||||
void add(BoundingVolume* bv) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // BOUNDINGVOLUMEHIERARCHY_H
|
||||
18
geo/volume/BoundingVolume.h
Normal file
18
geo/volume/BoundingVolume.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef BOUNDINGVOLUME_H
|
||||
#define BOUNDINGVOLUME_H
|
||||
|
||||
#include "../Point3.h"
|
||||
|
||||
class BoundingVolume {
|
||||
|
||||
public:
|
||||
|
||||
/** get the volume's size (something like m^3) */
|
||||
virtual float getVolumeSize() const = 0;
|
||||
|
||||
/** does the volume contain the given point? */
|
||||
virtual bool contains(const Point3 p) const = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // BOUNDINGVOLUME_H
|
||||
30
geo/volume/BoundingVolumeAABB.h
Normal file
30
geo/volume/BoundingVolumeAABB.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef BOUNDINGVOLUMEBOX_H
|
||||
#define BOUNDINGVOLUMEBOX_H
|
||||
|
||||
#include "BoundingVolume.h"
|
||||
#include "../Point3.h"
|
||||
|
||||
class BoundingVolumeAABB : public BoundingVolume {
|
||||
|
||||
static constexpr float MAX = +99999;
|
||||
static constexpr float MIN = -99999;
|
||||
|
||||
/** minimum */
|
||||
Point3 p1;
|
||||
|
||||
/** maximum */
|
||||
Point3 p2;
|
||||
|
||||
public:
|
||||
|
||||
/** empty ctor */
|
||||
BoundingVolumeAABB() : p1(MAX,MAX,MAX), p2(MIN,MIN,MIN) {;}
|
||||
|
||||
float getVolumeSize() const override {
|
||||
return (p2.x-p1.x) * (p2.y-p1.y) * (p2.z-p1.z);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // BOUNDINGVOLUMEBOX_H
|
||||
4
geo/volume/BoundingVolumeBox.h
Normal file
4
geo/volume/BoundingVolumeBox.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef BOUNDINGVOLUMEBOX_H
|
||||
#define BOUNDINGVOLUMEBOX_H
|
||||
|
||||
#endif // BOUNDINGVOLUMEBOX_H
|
||||
4
geo/volume/BoundingVolumeHierarchy.h
Normal file
4
geo/volume/BoundingVolumeHierarchy.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef BOUNDINGVOLUMEHIERARCHY_H
|
||||
#define BOUNDINGVOLUMEHIERARCHY_H
|
||||
|
||||
#endif // BOUNDINGVOLUMEHIERARCHY_H
|
||||
27
geo/volume/BoundingVolumeSphere.h
Normal file
27
geo/volume/BoundingVolumeSphere.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef BOUNDINGVOLUMESPHERE_H
|
||||
#define BOUNDINGVOLUMESPHERE_H
|
||||
|
||||
#include "../Point3.h"
|
||||
|
||||
class BoundingVolumeSphere : public BoundingVolume {
|
||||
|
||||
private:
|
||||
|
||||
Point3 center;
|
||||
|
||||
float radius;
|
||||
|
||||
public:
|
||||
|
||||
float getVolumeSize() const override {
|
||||
return (4.0f / 3.0f) * M_PI * (radius*radius*radius);
|
||||
}
|
||||
|
||||
/** does the volume contain the given point? */
|
||||
virtual bool contains(const Point3 p) const {
|
||||
return (center-p).length() <= radius;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // BOUNDINGVOLUMESPHERE_H
|
||||
Reference in New Issue
Block a user