move shapes to extra source file
add serialize header and source file with common serialization functions
dump/load feature for shapes and kd-tree
fix few minor bugs
#include "raytracer.h"#include "octree.h"#include "image.h"#include "common_sdl.h"Camera cam(Vector3(0.,6.,6.), Vector3(0.,2.,-7.), Vector3(0.,0.,-1.));Light light(Vector3(-2.0, 10.0, -2.0), Colour(0.9, 0.9, 0.9));Float lx, ly, lz, cf;/*class CloudTexture: public Texture{ Vector3 centre;public: Colour evaluate(Vector3 point) { Float sum = 0.0; for (int i = 1; i < 5; i++) sum += fabsf(perlin(point.x*i, point.y*i, point.z*i))/i; Float value = sinf(point.x + sum)/2 + 0.5; return Colour(value, value*0.5, value*0.5); };};*/void texture2D(Float u, Float v, Float &r, Float &g, Float &b){ // checkers r = fabs((int)(u*4.2)%2 + (int)(v*4.2)%2 - 1); g=r; b=r;}class PlanarMapTexture: public Texture{ Vector3 centre;public: PlanarMapTexture(Vector3 acentre): centre(acentre) {}; Colour evaluate(Vector3 point) { point = point - centre; Float u = 1000+point.x; Float v = 1000+point.y; Float r,g,b; texture2D(u,v, r,g,b); return Colour(r, g, b); };};class CubicMapTexture: public Texture{ Vector3 centre;public: CubicMapTexture(Vector3 acentre): centre(acentre) {}; Colour evaluate(Vector3 point) { point = point - centre; Float u,v; if (fabs(point.x) > fabs(point.y)) { if (fabs(point.x) > fabs(point.z)) { if (point.x < 0) u = -point.y; else u = point.y; v = point.z; } else { if (point.z < 0) u = -point.x; else u = point.x; v = point.y; } } else { if (fabs(point.y) > fabs(point.z)) { if (point.y < 0) u = -point.x; else u = point.x; v = point.z; } else { if (point.z < 0) u = -point.x; else u = point.x; v = point.y; } } u += 1000; v += 1000; Float r,g,b; texture2D(u,v, r,g,b); return Colour(r, g, b); };};class CylinderMapTexture: public Texture{ Vector3 centre;public: CylinderMapTexture(Vector3 acentre): centre(acentre) {}; Colour evaluate(Vector3 point) { point = point - centre; Float u,v; v = 1000+point.y; u = M_PI + atan2(point.z, point.x); Float r,g,b; texture2D(u,v, r,g,b); return Colour(r, g, b); };};class SphereMapTexture: public Texture{ Vector3 centre;public: SphereMapTexture(Vector3 acentre): centre(acentre) {}; Colour evaluate(Vector3 point) { point = point - centre; Float u,v; v = acos(point.y / point.mag()); u = M_PI + atan2(point.z, point.x); Float r,g,b; texture2D(u,v, r,g,b); return Colour(r, g, b); };};void update_callback(){ if (lx != 0.0) light.pos.x += lx; if (ly != 0.0) light.pos.y += ly; if (lz != 0.0) light.pos.z += lz; if (cf != 0.0) cam.F += cf;}void key_callback(int key, int down){ switch (key) { case SDLK_r: lx = -0.1 * down; break; case SDLK_t: lx = +0.1 * down; break; case SDLK_f: ly = -0.1 * down; break; case SDLK_g: ly = +0.1 * down; break; case SDLK_v: lz = -0.1 * down; break; case SDLK_b: lz = +0.1 * down; break; case SDLK_z: cf = -0.02 * down; break; case SDLK_x: cf = +0.02 * down; break; }}int main(int argc, char **argv){ Raytracer rt; Octree top; rt.setCamera(&cam); rt.setTop(&top); rt.addLight(&light); light.castShadows(false); Material mat0a(Colour(0.7, 0.7, 0.7)); mat0a. setReflectivity(0.0); Box box(Vector3(-12.0, -1.2, -20.0), Vector3(12.0, -1.0, 0.0), &mat0a); rt.addShape(&box); Material mat0b(Colour(0.1, 0.7, 0.8)); mat0b.setReflectivity(0.7); Box box2(Vector3(-12.0, -1.2, -10.0), Vector3(12.0, 10.0, -10.2), &mat0b); rt.addShape(&box2); // spheres Material mat1(Colour(1.0, 1.0, 1.0)); mat1.texture = new PlanarMapTexture(Vector3(-4.5, 2.0, -7.0)); Sphere sphere1(Vector3(-4.5, 2.0, -7.0), 1.0, &mat1); rt.addShape(&sphere1); Material mat2(Colour(1.0, 1.0, 1.0)); mat2.texture = new CubicMapTexture(Vector3(-1.5, 2.0, -7.0)); Sphere sphere2(Vector3(-1.5, 2.0, -7.0), 1.0, &mat2); rt.addShape(&sphere2); Material mat3(Colour(1.0, 1.0, 1.0)); mat3.texture = new CylinderMapTexture(Vector3(1.5, 2.0, -7.0)); Sphere sphere3(Vector3(1.5, 2.0, -7.0), 1.0, &mat3); rt.addShape(&sphere3); Material mat4(Colour(1.0, 1.0, 1.0)); mat4.texture = new SphereMapTexture(Vector3(4.5, 2.0, -7.0)); Sphere sphere4(Vector3(4.5, 2.0, -7.0), 1.0, &mat4); rt.addShape(&sphere4); // cubes Material mat5(Colour(1.0, 1.0, 1.0)); mat5.texture = new PlanarMapTexture(Vector3(-4.5, 0.0, -7.0)); Box cube1(Vector3(-4.5, 0.0, -7.0)-1.0, Vector3(-4.5, 0.0, -7.0)+1.0, &mat5); rt.addShape(&cube1); Material mat6(Colour(1.0, 1.0, 1.0)); mat6.texture = new CubicMapTexture(Vector3(-1.5, 0.0, -7.0)); Box cube2(Vector3(-1.5, 0.0, -7.0)-1.0, Vector3(-1.5, 0.0, -7.0)+1.0, &mat6); rt.addShape(&cube2); Material mat7(Colour(1.0, 1.0, 1.0)); mat7.texture = new CylinderMapTexture(Vector3(1.5, 0.0, -7.0)); Box cube3(Vector3(1.5, 0.0, -7.0)-1.0, Vector3(1.5, 0.0, -7.0)+1.0, &mat7); rt.addShape(&cube3); Material mat8(Colour(1.0, 1.0, 1.0)); mat8.texture = new SphereMapTexture(Vector3(4.5, 0.0, -7.0)); Box cube4(Vector3(4.5, 0.0, -7.0)-1.0, Vector3(4.5, 0.0, -7.0)+1.0, &mat8); rt.addShape(&cube4); mat1.setReflectivity(0); mat2.setReflectivity(0); mat3.setReflectivity(0); mat4.setReflectivity(0); mat5.setReflectivity(0); mat6.setReflectivity(0); mat7.setReflectivity(0); mat8.setReflectivity(0); top.optimize(); w = 1024; h = 600; /* run interactive mode */ loop_sdl(rt, cam, update_callback, key_callback); /* render image */ if (argc == 2 && !strcmp(argv[1], "-r")) { pyrit_verbosity = 2; Float *fdata = (Float *) malloc(w*h*3*sizeof(Float)); rt.ambientOcclusion(300, 5.0, 0.5); DefaultSampler sampler(fdata, w, h); sampler.setOversample(2); sampler.setSubsample(1); rt.setSampler(&sampler); rt.render(); struct image *img; new_image(&img, w, h, 3); Float *fd = fdata; for (unsigned char *cd = img->data; cd != img->data + w*h*3; cd++, fd++) { if (*fd > 1.0) *cd = 255; else *cd = (unsigned char)(*fd * 255.0); } free(fdata); save_png("textures.png", img); destroy_image(&img); }}