#include #include #include #include #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::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; } }