diff --git a/raytrace.cpp b/raytrace.cpp index 192ee6567d42ae93987b8979b347609f952d5a4e..3e172b939908dfca7ce43765c01f7adf3723a6af 100644 --- a/raytrace.cpp +++ b/raytrace.cpp @@ -3,6 +3,15 @@ //============================================================================================= #include "framework.h" +mat4 TMatrix4(mat4 m) { + return mat4( + m.rows[0].x, m.rows[1].x, m.rows[2].x, m.rows[3].x, + m.rows[0].y, m.rows[1].y, m.rows[2].y, m.rows[3].y, + m.rows[0].z, m.rows[1].z, m.rows[2].z, m.rows[3].z, + m.rows[0].w, m.rows[1].w, m.rows[2].w, m.rows[3].w + ); +} + enum MaterialType { ROUGH, REFLECTIVE }; @@ -100,11 +109,35 @@ struct Quadric : public Intersectable { virtual vec3 gradf(vec4 r) { //r.w = 1 vec4 g = r * Q * 2; - return vec3(g.x, g.y, g.z); + return normalize(vec3(g.x, g.y, g.z)); + } + + void Translate(vec3 t) { + mat4 m = TranslateMatrix(-1 * t); //inverse matrix of the transformation + Q = m * Q * TMatrix4(m); + } + + void Translate(float x, float y, float z) { + Translate(vec3(x, y, z)); + } + + void Scale(vec3 s) { + mat4 m = ScaleMatrix(vec3(1/s.x, 1/s.y, 1/s.z)); //inverse matrix of the transformation + Q = m * Q * TMatrix4(m); + } + + void Scale(float x, float y, float z){ + Scale(vec3(x,y,z)); + } + + void Rotate(float angle, vec3 w) { + mat4 m = RotationMatrix(-1 * angle, w); //inverse matrix of the transformation + Q = m * Q * TMatrix4(m); } Hit intersect(const Ray &ray) { Hit hit; + vec4 S(ray.start.x, ray.start.y, ray.start.z, 1); vec4 D(ray.dir.x, ray.dir.y, ray.dir.z, 0); @@ -136,7 +169,7 @@ struct Quadric : public Intersectable { else if(t2CutOff) hit.t = t1; else hit.t = (t2 > 0) ? t2 : t1; - hit.position = ray.start + ray.dir * hit.t; + hit.position = ray.start + ray.dir * hit.t; //+ translate; hit.normal = gradf(vec4(hit.position.x, hit.position.y, hit.position.z, 1)); hit.material = material; return hit; @@ -154,6 +187,35 @@ struct Ellipsoid : public Quadric { vec4(0.0f, 0.0f, 1 / c / c, 0.0f), vec4(0.0f, 0.0f, 0.0f, -1.0f) ); + + } +}; + +struct Paraboloid : public Quadric { + float a, b; + + Paraboloid(float _a, float _b, Material *_material): a(_a), b(_b) { + material = _material; + Q = mat4( + 1/a/a, 0.0f, 0.0f, 0.0f, + 0.0f , 1/b/b, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f + ); + } +}; + +struct Hyperboloid : public Quadric { + float a, b, c; + + Hyperboloid(float _a, float _b, float _c, Material *_material): a(_a), b(_b), c(_c) { + material = _material; + Q = mat4( + 1/a/a, 0.0f, 0.0f, 0.0f, + 0.0f, 1/b/b, 0.0f, 0.0f, + 0.0f, 0.0f, -1/c/c, 0.0f, + 0.0f, 0.0f, 0.0f, -1.0f + ); } }; @@ -197,7 +259,7 @@ struct Plane : public Quadric { } vec3 gradf(vec4 r) override { - return n + vec3(r.x, r.y, r.z); + return n; } }; @@ -244,7 +306,7 @@ class Scene { vec3 La; public: void build() { - vec3 eye = vec3(0, 3, 3), vup = vec3(0, 0, 1), lookat = vec3(0, 0, 0); + vec3 eye = vec3(0, 3.0f, 3.0f), vup = vec3(0, 0, 1), lookat = vec3(0, 0, 0); float fov = 80 * M_PI / 180; camera.set(eye, lookat, vup, fov); @@ -263,31 +325,39 @@ public: Material *materialSilver = new ReflectiveMaterial(nSilver, kSilver); vec3 kd2(0.2f, 0.2f, 0.4f); Material *materialCylinder = new RoughMaterial(kd2, ks, 50); + vec3 kd3(0.2f, 0.4f, 0.2f); + Material *materialVial = new RoughMaterial(kd3, ks, 50); //BULDING THE ROOM - Ellipsoid* roomEllipsoid = new Ellipsoid(2.0f, 2.0f, 1, materialGold); - objects.push_back(roomEllipsoid); + Ellipsoid* roomEllipsoid = new Ellipsoid(2.0f, 2.0f, 1, materialRoom); //cutting the hole at the top Plane* topHolePlane = new Plane(vec3(0.0f, 0.0f, 0.95f), vec3(0.0f, 0.0f, 1.0f), materialCylinder); roomEllipsoid->intersectors.push_back(topHolePlane); - Plane* floorPlane = new Plane(vec3(0.0f, 0.0f, 0.0f),vec3(0.0f, 0.0f, 1.0f), materialCylinder); - objects.push_back(floorPlane); - printf("%f", floorPlane->f(vec4(0,0,0,1))); - - //objects.push_back(new Sphere(vec3(0,0,0), 1.0f, materialCylinder)); - - Quadric* cylinder = new Cylinder(0.05f, 0.05f, materialCylinder); + // BULDING THE BLUE CYLINDER + Quadric* cylinder = new Cylinder(0.4f, 0.4f, materialCylinder); cylinder->intersectors.push_back(new Plane(vec3(0.0f,0.0f,0.3f), vec3(0.0f,0.0f,1.0f), materialRoom)); -// cylinder->intersectors.push_back(floorPlane); - objects.push_back(cylinder); - - -// objects.push_back(new Sphere(vec3(0,0,0), 0.1f, materialCylinder)); + cylinder->Scale(0.8, 0.8, 1.0f); + cylinder->Translate(vec3(0.5f,-0.7f,0.0f)); + // BUILDING THE GOLDEN PARABOLOID + Quadric* paraboloid = new Paraboloid(0.7f, 0.85f, materialGold); + paraboloid->Translate(-0.75f, -0.45f, 0.0f); + //BULILDING THE GREEN VIAL + Quadric* vial = new Hyperboloid(0.5f, 0.5f, 0.65f, materialVial); + vial->intersectors.push_back(new Plane(vec3(0.0f, 0.0f, 0.25f),vec3(0.0f, 0.0f,1.0f), materialRoom)); + vial->Scale(0.3f, 0.3f, 0.6f); + vial->Scale(0.75f, 0.75f, 1.0f); + vial->Translate(0.8f, 0.3f, 0.0f); + // INSERTING THE OBJECTS INTO THE ROOM + objects.push_back(roomEllipsoid); + objects.push_back(cylinder); + objects.push_back(paraboloid); + objects.push_back(vial); + //objects.push_back(new Sphere(vec3(0,0,0), 0.1f, materialCylinder)); } void render(std::vector<vec4> &image) { @@ -419,8 +489,6 @@ void onInitialization() { glViewport(0, 0, windowWidth, windowHeight); scene.build(); - - long timeStart = glutGet(GLUT_ELAPSED_TIME); std::vector<vec4> image(windowWidth * windowHeight); scene.render(image);