rayzor

changeset 12:d94a69933a71

lots of stuff, can't remember
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 12 Apr 2014 23:28:24 +0300
parents fe94d9e986ae
children 964f8ea5f095
files GNUmakefile Makefile src/camera.cc src/camera.h src/dosemu/dosemu.c src/keyb.c src/keyb.h src/light.cc src/light.h src/m3drast.c src/main.cc src/modeller.cc src/object.cc src/object.h src/scancode.h src/scene.cc src/scene.h src/stl/vector.h src/vmath.cc src/vmath.h src/vmathmat.h
diffstat 21 files changed, 517 insertions(+), 108 deletions(-) [+]
line diff
     1.1 --- a/GNUmakefile	Thu Apr 10 08:42:33 2014 +0300
     1.2 +++ b/GNUmakefile	Sat Apr 12 23:28:24 2014 +0300
     1.3 @@ -1,7 +1,7 @@
     1.4  baseobj = src/main.o src/logger.o src/screen.o src/scrman.o
     1.5  modelobj = src/modeller.o src/min3d.o src/m3drast.o src/lines.o
     1.6  rendobj = src/renderer.o src/vmath.o
     1.7 -scnobj = src/scene.o src/object.o
     1.8 +scnobj = src/scene.o src/object.o src/xfnode.o
     1.9  sysobj = src/dosemu/dosemu.o
    1.10  obj = $(baseobj) $(modelobj) $(rendobj) $(scnobj) $(sysobj)
    1.11  dep = $(obj:.o=.d)
     2.1 --- a/Makefile	Thu Apr 10 08:42:33 2014 +0300
     2.2 +++ b/Makefile	Sat Apr 12 23:28:24 2014 +0300
     2.3 @@ -1,7 +1,7 @@
     2.4  baseobj = main.obj logger.obj screen.obj scrman.obj swapbuf.obj
     2.5  modelobj = modeller.obj min3d.obj m3drast.obj lines.obj
     2.6  rendobj = renderer.obj vmath.obj
     2.7 -scnobj = scene.obj object.obj
     2.8 +scnobj = scene.obj object.obj xfnode.obj
     2.9  sysobj = gfx.obj vbe.obj dpmi.obj timer.obj mouse.obj keyb.obj
    2.10  obj = $(baseobj) $(modelobj) $(rendobj) $(scnobj) $(sysobj)
    2.11  bin = rayzor.exe
     3.1 --- a/src/camera.cc	Thu Apr 10 08:42:33 2014 +0300
     3.2 +++ b/src/camera.cc	Sat Apr 12 23:28:24 2014 +0300
     3.3 @@ -1,29 +1,20 @@
     3.4  #include "camera.h"
     3.5  
     3.6  Camera::Camera()
     3.7 -	: pos(0, 0, 10)
     3.8  {
     3.9 +	type = NODE_CAMERA;
    3.10  	fov = M_PI;
    3.11 -}
    3.12 -
    3.13 -void Camera::set_position(const Vector3 &pos)
    3.14 -{
    3.15 -	this->pos = pos;
    3.16 -}
    3.17 -
    3.18 -const Vector3 &Camera::get_position() const
    3.19 -{
    3.20 -	return pos;
    3.21 +	set_position(Vector3(0, 0, 10));
    3.22  }
    3.23  
    3.24  void Camera::set_target(const Vector3 &target)
    3.25  {
    3.26 -	this->target = target;
    3.27 +	this->target->set_position(target);
    3.28  }
    3.29  
    3.30  const Vector3 &Camera::get_target() const
    3.31  {
    3.32 -	return target;
    3.33 +	return target->get_position();
    3.34  }
    3.35  
    3.36  void Camera::set_fov(float fov)
    3.37 @@ -36,15 +27,23 @@
    3.38  	return fov;
    3.39  }
    3.40  
    3.41 -Matrix4x4 Camera::get_matrix() const
    3.42 +void Camera::calc_matrix() const
    3.43  {
    3.44 -	Matrix4x4 res;
    3.45 -	res.lookat(pos, target, Vector3(0, 1, 0));
    3.46 -	return res;
    3.47 +	xform.set_identity();
    3.48 +	xform.lookat(pos, target, Vector3(0, 1, 0));
    3.49 +	xform_valid = true;
    3.50  }
    3.51  
    3.52 -Matrix4x4 Camera::get_inv_matrix() const
    3.53 +void Camera::calc_inv_matrix() const
    3.54  {
    3.55 -	Matrix4x4 res;
    3.56 -	return res;	// TODO
    3.57 +	// TODO
    3.58  }
    3.59 +
    3.60 +void Camera::draw() const
    3.61 +{
    3.62 +}
    3.63 +
    3.64 +bool Camera::intersect(const Ray &ray, float *dist)
    3.65 +{
    3.66 +	return false;
    3.67 +}
     4.1 --- a/src/camera.h	Thu Apr 10 08:42:33 2014 +0300
     4.2 +++ b/src/camera.h	Sat Apr 12 23:28:24 2014 +0300
     4.3 @@ -2,27 +2,28 @@
     4.4  #define CAMERA_H_
     4.5  
     4.6  #include "vmath.h"
     4.7 +#include "xfnode.h"
     4.8  
     4.9 -class Camera {
    4.10 +class Camera : public SceneNode {
    4.11  private:
    4.12 -	Vector3 pos;
    4.13 -	Vector3 target;
    4.14 +	SceneNode target;
    4.15  	float fov;
    4.16  
    4.17 +	void calc_matrix() const;
    4.18 +	void calc_inv_matrix() const;
    4.19 +
    4.20  public:
    4.21  	Camera();
    4.22  
    4.23 -	void set_position(const Vector3 &pos);
    4.24 -	const Vector3 &get_position() const;
    4.25 -
    4.26  	void set_target(const Vector3 &target);
    4.27  	const Vector3 &get_target() const;
    4.28  
    4.29  	void set_fov(float fov);
    4.30  	float get_fov() const;
    4.31  
    4.32 -	Matrix4x4 get_matrix() const;
    4.33 -	Matrix4x4 get_inv_matrix() const;
    4.34 +	void draw() const;
    4.35 +
    4.36 +	bool intersect(const Ray &ray, float *dist = 0) const;
    4.37  };
    4.38  
    4.39  #endif	// CAMERA_H_
     5.1 --- a/src/dosemu/dosemu.c	Thu Apr 10 08:42:33 2014 +0300
     5.2 +++ b/src/dosemu/dosemu.c	Sat Apr 12 23:28:24 2014 +0300
     5.3 @@ -12,6 +12,8 @@
     5.4  
     5.5  static void cleanup(void);
     5.6  static void proc_events(void);
     5.7 +static int translate_sdlkey(int sym);
     5.8 +static void update_modkeys(void);
     5.9  static void capture_frame(unsigned char *frame);
    5.10  
    5.11  static void init_sdl(void)
    5.12 @@ -314,11 +316,51 @@
    5.13  }
    5.14  
    5.15  /* ----- improved event handling (keyb.h) ---- */
    5.16 +static char sdlkey_tbl[SDLK_LAST];
    5.17  
    5.18  int kb_init(int bufsz)
    5.19  {
    5.20 +	int i;
    5.21  	init_sdl();
    5.22  
    5.23 +	/* construct the SDL key translation table */
    5.24 +	for(i=0; i<256; i++) {
    5.25 +		sdlkey_tbl[i] = i;	/* start from an identity mapping for the first 256 */
    5.26 +	}
    5.27 +	/* then change the special keys */
    5.28 +	sdlkey_tbl[SDLK_LALT] = KB_LALT;
    5.29 +	sdlkey_tbl[SDLK_RALT] = KB_RALT;
    5.30 +	sdlkey_tbl[SDLK_LCTRL] = KB_LCTRL;
    5.31 +	sdlkey_tbl[SDLK_RCTRL] = KB_RCTRL;
    5.32 +	sdlkey_tbl[SDLK_LSHIFT] = KB_LSHIFT;
    5.33 +	for(i=0; i<12; i++) {
    5.34 +		sdlkey_tbl[SDLK_F1 + i] = KB_F1 + i;
    5.35 +	}
    5.36 +	sdlkey_tbl[SDLK_CAPSLOCK] = KB_CAPSLK;
    5.37 +	sdlkey_tbl[SDLK_NUMLOCK] = KB_NUMLK;
    5.38 +	sdlkey_tbl[SDLK_SCROLLOCK] = KB_SCRLK;
    5.39 +	sdlkey_tbl[SDLK_SYSREQ] = KB_SYSRQ;
    5.40 +	sdlkey_tbl[SDLK_ESCAPE] = KB_ESC;
    5.41 +	sdlkey_tbl[SDLK_INSERT] = KB_INSERT;
    5.42 +	sdlkey_tbl[SDLK_DELETE] = KB_DEL;
    5.43 +	sdlkey_tbl[SDLK_HOME] = KB_HOME;
    5.44 +	sdlkey_tbl[SDLK_END] = KB_END;
    5.45 +	sdlkey_tbl[SDLK_PAGEUP] = KB_PGUP;
    5.46 +	sdlkey_tbl[SDLK_PAGEDOWN] = KB_PGDN;
    5.47 +	sdlkey_tbl[SDLK_LEFT] = KB_LEFT;
    5.48 +	sdlkey_tbl[SDLK_RIGHT] = KB_RIGHT;
    5.49 +	sdlkey_tbl[SDLK_UP] = KB_UP;
    5.50 +	sdlkey_tbl[SDLK_DOWN] = KB_DOWN;
    5.51 +	sdlkey_tbl[SDLK_KP_PERIOD] = KB_NUM_DOT;
    5.52 +	sdlkey_tbl[SDLK_KP_ENTER] = KB_NUM_ENTER;
    5.53 +	sdlkey_tbl[SDLK_KP_PLUS] = KB_NUM_PLUS;
    5.54 +	sdlkey_tbl[SDLK_KP_MINUS] = KB_NUM_MINUS;
    5.55 +	sdlkey_tbl[SDLK_KP_MULTIPLY] = KB_NUM_MUL;
    5.56 +	sdlkey_tbl[SDLK_KP_DIVIDE] = KB_NUM_DIV;
    5.57 +	/* TODO missing numeric keypad numbers */
    5.58 +	sdlkey_tbl[SDLK_BACKSPACE] = KB_BACKSP;
    5.59 +
    5.60 +
    5.61  	return 0;
    5.62  }
    5.63  
    5.64 @@ -332,7 +374,7 @@
    5.65  
    5.66  	proc_events();
    5.67  	if(keybev) {
    5.68 -		res = keybev->key.keysym.sym;
    5.69 +		res = translate_sdlkey(keybev->key.keysym.sym);
    5.70  		keybev = 0;
    5.71  	}
    5.72  	return res;
    5.73 @@ -340,8 +382,15 @@
    5.74  
    5.75  int kb_isdown(int key)
    5.76  {
    5.77 -	if(key == KB_ANY) {
    5.78 +	switch(key) {
    5.79 +	case KB_ANY:
    5.80  		return num_pressed;
    5.81 +
    5.82 +	case KB_ALT:
    5.83 +		return keystate[KB_LALT] + keystate[KB_RALT];
    5.84 +
    5.85 +	case KB_CTRL:
    5.86 +		return keystate[KB_LCTRL] + keystate[KB_RCTRL];
    5.87  	}
    5.88  	return keystate[key];
    5.89  }
    5.90 @@ -388,7 +437,7 @@
    5.91  		switch(ev.type) {
    5.92  		case SDL_KEYDOWN:
    5.93  			{
    5.94 -				int key = ev.key.keysym.sym;
    5.95 +				int key = translate_sdlkey(ev.key.keysym.sym);
    5.96  
    5.97  				if(!keybev) {
    5.98  					keybev = &ev;
    5.99 @@ -398,12 +447,14 @@
   5.100  					keystate[key] = 1;
   5.101  					num_pressed++;
   5.102  				}
   5.103 +
   5.104 +				update_modkeys();
   5.105  			}
   5.106  			break;
   5.107  
   5.108  		case SDL_KEYUP:
   5.109  			{
   5.110 -				int key = ev.key.keysym.sym;
   5.111 +				int key = translate_sdlkey(ev.key.keysym.sym);
   5.112  
   5.113  				if(keystate[key]) {
   5.114  					keystate[key] = 0;
   5.115 @@ -411,6 +462,8 @@
   5.116  						num_pressed = 0;
   5.117  					}
   5.118  				}
   5.119 +
   5.120 +				update_modkeys();
   5.121  			}
   5.122  			break;
   5.123  
   5.124 @@ -453,6 +506,26 @@
   5.125  	}
   5.126  }
   5.127  
   5.128 +static int translate_sdlkey(int sym)
   5.129 +{
   5.130 +	if(sym >= 0 && sym < 256) {
   5.131 +		return sdlkey_tbl[sym];
   5.132 +	}
   5.133 +	return sym;
   5.134 +}
   5.135 +
   5.136 +static void update_modkeys(void)
   5.137 +{
   5.138 +	unsigned int mod = SDL_GetModState();
   5.139 +
   5.140 +	keystate[KB_LALT] = mod & KMOD_LALT;
   5.141 +	keystate[KB_RALT] = mod & KMOD_RALT;
   5.142 +	keystate[KB_LCTRL] = mod & KMOD_LCTRL;
   5.143 +	keystate[KB_RCTRL] = mod & KMOD_RCTRL;
   5.144 +	keystate[KB_LSHIFT] = mod & KMOD_LSHIFT;
   5.145 +	keystate[KB_RSHIFT] = mod & KMOD_RSHIFT;
   5.146 +}
   5.147 +
   5.148  /* ---- timer.c implementation ---- */
   5.149  static Uint32 start_time;
   5.150  
     6.1 --- a/src/keyb.c	Thu Apr 10 08:42:33 2014 +0300
     6.2 +++ b/src/keyb.c	Sat Apr 12 23:28:24 2014 +0300
     6.3 @@ -90,10 +90,17 @@
     6.4  
     6.5  int kb_isdown(int key)
     6.6  {
     6.7 -	if(key == KB_ANY) {
     6.8 +	switch(key) {
     6.9 +	case KB_ANY:
    6.10  		return num_pressed;
    6.11 +
    6.12 +	case KB_ALT:
    6.13 +		return keystate[KB_LALT] + keystate[KB_RALT];
    6.14 +
    6.15 +	case KB_CTRL:
    6.16 +		return keystate[KB_LCTRL] + keystate[KB_RCTRL];
    6.17  	}
    6.18 -	return (int)keystate[key];
    6.19 +	return keystate[key];
    6.20  }
    6.21  
    6.22  void kb_wait(void)
     7.1 --- a/src/keyb.h	Thu Apr 10 08:42:33 2014 +0300
     7.2 +++ b/src/keyb.h	Sat Apr 12 23:28:24 2014 +0300
     7.3 @@ -18,7 +18,28 @@
     7.4  #ifndef KEYB_H_
     7.5  #define KEYB_H_
     7.6  
     7.7 -#define KB_ANY	(-1)
     7.8 +#define KB_ANY		(-1)
     7.9 +#define KB_ALT		(-2)
    7.10 +#define KB_CTRL		(-3)
    7.11 +#define KB_SHIFT	(-4)
    7.12 +
    7.13 +/* special keys */
    7.14 +enum {
    7.15 +	KB_LALT, KB_RALT,
    7.16 +	KB_LCTRL, KB_RCTRL,
    7.17 +	KB_LSHIFT, KB_RSHIFT,
    7.18 +	KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6,
    7.19 +	KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12,
    7.20 +	KB_CAPSLK, KB_NUMLK, KB_SCRLK, KB_SYSRQ,
    7.21 +	KB_ESC = 27,
    7.22 +	KB_INSERT, KB_DEL, KB_HOME, KB_END, KB_PGUP, KB_PGDN,
    7.23 +	KB_LEFT, KB_RIGHT, KB_UP, KB_DOWN,
    7.24 +	KB_NUM_DOT, KB_NUM_ENTER, KB_NUM_PLUS, KB_NUM_MINUS, KB_NUM_MUL, KB_NUM_DIV,
    7.25 +	KB_NUM_0, KB_NUM_1, KB_NUM_2, KB_NUM_3, KB_NUM_4,
    7.26 +	KB_NUM_5, KB_NUM_6, KB_NUM_7, KB_NUM_8, KB_NUM_9,
    7.27 +	KB_BACKSP = 127
    7.28 +};
    7.29 +
    7.30  
    7.31  #ifdef __cplusplus
    7.32  extern "C" {
     8.1 --- a/src/light.cc	Thu Apr 10 08:42:33 2014 +0300
     8.2 +++ b/src/light.cc	Sat Apr 12 23:28:24 2014 +0300
     8.3 @@ -2,23 +2,13 @@
     8.4  
     8.5  Light::Light()
     8.6  {
     8.7 +	type = NODE_LIGHT;
     8.8  	color.x = color.y = color.z = 1.0;
     8.9  	atten.x = 1.0;
    8.10  	atten.y = 0.0;
    8.11  	atten.z = 0.0;
    8.12  }
    8.13  
    8.14 -void Light::set_position(const Vector3 &pos)
    8.15 -{
    8.16 -	this->pos = pos;
    8.17 -}
    8.18 -
    8.19 -const Vector3 &Light::get_position() const
    8.20 -{
    8.21 -	return pos;
    8.22 -}
    8.23 -
    8.24 -
    8.25  void Light::set_color(const Vector3 &color)
    8.26  {
    8.27  	this->color = color;
    8.28 @@ -39,3 +29,12 @@
    8.29  {
    8.30  	return atten;
    8.31  }
    8.32 +
    8.33 +void Light::draw() const
    8.34 +{
    8.35 +}
    8.36 +
    8.37 +bool Light::intersect(const Ray &ray, float *dist)
    8.38 +{
    8.39 +	return false;
    8.40 +}
     9.1 --- a/src/light.h	Thu Apr 10 08:42:33 2014 +0300
     9.2 +++ b/src/light.h	Sat Apr 12 23:28:24 2014 +0300
     9.3 @@ -2,24 +2,25 @@
     9.4  #define LIGHT_H_
     9.5  
     9.6  #include "vmath.h"
     9.7 +#include "xfnode.h"
     9.8  
     9.9 -class Light {
    9.10 +class Light : public SceneNode {
    9.11  private:
    9.12 -	Vector3 pos;
    9.13  	Vector3 color;
    9.14  	Vector3 atten;
    9.15  
    9.16  public:
    9.17  	Light();
    9.18  
    9.19 -	void set_position(const Vector3 &pos);
    9.20 -	const Vector3 &get_position() const;
    9.21 -
    9.22  	void set_color(const Vector3 &color);
    9.23  	const Vector3 &get_color() const;
    9.24  
    9.25  	void set_attenuation(const Vector3 &atten);
    9.26  	const Vector3 &get_attenuation() const;
    9.27 +
    9.28 +	void draw() const;
    9.29 +
    9.30 +	bool intersect(const Ray &ray, float *dist);
    9.31  };
    9.32  
    9.33  #endif	// LIGHT_H_
    10.1 --- a/src/m3drast.c	Thu Apr 10 08:42:33 2014 +0300
    10.2 +++ b/src/m3drast.c	Sat Apr 12 23:28:24 2014 +0300
    10.3 @@ -43,7 +43,7 @@
    10.4  			crossz += a[0] * b[1] - a[1] * b[0];
    10.5  		}
    10.6  
    10.7 -		if(crossz < 0) return;
    10.8 +		if(crossz > 0) return;
    10.9  	}
   10.10  
   10.11  	last[0] = v[numv - 1];
    11.1 --- a/src/main.cc	Thu Apr 10 08:42:33 2014 +0300
    11.2 +++ b/src/main.cc	Sat Apr 12 23:28:24 2014 +0300
    11.3 @@ -140,7 +140,11 @@
    11.4  	scene = new Scene;
    11.5  
    11.6  	Sphere *sph = new Sphere;
    11.7 -	scene->add_object(sph);
    11.8 +	scene->add(sph);
    11.9 +
   11.10 +	Box *box = new Box;
   11.11 +	scene->add(box);
   11.12 +	box->set_scaling(Vector3(2, 0.25, 2));
   11.13  
   11.14  	Modeller *modeller = new Modeller;
   11.15  	if(!modeller->init()) {
   11.16 @@ -288,6 +292,13 @@
   11.17  			use_asm_swap = !use_asm_swap;
   11.18  			break;
   11.19  
   11.20 +		case 'q':
   11.21 +		case 'x':
   11.22 +			if(kb_isdown(KB_ALT)) {
   11.23 +				quit_app();
   11.24 +			}
   11.25 +			break;
   11.26 +
   11.27  		default:
   11.28  			break;
   11.29  		}
    12.1 --- a/src/modeller.cc	Thu Apr 10 08:42:33 2014 +0300
    12.2 +++ b/src/modeller.cc	Sat Apr 12 23:28:24 2014 +0300
    12.3 @@ -1,9 +1,11 @@
    12.4 +#include <stdio.h>
    12.5  #include <string.h>
    12.6  #include <assert.h>
    12.7  #include "modeller.h"
    12.8  #include "min3d.h"
    12.9  #include "rayzor.h"
   12.10  #include "scene.h"
   12.11 +#include "keyb.h"
   12.12  
   12.13  struct ModellerImpl {
   12.14  	int mx, my;
   12.15 @@ -112,8 +114,25 @@
   12.16  {
   12.17  	if(press) {
   12.18  		switch(key) {
   12.19 +		case 'q':
   12.20 +			quit_app();
   12.21 +			break;
   12.22 +
   12.23  		case 27:
   12.24 -			quit_app();
   12.25 +			scene->clear_selection();
   12.26 +			break;
   12.27 +
   12.28 +		case '\t':
   12.29 +			{
   12.30 +				int s = scene->get_selection();
   12.31 +				if(s >= 0) {
   12.32 +					s = (s + 1) % scene->get_node_count();
   12.33 +					scene->clear_selection();
   12.34 +				} else {
   12.35 +					s = 0;
   12.36 +				}
   12.37 +				scene->select(s);
   12.38 +			}
   12.39  			break;
   12.40  
   12.41  		default:
   12.42 @@ -136,15 +155,17 @@
   12.43  	mod->prev_x = x;
   12.44  	mod->prev_y = y;
   12.45  
   12.46 -	if(mod->bnstate[0]) {
   12.47 -		mod->cam_theta += dx * 0.5;
   12.48 -		mod->cam_phi += dy * 0.5;
   12.49 +	if(kb_isdown(KB_ALT) || kb_isdown(KB_CTRL)) {
   12.50 +		if(mod->bnstate[0]) {
   12.51 +			mod->cam_theta += dx * 0.5;
   12.52 +			mod->cam_phi += dy * 0.5;
   12.53  
   12.54 -		if(mod->cam_phi < -90) mod->cam_phi = -90;
   12.55 -		if(mod->cam_phi > 90) mod->cam_phi = 90;
   12.56 -	}
   12.57 -	if(mod->bnstate[1]) {
   12.58 -		mod->cam_dist += dy * 0.1;
   12.59 -		if(mod->cam_dist < 0) mod->cam_dist = 0;
   12.60 +			if(mod->cam_phi < -90) mod->cam_phi = -90;
   12.61 +			if(mod->cam_phi > 90) mod->cam_phi = 90;
   12.62 +		}
   12.63 +		if(mod->bnstate[1]) {
   12.64 +			mod->cam_dist += dy * 0.1;
   12.65 +			if(mod->cam_dist < 0) mod->cam_dist = 0;
   12.66 +		}
   12.67  	}
   12.68  }
    13.1 --- a/src/object.cc	Thu Apr 10 08:42:33 2014 +0300
    13.2 +++ b/src/object.cc	Sat Apr 12 23:28:24 2014 +0300
    13.3 @@ -5,12 +5,25 @@
    13.4  
    13.5  Object::Object()
    13.6  {
    13.7 +	type = NODE_OBJECT;
    13.8  }
    13.9  
   13.10  Object::~Object()
   13.11  {
   13.12  }
   13.13  
   13.14 +void Object::pre_draw() const
   13.15 +{
   13.16 +	m3d_matrix_mode(M3D_MODELVIEW);
   13.17 +	m3d_push_matrix();
   13.18 +	m3d_mult_matrix(get_matrix()[0]);
   13.19 +}
   13.20 +
   13.21 +void Object::post_draw() const
   13.22 +{
   13.23 +	m3d_pop_matrix();
   13.24 +}
   13.25 +
   13.26  // ---- sphere ----
   13.27  Sphere::Sphere()
   13.28  {
   13.29 @@ -45,7 +58,7 @@
   13.30  				float theta = u * M_PI * 2.0;
   13.31  
   13.32  				float x = sin(theta) * sin(phi);
   13.33 -				float y = cos(phi);
   13.34 +				float y = -cos(phi);
   13.35  				float z = cos(theta) * sin(phi);
   13.36  
   13.37  				*vptr++ = Vector3(x, y, z);
   13.38 @@ -71,9 +84,70 @@
   13.39  		printlog("  quads: %d (%d indices, %d usub, %d vsub)\n", USUB * VSUB, num_indices, USUB, VSUB);
   13.40  	}
   13.41  
   13.42 -	m3d_color(1, 1, 1);
   13.43 +	pre_draw();
   13.44  
   13.45  	m3d_vertex_array(&varr->x);
   13.46  	m3d_draw_indexed(M3D_QUADS, iarr, num_indices);
   13.47  	m3d_vertex_array(0);
   13.48 +
   13.49 +	post_draw();
   13.50  }
   13.51 +
   13.52 +bool Sphere::intersect(const Ray &ray, float *dist) const
   13.53 +{
   13.54 +	return false;	// TODO
   13.55 +}
   13.56 +
   13.57 +// ---- box ----
   13.58 +
   13.59 +Box::Box()
   13.60 +{
   13.61 +}
   13.62 +
   13.63 +Box::~Box()
   13.64 +{
   13.65 +}
   13.66 +
   13.67 +/*
   13.68 +     3--------2
   13.69 +    /.        .\
   13.70 +   0------------1
   13.71 +   | 7--------6 |
   13.72 +   |/          \|
   13.73 +   4------------5
   13.74 +
   13.75 + */
   13.76 +void Box::draw() const
   13.77 +{
   13.78 +	static const float verts[] = {
   13.79 +		-1, 1, 1,
   13.80 +		1, 1, 1,
   13.81 +		1, 1, -1,
   13.82 +		-1, 1, -1,
   13.83 +		-1, -1, 1,
   13.84 +		1, -1, 1,
   13.85 +		1, -1, -1,
   13.86 +		-1, -1, -1
   13.87 +	};
   13.88 +	static const unsigned int indices[] = {
   13.89 +		0, 1, 2, 3,		// top
   13.90 +		4, 7, 6, 5,		// bottom
   13.91 +		0, 4, 5, 1,		// front
   13.92 +		5, 6, 2, 1,		// right
   13.93 +		6, 7, 3, 2,		// back
   13.94 +		7, 4, 0, 3		// left
   13.95 +	};
   13.96 +
   13.97 +	pre_draw();
   13.98 +
   13.99 +	m3d_vertex_array(verts);
  13.100 +	m3d_draw_indexed(M3D_QUADS, indices, sizeof indices / sizeof *indices);
  13.101 +	m3d_vertex_array(0);
  13.102 +
  13.103 +	post_draw();
  13.104 +}
  13.105 +
  13.106 +bool Box::intersect(const Ray &ray, float *dist) const
  13.107 +{
  13.108 +	return false;	// TODO
  13.109 +}
    14.1 --- a/src/object.h	Thu Apr 10 08:42:33 2014 +0300
    14.2 +++ b/src/object.h	Sat Apr 12 23:28:24 2014 +0300
    14.3 @@ -1,12 +1,17 @@
    14.4  #ifndef OBJECT_H_
    14.5  #define OBJECT_H_
    14.6  
    14.7 -class Object {
    14.8 +#include "vmath.h"
    14.9 +#include "xfnode.h"
   14.10 +
   14.11 +class Object : public SceneNode {
   14.12 +protected:
   14.13 +	void pre_draw() const;
   14.14 +	void post_draw() const;
   14.15 +
   14.16  public:
   14.17  	Object();
   14.18  	virtual ~Object();
   14.19 -
   14.20 -	virtual void draw() const = 0;
   14.21  };
   14.22  
   14.23  class Sphere : public Object {
   14.24 @@ -15,6 +20,18 @@
   14.25  	~Sphere();
   14.26  
   14.27  	void draw() const;
   14.28 +
   14.29 +	bool intersect(const Ray &ray, float *dist = 0) const;
   14.30 +};
   14.31 +
   14.32 +class Box : public Object {
   14.33 +public:
   14.34 +	Box();
   14.35 +	~Box();
   14.36 +
   14.37 +	void draw() const;
   14.38 +
   14.39 +	bool intersect(const Ray &ray, float *dist = 0) const;
   14.40  };
   14.41  
   14.42  #endif	// OBJECT_H_
    15.1 --- a/src/scancode.h	Thu Apr 10 08:42:33 2014 +0300
    15.2 +++ b/src/scancode.h	Sat Apr 12 23:28:24 2014 +0300
    15.3 @@ -2,29 +2,15 @@
    15.4  #error "do not include scancode.h anywhere..."
    15.5  #endif
    15.6  
    15.7 -/* special keys */
    15.8 -enum {
    15.9 -	LALT, RALT,
   15.10 -	LCTRL, RCTRL,
   15.11 -	LSHIFT, RSHIFT,
   15.12 -	F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
   15.13 -	CAPSLK, NUMLK, SCRLK, SYSRQ,
   15.14 -	ESC		= 27,
   15.15 -	INSERT, DEL, HOME, END, PGUP, PGDN, LEFT, RIGHT, UP, DOWN,
   15.16 -	NUM_DOT, NUM_ENTER, NUM_PLUS, NUM_MINUS, NUM_MUL, NUM_DIV,
   15.17 -	NUM_0, NUM_1, NUM_2, NUM_3, NUM_4, NUM_5, NUM_6, NUM_7, NUM_8, NUM_9,
   15.18 -	BACKSP	= 127
   15.19 -};
   15.20 -
   15.21  /* table with rough translations from set 1 scancodes to ASCII-ish */
   15.22  static int scantbl[] = {
   15.23 -	0, ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',		/* 0 - e */
   15.24 +	0, KB_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',		/* 0 - e */
   15.25  	'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',			/* f - 1c */
   15.26 -	LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',				/* 1d - 29 */
   15.27 -	LSHIFT, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', RSHIFT,			/* 2a - 36 */
   15.28 -	NUM_MUL, LALT, ' ', CAPSLK, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10,			/* 37 - 44 */
   15.29 -	NUMLK, SCRLK, NUM_7, NUM_8, NUM_9, NUM_MINUS, NUM_4, NUM_5, NUM_6, NUM_PLUS,	/* 45 - 4e */
   15.30 -	NUM_1, NUM_2, NUM_3, NUM_0, NUM_DOT, SYSRQ, 0, 0, F11, F12,						/* 4d - 58 */
   15.31 +	KB_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',				/* 1d - 29 */
   15.32 +	KB_LSHIFT, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', KB_RSHIFT,			/* 2a - 36 */
   15.33 +	KB_NUM_KB_MUL, KB_LALT, ' ', KB_CAPSLK, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10,			/* 37 - 44 */
   15.34 +	KB_NUMLK, KB_SCRLK, KB_NUM_7, KB_NUM_8, KB_NUM_9, KB_NUM_KB_MINUS, KB_NUM_4, KB_NUM_5, KB_NUM_6, KB_NUM_KB_PLUS,	/* 45 - 4e */
   15.35 +	KB_NUM_1, KB_NUM_2, KB_NUM_3, KB_NUM_0, KB_NUM_KB_DOT, KB_SYSRQ, 0, 0, KB_F11, KB_F12,						/* 4d - 58 */
   15.36  	0, 0, 0, 0, 0, 0, 0,															/* 59 - 5f */
   15.37  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,									/* 60 - 6f */
   15.38  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0									/* 70 - 7f */
    16.1 --- a/src/scene.cc	Thu Apr 10 08:42:33 2014 +0300
    16.2 +++ b/src/scene.cc	Sat Apr 12 23:28:24 2014 +0300
    16.3 @@ -1,5 +1,6 @@
    16.4  #include <string.h>
    16.5  #include "scene.h"
    16.6 +#include "min3d.h"
    16.7  
    16.8  Scene::Scene()
    16.9  {
   16.10 @@ -40,22 +41,35 @@
   16.11  	return name ? name : "<unknown>";
   16.12  }
   16.13  
   16.14 -void Scene::add_object(Object *obj)
   16.15 +void Scene::add(SceneNode *node)
   16.16  {
   16.17 -	objects.push_back(obj);
   16.18 +	nodes.push_back(node);
   16.19 +
   16.20 +	switch(node->get_type()) {
   16.21 +	case NODE_OBJECT:
   16.22 +		objects.push_back((Object*)node);
   16.23 +		break;
   16.24 +
   16.25 +	case NODE_LIGHT:
   16.26 +		lights.push_back((Light*)node);
   16.27 +		break;
   16.28 +
   16.29 +	case NODE_CAMERA:
   16.30 +		cameras.push_back((Camera*)node);
   16.31 +		break;
   16.32 +
   16.33 +	default:
   16.34 +		break;
   16.35 +	}
   16.36 +
   16.37 +	sel.clear();
   16.38  }
   16.39  
   16.40 -void Scene::add_light(Light *lt)
   16.41 +int Scene::get_node_count() const
   16.42  {
   16.43 -	lights.push_back(lt);
   16.44 +	return (int)nodes.size();
   16.45  }
   16.46  
   16.47 -void Scene::add_camera(Camera *cam)
   16.48 -{
   16.49 -	cameras.push_back(cam);
   16.50 -}
   16.51 -
   16.52 -
   16.53  int Scene::get_object_count() const
   16.54  {
   16.55  	return (int)objects.size();
   16.56 @@ -71,6 +85,15 @@
   16.57  	return (int)cameras.size();
   16.58  }
   16.59  
   16.60 +SceneNode *Scene::get_node(int idx)
   16.61 +{
   16.62 +	return nodes[idx];
   16.63 +}
   16.64 +
   16.65 +const SceneNode *Scene::get_node(int idx) const
   16.66 +{
   16.67 +	return nodes[idx];
   16.68 +}
   16.69  
   16.70  Object *Scene::get_object(int idx)
   16.71  {
   16.72 @@ -108,8 +131,43 @@
   16.73  		// TODO
   16.74  	}
   16.75  
   16.76 -	int nobj = get_object_count();
   16.77 -	for(int i=0; i<nobj; i++) {
   16.78 -		objects[i]->draw();
   16.79 +	int num_nodes = get_node_count();
   16.80 +	for(int i=0; i<num_nodes; i++) {
   16.81 +		bool selected = false;
   16.82 +
   16.83 +		for(size_t j=0; j<sel.size(); j++) {
   16.84 +			if(sel[j] == i) {
   16.85 +				selected = true;
   16.86 +				break;
   16.87 +			}
   16.88 +		}
   16.89 +
   16.90 +		m3d_color(1, 1, selected ? 0.25 : 1);
   16.91 +		nodes[i]->draw();
   16.92  	}
   16.93  }
   16.94 +
   16.95 +void Scene::select(int s)
   16.96 +{
   16.97 +	for(size_t i=0; i<sel.size(); i++) {
   16.98 +		if(sel[i] == s) {
   16.99 +			return;
  16.100 +		}
  16.101 +	}
  16.102 +	sel.push_back(s);
  16.103 +}
  16.104 +
  16.105 +void Scene::clear_selection()
  16.106 +{
  16.107 +	sel.clear();
  16.108 +}
  16.109 +
  16.110 +int Scene::get_selection_count() const
  16.111 +{
  16.112 +	return (int)sel.size();
  16.113 +}
  16.114 +
  16.115 +int Scene::get_selection(int idx) const
  16.116 +{
  16.117 +	return idx >= 0 && idx < (int)sel.size() ? sel[idx] : -1;
  16.118 +}
    17.1 --- a/src/scene.h	Thu Apr 10 08:42:33 2014 +0300
    17.2 +++ b/src/scene.h	Sat Apr 12 23:28:24 2014 +0300
    17.3 @@ -3,6 +3,7 @@
    17.4  
    17.5  #include <string>
    17.6  #include <vector.h>
    17.7 +#include "xfnode.h"
    17.8  #include "object.h"
    17.9  #include "light.h"
   17.10  #include "camera.h"
   17.11 @@ -10,11 +11,15 @@
   17.12  class Scene {
   17.13  private:
   17.14  	char *name;
   17.15 +	vector<SceneNode*> nodes;
   17.16 +
   17.17  	vector<Object*> objects;
   17.18  	vector<Light*> lights;
   17.19  	vector<Camera*> cameras;
   17.20  	Camera *active_cam;
   17.21  
   17.22 +	vector<int> sel;
   17.23 +
   17.24  public:
   17.25  	Scene();
   17.26  	~Scene();
   17.27 @@ -24,14 +29,15 @@
   17.28  	void set_name(const char *name);
   17.29  	const char *get_name() const;
   17.30  
   17.31 -	void add_object(Object *obj);
   17.32 -	void add_light(Light *lt);
   17.33 -	void add_camera(Camera *cam);
   17.34 +	void add(SceneNode *node);
   17.35  
   17.36 +	int get_node_count() const;
   17.37  	int get_object_count() const;
   17.38  	int get_light_count() const;
   17.39  	int get_camera_count() const;
   17.40  
   17.41 +	SceneNode *get_node(int idx);
   17.42 +	const SceneNode *get_node(int idx) const;
   17.43  	Object *get_object(int idx);
   17.44  	const Object *get_object(int idx) const;
   17.45  	Light *get_light(int idx);
   17.46 @@ -40,6 +46,11 @@
   17.47  	const Camera *get_camera(int idx) const;
   17.48  
   17.49  	void draw() const;
   17.50 +
   17.51 +	void select(int s);
   17.52 +	void clear_selection();
   17.53 +	int get_selection_count() const;
   17.54 +	int get_selection(int idx = 0) const;
   17.55  };
   17.56  
   17.57  #endif	// SCENE_H_
    18.1 --- a/src/stl/vector.h	Thu Apr 10 08:42:33 2014 +0300
    18.2 +++ b/src/stl/vector.h	Sat Apr 12 23:28:24 2014 +0300
    18.3 @@ -2,6 +2,8 @@
    18.4  #ifndef VECTOR_H_
    18.5  #define VECTOR_H_
    18.6  
    18.7 +#include <stdlib.h>
    18.8 +
    18.9  template <class T>
   18.10  class vector {
   18.11  private:
    19.1 --- a/src/vmath.cc	Thu Apr 10 08:42:33 2014 +0300
    19.2 +++ b/src/vmath.cc	Sat Apr 12 23:28:24 2014 +0300
    19.3 @@ -16,3 +16,109 @@
    19.4  	translate(-pos.x, -pos.y, -pos.z);
    19.5  	*this = *this * m;
    19.6  }
    19.7 +
    19.8 +void Matrix4x4::transpose()
    19.9 +{
   19.10 +	Matrix4x4 tmp = *this;
   19.11 +	for(int i=0; i<4; i++) {
   19.12 +		for(int j=0; j<4; j++) {
   19.13 +			m[i][j] = tmp[j][i];
   19.14 +		}
   19.15 +	}
   19.16 +}
   19.17 +
   19.18 +float Matrix4x4::determinant() const
   19.19 +{
   19.20 +	float det11 =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   19.21 +					(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
   19.22 +					(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
   19.23 +
   19.24 +	float det12 =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   19.25 +					(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   19.26 +					(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
   19.27 +
   19.28 +	float det13 =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
   19.29 +					(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   19.30 +					(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   19.31 +
   19.32 +	float det14 =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
   19.33 +					(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
   19.34 +					(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   19.35 +
   19.36 +	return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14;
   19.37 +}
   19.38 +
   19.39 +
   19.40 +Matrix4x4 Matrix4x4::adjoint() const
   19.41 +{
   19.42 +	Matrix4x4 coef;
   19.43 +
   19.44 +	coef.m[0][0] =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   19.45 +					(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
   19.46 +					(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
   19.47 +	coef.m[0][1] =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   19.48 +					(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   19.49 +					(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
   19.50 +	coef.m[0][2] =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
   19.51 +					(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   19.52 +					(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   19.53 +	coef.m[0][3] =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
   19.54 +					(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
   19.55 +					(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   19.56 +
   19.57 +	coef.m[1][0] =	(m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   19.58 +					(m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
   19.59 +					(m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
   19.60 +	coef.m[1][1] =	(m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   19.61 +					(m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   19.62 +					(m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
   19.63 +	coef.m[1][2] =	(m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
   19.64 +					(m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   19.65 +					(m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   19.66 +	coef.m[1][3] =	(m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
   19.67 +					(m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
   19.68 +					(m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   19.69 +
   19.70 +	coef.m[2][0] =	(m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
   19.71 +					(m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) +
   19.72 +					(m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2]));
   19.73 +	coef.m[2][1] =	(m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
   19.74 +					(m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
   19.75 +					(m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2]));
   19.76 +	coef.m[2][2] =	(m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) -
   19.77 +					(m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
   19.78 +					(m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
   19.79 +	coef.m[2][3] =	(m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) -
   19.80 +					(m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) +
   19.81 +					(m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
   19.82 +
   19.83 +	coef.m[3][0] =	(m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
   19.84 +					(m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) +
   19.85 +					(m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]));
   19.86 +	coef.m[3][1] =	(m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
   19.87 +					(m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
   19.88 +					(m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2]));
   19.89 +	coef.m[3][2] =	(m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) -
   19.90 +					(m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
   19.91 +					(m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
   19.92 +	coef.m[3][3] =	(m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) -
   19.93 +					(m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) +
   19.94 +					(m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
   19.95 +
   19.96 +	coef.transpose();
   19.97 +
   19.98 +	for(int i=0; i<4; i++) {
   19.99 +		for(int j=0; j<4; j++) {
  19.100 +			coef.m[i][j] = j % 2 ? -coef.m[i][j] : coef.m[i][j];
  19.101 +			if(i % 2) coef.m[i][j] = -coef.m[i][j];
  19.102 +		}
  19.103 +	}
  19.104 +
  19.105 +	return coef;
  19.106 +}
  19.107 +
  19.108 +Matrix4x4 Matrix4x4::inverse() const
  19.109 +{
  19.110 +	Matrix4x4 adj = adjoint();
  19.111 +	return adj * (1.0f / determinant());
  19.112 +}
    20.1 --- a/src/vmath.h	Thu Apr 10 08:42:33 2014 +0300
    20.2 +++ b/src/vmath.h	Sat Apr 12 23:28:24 2014 +0300
    20.3 @@ -47,6 +47,11 @@
    20.4  	return Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
    20.5  }
    20.6  
    20.7 +inline Vector3 operator *(const Vector3 &a, const Vector3 &b)
    20.8 +{
    20.9 +	return Vector3(a.x * b.x, a.y * b.y, a.z * b.z);
   20.10 +}
   20.11 +
   20.12  inline Vector3 operator *(const Vector3 &v, float s)
   20.13  {
   20.14  	return Vector3(v.x * s, v.y * s, v.z * s);
   20.15 @@ -65,7 +70,7 @@
   20.16  inline Vector3 cross(const Vector3 &a, const Vector3 &b)
   20.17  {
   20.18  	return Vector3(a.y * b.z - a.z * b.y,
   20.19 -			a.z * b.z - a.x * b.z,
   20.20 +			a.z * b.x - a.x * b.z,
   20.21  			a.x * b.y - a.y * b.x);
   20.22  }
   20.23  
    21.1 --- a/src/vmathmat.h	Thu Apr 10 08:42:33 2014 +0300
    21.2 +++ b/src/vmathmat.h	Sat Apr 12 23:28:24 2014 +0300
    21.3 @@ -38,6 +38,12 @@
    21.4  
    21.5  	float *operator [](int idx) { return m[idx]; }
    21.6  	const float *operator [](int idx) const { return m[idx]; }
    21.7 +
    21.8 +	void transpose();
    21.9 +
   21.10 +	float determinant() const;
   21.11 +	Matrix4x4 adjoint() const;
   21.12 +	Matrix4x4 inverse() const;
   21.13  };
   21.14  
   21.15  inline Matrix4x4 operator *(const Matrix4x4 &a, const Matrix4x4 &b)
   21.16 @@ -52,6 +58,18 @@
   21.17  	return res;
   21.18  }
   21.19  
   21.20 +inline Matrix4x4 operator *(const Matrix4x4 &mat, float scalar)
   21.21 +{
   21.22 +	Matrix4x4 res;
   21.23 +
   21.24 +	for(int i=0; i<4; i++) {
   21.25 +		for(int j=0; j<4; j++) {
   21.26 +			res.m[i][j] = mat.m[i][j] * scalar;
   21.27 +		}
   21.28 +	}
   21.29 +	return res;
   21.30 +}
   21.31 +
   21.32  inline void Matrix4x4::set_identity()
   21.33  {
   21.34  	m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0;
   21.35 @@ -112,5 +130,4 @@
   21.36  	*this = *this * m;
   21.37  }
   21.38  
   21.39 -
   21.40  #endif	// VMATH_MATRIX_H_