new C++ demo: realtime_dragon.cc pyrit
authorRadek Brich <radek.brich@devl.cz>
Wed, 05 Dec 2007 18:54:23 +0100
branchpyrit
changeset 24 d0d76e8a5203
parent 23 7e258561a690
child 25 b8232edee786
new C++ demo: realtime_dragon.cc class Container moved to its own source file (from kdtree.*) new directory for models and Makefile which downloads and prepares them fixed python module path in some forgotten demos ShapeList moved to scene.h
.bzrignore
Makefile
ccdemos/Makefile
ccdemos/realtime_dragon.cc
demos/Makefile
demos/buddha.py
demos/demo.py
demos/dragon.py
include/container.h
include/kdtree.h
include/scene.h
models/Makefile
src/Makefile
src/container.cc
src/kdtree.cc
src/scene.cc
--- a/.bzrignore	Tue Dec 04 08:58:05 2007 +0100
+++ b/.bzrignore	Wed Dec 05 18:54:23 2007 +0100
@@ -1,8 +1,11 @@
 demos/ModulePath
 demos/*.png
 demos/kdtree.obj
-demos/*.ply
 ccdemos/*.png
 ccdemos/spheres_shadow
 ccdemos/realtime
-bin/*
\ No newline at end of file
+ccdemos/realtime_dragon
+models/bunny
+models/happy
+models/dragon
+bin/*
--- a/Makefile	Tue Dec 04 08:58:05 2007 +0100
+++ b/Makefile	Wed Dec 05 18:54:23 2007 +0100
@@ -1,17 +1,20 @@
 ROOT=$(shell pwd)
 include config.mk
 
-all: python-module demos ccdemos
+all: python-module demos ccdemos models
 
 python-module: libs-float
 	$(MAKE) -C src python-module
 
-demos: python-module
+demos: python-module models
 	$(MAKE) -C demos
 
-ccdemos: libs-float libs-double
+ccdemos: libs-float libs-double models
 	$(MAKE) -C ccdemos
 
+models:
+	$(MAKE) -C models
+
 libs-float:
 	$(MAKE) -C src libs-float
 
--- a/ccdemos/Makefile	Tue Dec 04 08:58:05 2007 +0100
+++ b/ccdemos/Makefile	Wed Dec 05 18:54:23 2007 +0100
@@ -6,11 +6,14 @@
 
 
 ### Targets ###
-all: realtime spheres_shadow
+all: realtime realtime_dragon spheres_shadow
 
 realtime: realtime.o libs-double
 	$(CXX) -o $@ $(ROOT)/bin/libs-double/*.o $< $(LDFLAGS) $(SDL_LDFLAGS)
 
+realtime_dragon: realtime_dragon.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
 
@@ -23,6 +26,9 @@
 realtime.o: realtime.cc
 	$(CXX) -c -o $@ $(CCFLAGS) $(SDL_CCFLAGS) $< $(DEFS) -DPYRIT_DOUBLE
 
+realtime_dragon.o: realtime_dragon.cc
+	$(CXX) -c -o $@ $(CCFLAGS) $(SDL_CCFLAGS) $< $(DEFS) -DPYRIT_DOUBLE
+
 image.o: image.c
 	$(CXX) -c -o $@ $*.c
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ccdemos/realtime_dragon.cc	Wed Dec 05 18:54:23 2007 +0100
@@ -0,0 +1,218 @@
+#include <SDL.h>
+
+#include "raytracer.h"
+#include <iostream>
+#include <fstream>
+
+int w = 320;
+int h = 200;
+Float *render_buffer;
+
+Raytracer rt;
+Camera cam;
+
+void load_ply(const char *filename, Material *mat, Float scale)
+{
+	vector<Vector3> vertices;
+	ifstream f(filename);
+	string token = "a";
+	if (!f.is_open())
+	{
+		cout << "File not found: " << filename <<endl;
+		exit(1);
+	}
+	// read header
+	int vertex_num, face_num;
+	while (token != "end_header")
+	{
+		f >> token;
+		if (token == "element")
+		{
+			f >> token;
+			if (token == "vertex")
+				f >> vertex_num;
+			if (token == "face")
+				f >> face_num;
+		}
+	}
+
+	// read vertices
+	Vector3 v;
+	while (vertex_num--)
+	{
+		f >> v.x >> v.y >> v.z;
+		v.x = -scale*v.x;
+		v.y = scale*v.y - 3.6;
+		v.z = -scale*v.z;
+		vertices.push_back(v);
+	}
+
+	// read faces
+	Triangle *face;
+	int num, v1, v2, v3;
+	while (face_num--)
+	{
+		f >> num;
+		if (num != 3)
+		{
+			printf("ply error: faces of %d vertices not supported", num);
+			return;
+		}
+		f >> v1 >> v2 >> v3;
+		face = new Triangle(vertices.at(v1), vertices.at(v2), vertices.at(v3), mat);
+		rt.addshape(face);
+	}
+
+	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(2);
+	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/dragon/dragon_vrip_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);
+}
--- a/demos/Makefile	Tue Dec 04 08:58:05 2007 +0100
+++ b/demos/Makefile	Wed Dec 05 18:54:23 2007 +0100
@@ -11,6 +11,7 @@
 reqs:
 	$(MAKE) -C .. libs-float python-module
 
-models: ;
+models:
+	$(MAKE) -C .. models
 
 clean: ;
--- a/demos/buddha.py	Tue Dec 04 08:58:05 2007 +0100
+++ b/demos/buddha.py	Wed Dec 05 18:54:23 2007 +0100
@@ -4,7 +4,7 @@
 # http://graphics.stanford.edu/data/3Dscanrep/
 
 import sys
-sys.path.append("..")
+sys.path.append(open('ModulePath').read().strip())
 
 from raytracer import Raytracer, Light, Sphere, Triangle, Material
 import Image
@@ -42,7 +42,7 @@
 
 rt = Raytracer()
 mat = Material(colour=(0.9, 0.9, 0.9))
-LoadStanfordPlyFile(rt, mat ,"happy_vrip_res2.ply", 20.0)
+LoadStanfordPlyFile(rt, mat ,"../models/happy/happy_vrip_res2.ply", 20.0)
 
 light = Light(position=(-5.0, 2.0, 8.0), colour=(0.9, 0.3, 0.6))
 rt.addlight(light)
--- a/demos/demo.py	Tue Dec 04 08:58:05 2007 +0100
+++ b/demos/demo.py	Wed Dec 05 18:54:23 2007 +0100
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 
 import sys
-sys.path.append("..")
+sys.path.append(open('ModulePath').read().strip())
 
 from raytracer import Raytracer, Material, Box, Sphere, Light
 #, SphericalLight
--- a/demos/dragon.py	Tue Dec 04 08:58:05 2007 +0100
+++ b/demos/dragon.py	Wed Dec 05 18:54:23 2007 +0100
@@ -4,7 +4,7 @@
 # http://graphics.stanford.edu/data/3Dscanrep/
 
 import sys
-sys.path.append("..")
+sys.path.append(open('ModulePath').read().strip())
 
 from raytracer import Raytracer, Light, Sphere, Triangle, Material
 import Image
@@ -44,7 +44,7 @@
 
 rt = Raytracer()
 mat = Material(colour=(0.9, 0.9, 0.9))
-LoadStanfordPlyFile(rt, mat, "dragon_vrip.ply", 29.0)
+LoadStanfordPlyFile(rt, mat, "../models/dragon/dragon_vrip_res4.ply", 29.0)
 
 light = Light(position=(-5.0, 2.0, 8.0), colour=(0.9, 0.3, 0.6))
 rt.addlight(light)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/container.h	Wed Dec 05 18:54:23 2007 +0100
@@ -0,0 +1,25 @@
+#ifndef CONTAINER_H
+#define CONTAINER_H
+
+#include <vector>
+
+#include "scene.h"
+
+using namespace std;
+
+class Container
+{
+protected:
+	BBox bbox;
+public:
+	ShapeList shapes;
+	Container(): bbox(), shapes() {};
+	virtual ~Container() {};
+	virtual void addShape(Shape* aShape);
+	//void addShapeNoExtend(Shape* aShape) { shapes.push_back(aShape); };
+	virtual Shape *nearest_intersection(const Shape *origin_shape, const Ray &ray,
+		Float &nearest_distance);
+	virtual void optimize() {};
+};
+
+#endif
--- a/include/kdtree.h	Tue Dec 04 08:58:05 2007 +0100
+++ b/include/kdtree.h	Wed Dec 05 18:54:23 2007 +0100
@@ -1,33 +1,15 @@
 #ifndef KDTREE_H
 #define KDTREE_H
 
-#include <vector>
 #include <iostream>
 #include <fstream>
 
+#include "container.h"
+#include "vector.h"
 #include "scene.h"
 
 using namespace std;
 
-class ShapeList: public vector<Shape*>
-{
-};
-
-class Container
-{
-protected:
-	BBox bbox;
-public:
-	ShapeList shapes;
-	Container(): bbox(), shapes() {};
-	virtual ~Container() {};
-	virtual void addShape(Shape* aShape);
-	//void addShapeNoExtend(Shape* aShape) { shapes.push_back(aShape); };
-	virtual Shape *nearest_intersection(const Shape *origin_shape, const Ray &ray,
-		Float &nearest_distance);
-	virtual void optimize() {};
-};
-
 class KdNode
 {
 	Float split;
--- a/include/scene.h	Tue Dec 04 08:58:05 2007 +0100
+++ b/include/scene.h	Wed Dec 05 18:54:23 2007 +0100
@@ -151,6 +151,10 @@
 	virtual BBox get_bbox() = 0;
 };
 
+class ShapeList: public vector<Shape*>
+{
+};
+
 class Sphere: public Shape
 {
 	Float sqr_radius;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/models/Makefile	Wed Dec 05 18:54:23 2007 +0100
@@ -0,0 +1,35 @@
+ifndef $(ROOT)
+    ROOT=$(shell pwd)/..
+endif
+    
+
+all: models
+
+models: bunny happy dragon
+
+bunny:
+	wget ftp://graphics.stanford.edu/pub/3Dscanrep/bunny.tar.gz
+	tar xzf bunny.tar.gz
+	rm bunny.tar.gz
+	rm -rf bunny/data
+	mv bunny/reconstruction/* bunny
+	rmdir bunny/reconstruction
+
+happy:
+	wget ftp://graphics.stanford.edu/pub/3Dscanrep/happy/happy_recon.tar.gz
+	tar xzf happy_recon.tar.gz
+	rm happy_recon.tar.gz
+	mv happy_recon happy
+
+dragon:
+	wget ftp://graphics.stanford.edu/pub/3Dscanrep/dragon/dragon_recon.tar.gz
+	tar xzf dragon_recon.tar.gz
+	rm dragon_recon.tar.gz
+	mv dragon_recon dragon
+
+clean: ;
+
+distclean:
+	rm -rf bunny
+	rm -rf happy
+	rm -rf dragon
--- a/src/Makefile	Tue Dec 04 08:58:05 2007 +0100
+++ b/src/Makefile	Wed Dec 05 18:54:23 2007 +0100
@@ -6,7 +6,7 @@
 
 vpath %.cc $(ROOT)/src
 vpath %.h $(ROOT)/include
-LIBOBJS=raytracer.o scene.o noise.o kdtree.o
+LIBOBJS=raytracer.o scene.o noise.o container.o kdtree.o
 CCFLAGS+=-I$(ROOT)/include
 
 ### Targets ###
@@ -43,6 +43,7 @@
 matrix.o: matrix.cc matrix.h vector.h common.h
 noise.o: noise.cc noise.h common.h
 scene.o: scene.cc scene.h vector.h noise.h common.h
+container.o: container.cc container.h scene.h common.h
 kdtree.o: kdtree.cc kdtree.h scene.h common.h
 raytracer.o: raytracer.cc raytracer.h scene.h vector.h noise.h common.h
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/container.cc	Wed Dec 05 18:54:23 2007 +0100
@@ -0,0 +1,31 @@
+#include "common.h"
+#include "container.h"
+
+void Container::addShape(Shape* aShape)
+{
+        shapes.push_back(aShape);
+        if (shapes.size() == 0) {
+                /* initialize bounding box */
+                bbox = aShape->get_bbox();
+        } else {
+                /* adjust bounding box */
+                BBox shapebb = aShape->get_bbox();
+                if (shapebb.L.x < bbox.L.x)  bbox.L.x = shapebb.L.x;
+                if (shapebb.L.y < bbox.L.y)  bbox.L.y = shapebb.L.y;
+                if (shapebb.L.z < bbox.L.z)  bbox.L.z = shapebb.L.z;
+                if (shapebb.H.x > bbox.H.x)  bbox.H.x = shapebb.H.x;
+                if (shapebb.H.y > bbox.H.y)  bbox.H.y = shapebb.H.y;
+                if (shapebb.H.z > bbox.H.z)  bbox.H.z = shapebb.H.z;
+        }
+};
+
+Shape *Container::nearest_intersection(const Shape *origin_shape, const Ray &ray,
+        Float &nearest_distance)
+{
+        Shape *nearest_shape = NULL;
+        ShapeList::iterator shape;
+        for (shape = shapes.begin(); shape != shapes.end(); shape++)
+                if (*shape != origin_shape && (*shape)->intersect(ray, nearest_distance))
+                        nearest_shape = *shape;
+        return nearest_shape;
+}
--- a/src/kdtree.cc	Tue Dec 04 08:58:05 2007 +0100
+++ b/src/kdtree.cc	Wed Dec 05 18:54:23 2007 +0100
@@ -62,35 +62,6 @@
 
 // ----------------------------------------
 
-void Container::addShape(Shape* aShape)
-{
-	shapes.push_back(aShape);
-	if (shapes.size() == 0) {
-		/* initialize bounding box */
-		bbox = aShape->get_bbox();
-	} else {
-		/* adjust bounding box */
-		BBox shapebb = aShape->get_bbox();
-		if (shapebb.L.x < bbox.L.x)  bbox.L.x = shapebb.L.x;
-		if (shapebb.L.y < bbox.L.y)  bbox.L.y = shapebb.L.y;
-		if (shapebb.L.z < bbox.L.z)  bbox.L.z = shapebb.L.z;
-		if (shapebb.H.x > bbox.H.x)  bbox.H.x = shapebb.H.x;
-		if (shapebb.H.y > bbox.H.y)  bbox.H.y = shapebb.H.y;
-		if (shapebb.H.z > bbox.H.z)  bbox.H.z = shapebb.H.z;
-	}
-};
-
-Shape *Container::nearest_intersection(const Shape *origin_shape, const Ray &ray,
-	Float &nearest_distance)
-{
-	Shape *nearest_shape = NULL;
-	ShapeList::iterator shape;
-	for (shape = shapes.begin(); shape != shapes.end(); shape++)
-		if (*shape != origin_shape && (*shape)->intersect(ray, nearest_distance))
-			nearest_shape = *shape;
-	return nearest_shape;
-}
-
 KdNode::~KdNode()
 {
 	if (isLeaf())
--- a/src/scene.cc	Tue Dec 04 08:58:05 2007 +0100
+++ b/src/scene.cc	Wed Dec 05 18:54:23 2007 +0100
@@ -246,7 +246,7 @@
 	const Float lnd = 1.0f / (D[k] + nu * D[ku] + nv * D[kv]);
 	const Float t = (nd - O[k] - nu * O[ku] - nv * O[kv]) * lnd;
 
-	if (!(t < dist && t > 0))
+	if (t < 0 || t >= dist)
 		return false;
 
 	Float hu = O[ku] + t * D[ku] - A[ku];