eqemu

changeset 4:3d3656360a82

rendering properly, added picking, almost done...
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 17 Jul 2014 08:51:17 +0300
parents f9274bebe55e
children 9b5bb05ae53a
files Makefile data/device.obj src/bvol.cc src/bvol.h src/main.cc src/material.cc src/mesh.cc src/mesh.h src/object.cc src/object.h src/objfile.cc src/scene.cc src/scene.h src/vmath.h
diffstat 14 files changed, 388 insertions(+), 21 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Thu Jul 17 02:35:19 2014 +0300
     1.2 +++ b/Makefile	Thu Jul 17 08:51:17 2014 +0300
     1.3 @@ -5,7 +5,7 @@
     1.4  
     1.5  CFLAGS = -pedantic -Wall -g
     1.6  CXXFLAGS = $(CFLAGS)
     1.7 -LDFLAGS = -lGL -lGLU -lglut -lGLEW -lX11 -lm -lpthread
     1.8 +LDFLAGS = -lGL -lGLU -lGLEW -lX11 -lm -lpthread
     1.9  
    1.10  $(bin): $(obj)
    1.11  	$(CXX) -o $@ $(obj) $(LDFLAGS)
     2.1 --- a/data/device.obj	Thu Jul 17 02:35:19 2014 +0300
     2.2 +++ b/data/device.obj	Thu Jul 17 08:51:17 2014 +0300
     2.3 @@ -1,7 +1,7 @@
     2.4  # 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
     2.5  # File Created: 14.07.2014 08:46:21
     2.6  
     2.7 -mtllib device.mtl
     2.8 +mtllib data/device.mtl
     2.9  
    2.10  #
    2.11  # object box
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/bvol.cc	Thu Jul 17 08:51:17 2014 +0300
     3.3 @@ -0,0 +1,62 @@
     3.4 +#include <math.h>
     3.5 +#include "bvol.h"
     3.6 +
     3.7 +BSphere::BSphere()
     3.8 +{
     3.9 +	radius = 1.0f;
    3.10 +}
    3.11 +
    3.12 +BSphere::BSphere(const Vector3 &c, float rad)
    3.13 +	: center(c)
    3.14 +{
    3.15 +	radius = rad;
    3.16 +}
    3.17 +
    3.18 +void BSphere::set_center(const Vector3 &center)
    3.19 +{
    3.20 +	this->center = center;
    3.21 +}
    3.22 +
    3.23 +const Vector3 &BSphere::get_center() const
    3.24 +{
    3.25 +	return center;
    3.26 +}
    3.27 +
    3.28 +void BSphere::set_radius(float rad)
    3.29 +{
    3.30 +	radius = rad;
    3.31 +}
    3.32 +
    3.33 +float BSphere::get_radius() const
    3.34 +{
    3.35 +	return radius;
    3.36 +}
    3.37 +
    3.38 +bool BSphere::intersect(const Ray &ray, HitPoint *hit) const
    3.39 +{
    3.40 +	float a = dot(ray.dir, ray.dir);
    3.41 +	float b = 2.0 * dot(ray.dir, ray.origin - center);
    3.42 +	float c = dot(ray.origin, ray.origin) + dot(center, center) -
    3.43 +		2.0 * dot(ray.origin, center) - radius * radius;
    3.44 +
    3.45 +	float disc = b * b - 4.0f * a * c;
    3.46 +	if(disc < 1e-6) {
    3.47 +		return false;
    3.48 +	}
    3.49 +
    3.50 +	float sqrt_disc = sqrt(disc);
    3.51 +	float x1 = (-b + sqrt_disc) / (2.0f * a);
    3.52 +	float x2 = (-b - sqrt_disc) / (2.0f * a);
    3.53 +
    3.54 +	if(x1 < 1e-6) x1 = x2;
    3.55 +	if(x2 < 1e-6) x2 = x1;
    3.56 +
    3.57 +	float t = x1 < x2 ? x1 : x2;
    3.58 +	if(t < 1e-6) {
    3.59 +		return false;
    3.60 +	}
    3.61 +
    3.62 +	hit->t = t;
    3.63 +	hit->pos = ray.origin + ray.dir * t;
    3.64 +	return true;
    3.65 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/bvol.h	Thu Jul 17 08:51:17 2014 +0300
     4.3 @@ -0,0 +1,36 @@
     4.4 +#ifndef BVOL_H_
     4.5 +#define BVOL_H_
     4.6 +
     4.7 +#include "vmath.h"
     4.8 +
     4.9 +struct HitPoint {
    4.10 +	float t;
    4.11 +	Vector3 pos;
    4.12 +};
    4.13 +
    4.14 +class BVolume {
    4.15 +public:
    4.16 +	virtual ~BVolume() {}
    4.17 +
    4.18 +	virtual bool intersect(const Ray &ray, HitPoint *hit) const = 0;
    4.19 +};
    4.20 +
    4.21 +class BSphere : public BVolume {
    4.22 +private:
    4.23 +	Vector3 center;
    4.24 +	float radius;
    4.25 +
    4.26 +public:
    4.27 +	BSphere();
    4.28 +	explicit BSphere(const Vector3 &c, float rad = 1.0);
    4.29 +
    4.30 +	void set_center(const Vector3 &center);
    4.31 +	const Vector3 &get_center() const;
    4.32 +
    4.33 +	void set_radius(float rad);
    4.34 +	float get_radius() const;
    4.35 +
    4.36 +	bool intersect(const Ray &ray, HitPoint *hit) const;
    4.37 +};
    4.38 +
    4.39 +#endif	// BVOL_H_
     5.1 --- a/src/main.cc	Thu Jul 17 02:35:19 2014 +0300
     5.2 +++ b/src/main.cc	Thu Jul 17 08:51:17 2014 +0300
     5.3 @@ -1,5 +1,6 @@
     5.4  #include <stdio.h>
     5.5  #include <stdlib.h>
     5.6 +#include <float.h>
     5.7  #include <assert.h>
     5.8  #include <errno.h>
     5.9  #include <unistd.h>
    5.10 @@ -8,6 +9,7 @@
    5.11  #include <X11/Xlib.h>
    5.12  #include <GL/glx.h>
    5.13  #include "dev.h"
    5.14 +#include "scene.h"
    5.15  
    5.16  static bool init();
    5.17  static void cleanup();
    5.18 @@ -15,6 +17,7 @@
    5.19  static void keyb(int key, bool pressed);
    5.20  static void mouse(int bn, bool pressed, int x, int y);
    5.21  static void motion(int x, int y);
    5.22 +static Ray calc_pick_ray(int x, int y);
    5.23  
    5.24  static Window create_window(const char *title, int xsz, int ysz);
    5.25  static void process_events();
    5.26 @@ -29,12 +32,19 @@
    5.27  
    5.28  static int win_width, win_height;
    5.29  
    5.30 -static bool redisplay_pending;
    5.31 +static bool draw_pending;
    5.32  static bool win_mapped;
    5.33  
    5.34  static int fakefd = -1;
    5.35  static char *fake_devpath;
    5.36  
    5.37 +static float cam_theta, cam_phi, cam_dist = 140;
    5.38 +static Scene *scn;
    5.39 +
    5.40 +enum { BN_TICKET, BN_NEXT, NUM_BUTTONS };
    5.41 +const char *button_names[] = { "button1", "button2" };
    5.42 +static Object *button_obj[NUM_BUTTONS];
    5.43 +
    5.44  int main(int argc, char **argv)
    5.45  {
    5.46  	if(proc_args(argc, argv) == -1) {
    5.47 @@ -47,6 +57,9 @@
    5.48  
    5.49  	int xfd = ConnectionNumber(dpy);
    5.50  
    5.51 +	// run once through pending events before going into the select loop
    5.52 +	process_events();
    5.53 +
    5.54  	for(;;) {
    5.55  		fd_set rd;
    5.56  		FD_ZERO(&rd);
    5.57 @@ -54,9 +67,9 @@
    5.58  		FD_SET(xfd, &rd);
    5.59  		FD_SET(fakefd, &rd);
    5.60  
    5.61 +		struct timeval noblock = {0, 0};
    5.62  		int maxfd = xfd > fakefd ? xfd : fakefd;
    5.63 -
    5.64 -		while(select(maxfd + 1, &rd, 0, 0, 0) == -1 && errno == EINTR);
    5.65 +		while(select(maxfd + 1, &rd, 0, 0, draw_pending ? &noblock : 0) == -1 && errno == EINTR);
    5.66  
    5.67  		if(FD_ISSET(xfd, &rd)) {
    5.68  			process_events();
    5.69 @@ -65,9 +78,9 @@
    5.70  			proc_dev_input();
    5.71  		}
    5.72  
    5.73 -		if(redisplay_pending) {
    5.74 +		if(draw_pending) {
    5.75  			display();
    5.76 -			redisplay_pending = false;
    5.77 +			draw_pending = false;
    5.78  		}
    5.79  	}
    5.80  	return 0;
    5.81 @@ -86,15 +99,42 @@
    5.82  		return false;
    5.83  	}
    5.84  
    5.85 -	if(!(win = create_window("dummy equeue device", 800, 600))) {
    5.86 +	if(!(win = create_window("equeue device emulator", 800, 600))) {
    5.87  		return false;
    5.88  	}
    5.89  
    5.90 +	glewInit();
    5.91 +
    5.92 +	scn = new Scene;
    5.93 +	if(!scn->load("data/device.obj")) {
    5.94 +		fprintf(stderr, "failed to load device 3D model\n");
    5.95 +		return false;
    5.96 +	}
    5.97 +
    5.98 +	for(int i=0; i<NUM_BUTTONS; i++) {
    5.99 +		button_obj[i] = scn->get_object(button_names[i]);
   5.100 +		if(!button_obj[i]) {
   5.101 +			fprintf(stderr, "invalid 3D model\n");
   5.102 +			return false;
   5.103 +		}
   5.104 +		BSphere &bs = button_obj[i]->get_mesh()->get_bounds();
   5.105 +		bs.set_radius(bs.get_radius() * 1.5);
   5.106 +	}
   5.107 +
   5.108 +	glEnable(GL_DEPTH_TEST);
   5.109 +	glEnable(GL_CULL_FACE);
   5.110 +	glEnable(GL_LIGHTING);
   5.111 +	glEnable(GL_LIGHT0);
   5.112 +
   5.113 +	glClearColor(0.1, 0.1, 0.1, 1);
   5.114 +
   5.115  	return true;
   5.116  }
   5.117  
   5.118  static void cleanup()
   5.119  {
   5.120 +	delete scn;
   5.121 +
   5.122  	stop_dev();
   5.123  
   5.124  	if(!dpy) return;
   5.125 @@ -111,6 +151,14 @@
   5.126  
   5.127  	glMatrixMode(GL_MODELVIEW);
   5.128  	glLoadIdentity();
   5.129 +	glTranslatef(0, 0, -cam_dist);
   5.130 +	glRotatef(cam_phi, 1, 0, 0);
   5.131 +	glRotatef(cam_theta, 0, 1, 0);
   5.132 +
   5.133 +	float lpos[] = {-7, 5, 10, 0};
   5.134 +	glLightfv(GL_LIGHT0, GL_POSITION, lpos);
   5.135 +
   5.136 +	scn->render();
   5.137  
   5.138  	glXSwapBuffers(dpy, win);
   5.139  	assert(glGetError() == GL_NO_ERROR);
   5.140 @@ -122,7 +170,10 @@
   5.141  
   5.142  	glMatrixMode(GL_PROJECTION);
   5.143  	glLoadIdentity();
   5.144 -	gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
   5.145 +	gluPerspective(50.0, (float)x / (float)y, 1.0, 1000.0);
   5.146 +
   5.147 +	win_width = x;
   5.148 +	win_height = y;
   5.149  }
   5.150  
   5.151  static void keyb(int key, bool pressed)
   5.152 @@ -135,12 +186,87 @@
   5.153  	}
   5.154  }
   5.155  
   5.156 +static bool bnstate[32];
   5.157 +static int prev_x, prev_y;
   5.158 +
   5.159  static void mouse(int bn, bool pressed, int x, int y)
   5.160  {
   5.161 +	bnstate[bn] = pressed;
   5.162 +	prev_x = x;
   5.163 +	prev_y = y;
   5.164 +
   5.165 +	if(bn == 0 && pressed) {
   5.166 +		// do picking
   5.167 +		Ray ray = calc_pick_ray(x, win_height - y);
   5.168 +
   5.169 +		HitPoint minhit;
   5.170 +		minhit.t = FLT_MAX;
   5.171 +		int hit_found = -1;
   5.172 +
   5.173 +		for(int i=0; i<NUM_BUTTONS; i++) {
   5.174 +			HitPoint hit;
   5.175 +			if(button_obj[i]->get_mesh()->get_bounds().intersect(ray, &hit) && hit.t < minhit.t) {
   5.176 +				minhit = hit;
   5.177 +				hit_found = i;
   5.178 +			}
   5.179 +		}
   5.180 +
   5.181 +		if(hit_found != -1) {
   5.182 +			switch(hit_found) {
   5.183 +			case BN_TICKET:
   5.184 +				issue_ticket();
   5.185 +				printf("issue ticket\n");
   5.186 +				break;
   5.187 +
   5.188 +			case BN_NEXT:
   5.189 +				next_customer();
   5.190 +				printf("next customer\n");
   5.191 +				break;
   5.192 +			}
   5.193 +			draw_pending = true;
   5.194 +		}
   5.195 +	}
   5.196  }
   5.197  
   5.198  static void motion(int x, int y)
   5.199  {
   5.200 +	int dx = x - prev_x;
   5.201 +	int dy = y - prev_y;
   5.202 +	prev_x = x;
   5.203 +	prev_y = y;
   5.204 +
   5.205 +	if(bnstate[0]) {
   5.206 +		cam_theta += dx * 0.5;
   5.207 +		cam_phi += dy * 0.5;
   5.208 +		if(cam_phi < -90) cam_phi = -90;
   5.209 +		if(cam_phi > 90) cam_phi = 90;
   5.210 +		draw_pending = true;
   5.211 +	}
   5.212 +	if(bnstate[2]) {
   5.213 +		cam_dist += dy * 0.5;
   5.214 +		if(cam_dist < 0.0) cam_dist = 0.0;
   5.215 +		draw_pending = true;
   5.216 +	}
   5.217 +}
   5.218 +
   5.219 +static Ray calc_pick_ray(int x, int y)
   5.220 +{
   5.221 +	double mv[16], proj[16];
   5.222 +	int vp[4];
   5.223 +	double resx, resy, resz;
   5.224 +	Ray ray;
   5.225 +
   5.226 +	glGetDoublev(GL_MODELVIEW_MATRIX, mv);
   5.227 +	glGetDoublev(GL_PROJECTION_MATRIX, proj);
   5.228 +	glGetIntegerv(GL_VIEWPORT, vp);
   5.229 +
   5.230 +	gluUnProject(x, y, 0, mv, proj, vp, &resx, &resy, &resz);
   5.231 +	ray.origin = Vector3(resx, resy, resz);
   5.232 +
   5.233 +	gluUnProject(x, y, 1, mv, proj, vp, &resx, &resy, &resz);
   5.234 +	ray.dir = normalize(Vector3(resx, resy, resz) - ray.origin);
   5.235 +
   5.236 +	return ray;
   5.237  }
   5.238  
   5.239  static Window create_window(const char *title, int xsz, int ysz)
   5.240 @@ -231,7 +357,7 @@
   5.241  
   5.242  		case Expose:
   5.243  			if(win_mapped && ev.xexpose.count == 0) {
   5.244 -				redisplay_pending = 1;
   5.245 +				draw_pending = 1;
   5.246  			}
   5.247  			break;
   5.248  
     6.1 --- a/src/material.cc	Thu Jul 17 02:35:19 2014 +0300
     6.2 +++ b/src/material.cc	Thu Jul 17 08:51:17 2014 +0300
     6.3 @@ -2,7 +2,7 @@
     6.4  #include "material.h"
     6.5  
     6.6  Material::Material()
     6.7 -	: color(1, 1, 1), specular(0, 0, 0)
     6.8 +	: diffuse(1, 1, 1), specular(0, 0, 0)
     6.9  {
    6.10  	shininess = 1.0;
    6.11  	alpha = 1.0;
    6.12 @@ -10,7 +10,7 @@
    6.13  
    6.14  void Material::setup() const
    6.15  {
    6.16 -	float col[] = {color.x, color.y, color.z, alpha};
    6.17 +	float col[] = {diffuse.x, diffuse.y, diffuse.z, alpha};
    6.18  	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
    6.19  
    6.20  	float spec[] = {specular.x, specular.y, specular.z, 1.0};
     7.1 --- a/src/mesh.cc	Thu Jul 17 02:35:19 2014 +0300
     7.2 +++ b/src/mesh.cc	Thu Jul 17 08:51:17 2014 +0300
     7.3 @@ -1,5 +1,6 @@
     7.4  #include <stdio.h>
     7.5  #include <string.h>
     7.6 +#include <math.h>
     7.7  #include <GL/glew.h>
     7.8  #include "mesh.h"
     7.9  
    7.10 @@ -8,8 +9,9 @@
    7.11  Mesh::Mesh()
    7.12  {
    7.13  	buf_valid = ALL_VALID;
    7.14 +	bsph_valid = false;
    7.15  
    7.16 -	for(int i=0; i<vcount; i++) {
    7.17 +	for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
    7.18  		attr[i] = 0;
    7.19  		attr_size[i] = 0;
    7.20  		buf_valid &= ~(1 << i);
    7.21 @@ -20,7 +22,7 @@
    7.22  
    7.23  Mesh::~Mesh()
    7.24  {
    7.25 -	for(int i=0; i<vcount; i++) {
    7.26 +	for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
    7.27  		delete [] attr[i];
    7.28  	}
    7.29  	glDeleteBuffers(NUM_MESH_ATTRIBS, vbo);
    7.30 @@ -28,18 +30,26 @@
    7.31  
    7.32  float *Mesh::set_attrib(int aidx, int count, int elemsz, float *data)
    7.33  {
    7.34 -	if(attr[aidx]) {
    7.35 -		delete [] attr[aidx];
    7.36 -	}
    7.37 +	delete [] attr[aidx];
    7.38  	attr[aidx] = new float[count * elemsz];
    7.39 +	memcpy(attr[aidx], data, count * elemsz * sizeof *data);
    7.40 +	vcount = count;
    7.41  	attr_size[aidx] = elemsz;
    7.42  	buf_valid &= ~(1 << aidx);
    7.43 +
    7.44 +	if(aidx == MESH_ATTR_VERTEX) {
    7.45 +		bsph_valid = false;
    7.46 +	}
    7.47 +
    7.48  	return attr[aidx];
    7.49  }
    7.50  
    7.51  float *Mesh::get_attrib(int aidx)
    7.52  {
    7.53  	buf_valid &= ~(1 << aidx);
    7.54 +	if(aidx == MESH_ATTR_VERTEX) {
    7.55 +		bsph_valid = false;
    7.56 +	}
    7.57  	return attr[aidx];
    7.58  }
    7.59  
    7.60 @@ -50,6 +60,8 @@
    7.61  
    7.62  void Mesh::draw() const
    7.63  {
    7.64 +	if(!vcount) return;
    7.65 +
    7.66  	update_buffers();
    7.67  
    7.68  	if(!vbo[MESH_ATTR_VERTEX]) {
    7.69 @@ -84,6 +96,18 @@
    7.70  	}
    7.71  }
    7.72  
    7.73 +BSphere &Mesh::get_bounds()
    7.74 +{
    7.75 +	calc_bsph();
    7.76 +	return bsph;
    7.77 +}
    7.78 +
    7.79 +const BSphere &Mesh::get_bounds() const
    7.80 +{
    7.81 +	calc_bsph();
    7.82 +	return bsph;
    7.83 +}
    7.84 +
    7.85  void Mesh::update_buffers() const
    7.86  {
    7.87  	if(buf_valid == ALL_VALID) {
    7.88 @@ -99,3 +123,34 @@
    7.89  		}
    7.90  	}
    7.91  }
    7.92 +
    7.93 +void Mesh::calc_bsph() const
    7.94 +{
    7.95 +	if(bsph_valid || !vcount) {
    7.96 +		return;
    7.97 +	}
    7.98 +
    7.99 +	Vector3 center;
   7.100 +
   7.101 +	float *vptr = attr[MESH_ATTR_VERTEX];
   7.102 +	for(int i=0; i<vcount; i++) {
   7.103 +		center = center + Vector3(vptr[0], vptr[1], vptr[2]);
   7.104 +		vptr += 3;
   7.105 +	}
   7.106 +	center = center * (1.0f / (float)vcount);
   7.107 +
   7.108 +	float max_lensq = 0.0f;
   7.109 +	vptr = attr[MESH_ATTR_VERTEX];
   7.110 +	for(int i=0; i<vcount; i++) {
   7.111 +		Vector3 v = Vector3(vptr[0], vptr[1], vptr[2]) - center;
   7.112 +		float lensq = dot(v, v);
   7.113 +		if(lensq > max_lensq) {
   7.114 +			max_lensq = lensq;
   7.115 +		}
   7.116 +	}
   7.117 +
   7.118 +	bsph.set_center(center);
   7.119 +	bsph.set_radius(sqrt(max_lensq));
   7.120 +
   7.121 +	bsph_valid = true;
   7.122 +}
     8.1 --- a/src/mesh.h	Thu Jul 17 02:35:19 2014 +0300
     8.2 +++ b/src/mesh.h	Thu Jul 17 08:51:17 2014 +0300
     8.3 @@ -1,6 +1,8 @@
     8.4  #ifndef MESH_H_
     8.5  #define MESH_H_
     8.6  
     8.7 +#include "bvol.h"
     8.8 +
     8.9  enum {
    8.10  	MESH_ATTR_VERTEX,
    8.11  	MESH_ATTR_NORMAL,
    8.12 @@ -19,6 +21,10 @@
    8.13  	mutable unsigned int buf_valid;	/* bitmask */
    8.14  	void update_buffers() const;
    8.15  
    8.16 +	mutable BSphere bsph;
    8.17 +	mutable bool bsph_valid;
    8.18 +	void calc_bsph() const;
    8.19 +
    8.20  public:
    8.21  	Mesh();
    8.22  	~Mesh();
    8.23 @@ -28,6 +34,9 @@
    8.24  	const float *get_attrib(int aidx) const;
    8.25  
    8.26  	void draw() const;
    8.27 +
    8.28 +	BSphere &get_bounds();
    8.29 +	const BSphere &get_bounds() const;
    8.30  };
    8.31  
    8.32  #endif	// MESH_H_
     9.1 --- a/src/object.cc	Thu Jul 17 02:35:19 2014 +0300
     9.2 +++ b/src/object.cc	Thu Jul 17 08:51:17 2014 +0300
     9.3 @@ -5,6 +5,16 @@
     9.4  	mesh = 0;
     9.5  }
     9.6  
     9.7 +void Object::set_name(const char *name)
     9.8 +{
     9.9 +	this->name = std::string(name);
    9.10 +}
    9.11 +
    9.12 +const char *Object::get_name() const
    9.13 +{
    9.14 +	return name.c_str();
    9.15 +}
    9.16 +
    9.17  void Object::set_mesh(Mesh *mesh)
    9.18  {
    9.19  	this->mesh = mesh;
    10.1 --- a/src/object.h	Thu Jul 17 02:35:19 2014 +0300
    10.2 +++ b/src/object.h	Thu Jul 17 08:51:17 2014 +0300
    10.3 @@ -1,11 +1,13 @@
    10.4  #ifndef OBJECT_H_
    10.5  #define OBJECT_H_
    10.6  
    10.7 +#include <string>
    10.8  #include "mesh.h"
    10.9  #include "material.h"
   10.10  
   10.11  class Object {
   10.12  private:
   10.13 +	std::string name;
   10.14  	Mesh *mesh;
   10.15  
   10.16  public:
   10.17 @@ -13,6 +15,9 @@
   10.18  
   10.19  	Object();
   10.20  
   10.21 +	void set_name(const char *name);
   10.22 +	const char *get_name() const;
   10.23 +
   10.24  	void set_mesh(Mesh *mesh);
   10.25  	Mesh *get_mesh() const;
   10.26  
    11.1 --- a/src/objfile.cc	Thu Jul 17 02:35:19 2014 +0300
    11.2 +++ b/src/objfile.cc	Thu Jul 17 08:51:17 2014 +0300
    11.3 @@ -2,6 +2,7 @@
    11.4  #include <string.h>
    11.5  #include <ctype.h>
    11.6  #include <limits.h>
    11.7 +#include <assert.h>
    11.8  #include <vector>
    11.9  #include <map>
   11.10  #include <string>
   11.11 @@ -284,6 +285,9 @@
   11.12  
   11.13  	int nelem = obj->f.size() * 3;
   11.14  
   11.15 +	assert(sizeof(Vector3) == 3 * sizeof(float));
   11.16 +	assert(sizeof(Vector2) == 2 * sizeof(float));
   11.17 +
   11.18  	try {
   11.19  		robj = new Object;
   11.20  		varr = new Vector3[nelem];
   11.21 @@ -293,15 +297,15 @@
   11.22  	catch(...) {
   11.23  		return 0;
   11.24  	}
   11.25 -	/*if(obj->cur_obj.length() > 0) {
   11.26 +	if(obj->cur_obj.length() > 0) {
   11.27  		robj->set_name(obj->cur_obj.c_str());
   11.28 -	}*/
   11.29 +	}
   11.30  
   11.31  	// need at least one of each element
   11.32  	bool added_norm = false, added_tc = false;
   11.33  	if(obj->vn.empty()) {
   11.34  		obj->vn.push_back(Vector3(0, 0, 0));
   11.35 -		added_norm = true;;
   11.36 +		added_norm = true;
   11.37  	}
   11.38  	if(obj->vt.empty()) {
   11.39  		obj->vt.push_back(Vector2(0, 0));
   11.40 @@ -329,10 +333,13 @@
   11.41  		obj->vt.pop_back();
   11.42  	}
   11.43  
   11.44 -	Mesh *mesh = robj->get_mesh();
   11.45 +	Mesh *mesh = new Mesh;
   11.46  	mesh->set_attrib(MESH_ATTR_VERTEX, nelem, 3, &varr->x);
   11.47  	mesh->set_attrib(MESH_ATTR_NORMAL, nelem, 3, &narr->x);
   11.48  	mesh->set_attrib(MESH_ATTR_TEXCOORD, nelem, 2, &tarr->x);
   11.49 +	robj->set_mesh(mesh);
   11.50 +
   11.51 +	printf("loaded object %s: %d faces\n", obj->cur_obj.c_str(), nelem / 3);
   11.52  
   11.53  	delete [] varr;
   11.54  	delete [] narr;
    12.1 --- a/src/scene.cc	Thu Jul 17 02:35:19 2014 +0300
    12.2 +++ b/src/scene.cc	Thu Jul 17 08:51:17 2014 +0300
    12.3 @@ -1,5 +1,6 @@
    12.4  #include <stdio.h>
    12.5  #include <stdlib.h>
    12.6 +#include <string.h>
    12.7  #include "scene.h"
    12.8  
    12.9  Scene::~Scene()
   12.10 @@ -50,6 +51,16 @@
   12.11  	return objects[idx];
   12.12  }
   12.13  
   12.14 +Object *Scene::get_object(const char *name) const
   12.15 +{
   12.16 +	for(size_t i=0; i<objects.size(); i++) {
   12.17 +		if(strcmp(objects[i]->get_name(), name) == 0) {
   12.18 +			return objects[i];
   12.19 +		}
   12.20 +	}
   12.21 +	return 0;
   12.22 +}
   12.23 +
   12.24  Mesh *Scene::get_mesh(int idx) const
   12.25  {
   12.26  	return meshes[idx];
    13.1 --- a/src/scene.h	Thu Jul 17 02:35:19 2014 +0300
    13.2 +++ b/src/scene.h	Thu Jul 17 08:51:17 2014 +0300
    13.3 @@ -27,6 +27,8 @@
    13.4  	Object *get_object(int idx) const;
    13.5  	Mesh *get_mesh(int idx) const;
    13.6  
    13.7 +	Object *get_object(const char *name) const;
    13.8 +
    13.9  	void update(long msec);
   13.10  	void render() const;
   13.11  };
    14.1 --- a/src/vmath.h	Thu Jul 17 02:35:19 2014 +0300
    14.2 +++ b/src/vmath.h	Thu Jul 17 08:51:17 2014 +0300
    14.3 @@ -1,6 +1,8 @@
    14.4  #ifndef VMATH_H_
    14.5  #define VMATH_H_
    14.6  
    14.7 +#include <math.h>
    14.8 +
    14.9  class Vector2 {
   14.10  public:
   14.11  	float x, y;
   14.12 @@ -23,6 +25,40 @@
   14.13  	const float &operator [](int idx) const { return (&x)[idx]; }
   14.14  };
   14.15  
   14.16 +inline Vector3 operator +(const Vector3 &a, const Vector3 &b)
   14.17 +{
   14.18 +	return Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
   14.19 +}
   14.20 +
   14.21 +inline Vector3 operator -(const Vector3 &a, const Vector3 &b)
   14.22 +{
   14.23 +	return Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
   14.24 +}
   14.25 +
   14.26 +inline Vector3 operator *(const Vector3 &a, float s)
   14.27 +{
   14.28 +	return Vector3(a.x * s, a.y * s, a.z * s);
   14.29 +}
   14.30 +
   14.31 +inline float dot(const Vector3 &a, const Vector3 &b)
   14.32 +{
   14.33 +	return a.x * b.x + a.y * b.y + a.z * b.z;
   14.34 +}
   14.35 +
   14.36 +inline float length(const Vector3 &v)
   14.37 +{
   14.38 +	return sqrt(dot(v, v));
   14.39 +}
   14.40 +
   14.41 +inline Vector3 normalize(const Vector3 &v)
   14.42 +{
   14.43 +	float len = length(v);
   14.44 +	if(len == 0.0) {
   14.45 +		return v;
   14.46 +	}
   14.47 +	return Vector3(v.x / len, v.y / len, v.z / len);
   14.48 +}
   14.49 +
   14.50  class Vector4 {
   14.51  public:
   14.52  	float x, y, z, w;
   14.53 @@ -34,4 +70,12 @@
   14.54  	const float &operator [](int idx) const {  return (&x)[idx]; }
   14.55  };
   14.56  
   14.57 +class Ray {
   14.58 +public:
   14.59 +	Vector3 origin, dir;
   14.60 +
   14.61 +	Ray() : origin(0, 0, 0), dir(0, 0, 1) {}
   14.62 +	Ray(const Vector3 &o, const Vector3 &d) : origin(o), dir(d) {}
   14.63 +};
   14.64 +
   14.65  #endif	// VMATH_H_