work on raytracing

This commit is contained in:
2017-09-06 08:34:20 +02:00
parent c21925e86f
commit e4cd9c6b8d
32 changed files with 2790 additions and 3 deletions

26
geo/Plane3.h Normal file
View 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

View File

@@ -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
View 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
View 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
View File

118
geo/Triangle3.h Normal file
View 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
View 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

View 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

View 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

View File

@@ -0,0 +1,4 @@
#ifndef BOUNDINGVOLUMEBOX_H
#define BOUNDINGVOLUMEBOX_H
#endif // BOUNDINGVOLUMEBOX_H

View File

@@ -0,0 +1,4 @@
#ifndef BOUNDINGVOLUMEHIERARCHY_H
#define BOUNDINGVOLUMEHIERARCHY_H
#endif // BOUNDINGVOLUMEHIERARCHY_H

View 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