# HG changeset patch # User Radek Brich # Date 1197119262 -3600 # Node ID 574c34441a1cb7c6d139887f5644e11ed2583cad # Parent ffe83ca074f3416af55c205d32f2a487a1f86ae8 new C++ demo: realtime_bunny obj/ply loading functions moved to *reader.py from Python demos diff -r ffe83ca074f3 -r 574c34441a1c .bzrignore --- a/.bzrignore Sat Dec 08 12:37:45 2007 +0100 +++ b/.bzrignore Sat Dec 08 14:07:42 2007 +0100 @@ -5,6 +5,7 @@ ccdemos/spheres_shadow ccdemos/realtime ccdemos/realtime_dragon +ccdemos/realtime_bunny models/bunny models/happy models/dragon diff -r ffe83ca074f3 -r 574c34441a1c ccdemos/Makefile --- a/ccdemos/Makefile Sat Dec 08 12:37:45 2007 +0100 +++ b/ccdemos/Makefile Sat Dec 08 14:07:42 2007 +0100 @@ -6,7 +6,7 @@ ### Targets ### -all: realtime realtime_dragon spheres_shadow +all: realtime realtime_dragon realtime_bunny spheres_shadow realtime: realtime.o libs-double $(CXX) -o $@ $(ROOT)/bin/libs-double/*.o $< $(LDFLAGS) $(SDL_LDFLAGS) @@ -14,6 +14,9 @@ realtime_dragon: realtime_dragon.o libs-double $(CXX) -o $@ $(ROOT)/bin/libs-double/*.o $< $(LDFLAGS) $(SDL_LDFLAGS) +realtime_bunny: realtime_bunny.o libs-double + $(CXX) -o $@ $(ROOT)/bin/libs-double/*.o $< $(LDFLAGS) $(SDL_LDFLAGS) + spheres_shadow: spheres_shadow.o image.o libs-float $(CXX) -o $@ $(ROOT)/bin/libs-float/*.o $< image.o $(LDFLAGS) -lpng @@ -29,6 +32,9 @@ realtime_dragon.o: realtime_dragon.cc $(CXX) -c -o $@ $(CCFLAGS) $(SDL_CCFLAGS) $< $(DEFS) -DPYRIT_DOUBLE +realtime_bunny.o: realtime_bunny.cc + $(CXX) -c -o $@ $(CCFLAGS) $(SDL_CCFLAGS) $< $(DEFS) -DPYRIT_DOUBLE + image.o: image.c $(CXX) -c -o $@ $*.c @@ -36,4 +42,4 @@ $(CXX) -c -o $@ $*.cc $(CCFLAGS) $(DEFS) clean: - rm -f spheres_shadow realtime realtime_dragon *.o + rm -f spheres_shadow realtime realtime_dragon realtime_bunny *.o diff -r ffe83ca074f3 -r 574c34441a1c ccdemos/realtime_bunny.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ccdemos/realtime_bunny.cc Sat Dec 08 14:07:42 2007 +0100 @@ -0,0 +1,243 @@ +#include + +#include "raytracer.h" +#include +#include +#include + +int w = 320; +int h = 200; +Float *render_buffer; + +Raytracer rt; +Camera cam; + +void load_ply(const char *filename, Material *mat, Float scale) +{ + vector vertices; + vector normals; + vector vertex_face_num; + ifstream f(filename); + string token = "a"; + if (!f.is_open()) + { + cout << "File not found: " << filename <> token; + cout << token << endl; + if (token == "element") + { + f >> token; + if (token == "vertex") + f >> vertex_num; + if (token == "face") + f >> face_num; + } + f.ignore(1000,'\n'); + } + + // read vertices + Vector3 P; + int num = vertex_num; + while (num--) + { + f >> P.x >> P.y >> P.z; + P.x = -scale*P.x - 1.0; + P.y = scale*P.y - 3.0; + P.z = scale*P.z; + vertices.push_back(new NormalVertex(P)); + normals.push_back(Vector3()); + vertex_face_num.push_back(0); + f.ignore(1000,'\n'); + } + + // read faces + Triangle *face; + int v1, v2, v3; + while (face_num--) + { + f >> num; + if (num != 3) + { + printf("ply error: faces of %d vertices not supported", num); + continue; + } + f >> v1 >> v2 >> v3; + face = new Triangle(vertices.at(v1), vertices.at(v3), vertices.at(v2), mat); + rt.addshape(face); + face->setSmooth(); + + normals.at(v1) += face->getNormal(); + vertex_face_num.at(v1)++; + normals.at(v2) += face->getNormal(); + vertex_face_num.at(v2)++; + normals.at(v3) += face->getNormal(); + vertex_face_num.at(v3)++; + f.ignore(1000,'\n'); + } + + for (int i; i < vertex_num; i++) + { + normals.at(i) /= vertex_face_num.at(i); + normals.at(i).normalize(); + vertices.at(i)->N = normals.at(i); + } + + f.close(); +} + +void update(SDL_Surface *screen) +{ + rt.render(w, h, render_buffer); + + if (SDL_MUSTLOCK(screen)) + if (SDL_LockSurface(screen) < 0) + return; + + Uint32 *bufp = (Uint32 *)screen->pixels; + unsigned char c[3]; + for (Float *fd = render_buffer; fd != render_buffer + w*h*3; fd += 3) + { + for (int i = 0; i < 3; i++) + { + if (fd[i] > 1.0) + c[i] = 255; + else + c[i] = (unsigned char)(fd[i] * 255.0); + } + *bufp = SDL_MapRGB(screen->format, c[0], c[1], c[2]); + bufp++; + } + + if (SDL_MUSTLOCK(screen)) + SDL_UnlockSurface(screen); + + if (screen->flags & SDL_DOUBLEBUF) + SDL_Flip(screen); + else + SDL_UpdateRect(screen, 0, 0, w, h); +} + +int main() +{ + /* initialize SDL */ + SDL_Surface *screen; + + if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + atexit(SDL_Quit); + + screen = SDL_SetVideoMode(w, h, 32, SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE); + if ( screen == NULL ) { + fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError()); + exit(1); + } + + /* initialize raytracer and prepare scene */ + render_buffer = (Float *) malloc(w*h*3*sizeof(Float)); + + rt.setThreads(1); + rt.setMaxDepth(3); + + KdTree top; + rt.setTop(&top); + + Light light1(Vector3(-5.0, 2.0, 8.0), Colour(0.9, 0.3, 0.6)); + light1.castShadows(false); + rt.addlight(&light1); + + //Light light2(Vector3(-2.0, 10.0, 2.0), Colour(0.4, 0.6, 0.3)); + //light2.castShadows(false); + //rt.addlight(&light2); + + Material mat(Colour(0.9, 0.9, 0.9)); + load_ply("../models/bunny/bun_zipper_res4.ply", &mat, 29); + + rt.setCamera(&cam); + cam.setEye(Vector3(0,0,10)); + + /* build kd-tree */ + top.setMaxDepth(100); + top.optimize(); + + /* loop... */ + SDL_Event event; + bool quit = false; + Float roty = 0.0, rotx = 0.0, move = 0.0; + while (!quit) + { + while (SDL_PollEvent(&event)) + { + switch (event.type) { + case SDL_VIDEORESIZE: + w = event.resize.w; + h = event.resize.h; + render_buffer = (Float *) realloc(render_buffer, w*h*3*sizeof(Float)); + screen = SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE); + break; + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_ESCAPE) { + quit = true; + break; + } + if (event.key.keysym.sym == SDLK_LEFT) { + roty = -0.01; + break; + } + if (event.key.keysym.sym == SDLK_RIGHT) { + roty = +0.01; + break; + } + if (event.key.keysym.sym == SDLK_DOWN) { + rotx = +0.01; + break; + } + if (event.key.keysym.sym == SDLK_UP) { + rotx = -0.01; + break; + } + if (event.key.keysym.sym == SDLK_w) { + move = +0.5; + break; + } + if (event.key.keysym.sym == SDLK_s) { + move = -0.5; + break; + } + break; + case SDL_KEYUP: + if (event.key.keysym.sym == SDLK_LEFT || event.key.keysym.sym == SDLK_RIGHT) { + roty = 0.0; + break; + } + if (event.key.keysym.sym == SDLK_UP || event.key.keysym.sym == SDLK_DOWN) { + rotx = 0.0; + break; + } + if (event.key.keysym.sym == SDLK_w || event.key.keysym.sym == SDLK_s) { + move = 0.0; + break; + } + break; + case SDL_QUIT: + quit = true; + } + } + cam.rotate(Quaternion(cos(roty),0,sin(roty),0).normalize()); + cam.rotate(Quaternion(cos(rotx),cam.u[0]*sin(rotx),0,cam.u[2]*sin(rotx)).normalize()); + cam.u.y = 0; + cam.u.normalize(); + cam.move(move,0,0); + update(screen); + } + + free(render_buffer); +} diff -r ffe83ca074f3 -r 574c34441a1c demos/buddha.py --- a/demos/buddha.py Sat Dec 08 12:37:45 2007 +0100 +++ b/demos/buddha.py Sat Dec 08 14:07:42 2007 +0100 @@ -7,42 +7,13 @@ sys.path.append(open('ModulePath').read().strip()) from raytracer import Raytracer, Light, Sphere, Triangle, Material +from plyreader import LoadStanfordPlyFile import Image -def LoadStanfordPlyFile(rt, mat, filename, scale): - vertices = [] - fp = file(filename) - # read header - tokens = (0,) - while (tokens[0] != "end_header"): - tokens = fp.readline().split() - if (tokens[0] == "element"): - if (tokens[1] == "vertex"): - vertex_num = int(tokens[2]) - if (tokens[1] == "face"): - face_num = int(tokens[2]) - - # read vertices - while (vertex_num): - tokens = fp.readline().split() - v = [scale*float(x) for x in tokens[0:3]] - v[1] = v[1]-3 - vertices.append(tuple(v)) - vertex_num -= 1 - - # read faces - while (face_num): - tokens = fp.readline().split() - if (tokens[0] != "3"): - print "ply warning: faces of %d vertices not supported" % tokens[0] - f = [vertices[int(x)] for x in tokens[1:4]] - face = Triangle(NormalVertex(f[0]), NormalVertex(f[1]), NormalVertex(f[2]), mat) - rt.addshape(face) - face_num -= 1 - rt = Raytracer() mat = Material(colour=(0.9, 0.9, 0.9)) -LoadStanfordPlyFile(rt, mat ,"../models/happy/happy_vrip_res2.ply", 20.0) +LoadStanfordPlyFile(rt, "../models/happy/happy_vrip_res2.ply", + mat, smooth=True, scale=20.0, trans=(-3,0,0)) light = Light(position=(-5.0, 2.0, 8.0), colour=(0.9, 0.3, 0.6)) rt.addlight(light) diff -r ffe83ca074f3 -r 574c34441a1c demos/bunny.py --- a/demos/bunny.py Sat Dec 08 12:37:45 2007 +0100 +++ b/demos/bunny.py Sat Dec 08 14:07:42 2007 +0100 @@ -7,63 +7,13 @@ sys.path.append(open('ModulePath').read().strip()) from raytracer import Raytracer, Light, Sphere, Triangle, NormalVertex, Material +from plyreader import LoadStanfordPlyFile import Image -def LoadStanfordPlyFile(rt, mat, filename, scale): - vertices = [] - normals = [] - vertex_face_num = [] - fp = file(filename) - # read header - tokens = (0,) - while (tokens[0] != "end_header"): - tokens = fp.readline().split() - if (tokens[0] == "element"): - if (tokens[1] == "vertex"): - vertex_num = int(tokens[2]) - if (tokens[1] == "face"): - face_num = int(tokens[2]) - - # read vertices - num = vertex_num - while (num): - tokens = fp.readline().split() - v = [scale*float(x) for x in tokens[0:3]] - v[0] = -v[0]-1 - v[1] = v[1]-3 - vertices.append(NormalVertex(tuple(v))) - normals.append([0.,0.,0.]) - vertex_face_num.append(0) - num -= 1 - - # read faces - while (face_num): - tokens = fp.readline().split() - if (tokens[0] != "3"): - print "ply warning: faces of %d vertices not supported" % tokens[0] - v = [vertices[int(x)] for x in tokens[1:4]] - face = Triangle(v[0], v[2], v[1], mat) - n = face.getNormal() - for x in tokens[1:4]: - for i in range(3): - normals[int(x)][i] += n[i] - vertex_face_num[int(x)] += 1 - face.setSmooth() - rt.addshape(face) - face_num -= 1 - - # interpolate normals at vertices - num = 0 - while (num < vertex_num): - if (vertex_face_num[num] > 0): - for i in range(3): - normals[num][i] /= vertex_face_num[num] - vertices[num].setNormal(tuple(normals[num])) - num += 1 - rt = Raytracer() mat = Material(colour=(0.9, 0.9, 0.9)) -LoadStanfordPlyFile(rt, mat, "../models/bunny/bun_zipper.ply", 29.0) +LoadStanfordPlyFile(rt, "../models/bunny/bun_zipper.ply", + mat, smooth=True, scale=(-29.0, 29.0, 29.0), trans=(-1,-3,-3)) light = Light(position=(-5.0, 2.0, 10.0), colour=(0.9, 0.3, 0.6)) rt.addlight(light) diff -r ffe83ca074f3 -r 574c34441a1c demos/dragon.py --- a/demos/dragon.py Sat Dec 08 12:37:45 2007 +0100 +++ b/demos/dragon.py Sat Dec 08 14:07:42 2007 +0100 @@ -7,44 +7,13 @@ sys.path.append(open('ModulePath').read().strip()) from raytracer import Raytracer, Light, Sphere, Triangle, Material +from plyreader import LoadStanfordPlyFile import Image -def LoadStanfordPlyFile(rt, mat, filename, scale): - vertices = [] - fp = file(filename) - # read header - tokens = (0,) - while (tokens[0] != "end_header"): - tokens = fp.readline().split() - if (tokens[0] == "element"): - if (tokens[1] == "vertex"): - vertex_num = int(tokens[2]) - if (tokens[1] == "face"): - face_num = int(tokens[2]) - - # read vertices - while (vertex_num): - tokens = fp.readline().split() - v = [scale*float(x) for x in tokens[0:3]] - v[0] = -v[0] - v[1] = v[1]-3.6 - v[2] = -v[2] - vertices.append(tuple(v)) - vertex_num -= 1 - - # read faces - while (face_num): - tokens = fp.readline().split() - if (tokens[0] != "3"): - print "ply warning: faces of %d vertices not supported" % tokens[0] - f = [vertices[int(x)] for x in tokens[1:4]] - face = Triangle(NormalVertex(f[0]), NormalVertex(f[1]), NormalVertex(f[2]), mat) - rt.addshape(face) - face_num -= 1 - rt = Raytracer() mat = Material(colour=(0.9, 0.9, 0.9)) -LoadStanfordPlyFile(rt, mat, "../models/dragon/dragon_vrip_res2.ply", 29.0) +LoadStanfordPlyFile(rt, "../models/dragon/dragon_vrip_res2.ply", + mat, smooth=True, scale=(-29.0, 29.0, -29.0), trans=(0.0, -3.6, 0.0)) light1 = Light(position=(-5.0, 2.0, 8.0), colour=(0.9, 0.3, 0.2)) rt.addlight(light1) diff -r ffe83ca074f3 -r 574c34441a1c demos/objreader.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/objreader.py Sat Dec 08 14:07:42 2007 +0100 @@ -0,0 +1,17 @@ +from raytracer import Triangle, NormalVertex + +def LoadWavefrontObjFile(rt, filename, mat, scale): + vertices = [] + fp = file(filename) + while True: + ln = fp.readline() + if ln == "": + break; + ln = ln.split() + if ln[0] == "v": + v = [scale*float(x) for x in ln[1:4]] + vertices.append(tuple(v)) + if ln[0] == "f": + f = [vertices[int(x)-1] for x in ln[1:4]] + face = Triangle(NormalVertex(f[0]), NormalVertex(f[1]), NormalVertex(f[2]), mat) + rt.addshape(face) diff -r ffe83ca074f3 -r 574c34441a1c demos/plyreader.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/plyreader.py Sat Dec 08 14:07:42 2007 +0100 @@ -0,0 +1,57 @@ +from raytracer import Triangle, NormalVertex + +def LoadStanfordPlyFile(rt, filename, mat, smooth, scale=(1,1,1), trans=(0,0,0)): + if (type(scale) == float or type(scale) == int): + scale = (scale,)*3 + vertices = [] + normals = [] + vertex_face_num = [] + fp = file(filename) + # read header + tokens = (0,) + while (tokens[0] != "end_header"): + tokens = fp.readline().split() + if (tokens[0] == "element"): + if (tokens[1] == "vertex"): + vertex_num = int(tokens[2]) + if (tokens[1] == "face"): + face_num = int(tokens[2]) + + # read vertices + num = vertex_num + while (num): + tokens = fp.readline().split() + v = [float(x) for x in tokens[0:3]] + v[0] = scale[0]*v[0] + trans[0] + v[1] = scale[1]*v[1] + trans[1] + v[2] = scale[2]*v[2] + trans[2] + vertices.append(NormalVertex(tuple(v))) + normals.append([0.,0.,0.]) + vertex_face_num.append(0) + num -= 1 + + # read faces + while (face_num): + tokens = fp.readline().split() + if (tokens[0] != "3"): + print "ply warning: faces of %d vertices not supported" % tokens[0] + v = [vertices[int(x)] for x in tokens[1:4]] + face = Triangle(v[0], v[2], v[1], mat) + n = face.getNormal() + for x in tokens[1:4]: + for i in range(3): + normals[int(x)][i] += n[i] + vertex_face_num[int(x)] += 1 + if (smooth): + face.setSmooth() + rt.addshape(face) + face_num -= 1 + + # interpolate normals at vertices + num = 0 + while (num < vertex_num): + if (vertex_face_num[num] > 0): + for i in range(3): + normals[num][i] /= vertex_face_num[num] + vertices[num].setNormal(tuple(normals[num])) + num += 1 diff -r ffe83ca074f3 -r 574c34441a1c demos/triangles_monkey.py --- a/demos/triangles_monkey.py Sat Dec 08 12:37:45 2007 +0100 +++ b/demos/triangles_monkey.py Sat Dec 08 14:07:42 2007 +0100 @@ -3,28 +3,13 @@ import sys sys.path.append(open('ModulePath').read().strip()) -from raytracer import Raytracer, Light, Sphere, Triangle, Material +from raytracer import Raytracer, Light, Sphere, Triangle, NormalVertex, Material +from objreader import LoadWavefrontObjFile import Image -def LoadWavefrontObjFile(rt, mat, filename): - vertices = [] - fp = file(filename) - while True: - ln = fp.readline() - if ln == "": - break; - ln = ln.split() - if ln[0] == "v": - v = [1.5*float(x) for x in ln[1:4]] - vertices.append(tuple(v)) - if ln[0] == "f": - f = [vertices[int(x)-1] for x in ln[1:4]] - face = Triangle(NormalVertex(f[0]), NormalVertex(f[1]), NormalVertex(f[2]), mat) - rt.addshape(face) - rt = Raytracer() mat = Material(colour=(0.9, 0.9, 0.9)) -LoadWavefrontObjFile(rt, mat, "monkey.obj") +LoadWavefrontObjFile(rt, "monkey.obj", mat, 1.5) light = Light(position=(-5.0, 2.0, 8.0), colour=(0.9, 0.3, 0.6)) rt.addlight(light) diff -r ffe83ca074f3 -r 574c34441a1c demos/triangles_sphere.py --- a/demos/triangles_sphere.py Sat Dec 08 12:37:45 2007 +0100 +++ b/demos/triangles_sphere.py Sat Dec 08 14:07:42 2007 +0100 @@ -4,27 +4,12 @@ sys.path.append(open('ModulePath').read().strip()) from raytracer import Raytracer, Light, Sphere, Triangle, NormalVertex, Material +from objreader import LoadWavefrontObjFile import Image -def LoadWavefrontObjFile(rt, mat, filename): - vertices = [] - fp = file(filename) - while True: - ln = fp.readline() - if ln == "": - break; - ln = ln.split() - if ln[0] == "v": - v = [1.5*float(x) for x in ln[1:4]] - vertices.append(tuple(v)) - if ln[0] == "f": - f = [vertices[int(x)-1] for x in ln[1:4]] - face = Triangle(NormalVertex(f[0]), NormalVertex(f[1]), NormalVertex(f[2]), mat) - rt.addshape(face) - rt = Raytracer() mat = Material(colour=(0.9, 0.9, 0.9)) -LoadWavefrontObjFile(rt, mat, "sphere.obj") +LoadWavefrontObjFile(rt, "sphere.obj", mat, 1.5) light1 = Light(position=(0.0, 2.0, 6.0), colour=(0.9, 0.3, 0.6)) light1.castshadows(False); diff -r ffe83ca074f3 -r 574c34441a1c src/kdtree.cc --- a/src/kdtree.cc Sat Dec 08 12:37:45 2007 +0100 +++ b/src/kdtree.cc Sat Dec 08 14:07:42 2007 +0100 @@ -183,7 +183,7 @@ return; } -#if 1 +#if 0 // export kd-tree as .obj for visualization // this would be hard to reconstruct later static ofstream F("kdtree.obj");