Files
GTSchoolShit/CS4451/proj1/functions.cpp
2025-06-07 01:59:34 -04:00

443 lines
9.9 KiB
C++

#include <math.h>
#include <iostream>
#include <stdlib.h>
#include <vector>
#include "defs.h"
#include "functions.h"
using namespace std;
void printObject(Vector v) {
cerr << v.x << " " << v.y << " " << v.z << endl;
}
void printObject(int i) {
cerr << i << endl;
}
void printObject(double f) {
cerr << f << endl;
}
void printObject(Light l) {
cerr << l.center.x << " " << l.center.y << " " << l.center.z << " I: " << l.intensity << endl;
}
void printObject(MaterialAttributes attrib) {
cerr << " k_dr, k_dg, k_db " << attrib.k_dr << " " << attrib.k_dg << " " << attrib.k_db << " "
<< attrib.k_ar << " " << attrib.k_ag << " " << attrib.k_ab << " "
<< attrib.k_s << " " << attrib.n_spec << endl;
}
void scanInput(MaterialAttributes &attrib, char* input) {
char *pEnd;
cin.getline(input,81);
attrib.k_dr = strtod(input,&pEnd);
attrib.k_dg = strtod(pEnd,&pEnd);
attrib.k_db = strtod(pEnd,&pEnd);
attrib.k_ar = strtod(pEnd,&pEnd);
attrib.k_ag = strtod(pEnd,&pEnd);
attrib.k_ab = strtod(pEnd,&pEnd);
attrib.k_s = strtod(pEnd,&pEnd);
attrib.n_spec = strtod(pEnd,NULL);
}
void scanInput(vector<Primitive*> &primitives, int numPrimitives, char* input) {
int i;
char *pEnd;
for (i = 0; i < numPrimitives; i++) {
cin.getline(input,81);
switch (input[0]) {
case 'S': {
Sphere* sphere = new Sphere();
cin.getline(input,81);
sphere->center.x = strtod(input, &pEnd);
sphere->center.y = strtod(pEnd, &pEnd);
sphere->center.z = strtod(pEnd, &pEnd);
sphere->radius = strtod(pEnd,NULL);
scanInput(sphere->attrib, input);
primitives.push_back(sphere);
//printObject(sphere->attrib);
#ifdef bDebug
cout << "Got Sphere.." << endl;
printObject(sphere->center);
printObject(sphere->radius);
printObject(sphere->attrib);
#endif
break;
}
case 'T': {
Triangle* triangle = new Triangle();
scanInput(triangle->a1,input);
scanInput(triangle->a2,input);
scanInput(triangle->a3,input);
scanInput(triangle->attrib, input);
primitives.push_back(triangle);
#ifdef bDebug
cout << "Got Triangle.." << endl;
printObject(triangle->a1);
printObject(triangle->a2);
printObject(triangle->a3);
printObject(triangle->attrib);
#endif
break;
}
default:
cout << "Error bad\n";
break;
};
}
}
void scanInput(Vector &v, char* input) {
char* pEnd;
cin.getline(input, 81);
v.x = strtod(input,&pEnd);
v.y = strtod(pEnd,&pEnd);
v.z = strtod(pEnd,NULL);
}
void scanInput(Light &light, char* input) {
char* pEnd;
cin.getline(input,81);
light.center.x = strtod(input, &pEnd);
light.center.y = strtod(pEnd, &pEnd);
light.center.z = strtod(pEnd, &pEnd);
light.intensity = strtod(pEnd, NULL);
}
/* Useful operator overloads */
/* ------------- <Vector> -------------*/
Vector Vector::operator+(Vector &other) {
Vector v;
v.x = x + other.x;
v.y = y + other.y;
v.z = z + other.z;
return v;
}
Vector Vector::operator-(Vector &other) {
Vector v;
v.x = x - other.x;
v.y = y - other.y;
v.z = z - other.z;
return v;
}
Vector Vector::operator*(Vector &other) {
Vector v;
v.x = x * other.x;
v.y = y * other.y;
v.z = z * other.z;
return v;
}
Vector Vector::operator/(Vector &other) {
Vector v;
v.x = x / other.x;
v.y = y / other.y;
v.z = z / other.z;
return v;
}
Vector Vector::operator*(int &other) {
Vector v;
v.x = x * other;
v.y = y * other;
v.z = z * other;
return v;
}
Vector Vector::operator*(double &other) {
Vector v;
v.x = x * other;
v.y = y * other;
v.z = z * other;
return v;
}
/* ------------ </Vector> ----------- */
/* ------------ <ostream> ----------- */
ostream &operator<< ( ostream &ofs, struct MaterialAttributes m ) {
ofs << " Material Attributes: " << endl;
ofs << " k_dr: " << m.k_dr << " k_dg: " << m.k_dg << " k_db: " << m.k_db << endl;
ofs << " k_ar: " << m.k_ar << " k_ag: " << m.k_ag << " k_ab: " << m.k_ab << endl;
ofs << " k_s: " << m.k_s << " n_spec: " << m.n_spec << endl;
return ofs;
}
ostream &operator<< ( ostream &ofs, Sphere s ) {
ofs << "Sphere: " << endl;
ofs << " Center: " << "(" << s.center.x << ","
<< s.center.y << "," << s.center.z << endl;
return ofs;
}
ostream &operator<< ( ostream &ofs, Triangle t ) {
ofs << "Triangle: " << endl;
return ofs;
}
/* ------------ </ostream> ------------- */
/* ----------- Primitive stuff ----------- */
double length(Vector p) {
double toRet;
toRet = pow(p.x,2)+pow(p.y,2)+pow(p.z,2);
toRet = sqrt(toRet);
return toRet;
}
double dot(Vector v1, Vector v2) {
double toRet;
toRet = (v1.x*v2.x) + (v1.y*v2.y) + (v1.z*v2.z);
return toRet;
}
inline double discriminant(double A, double B, double C) {
return ((B*B) - (4*A*C));
}
void Sphere::printName() {
cout << "This is of type Sphere" << endl;
}
bool Sphere::intersectsWithSelf(Point p, Light l, Point v) {
Vector cp, pl;
cp = p - this->center;
pl = l.center - p;
if (dot(cp,pl) < 0) {
return true;
} else return false;
}
double Sphere::intersectsWith(Ray ray) {
double C = pow(length(ray.origin - this->center),2) - pow(this->radius,2);
double B;
double A;
double discrim;
A = pow(length(ray.direction),2);
B = 2*dot(ray.direction,ray.origin - this->center);
discrim = discriminant(A,B,C);
if (discrim < 0) {
return -1;
} else if (discrim > 0) {
double a, b;
a = ((-1*B)+sqrt(discrim))/(2*A);
b = ((-1*B)-sqrt(discrim))/(2*A);
if (b>=0) return b;
else return a;
} else { //discrim==0
return ((-1*B) / (2*A));
}
}
void Triangle::printName() {
cout << "This is of type Triangle" << endl;
}
inline Vector cross(Vector a, Vector b) {
Vector toRet;
toRet.x = ( (a.y*b.z) - (a.z*b.y) ); //i
toRet.y = ( (a.z*b.x) - (a.x*b.z) ); //j
toRet.z = ( (a.x*b.y) - (a.y*b.x) ); //k
return toRet;
}
inline char bestCoord(Vector v1) {
//Lazy fast method
if (abs((int)v1.x) > abs((int)v1.y)) {
if (abs((int)v1.x) > abs((int)v1.z)) {
return 'x';
} else {
return 'z';
}
} else {
if (abs((int)v1.y) > abs((int)v1.z)) {
return 'y';
} else {
return 'z';
}
}
}
Vector Sphere::normal(Point p, Light l) {
Vector normal;
normal = p-this->center;
return normal;
}
Vector Triangle::normal(Point p, Light l) {
Vector normal, a1a2, a1a3, pl;
a1a2 = this->a2 - this->a1;
a1a3 = this->a3 - this->a1;
normal = cross(a1a2,a1a3);
pl = l.center - p;
if (dot(normal,pl) < 0) {
//normal = normal * ((double)-1.0);
//STUPID OPERATOR OVERLOADING DOESNT WORK
normal.x = normal.x * -1;
normal.y = normal.y * -1;
normal.z = normal.z * -1;
}
return normal;
}
Vector Triangle::normal(Point p) {
Vector normal, a1a2, a1a3, pl;
a1a2 = this->a2 - this->a1;
a1a3 = this->a3 - this->a1;
normal = cross(a1a2,a1a3);
return normal;
}
bool Triangle::intersectsWithSelf(Point p, Light l, Point v) {
Vector normal = this->normal(p,l), pv;
pv = v - p;
if (dot(normal,pv) < 0) {
return true;
} else return false;
}
double Triangle::intersectsWith(Ray ray) {
Vector normal = this->normal(this->a1);
//calculate t
double top = dot(ray.origin - a1,normal);
double bottom = dot(ray.direction, normal);
double t = -1.0 * (top/bottom);
if (t < 0) {
return -1;
} else {
Point p = (ray.direction * t) + ray.origin;
Vector pa1 = this->a1 - p;
Vector pa2 = this->a2 - p;
Vector pa3 = this->a3 - p;
Vector pa1pa2 = cross(pa1,pa2);
Vector pa2pa3 = cross(pa2,pa3);
Vector pa3pa1 = cross(pa3,pa1);
char best = bestCoord(pa1pa2);
switch (best) {
case 'x':
if ((pa1pa2.x > 0 && pa2pa3.x > 0 && pa3pa1.x > 0)
|| (pa1pa2.x < 0 && pa2pa3.x < 0 && pa3pa1.x < 0))
{
return t;
} else {
return -1;
}
case 'y':
if ((pa1pa2.y > 0 && pa2pa3.y > 0 && pa3pa1.y > 0)
|| (pa1pa2.y < 0 && pa2pa3.y < 0 && pa3pa1.y < 0))
{
return t;
} else {
return -1;
}
case 'z':
if ((pa1pa2.z > 0 && pa2pa3.z > 0 && pa3pa1.z > 0)
|| (pa1pa2.z < 0 && pa2pa3.z < 0 && pa3pa1.z < 0))
{
return t;
} else {
return -1;
}
default:
cerr << "How?";
};
}
return -1;
}