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 ¢er) 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 ¢er); 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_