Example #1
0
static
Ray3D GetGizmoAxisInWorldSpace( const APlaceable* pEntity, const EGizmoAxis eAxis )
{
	const Vec3D& origin = pEntity->GetOrigin();

	const Matrix4	R = pEntity->GetOrientation().ToMat4();

	const Vec3D		axisX = R[0].ToVec3();
	const Vec3D		axisY = R[1].ToVec3();
	const Vec3D		axisZ = R[2].ToVec3();

	switch( eAxis )
	{
	case GizmoAxis_X :
		return Ray3D( origin, axisX );

	case GizmoAxis_Y :
		return Ray3D( origin, axisY );

	case GizmoAxis_Z :
		return Ray3D( origin, axisZ );

		mxNO_SWITCH_DEFAULT;
	}
	return Ray3D();
}
int RayDirectionalLight::isInShadow(RayIntersectionInfo& iInfo,RayShape* shape,int& isectCount){
	Point3D P = iInfo.iCoordinate;
	Point3D L = -direction;
	Ray3D temp = Ray3D(P,L);
	Ray3D tempRay = Ray3D(temp(.00001),L);
	RayIntersectionInfo info;
	double d = shape->intersect(tempRay, info, -1);
	//printf("hit distance:%f,%f,%f,%f\n",d,info.normal.p[0],info.normal.p[1],info.normal.p[2]);
	if (L.dot(info.normal) >= 0)
		return 1;
	if (d > 0) {return 0;}
	 else return 1;

}
Point3D RayDirectionalLight::transparency(RayIntersectionInfo& iInfo,RayShape* shape,Point3D cLimit){
	Point3D trans = Point3D(1,1,1);

	Ray3D shadeRay = Ray3D(iInfo.iCoordinate, -direction);
	shadeRay.position = shadeRay(0.00001);

	RayIntersectionInfo info;
	Point3D Kt = Point3D();

	while (Kt[0] < cLimit[0] && Kt[1] < cLimit[1] && Kt[2] < cLimit[2]) {
	                double dis = shape->intersect(shadeRay, info, -1);
	                Point3D N = info.normal;

	                if (dis < 0 || -direction.dot(N) >= 0)

	                	return trans;

	                Kt = info.material->transparent;

	                shadeRay.position = info.iCoordinate;
	                shadeRay.position = shadeRay(0.00001);
	                cLimit /= Kt;

	                trans -= Kt;
	}
    if(trans[0]<0) trans[0] =0;
    if(trans[1]<0) trans[1] =0;
    if(trans[2]<0) trans[2] =0;
	return trans;
}
int RaySpotLight::isInShadow(RayIntersectionInfo& iInfo,RayShape* shape,int& isectCount){
	
	Point3D temp = this->location - iInfo.iCoordinate;
	double dist = temp.length();

	Ray3D newRay = Ray3D();
	newRay.position = iInfo.iCoordinate;
	newRay.direction = temp.unit();

	if(shape->intersect(newRay, iInfo, dist) > 0){
		isectCount+=1;
		return 1;
	}
	return 0;
	
}
Example #5
0
int RayPointLight::isInShadow(RayIntersectionInfo& iInfo,RayShape* shape,int& isectCount){
	Point3D temp = location - iInfo.iCoordinate;
	double dist = sqrt(temp.dot(temp));
	double atten = 0;
	atten = (constAtten + (linearAtten*dist) + (quadAtten*pow(dist,2.0)));

	Ray3D testRay = Ray3D();
	testRay.position = iInfo.iCoordinate;
	testRay.direction = temp.unit();

	if(shape->intersect(testRay, iInfo, dist) != -1){
		return 1;
	}
	//1 = inShadow, 0 = no shadow
	return 0;
}
Example #6
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view, 
			Vector3D up, double fov, char* fileName, char mode ) {
	Matrix4x4 viewToWorld;
	_scrWidth = width;
	_scrHeight = height;
	double factor = (double(height)/2)/tan(fov*M_PI/360.0);

	initPixelBuffer();
	viewToWorld = initInvViewMatrix(eye, view, up);

	// Construct a ray for each pixel.
	for (int i = 0; i < _scrHeight; i++) {
		for (int j = 0; j < _scrWidth; j++) {
			// Sets up ray origin and direction in view space, 
			// image plane is at z = -1.
			Point3D origin(0, 0, 0);
			Point3D imagePlane;
			imagePlane[0] = (-double(width)/2 + 0.5 + j)/factor;
			imagePlane[1] = (-double(height)/2 + 0.5 + i)/factor;
			imagePlane[2] = -1;

			// TODO: Convert ray to world space and call 
			// shadeRay(ray) to generate pixel colour. 		

			/////////////////////// OUR CODE ///////////////////////////////
			
			Vector3D d = Vector3D(imagePlane[0], imagePlane[1], imagePlane[2]);
			d = viewToWorld*d;
			origin = viewToWorld*origin;
			Ray3D ray = Ray3D( origin , d );
			if (mode == 'd'){
			  (*(ray.intersection.mat)).specular = Colour(0,0,0);
			}
			Colour col;
			col = shadeRay(ray, mode); 
			/////////////////////// OUR CODE ///////////////////////////////
			_rbuffer[i*width+j] = int(col[0]*255);
			_gbuffer[i*width+j] = int(col[1]*255);
			_bbuffer[i*width+j] = int(col[2]*255);
		}
	}

	flushPixelBuffer(fileName);
}
Example #7
0
Colour Raytracer::shadeRay( Ray3D& ray ) {
	Colour col(0.0, 0.0, 0.0); 

	traverseScene(_root, ray); 
	
	// Don't bother shading if the ray didn't hit 
	// anything.
	if (!ray.intersection.none) {
		computeShading(ray);

        // You'll want to call shadeRay recursively (with a different ray, 
    	// of course) here to implement reflection/refraction effects.  
        float dampFactor = 0.0;

        // Calculate reflection ray
        Vector3D N = ray.intersection.normal;
        Vector3D D = ray.dir;
        Vector3D reflectionDir = -2*(D.dot(N))*N + D;
        reflectionDir.normalize();
        Point3D reflectionOrigin = ray.intersection.point + 0.01*reflectionDir;
        Ray3D reflectionRay = Ray3D(reflectionOrigin, reflectionDir);

        // calculate shade of reflected ray
        shadeRay(reflectionRay);

        // limit effective distance of reflections
        if (reflectionRay.intersection.t_value > 10.0 || reflectionRay.intersection.t_value <= 0.0) {
            col = ray.col;
        }
        else {
        dampFactor = fabs(1.0/reflectionRay.intersection.t_value);
        // contraint dampFactor to 0-0.9
        dampFactor = fmax(0, fmin(dampFactor,0.9));
        // Set colour to include reflection
        col = ray.col + dampFactor*reflectionRay.col;
        }

        col.clamp();
	}
	return col; 
}	
Example #8
0
Point3D RayPointLight::transparency(RayIntersectionInfo& iInfo,RayShape* shape,Point3D cLimit){
	Point3D temp = location - iInfo.iCoordinate;
	double dist = sqrt(temp.dot(temp));
	double atten = 0;
	atten = (constAtten + (linearAtten*dist) + (quadAtten*pow(dist,2.0)));

	Ray3D testRay = Ray3D();
	
	testRay.direction = temp.unit();
	testRay.position = iInfo.iCoordinate + testRay.direction;

	Point3D out = Point3D(1,1,1);	

	if(shape->intersect(testRay, iInfo, dist) != -1){		
		Point3D trans = iInfo.material->transparent;
		out = out * trans;
		out = out * transparency(iInfo, shape, cLimit / trans);
	}
	//1 = inShadow, 0 = no shadow
	return out;
}
//----------------------------------------------------------------------------------------------------------------
bool UnitSquare::intersect( Ray3D& ray, const Matrix4x4& worldToModel, const Matrix4x4& modelToWorld )
{
	// Implement intersection code for UnitSquare, which is
	// defined on the xy-plane, with vertices (0.5, 0.5, 0), 
	// (-0.5, 0.5, 0), (-0.5, -0.5, 0), (0.5, -0.5, 0), and normal
	// (0, 0, 1).
	//
	// Your goal here is to fill ray.intersection with correct values
	// should an intersection occur.  This includes intersection.point, 
	// intersection.normal, intersection.none, intersection.t_value.   
	//
	// HINT: Remember to first transform the ray into object space  
	// to simplify the intersection test.
	// The original point is at 0,0,0 at its own model coordinates 

	// Get ray direction in model coordinates
	Ray3D ObjectRay = Ray3D(worldToModel*ray.origin, worldToModel * ray.dir);
	Point3D origin(0,0,0);
	// always assume unitsquare is on x,y plane 
	Vector3D squareNormal(0,0,1);
	double t_value;
	Point3D intersectionPoint;

	// If the ray is not moving towards the square, it means there is no intersection since
	// the square lies on the x and y axis, ray must move at some value on the z direction 
	if (ObjectRay.dir[2] != 0)
	{
		t_value  = -ObjectRay.origin[2]/ObjectRay.dir[2];
		// Check for no self intersection 
		if ((t_value )< 0.001)
		{
			return false;
		}
	}

	//the ray and the square are on the same plane
	else if (ObjectRay.dir[2] == 0 && ObjectRay.origin[2] == 0)
	{
		double temp1 = (-1.5 - ObjectRay.origin[0])/ObjectRay.dir[0];
		double temp2 = (1.5 - ObjectRay.origin[0])/ObjectRay.dir[0];
		double temp3 = (-1.5 - ObjectRay.origin[1])/ObjectRay.dir[1];
		double temp4 = (1.5 - ObjectRay.origin[1])/ObjectRay.dir[1];
		t_value  = temp1;
		if (temp2 < t_value )
		{
			t_value  = temp2;
		}
		if (temp3 < t_value )
		{
			t_value  =temp3;
		}
		if (temp4< t_value )
		{
			t_value  = temp4;
		}
	}
	else
	{

		return false;
	}
	
	// Compute t_value from z intersection at z = 0
	
	// If the ray already has an intersection at an earlier t_value, return but don't update
	// ray.intersection fields
	if(ray.intersection.none == false) 
	{
		if(t_value > ray.intersection.t_value) 
		{
			return false;
		}
	}

	// Compute coordinates
	Vector3D intersection(ObjectRay.origin[0] + ObjectRay.dir[0] * t_value, ObjectRay.origin[1] + ObjectRay.dir[1] * t_value, 0);
	double x = ObjectRay.origin[0] + ObjectRay.dir[0] * t_value;
	double y = ObjectRay.origin[1] + ObjectRay.dir[1] * t_value;

	// Test x
	if(x >= -0.5 && x <= 0.5) {
		// Text y
		if(y >= -0.5 && y <= 0.5) {
			// We have an intersection
			ray.intersection.t_value = t_value;
			ray.intersection.point = modelToWorld * Point3D(x, y, 0);
			ray.intersection.normal = Vector3D(0, 0, 1);

			// For Image Mapping 			
			ray.intersection.CenterPoint = modelToWorld * Point3D(0,0,0); // every model thinks it is in the center 
			ray.intersection.normal = transNorm(worldToModel, ray.intersection.normal);
			ray.intersection.normal.normalize();
			ray.intersection.none = false; // false means there is an intersection 

			return true;
		}
	}

	return false;
}
bool UnitSphere::intersect( Ray3D& ray, const Matrix4x4& worldToModel, const Matrix4x4& modelToWorld )
{
	// TODO: implement intersection code for UnitSphere, which is centred 
	// on the origin.  
	//
	// Your goal here is to fill ray.intersection with correct values
	// should an intersection occur.  This includes intersection.point, 
	// intersection.normal, intersection.none, intersection.t_value.   

	//
	// HINT: Remember to first transform the ray into object space  
	// to simplify the intersection test.
	
	Ray3D ObjectRay = Ray3D(worldToModel * ray.origin, worldToModel * ray.dir);
	double a = pow(ObjectRay.dir[0], 2) + pow(ObjectRay.dir[1], 2) + pow(ObjectRay.dir[2], 2);
	double b = 2 * (ObjectRay.origin[0] * ObjectRay.dir[0] +
					ObjectRay.origin[1] * ObjectRay.dir[1] +
					ObjectRay.origin[2] * ObjectRay.dir[2]);

	double c = pow(ObjectRay.origin[0], 2) + 
			   pow(ObjectRay.origin[1], 2) + 
			   pow(ObjectRay.origin[2], 2) -1;

	double discriminant = pow(b, 2) - 4 * a * c;

	// No intersection since no real roots 
	if(discriminant < 0) 
	{ 
		return false;

	} 
	else 
	{
		double t_1 = (-1 * b + sqrt(discriminant)) / (2 * a);
		double t_2 = (-1 * b - sqrt(discriminant)) / (2 * a);
		double t_value = 0;

		if ( t_2 < 0 && t_1 < 0)
			return false;
		else if ( t_1 < 0 )
			t_value = t_2;
		else if ( t_2 < 0 )
			t_value = t_1;

		else
			t_value = fmin(t_1, t_2);

		// If the ray already has an intersection at an earlier t_value, return but don't update
		// ray.intersection fields

		if(ray.intersection.none == false) 
		{
			if(t_value > ray.intersection.t_value) 
			{
				return true;
			}
		}


		double x = ObjectRay.origin[0] + ObjectRay.dir[0]*t_value;
		double y = ObjectRay.origin[1] + ObjectRay.dir[1]*t_value;
		double z = ObjectRay.origin[2] + ObjectRay.dir[2]*t_value;
		
		Vector3D intersection = Vector3D(x, y, z);
		ray.intersection.t_value = t_value;		
		ray.intersection.point = modelToWorld * Point3D(x, y, z);
		ray.intersection.normal = transNorm(worldToModel, intersection);
		ray.intersection.normal.normalize();	
		// FOR TEXTURE MAPPING!
		ray.intersection.CenterPoint = modelToWorld * Point3D(0,0,0); // every model thinks it is in the center 
		ray.intersection.none = false;
		return true;
	}
}
Example #11
0
Ray3D RayScene::GetRay(RayCamera* camera,int i,int j,int width,int height){
	return Ray3D();
}
Example #12
0
int step_trace_ray::execute
	( const pair & frame_fragment, ray_tracer & rt ) const {

	int current_frame = frame_fragment.first;
	int current_fragment = frame_fragment.second;

	// Consume
	std::vector<Primitive*> scene;
	std::vector<Primitive*> static_scene = rt.static_scene;
	std::vector<Luminaire*> luminaires = rt.luminaires;
	std::vector<Primitive*> dynamic_scene;
	rt.dynamic_scene.get(current_frame, dynamic_scene);

	scene.insert(scene.end(), static_scene.begin(), static_scene.end());
	scene.insert(scene.end(), dynamic_scene.begin(), dynamic_scene.end());

	std::vector<Point2D*> points;
	rt.pixel_locations.get(pair(current_frame, current_fragment), points);

	// Execute

	double duration;
	std::clock_t start = std::clock();
	std::vector<Pixel*> pixels;

	double invWidth = 1/((double)rt.image_width);
	double invHeight = 1/((double)rt.image_height);
	int smaller = std::min(rt.image_width, rt.image_height);

	double fov = 30;

	double aspectratio = rt.image_width/((double)rt.image_height);
	double angle = tan(3.141592653589793 * 0.5 * fov / 180.0);

	for(int ij = 0; ij < points.size(); ij++) {
		double x = (double)points[ij]->i;
		double y = (double)points[ij]->j;
		double nSamp1D = sqrt(rt.number_pixel_samples);
		double duvSamp = 1.0/nSamp1D;
		Multispectral3D superSample = Multispectral3D();
		for(int i = 0; i < nSamp1D; ++i) {
			for(int j = 0; j < nSamp1D; ++j) {
				double u = x + (i + 0.5 * duvSamp)/smaller;
				double v = y + (j + 0.5 * duvSamp)/smaller;
				double xx = (2 * (u * invWidth) - 1) * angle * aspectratio;
				double yy = (1 - 2 * (v * invHeight)) * angle;
				Vector3D raydir = Vector3D(xx, yy, -1).normalize();
				Ray3D ray = Ray3D(Point3D(), raydir, NULL, 0);
				superSample = superSample + trace(ray, scene, luminaires);
			}
		}
		Multispectral3D rgb = superSample / rt.number_pixel_samples;
		pixels.push_back(new Pixel(points[ij]->i,points[ij]->j,rgb.r,rgb.g,rgb.b));
	}

	duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;

	// Produce
	rt.pixels.put(pair(current_frame, current_fragment), pixels);
	rt.execution_time.put(pair(current_frame, current_fragment), duration);



  return CnC::CNC_Success;
};
Example #13
0
//Comparison speed: 10.96
//Bounding Boxes: 5.89
//Ordering: 4.99
double RayGroup::intersect(Ray3D ray,RayIntersectionInfo& iInfo,double mx){
	//printf("This runs\n");
	bool ignoreMX = false;
	if (mx == -1) ignoreMX = true;
	Ray3D rayCopy = Ray3D();
	rayCopy.position = ray.position;
	rayCopy.direction = ray.direction;

	double min_t = -1;
	RayShape* min_shape = NULL;
	RayIntersectionInfo tempInfo = RayIntersectionInfo();

	double boxOut = bBox.intersect(ray);
	if (boxOut < mx || ignoreMX){
		if(boxOut > -1){

			Matrix4D matrix = getMatrix();
			ray.position = getInverseMatrix().multPosition(ray.position);
			ray.direction = getInverseMatrix().multDirection(ray.direction);
			double scaler = ray.direction.length();
			ray.direction = ray.direction.unit();

			int count = 0;
			for (int i = 0; i < sNum; i++)
			{
				RayShape* temp = shapes[i];
				double dist = temp->bBox.intersect(ray);
				if(dist < mx || ignoreMX)
				{
					if (dist > -1)
					{
						//Means we have a hit of the inner volume
						hits[count].shape = temp;
						hits[count].t = dist;
						count++;
					}					 
				}
			}
			qsort(hits,count,sizeof(RayShapeHit),RayShapeHit::Compare);
		
	
		//if (bBox.intersect(ray) > -1){
			for (int i = 0; i < count; i++)
			{
				//printf("something got hit!\n");
				//printf("i = %i\n",i);
				RayShape* temp = hits[i].shape;
		
				double t = -1;		
		
				t = temp->intersect(ray, tempInfo, mx);
				if (t > 0)
				{
					t = t / scaler;
					if (min_t == -1 || t < min_t) 
					{	
						min_t = t;
						min_shape = temp;
						iInfo.iCoordinate = tempInfo.iCoordinate;
						iInfo.normal = tempInfo.normal;
						iInfo.material = tempInfo.material;	
						break;
					}
				}
				
																																						//Checks if its a Static Ray Group with its own transform information
		
			/*StaticRayGroup* temp2 = dynamic_cast<StaticRayGroup*>(temp);
			if(temp2 != 0) 
			{  
				t = temp->intersect(rayCopy, tempInfo, mx);
				if (t > 0)
				{
					if (min_t == -1 || t < min_t) 
					{
						iInfo.iCoordinate = tempInfo.iCoordinate;
						iInfo.normal = tempInfo.normal;
						iInfo.material = tempInfo.material;
						min_t = t;
						min_shape = temp;
					}			
				}
			}
			else 
			{
				ray.position = getInverseMatrix().multPosition(rayCopy.position);
				ray.direction = getInverseMatrix().multDirection(rayCopy.direction).unit();
				t = temp->intersect(ray, tempInfo, mx);

				if (t > 0)
				{
					if (min_t == -1 || t < min_t) 
					{
						iInfo.iCoordinate = matrix.multPosition(tempInfo.iCoordinate);
						iInfo.normal = getNormalMatrix().multNormal(tempInfo.normal);
						iInfo.material = tempInfo.material;
						min_t = t;
						min_shape = temp;
					}			
				}
			}*/		
			}	
			iInfo.iCoordinate = matrix.multPosition(iInfo.iCoordinate);
			iInfo.normal = getNormalMatrix().multDirection(iInfo.normal).unit();
			//iInfo.material = iInfo.material;
		}
	}
	return min_t;

}
Example #14
0
Colour Raytracer::shadeRay( Ray3D& ray, char renderStyle ) {
    Colour col(0.0, 0.0, 0.0);
    traverseScene(_root, ray);

    // Don't bother shading if the ray didn't hit
    // anything.
    if (!ray.intersection.none) {
        //computeShading(ray);
        if (renderStyle != 's') {
            computeShading(ray, renderStyle);
            col = ray.col;

#ifdef USE_REFLECTIONS
            if ((ray.intersection.mat->reflectivity >= 0.01) && (ray.reflections < MAX_REFLECTIONS) && (renderStyle != 'd')) {
                // emit another ray
                Vector3D n = ray.intersection.normal;
                n.normalize();
                Vector3D d = ray.dir;
                d.normalize();



                double dot = n.dot(d);
                Vector3D newdir = d - (2 * dot * n);

                Ray3D newRay = Ray3D(ray.intersection.point + 0.01*newdir,
                                     newdir, ray.reflections+1, ray.refractions, ray.cLight);
                Colour secondaryColour = shadeRay(newRay, renderStyle);


                double ref = ray.intersection.mat->reflectivity;
                col = (1-ref)*ray.col + ref*secondaryColour;
            } else {
                col = ray.col;
            }
#else
            col = ray.col;
#endif
            // Check for refractions
            // Don't check for refractions of reflected rays
#ifdef USE_REFRACTIONS
            if((ray.intersection.mat->transitivity >= 0.1) && (ray.refractions < MAX_REFRACTIONS) && (renderStyle != 'd')) {
                double c1 = ray.cLight;
                double c2 = ray.intersection.mat->cLight;
                if (ray.cLight < 0.99) { //Ray leaves object to air/vacuum
                    c2= 1;
                }


                Vector3D n = ray.intersection.normal;
                n.normalize();
                Vector3D d = ray.dir;
                d.normalize();

                double dot = n.dot(d);
                Vector3D reflDir = d - (2 * dot * n);
                reflDir.normalize();

                //Now determine refraction direction
                //Depends on reflDir, c1, c2, n, as specified in the relation below
                double theta1 = acos( n.dot(-d) );
                if(dot > 0 ) { //Ray is leaving object
                    theta1 = acos( n.dot(d) );
                }
                double theta2 = asin(c2*sin(theta1)/c1);

                //Check for critical angle

                // Compute refraction direction
                Vector3D refractDir = (c2/c1)*ray.dir + ( (c2/c1)*cos(theta1) - cos(theta2))*n;
                if(dot > 0 ) { //Ray is leaving object     =====================changed sign
                    refractDir = (c2/c1)*ray.dir - ( (c2/c1)*cos(theta1) - cos(theta2))*n;
                }

                refractDir.normalize();

                Ray3D refractRay = Ray3D(ray.intersection.point + 0.0001*refractDir, refractDir,ray.reflections, ray.refractions+1, c2 );


                Colour colRefract = shadeRay(refractRay, renderStyle);
                double matTran = ray.intersection.mat->transitivity;
                if(!refractRay.intersection.none) { //Refracted ray does not go off into space
                    col = (1-matTran)*col + matTran*colRefract;
                }
            }//end of refractions
#endif

        }//End of check if(renderStyle != 's')
        else { //renderStyle == 's'
            col = (*(ray.intersection.mat)).diffuse;
        }
    }//End of check if (!ray.intersection.none)

    return col;
}// End of shadeRay
// Basically, this is an intersection with 3 different connected surfaces 
// The top disk, the bottom disk and the cylinder body. 
// Test the intersection of all 3 bodies and figure out which has the lowest t value
bool UnitCylinder::intersect( Ray3D& ray, const Matrix4x4& worldToModel, const Matrix4x4& modelToWorld ) 
{
	// Get the ray in the object coordinates
	Ray3D ObjectRay = Ray3D(worldToModel * ray.origin, worldToModel * ray.dir);
	// A reference to the origin point in object/model coordinates
	Point3D centerOfCylinder(0,0,0); // Center of cylinder 
	// T Values 
	// One to check for intersection with disks, one to check for intersection with sides 
	double t_value; double t_valueTwo; 
	double tempOne, tempTwo;
	double radius = 1.0; // the radius of the disk of the cylinder

	Vector3D normal; // The normal of the cylinder Disk as well as wall of cylinder
			// Gets reused
	Point3D intersectionPoint; // intersection point with the cylinder 

//---------------------------------------------------------------------------------
// Checking Intersection with Cylinder Disks 
//---------------------------------------------------------------------------------

	// Note: Will only intersect the disks of the cylinder
	// if the direction value for z is not 0
	// Getting the tValue for the closer base
	if (ObjectRay.dir[2] != 0)
	{
		// Tvalue to intersect bottom disk of cylinder (negative z axis)
		tempOne = (-0.5-ObjectRay.origin[2])/ObjectRay.dir[2];
		// Tvalue to intersect top disk of cylinder (positive z axis)
		tempTwo = (0.5-ObjectRay.origin[2])/ObjectRay.dir[2];
		
		// Update the normal depending on which disk is closer 
		if (tempOne < tempTwo)
		{
			t_value = tempOne;
			// Construct the normal for the closer disk, which points on the negative z axis
			Point3D normal_temp(0,0,-1);
			normal = normal_temp - centerOfCylinder;
			normal.normalize();

		}
		else
		{
			t_value = tempTwo;
			Point3D normal_temp(0,0,1);
			normal = normal_temp - centerOfCylinder;
			normal.normalize();
		}
	}



//---------------------------------------------------------------------------------
//  Calculate the intersection point for the disk  
//---------------------------------------------------------------------------------
	intersectionPoint = ObjectRay.origin + t_value * ObjectRay.dir;
	
	// Prevent self intersection
	if (t_value < 0.001)
	{
		return false;
	}

	// Base or top of cylinder 
	// need make sure within the radius of the disk 
	if (intersectionPoint[0]*intersectionPoint[0] + intersectionPoint[1] * intersectionPoint[1] <= (radius*radius))
	{
		// If it intersection before and it's tvalue is lower then this, 
		// means there is no intersection, return false. 
		if (!ray.intersection.none && (t_value > ray.intersection.t_value))
		{
			return false;
		}
		// Else, there is intersection, update and return true 
		ray.intersection.point = intersectionPoint;
		
		ray.intersection.normal = normal;
		ray.intersection.t_value = t_value;
		ray.intersection.none = false;
		// Every model thinks it is in the center
		ray.intersection.CenterPoint = modelToWorld * Point3D(0,0,0); 
		return true;
	}

	// No intersection with cylinder disk
	// Check for intersection with cylinder body 
//---------------------------------------------------------------------------------
// Checking Intersection with Cylinder Body 
//---------------------------------------------------------------------------------

// Source: http://www.csie.ntu.edu.tw/~cyy/courses/rendering/pbrt-2.00/html/cylinder_8cpp_source.html

	// Compute Quadratic Cylinder Coefficients 
	double a = ObjectRay.dir[0]*ObjectRay.dir[0] + ObjectRay.dir[1]*ObjectRay.dir[1];
	double b = (ObjectRay.origin[0]*ObjectRay.dir[0] + ObjectRay.origin[1]* ObjectRay.dir[1]);
					
	double c = ObjectRay.origin[0]*ObjectRay.origin[0] + ObjectRay.origin[1]*ObjectRay.origin[1] - radius*radius;
													
	double discriminant = b*b-a*c;


	// If ray is aligned with body of the cylinder, there is no intersection 
	if (a == 0.0)
	{
		// return false
	}

	//If discrimant is < 0 => No real roots to the cylinder quadratic equation. 
	if (discriminant<0)
	{
		// It means no intersection 
		return false;
	}
	else
	{
		double rootOne = -b/a + sqrt(discriminant) / a;
		double rootTwo = -b/a - sqrt(discriminant) / a;
		if (rootOne< 0 && rootTwo < 0)
		{
			return false;
		}
		else if (rootOne> 0 && rootTwo < 0)
		{
			t_valueTwo = rootOne;
		}
		else
		{
			t_valueTwo = rootTwo;
		}
	}
//---------------------------------------------------------------------------------
//  Calculate the intersection point for the walls of the cylinder   
//---------------------------------------------------------------------------------
	// There is no intersection with the base of the cylinder on x,y plane
	// Check if there is intersection with sides. 

		// Get the intersection point for the sides 
		intersectionPoint = ObjectRay.origin+ t_valueTwo * ObjectRay.dir;
		// Check for no self intersection 
		if (t_valueTwo < 0.001)
		{
			return false;
		}
		// Get the coordinate of the normals for the sides of the cylinder 
		normal[0] = intersectionPoint[0];
		normal[1] = intersectionPoint[1];
		normal[2] = 0;
		normal.normalize();

		// If the intersection point is within the height of the cylinder
		if (intersectionPoint[2] < 0.5 && intersectionPoint[2] > -0.5)
		{
			// Ensure no previous intersection with lower t value 
			if (!ray.intersection.none && t_value > ray.intersection.t_value)
			{
				return false;
			}
			// Update the intersection to the ray 
			ray.intersection.point = modelToWorld * intersectionPoint;
			Point3D normalTemp;
			normalTemp[0] = intersectionPoint[0];
			normalTemp[1] = intersectionPoint[1];
			normalTemp[2] = 0;
			ray.intersection.normal = modelToWorld * (normalTemp - centerOfCylinder);
			ray.intersection.t_value = t_valueTwo;
			ray.intersection.none = false;
			// Every model thinks it is in the center
			ray.intersection.CenterPoint = modelToWorld * Point3D(0,0,0); 
			return true;
		}
		// If the intersection is not within the height of the cylinder,
		// It means there wasn't really a cylinder intersection to begin with  
		else
		{
			return false;
		}
}
// Assume disk is flat on the x,y plane with radius 1 
bool UnitDisk::intersect( Ray3D& ray, const Matrix4x4& worldToModel, const Matrix4x4& modelToWorld ) 
{
	// Get the ray in the object coordinates
	Ray3D ObjectRay = Ray3D(worldToModel * ray.origin, worldToModel * ray.dir);
	// A reference to the origin point in object/model coordinates
	Point3D centerofDisk(0,0,0); // Center of cylinder 
	// T Values 
	// One to check for intersection with disks, one to check for intersection with sides 
	double t_value; double t_valueTwo; 
	double tempOne, tempTwo;
	double radius = 1.0; // the radius of the disk of the cylinder

	Vector3D normal; // The normal of the cylinder Disk as well as wall of cylinder
			// Gets reused
	Point3D intersectionPoint; // intersection point with the cylinder 

//---------------------------------------------------------------------------------
// Checking Intersection with Cylinder Disks 
//---------------------------------------------------------------------------------

	// Note: Will only intersect the disks of the cylinder
	// if the direction value for z is not 0
	// Getting the tValue for the closer base
	if (ObjectRay.dir[2] != 0)
	{
		// To know if intersect from top or bottom of disk, and set normal accordingly 
		tempOne = (-0.0000001-ObjectRay.origin[2])/ObjectRay.dir[2];
		// Tvalue  
		tempTwo = (0.00000001-ObjectRay.origin[2])/ObjectRay.dir[2];
		
		// Update the normal depending on which disk is closer 
		if (tempOne < tempTwo)
		{
			t_value = tempOne;
			// Construct the normal for the closer disk, which points on the negative z axis
			Point3D normal_temp(0,0,-1);
			normal = normal_temp - centerofDisk;
			normal.normalize();

		}
		else
		{
			t_value = tempTwo;
			Point3D normal_temp(0,0,1);
			normal = normal_temp - centerofDisk;
			normal.normalize();
		}
	}



//---------------------------------------------------------------------------------
//  Calculate the intersection point for the disk  
//---------------------------------------------------------------------------------
	intersectionPoint = ObjectRay.origin + t_value * ObjectRay.dir;
	
	// Prevent self intersection
	if (t_value < 0.001)
	{
		return false;
	}

	// Base or top of cylinder 
	// need make sure within the radius of the disk 
	if (intersectionPoint[0]*intersectionPoint[0] + intersectionPoint[1] * intersectionPoint[1] <= (radius*radius))
	{
		// If it intersection before and it's tvalue is lower then this, 
		// means there is no intersection, return false. 
		if (!ray.intersection.none && (t_value > ray.intersection.t_value))
		{
			return false;
		}
		// Else, there is intersection, update and return true 
		ray.intersection.point = intersectionPoint;
		
		ray.intersection.normal = normal;
		ray.intersection.t_value = t_value;
		ray.intersection.none = false;
		// Every model thinks it is in the center
		ray.intersection.CenterPoint = modelToWorld * Point3D(0,0,0); 
		return true;
	}
	return false; // no intersection with disk 
}
Example #17
0
Point3D RayScene::GetColor(Ray3D ray,int rDepth,Point3D cLimit)
{
    Point3D color;
    RayIntersectionInfo info;
    Ray3D reflection;
    Ray3D refraction;
    Ray3D reflectedRay;
    Point3D reflect, reflColor, refractColor;
    int shad;
    int numCrossed = 0;

    double dist;
    dist = group -> intersect(ray, info, -1);
    if (dist == -1)
        return background;

    color = ambient*info.material -> ambient + info.material -> emissive;

    if (ray.direction.dot(info.normal) < 0)
    {
        for (int j = 0; j < this->lightNum; j++)
        {
            shad = this->lights[j]->isInShadow(info, this->group, numCrossed);
            Point3D ts = lights[j]->transparency(info, group, cLimit);

            color += this->lights[j]->getDiffuse(ray.position, info) * ts;
            color += this->lights[j]->getSpecular(ray.position, info) * ts;
        }

        reflect = Reflect(ray.direction, info.normal);

        // Reflected ray
        reflectedRay = Ray3D(info.iCoordinate, reflect);
        reflectedRay.position = reflectedRay(0.0001);

        if (rDepth > 0 && (info.material->specular[0] > cLimit[0]) && (info.material->specular[1] > cLimit[1]) && (info.material->specular[2] > cLimit[2])) 
        {
            reflColor = GetColor(reflectedRay, rDepth - 1, (cLimit / info.material->specular));

            if (reflColor.p[0] == background.p[0] && reflColor.p[1] == background.p[1] && reflColor.p[2] == background.p[2])
                reflColor = Point3D();

            // reflected color added
            reflColor *= info.material -> specular;
            color += reflColor;
        }
    }

    // refraction
    if (this -> Refract(ray.direction, info.normal, info.material->refind, refraction.direction))
    {
        refraction.position = info.iCoordinate;
        refraction.position = refraction(0.0001);
        refractColor = this -> GetColor(refraction, rDepth - 1, cLimit);

        if (refractColor.p[0] == background.p[0] && refractColor.p[1] == background.p[1] && refractColor.p[2] == background.p[2])
            refractColor = Point3D();

        refractColor *= info.material -> transparent;
        color += refractColor;
    }

    for (int i = 0; i < 3; i++)
    {
        if (color.p[i] > 1)
            color.p[i] = 1;
    }

    for (int i = 0; i < 3; i++)
    {
        if (color.p[i] < 0)
            color.p[i] = 0;
    }

    return color;
}
Example #18
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view,
                        Vector3D up, double fov, int AA_level, char* fileName, char renderStyle ) {
    Matrix4x4 viewToWorld;
    _scrWidth = width;
    _scrHeight = height;
    double factor = (double(_scrHeight)/2)/tan(fov*M_PI/360.0);

    initPixelBuffer();
    viewToWorld = initInvViewMatrix(eye, view, up);

    /**
     * Extension: Anti-aliasing level via supersampling method
     * Algorithm:
     * Generate an image of dimensions equal to a multiple of the original
     * dimensions (as specified by the AA level)
     * Then sample individual pixels and average them to compose a pixel
     * on the actual screen
     */
    _aaLevel = AA_level;
    initSuperPixelBuffer();

    /// A little print for the user
    fprintf(stderr, "Rendering %dx%d scene, AA-level %d\n", _scrWidth,
            _scrHeight, _aaLevel);

    int superi, superj;
    double offi, offj;
    // Construct a ray for each pixel.
    for (int i = 0; i < _scrHeight; i++) {
        for (int j = 0; j < _scrWidth; j++) {
            // Prepare to supersample for anti aliasing
            for (int m = 0; m < _aaLevel; m++) {
                for (int n = 0; n < _aaLevel; n++) {

                    // Sets up ray origin and direction in view space,
                    // image plane is at z = -1.
                    Point3D origin(0, 0, 0);
                    Point3D imagePlane;
                    offj = double(1)/(0.5 * _aaLevel) + double(n)/_aaLevel;
                    offi = double(1)/(0.5 * _aaLevel) + double(m)/_aaLevel;
                    imagePlane[0] = (-double((_scrWidth))/2 + offj + j)/factor;
                    imagePlane[1] = (-double((_scrHeight))/2 + offi + i)/factor;
                    imagePlane[2] = -1;

                    // Create the transformed ray and shoot it out (shadeRay)
                    Vector3D pixelVector = Vector3D(imagePlane[0], imagePlane[1],
                                                    imagePlane[2]);
                    Vector3D transformedPixelVector = viewToWorld * pixelVector;
                    Point3D transformedOrigin = viewToWorld * origin;

                    Ray3D ray = Ray3D(transformedOrigin, transformedPixelVector);

                    //Check for scene render style
                    Colour col = shadeRay(ray, renderStyle);

                    superi = i*_aaLevel + m;
                    superj = j*_aaLevel + n;

                    _superrbuffer[superi*(_aaLevel*_scrWidth)+superj] = int(col[0]*255);
                    _supergbuffer[superi*(_aaLevel*_scrWidth)+superj] = int(col[1]*255);
                    _superbbuffer[superi*(_aaLevel*_scrWidth)+superj] = int(col[2]*255);

                }
            }//End supersampling loop
        }
    }//finsihed pixel loop

    // Now average out the pixels from the super buffer (supersampling)
    factor = double(1)/(_aaLevel * _aaLevel);
    unsigned long rtemp;
    unsigned long gtemp;
    unsigned long btemp;
    for (int i = 0; i < _scrHeight; i++) {
        for (int j = 0; j < _scrWidth; j++) {
            rtemp = 0;
            gtemp = 0;
            btemp = 0;
            for (int m = 0; m < _aaLevel; m++) {
                superi = i*_aaLevel + m;
                for (int n = 0; n < _aaLevel; n++) {
                    superj = j*_aaLevel + n;

                    rtemp += _superrbuffer[superi*(_aaLevel*_scrWidth)+superj];
                    gtemp += _supergbuffer[superi*(_aaLevel*_scrWidth)+superj];
                    btemp += _superbbuffer[superi*(_aaLevel*_scrWidth)+superj];
                }
            }
            _rbuffer[i*_scrWidth+j] = factor * rtemp;
            _gbuffer[i*_scrWidth+j] = factor * gtemp;
            _bbuffer[i*_scrWidth+j] = factor * btemp;
        }
    }

    flushPixelBuffer(fileName);
}
Example #19
0
Ray3D Ray3D::fromTo(const glm::vec3 & from, const glm::vec3 & to)
{
    return Ray3D(from, to - from);
}