164 lines
5.1 KiB
C++
164 lines
5.1 KiB
C++
#include <math.h>
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include "defs.h"
|
|
#include "functions.h"
|
|
|
|
void RayTracer::getPixelAt(int x, int y, RGB& pixel) {
|
|
Point p = l;
|
|
|
|
double xscale = ((double) x) / this->m;
|
|
double yscale = ((double) y) / this->n;
|
|
|
|
p.x = p.x + h.x *(xscale);
|
|
p.y = p.y + h.y *(xscale);
|
|
p.z = p.z + h.z *(xscale);
|
|
|
|
p.x = p.x + v.x *(yscale);
|
|
p.y = p.y + v.y *(yscale);
|
|
p.z = p.z + v.z *(yscale);
|
|
|
|
//Now that we have p, we need to get the Ray that goes from
|
|
//the viewpoint to the point
|
|
|
|
Ray ray;
|
|
|
|
ray.direction = p-e;
|
|
ray.origin = p;
|
|
|
|
//Now that we have the ray, let's see if it intersects anything
|
|
|
|
vector<Primitive*>::iterator theIterator, index;
|
|
double t=-1, temp;
|
|
|
|
for( theIterator = primitives.begin(); theIterator != primitives.end();
|
|
theIterator++ )
|
|
{
|
|
temp = (*theIterator)->intersectsWith(ray);
|
|
|
|
if (temp >= 0 && (temp < t || t < 0)) {
|
|
index = theIterator;
|
|
t = temp;
|
|
}
|
|
}
|
|
|
|
/* Add intensity code */
|
|
if (t >= 0) {
|
|
|
|
Point p = (ray.direction*t) + ray.origin;
|
|
Ray L;
|
|
L.direction = light.center-p;
|
|
L.origin = p;
|
|
double shadowT;
|
|
|
|
|
|
//Check if it is in shadow
|
|
for (theIterator = primitives.begin(); theIterator != primitives.end();
|
|
theIterator++)
|
|
{
|
|
if (theIterator == index) {
|
|
continue;
|
|
}
|
|
shadowT = (*theIterator)->intersectsWith(L);
|
|
if (shadowT > 0 && shadowT < 1) {
|
|
//object intersected, don't bother continuing
|
|
pixel.r = (*index)->attrib.k_ar * ambience;
|
|
pixel.g = (*index)->attrib.k_ag * ambience;
|
|
pixel.b = (*index)->attrib.k_ab * ambience;
|
|
return;
|
|
}
|
|
}
|
|
//nothing found, check for self intersection
|
|
if ((*index)->intersectsWithSelf(p, this->light, this->e)) {
|
|
pixel.r = (*index)->attrib.k_ar * ambience;
|
|
pixel.g = (*index)->attrib.k_ag * ambience;
|
|
pixel.b = (*index)->attrib.k_ab * ambience;
|
|
} else {
|
|
double temp;
|
|
Vector V, N, R;
|
|
|
|
/*pixel.r = (*index)->attrib.k_ar * ambience
|
|
+ (*index)->attrib.k_dr * this->light.intensity;
|
|
pixel.g = (*index)->attrib.k_ag * ambience
|
|
+ (*index)->attrib.k_dg * this->light.intensity;
|
|
pixel.b = (*index)->attrib.k_ab * ambience
|
|
+ (*index)->attrib.k_db * this->light.intensity;
|
|
*/
|
|
|
|
//Calculate the R, V, and L vectors
|
|
//We have L, but it needs to be converted to a unit vector
|
|
//L.direction = L.direction / length(L.direction);
|
|
temp = length(L.direction);
|
|
L.direction.x /= temp;
|
|
L.direction.y /= temp;
|
|
L.direction.z /= temp;
|
|
|
|
V = e-p;
|
|
temp = length(V);
|
|
V.x /= temp;
|
|
V.y /= temp;
|
|
V.z /= temp;
|
|
/*V.x /= -1*temp;
|
|
V.y /= -1*temp;
|
|
V.z /= -1*temp;*/
|
|
|
|
|
|
N = (*index)->normal(p,light);
|
|
temp = length(N);
|
|
N.x /= temp;
|
|
N.y /= temp;
|
|
N.z /= temp;
|
|
|
|
//diffuse
|
|
pixel.r = (*index)->attrib.k_dr * this->light.intensity
|
|
* dot(N,L.direction);
|
|
pixel.g = (*index)->attrib.k_dg * this->light.intensity
|
|
* dot(N,L.direction);
|
|
pixel.b = (*index)->attrib.k_db * this->light.intensity
|
|
* dot(N,L.direction);
|
|
|
|
//specular
|
|
R.x = (-1*L.direction.x)+(2.*((dot(N,L.direction)) * N.x));
|
|
R.y = (-1*L.direction.y)+(2.*((dot(N,L.direction)) * N.y));
|
|
R.z = (-1*L.direction.z)+(2.*((dot(N,L.direction)) * N.z));
|
|
|
|
pixel.r +=
|
|
(*index)->attrib.k_s * pow(max((double)0,dot(R,V)),(*index)->attrib.n_spec) * this->light.intensity;
|
|
|
|
pixel.g +=
|
|
(*index)->attrib.k_s * pow(max((double)0,dot(R,V)),(*index)->attrib.n_spec) * this->light.intensity;
|
|
|
|
pixel.b +=
|
|
(*index)->attrib.k_s * pow(max((double)0,dot(R,V)),(*index)->attrib.n_spec) * this->light.intensity;
|
|
|
|
//calculate distance from light for attenuation
|
|
/*double r = length(this->light.center - p);
|
|
|
|
pixel.r *= (1./(pow(r,((double)2)) + r));
|
|
pixel.g *= (1./(pow(r,((double)2)) + r));
|
|
pixel.b *= (1./(pow(r,((double)2)) + r));*/
|
|
|
|
//add ambient
|
|
pixel.r += (*index)->attrib.k_ar * ambience ;
|
|
pixel.g += (*index)->attrib.k_ag * ambience ;
|
|
pixel.b += (*index)->attrib.k_ab * ambience ;
|
|
return;
|
|
}
|
|
} else {
|
|
|
|
pixel.r = 0;
|
|
pixel.g = 0;
|
|
pixel.b = 0;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|