Untitled
unknown
plain_text
3 years ago
18 kB
6
Indexable
#include <iostream> #include <vector> #include<math.h> #define pi (2*acos(0.0)) using namespace std; class Point{ public: double x; double y; double z; Point(){} Point(double x, double y, double z){ this->x = x; this->y = y; this->z = z; } printPoint(){ cout << " Point : " << x << " " << y << " " << z << endl; } }; class Ray{ public: Point start; Point dir; Ray(Point eye, Point cur_pixel){ start = eye; dir.x = cur_pixel.x - eye.x; dir.y = cur_pixel.y - eye.y; dir.z = cur_pixel.z - eye.z; double length = sqrt( ( dir.x * dir.x ) + ( dir.y * dir.y ) + ( dir.z * dir.z ) ); dir.x = dir.x / length; dir.y = dir.y / length; dir.z = dir.z / length; } void printRay(){ cout << "Ray start " << endl; start.printPoint() ; cout << "Ray dir " << endl; dir.printPoint() ; } }; class Object{ public: Point reference_point; double height, width, length; double color[3]; double coEfficients[4]; int shine; Object(){ } virtual void draw(){} virtual double intersect(Ray *r, double* color, int level){ return INT_MAX; } void setLightingColor(double* c){ c[0] = color[0] * coEfficients[0]; c[1] = color[1] * coEfficients[0]; c[2] = color[2] * coEfficients[0]; } void setColor(double c[]){ this->color[0] = c[0]; this->color[1] = c[1]; this->color[2] = c[2]; } void setShine(int shine){ this->shine = shine; } void setCoefficients(double coeff[]){ this->coEfficients[0] = coeff[0]; this->coEfficients[1] = coeff[1]; this->coEfficients[2] = coeff[2]; this->coEfficients[3] = coeff[3]; } virtual void print_object(){ cout << "Color : " << color[0] << " " << color[1] << " " << color[2] << endl; cout << "Coefficients: " << coEfficients[0] << " " << coEfficients[1] << " " << coEfficients[2] << " " << coEfficients[3] << endl; cout << "Shine : " << shine << endl; } }; class Sphere : public Object{ public: Sphere(Point center, double radius){ reference_point = center; length = radius; } void draw(){ // printf("Draw circle\n"); Point points[100][100]; int i,j; int slices = 12; int stacks = 20; double h,r; double radius = length; // cout << "radius : " << radius << endl; //generate points for(i=0;i<=stacks;i++) { h=radius*sin(((double)i/(double)stacks)*(pi/2)); r=radius*cos(((double)i/(double)stacks)*(pi/2)); for(j=0;j<=slices;j++) { points[i][j].x=r*cos(((double)j/(double)slices)*2*pi); points[i][j].y=r*sin(((double)j/(double)slices)*2*pi); points[i][j].z=h; } } //draw quads using generated points for(i=0;i<stacks;i++) { glColor3f(color[0], color[1], color[2]); for(j=0;j<slices;j++) { glBegin(GL_QUADS);{ //upper hemisphere glVertex3f(points[i][j].x,points[i][j].y,points[i][j].z); glVertex3f(points[i][j+1].x,points[i][j+1].y,points[i][j+1].z); glVertex3f(points[i+1][j+1].x,points[i+1][j+1].y,points[i+1][j+1].z); glVertex3f(points[i+1][j].x,points[i+1][j].y,points[i+1][j].z); //lower hemisphere glVertex3f(points[i][j].x,points[i][j].y,-points[i][j].z); glVertex3f(points[i][j+1].x,points[i][j+1].y,-points[i][j+1].z); glVertex3f(points[i+1][j+1].x,points[i+1][j+1].y,-points[i+1][j+1].z); glVertex3f(points[i+1][j].x,points[i+1][j].y,-points[i+1][j].z); }glEnd(); } } // cout<<"drawing is over" << endl; } double intersect(Ray *r, double* color_in, int level){ Point r_start_translate( r->start.x - reference_point.x, r->start.y - reference_point.y, r->start.z - reference_point.z); double ld = - ( r->dir.x * r_start_translate.x ) - ( r->dir.y * r_start_translate.y ) - ( r->dir.z * r_start_translate.z ); if(ld < 0 ){ return INT_MAX; } double r_start_len = ( r_start_translate.x * r_start_translate.x ) + ( r_start_translate.y * r_start_translate.y ) + ( r_start_translate.z * r_start_translate.z ); double d_squared = ( r_start_len ) - ( ld * ld ); if(d_squared > ( length * length ) ){ return INT_MAX; } double l_prime = ( length*length ) - d_squared; double t1 = ld + l_prime; double t2 = ld - l_prime; // cout << "intersecting sphere on " << min(t1, t2) << endl; setLightingColor(color_in); double t = NULL; /* if(r_start_len < (length * length) ){ t = t1; } else if(r_start_len > ( length * length ) ){ t = t2; } else if(t == NULL ){ t = min(t1, t2); }*/ t = min(t1, t2); if( level != 0 ){ Point intersect_point( r->start.x + ( t * r->dir.x ), r->start.y + ( t * r->dir.y ), r->start.z + ( t * r->dir.z ) ); double len = sqrt( pow(intersect_point.x, 2) + pow(intersect_point.y, 2) + pow(intersect_point.z, 2) ); Point normal; normal.x = intersect_point.x / len; normal.y = intersect_point.y / len; normal.z = intersect_point.z / len; } return t; } void print_object(){ cout << "Sphere " << endl; cout << "Radius : " << length << endl; cout << "Center : " << reference_point.x << reference_point.y << reference_point.z <<endl; Object::print_object(); } }; class Triangle : public Object{ public: Point first, second, third; Triangle(Point first, Point second, Point third){ this->first = first; this->second = second; this->third = third; } void draw(){ // printf("Draw Triangle\n"); glColor3f(color[0], color[1], color[2]); glBegin(GL_TRIANGLES); { glVertex3f(first.x, first.y, first.z); glVertex3f(second.x, second.y, second.z); glVertex3f(third.x, third.y, third.z); } glEnd(); } void print_object(){ cout << "First : " << first.x << first.y << first.z <<endl; cout << "Second : " << second.x << second.y << second.z <<endl; cout << "Third : " << third.x << third.y << third.z <<endl; Object::print_object(); } double intersect(Ray *r, double* color_in, int level){ setLightingColor(color_in); double a1 = first.x - second.x; double a2 = first.y - second.y; double a3 = first.z - second.z; double b1 = third.x - second.x; double b2 = third.y - second.y; double b3 = third.z - second.z; double c1 = - r->dir.x; double c2 = - r->dir.y; double c3 = - r->dir.z; double d1 = r->start.x - second.x ; double d2 = r->start.y - second.y ; double d3 = r->start.z - second.z ; double D = a1 * (b2*c3 - c2*b3) + b1 * (c2*a3 - c3*a2) + c1 * (a2*b3 - a3*b2); double D1 = d1 * (b2*c3 - c2*b3) + b1 * (c2*d3 - c3*d2) + c1 * (d2*b3 - d3*b2); double D2 = a1 * (d2*c3 - c2*d3) + d1 * (c2*a3 - c3*a2) + c1 * (a2*d3 - a3*d2); double D3 = a1 * (b2*d3 - d2*b3) + b1 * (d2*a3 - d3*a2) + d1 * (a2*b3 - a3*b2); if( D != 0 ){ double k1 = D1 / D; double k2 = D2 / D; double t = D3 / D; // cout << (k1 + k2 ) << endl; if((k1 > 0 ) && (k2 > 0) && ( k1 + k2 <= 1 ) ){ if(level != 0){ Point intersect_point(r->start.x + ( t * r->dir.x ), r->start.y + ( t * r->dir.y ), r->start.z + ( t * r->dir.z )); Point normal; normal.x = ( a2 * b3 ) - ( b2 * a3 ); normal.y = ( a3 * b1 ) - ( a1 * b3 ); normal.z = ( a1 * b2 ) - ( a2 * b1 ); double len = sqrt( pow(normal.x, 2) + pow( normal.y, 2) + pow( normal.z, 2) ); normal.x = normal.x / len; normal.y = normal.y / len; normal.z = normal.z / len; } return t; } } return INT_MAX; } }; class General : public Object{ public: vector<double> degree_coeff; General( vector<double> coeff){ this->degree_coeff = coeff; /*cout<<"length : " << degree_coeff.size() << endl; for(double element : degree_coeff){ cout<<element << " "; } cout<<endl;*/ } void draw(){ } double intersect(Ray *r, double* color_in, int level){ setLightingColor(color_in); Point r_start(r->start.x - reference_point.x, r->start.y - reference_point.y, r->start.z - reference_point.z); /*r_start.x = r->start.x ; r_start.y = r->start.y ; r_start.z = r->start.z ;*/ double a = ( degree_coeff[0] * pow( r->dir.x , 2 ) ) + ( degree_coeff[1] * pow(r->dir.y, 2) ) + (degree_coeff[2] * pow(r->dir.z, 2) ) \ + ( degree_coeff[3] * r->dir.x * r->dir.y ) + ( degree_coeff[4] * r->dir.y * r->dir.z ) + ( degree_coeff[5] * r->dir.x * r->dir.z ); double b = ( 2 * degree_coeff[0] * r_start.x * r->dir.x ) + ( 2* degree_coeff[1] * r_start.y * r->dir.y ) + ( 2* degree_coeff[2] * r_start.z * r->dir.z ) \ + ( degree_coeff[3] * ( ( r->dir.x * r_start.y ) + ( r_start.x * r->dir.y ) ) ) + ( degree_coeff[4] * ( ( r->dir.y * r_start.z ) + ( r_start.y * r->dir.z ) ) ) \ + ( degree_coeff[5] * ( ( r->dir.z * r_start.x ) + ( r_start.z * r->dir.x ) ) ) + ( degree_coeff[6] * r->dir.x ) + ( degree_coeff[7] * r->dir.y ) + ( degree_coeff[8] * r->dir.z ); double c = ( degree_coeff[0] * pow( r_start.x , 2 ) ) + ( degree_coeff[1] * pow(r_start.y, 2) ) + (degree_coeff[2] * pow(r_start.z, 2) ) \ + ( degree_coeff[3] * r_start.x * r_start.y ) + ( degree_coeff[4] * r_start.y * r_start.z ) + ( degree_coeff[5] * r_start.x * r_start.z ) \ + ( degree_coeff[6] * r_start.x ) + ( degree_coeff[7] * r_start.y ) + ( degree_coeff[8] * r_start.z ) + degree_coeff[9]; double root_squared = ( b * b ) - ( 4 * a * c ); if(root_squared < 0 ){ return INT_MAX; } root_squared = sqrt( root_squared ); double t1 = ( - b + root_squared ) / ( 2 * a ); double t2 = ( - b - root_squared ) / ( 2 * a ); double t = INT_MAX; bool not_valid = false; Point min_intersect; if( t1 > 0 ){ Point intersect_point(r->start.x + ( t1 * r->dir.x ), r->start.y + ( t1 * r->dir.y ), r->start.z + ( t1 * r->dir.z )); if(length != 0 ){ if( ( intersect_point.x < reference_point.x ) || ( intersect_point.x > ( reference_point.x + length )) ){ not_valid = true; } } if(width != 0 ){ if( ( intersect_point.y < reference_point.y ) || ( intersect_point.y > ( reference_point.y + width )) ){ not_valid = true; } } if(height != 0 ){ if( ( intersect_point.z < reference_point.z ) || ( intersect_point.z > ( reference_point.z + height )) ){ not_valid = true; } } if( not_valid == false ){ min_intersect = intersect_point; t = min(t, t1); } } not_valid = false; if( t2 > 0 ){ Point intersect_point( r->start.x + ( t2 * r->dir.x ), r->start.y + ( t2 * r->dir.y ), r->start.z + ( t2 * r->dir.z ) ); if(length != 0 ){ if( ( intersect_point.x < reference_point.x ) || ( intersect_point.x > ( reference_point.x + length )) ){ not_valid = true; } } if(width != 0 ){ if( ( intersect_point.y < reference_point.y ) || ( intersect_point.y > ( reference_point.y + width )) ){ not_valid = true; } } if(height != 0 ){ if( ( intersect_point.z < reference_point.z ) || ( intersect_point.z > ( reference_point.z + height )) ){ not_valid = true; } } if( not_valid == false ){ if( t != NULL ){ t = min(t, t2); if( t == t2 ){ min_intersect = intersect_point; } } else{ min_intersect = intersect_point; t = t2; } } } if(level != 0 ){ Point normal; normal.x = ( 2 * coEfficients[0] * min_intersect.x ) + ( coEfficients[3] * min_intersect.y ) + ( coEfficients[5] * min_intersect.z ) + coEfficients[6]; normal.y = ( 2 * coEfficients[1] * min_intersect.y ) + ( coEfficients[3] * min_intersect.x ) + ( coEfficients[4] * min_intersect.y ) + coEfficients[7]; normal.z = ( 2 * coEfficients[2] * min_intersect.z ) + ( coEfficients[4] * min_intersect.y ) + ( coEfficients[5] * min_intersect.x ) + coEfficients[8]; double len = sqrt( pow(normal.x, 2) + pow( normal.y, 2) + pow( normal.z, 2) ); normal.x = normal.x / len; normal.y = normal.y / len; normal.z = normal.z / len; } return t; } }; class PointLight{ public: Point light_pos; double color[3]; PointLight(Point pos){ this->light_pos = pos; } void setColor(double c[]){ this->color[0] = c[0]; this->color[1] = c[1]; this->color[2] = c[2]; } }; class SpotLight{ public: PointLight* pl; Point light_direction; double cutoff_angle; SpotLight(PointLight pl, Point light_dir, double angle){ this-> pl = new PointLight(pl.light_pos); this->pl->setColor(pl.color); this->light_direction = light_dir; this->cutoff_angle = angle; } }; class Floor : public Object{ public: double floorwidth; Floor(double floorwidth, double tilewidth){ this->floorwidth = floorwidth; reference_point.x = - floorwidth / 2.0; reference_point.y = - floorwidth / 2.0; reference_point.z = 0; length = tilewidth; } void draw(){ int i; Point cur_point(0, 0, 0); double row_color[3] = {color[0], color[1], color[2]}; // cout << "y : " << cur_point.y << " " << reference_point.y << endl; while( cur_point.y <= floorwidth ){ double col_color[3] = {row_color[0], row_color[1], row_color[2]}; while(cur_point.x <= floorwidth){ // cout << "cur point y : " << cur_point.y << endl; glColor3f(col_color[0], col_color[1], col_color[2]); glBegin(GL_QUADS);{ glVertex3f(cur_point.x, cur_point.y, 0); glVertex3f(cur_point.x + length, cur_point.y, 0); glVertex3f(cur_point.x + length, cur_point.y + length, 0); glVertex3f(cur_point.x, cur_point.y + length, 0); }glEnd(); cur_point.x = cur_point.x + length; col_color[0] = 1 - col_color[0]; col_color[1] = 1 - col_color[1]; col_color[2] = 1 - col_color[2]; } cur_point.y = cur_point.y + length; cur_point.x = 0; row_color[0] = 1 - row_color[0]; row_color[1] = 1 - row_color[1]; row_color[2] = 1 - row_color[2]; // cout << "updated cur point y : " << cur_point.y << endl; } } double intersect(Ray *r, double* color_in, int level){ double dot_d_n = r->dir.z; if( dot_d_n == 0 ){ return INT_MAX; } double dot_p_n = reference_point.z * r->dir.z; double dot_r0_n = r->start.z - reference_point.z; double t = ( dot_p_n - dot_r0_n ) * 1.0 / dot_d_n; Point intersection_point( r->start.x + ( t * r->dir.x ),r->start.y + ( t * r->dir.y ), r->start.z + ( t * r->dir.z ) ); color_in[0] = 1 * coEfficients[0]; color_in[1] = 1 * coEfficients[0]; color_in[2] = 1 * coEfficients[0]; if( ( intersection_point.y >= reference_point.y ) && ( intersection_point.y <= - reference_point.y ) ){ int col_idx = int( (intersection_point.y - reference_point.y) / length ); if( ( intersection_point.x >= reference_point.x ) && ( intersection_point.x <= - reference_point.x ) ) { int row_idx = int( (intersection_point.x - reference_point.x) / length ); if( ( row_idx + col_idx ) % 2 == 0){ color_in[0] = 0; color_in[1] = 0; color_in[2] = 0; } if(level == 0) return t; // level != 0 Point normal(0, 0, 1); } } return INT_MAX; } }; vector<Object*> Objects; vector<PointLight*> pointLights; vector<SpotLight*> spotlights;
Editor is loading...