Untitled
unknown
plain_text
3 years ago
18 kB
8
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...