dungeon_crawler

changeset 1:96de911d05d4

started a rough prototype
author John Tsiombikas <nuclear@mutantstargoat.com>
date Thu, 28 Jun 2012 06:05:50 +0300
parents aebcd71cc3cf
children 1f61f2a02832
files prototype/Makefile prototype/src/camera.cc prototype/src/camera.h prototype/src/level.cc prototype/src/level.h prototype/src/main.cc prototype/src/opengl.h prototype/src/tile.cc prototype/src/tile.h prototype/vmath/basis.cc prototype/vmath/basis.h prototype/vmath/basis_c.c prototype/vmath/geom.c prototype/vmath/geom.h prototype/vmath/matrix.cc prototype/vmath/matrix.h prototype/vmath/matrix.inl prototype/vmath/matrix_c.c prototype/vmath/quat.cc prototype/vmath/quat.h prototype/vmath/quat.inl prototype/vmath/quat_c.c prototype/vmath/ray.cc prototype/vmath/ray.h prototype/vmath/ray.inl prototype/vmath/ray_c.c prototype/vmath/sphvec.cc prototype/vmath/sphvec.h prototype/vmath/vector.cc prototype/vmath/vector.h prototype/vmath/vector.inl prototype/vmath/vmath.c prototype/vmath/vmath.h prototype/vmath/vmath.inl prototype/vmath/vmath_config.h prototype/vmath/vmath_types.h
diffstat 36 files changed, 5001 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/prototype/Makefile	Thu Jun 28 06:05:50 2012 +0300
     1.3 @@ -0,0 +1,30 @@
     1.4 +csrc = $(wildcard src/*.c) $(wildcard vmath/*.c)
     1.5 +ccsrc = $(wildcard src/*.cc) $(wildcard vmath/*.cc)
     1.6 +obj = $(csrc:.c=.o) $(ccsrc:.cc=.o)
     1.7 +dep = $(obj:.o=.d)
     1.8 +bin = proto
     1.9 +
    1.10 +CFLAGS = -pedantic -Wall -g -Ivmath
    1.11 +CXXFLAGS = $(CFLAGS)
    1.12 +LDFLAGS = $(libgl) -lm
    1.13 +
    1.14 +ifeq ($(shell uname -s), Darwin)
    1.15 +	libgl = -framework OpenGL -framework GLUT -lglew
    1.16 +else
    1.17 +	libgl = -lGL -lGLU -lglut -lGLEW
    1.18 +endif
    1.19 +
    1.20 +$(bin): $(obj)
    1.21 +	$(CXX) -o $@ $(obj) $(LDFLAGS)
    1.22 +
    1.23 +-include $(dep)
    1.24 +
    1.25 +%.d: %.c
    1.26 +	@$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
    1.27 +
    1.28 +%.d: %.cc
    1.29 +	@$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@
    1.30 +
    1.31 +.PHONY: clean
    1.32 +clean:
    1.33 +	rm -f $(obj) $(bin) $(dep)
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/prototype/src/camera.cc	Thu Jun 28 06:05:50 2012 +0300
     2.3 @@ -0,0 +1,177 @@
     2.4 +#include "opengl.h"
     2.5 +#include "camera.h"
     2.6 +
     2.7 +Camera::Camera()
     2.8 +{
     2.9 +	inval_cache();
    2.10 +}
    2.11 +
    2.12 +Camera::~Camera()
    2.13 +{
    2.14 +}
    2.15 +
    2.16 +void Camera::calc_inv_matrix(Matrix4x4 *mat) const
    2.17 +{
    2.18 +	*mat = matrix().inverse();
    2.19 +}
    2.20 +
    2.21 +void Camera::set_glmat(const Matrix4x4 &mat) const
    2.22 +{
    2.23 +#ifdef SINGLE_PRECISION_MATH
    2.24 +	if(glLoadTransposeMatrixfARB) {
    2.25 +		glLoadTransposeMatrixfARB((float*)&mat);
    2.26 +	} else {
    2.27 +		Matrix4x4 tmat = mat.transposed();
    2.28 +		glLoadMatrixf((float*)&tmat);
    2.29 +	}
    2.30 +#else
    2.31 +	if(glLoadTransposeMatrixdARB) {
    2.32 +		glLoadTransposeMatrixdARB((double*)&mat);
    2.33 +	} else {
    2.34 +		Matrix4x4 tmat = mat.transposed();
    2.35 +		glLoadMatrixd((double*)&tmat);
    2.36 +	}
    2.37 +#endif
    2.38 +}
    2.39 +
    2.40 +const Matrix4x4 &Camera::matrix() const
    2.41 +{
    2.42 +	if(!mcache.valid) {
    2.43 +		calc_matrix(&mcache.mat);
    2.44 +		mcache.valid = true;
    2.45 +	}
    2.46 +	return mcache.mat;
    2.47 +}
    2.48 +
    2.49 +const Matrix4x4 &Camera::inv_matrix() const
    2.50 +{
    2.51 +	if(!mcache_inv.valid) {
    2.52 +		calc_inv_matrix(&mcache_inv.mat);
    2.53 +		mcache_inv.valid = true;
    2.54 +	}
    2.55 +	return mcache_inv.mat;
    2.56 +}
    2.57 +
    2.58 +void Camera::use() const
    2.59 +{
    2.60 +	set_glmat(matrix());
    2.61 +}
    2.62 +
    2.63 +void Camera::use_inverse() const
    2.64 +{
    2.65 +	set_glmat(inv_matrix());
    2.66 +}
    2.67 +
    2.68 +void Camera::input_move(float x, float y, float z)
    2.69 +{
    2.70 +}
    2.71 +
    2.72 +void Camera::input_rotate(float x, float y, float z)
    2.73 +{
    2.74 +}
    2.75 +
    2.76 +void Camera::input_zoom(float factor)
    2.77 +{
    2.78 +}
    2.79 +
    2.80 +
    2.81 +// ---- orbit camera ----
    2.82 +
    2.83 +OrbitCamera::OrbitCamera()
    2.84 +{
    2.85 +	theta = 0.0;
    2.86 +	phi = 0.0;
    2.87 +	rad = 10.0;
    2.88 +}
    2.89 +
    2.90 +OrbitCamera::~OrbitCamera()
    2.91 +{
    2.92 +}
    2.93 +
    2.94 +void OrbitCamera::calc_matrix(Matrix4x4 *mat) const
    2.95 +{
    2.96 +	mat->reset_identity();
    2.97 +	mat->translate(Vector3(0, 0, -rad));
    2.98 +	mat->rotate(Vector3(phi, 0, 0));
    2.99 +	mat->rotate(Vector3(0, theta, 0));
   2.100 +}
   2.101 +
   2.102 +void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const
   2.103 +{
   2.104 +	mat->reset_identity();
   2.105 +	mat->rotate(Vector3(0, theta, 0));
   2.106 +	mat->rotate(Vector3(phi, 0, 0));
   2.107 +	mat->translate(Vector3(0, 0, -rad));
   2.108 +}
   2.109 +
   2.110 +void OrbitCamera::input_rotate(float x, float y, float z)
   2.111 +{
   2.112 +	theta += x;
   2.113 +	phi += y;
   2.114 +
   2.115 +	if(phi < -M_PI / 2.0)
   2.116 +		phi = -M_PI / 2.0;
   2.117 +	if(phi > M_PI / 2.0)
   2.118 +		phi = M_PI / 2.0;
   2.119 +
   2.120 +	inval_cache();
   2.121 +}
   2.122 +
   2.123 +void OrbitCamera::input_zoom(float factor)
   2.124 +{
   2.125 +	rad += factor;
   2.126 +	if(rad < 0.0)
   2.127 +		rad = 0.0;
   2.128 +
   2.129 +	inval_cache();
   2.130 +}
   2.131 +
   2.132 +
   2.133 +FlyCamera::FlyCamera()
   2.134 +{
   2.135 +	pos.z = 10.0f;
   2.136 +}
   2.137 +
   2.138 +void FlyCamera::calc_matrix(Matrix4x4 *mat) const
   2.139 +{
   2.140 +	Matrix3x3 rmat = rot.get_rotation_matrix().transposed();
   2.141 +	Matrix4x4 tmat;
   2.142 +	tmat.set_translation(pos);
   2.143 +	*mat = tmat * Matrix4x4(rmat);
   2.144 +}
   2.145 +
   2.146 +/*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const
   2.147 +{
   2.148 +}*/
   2.149 +
   2.150 +const Vector3 &FlyCamera::get_position() const
   2.151 +{
   2.152 +	return pos;
   2.153 +}
   2.154 +
   2.155 +const Quaternion &FlyCamera::get_rotation() const
   2.156 +{
   2.157 +	return rot;
   2.158 +}
   2.159 +
   2.160 +void FlyCamera::input_move(float x, float y, float z)
   2.161 +{
   2.162 +	static const Vector3 vfwd(0, 0, 1), vright(1, 0, 0);
   2.163 +
   2.164 +	Vector3 k = vfwd.transformed(rot);
   2.165 +	Vector3	i = vright.transformed(rot);
   2.166 +	Vector3 j = cross_product(k, i);
   2.167 +
   2.168 +	pos += i * x + j * y + k * z;
   2.169 +	inval_cache();
   2.170 +}
   2.171 +
   2.172 +void FlyCamera::input_rotate(float x, float y, float z)
   2.173 +{
   2.174 +	Vector3 axis(x, y, z);
   2.175 +	float axis_len = axis.length();
   2.176 +	rot.rotate(axis / axis_len, axis_len);
   2.177 +	rot.normalize();
   2.178 +
   2.179 +	inval_cache();
   2.180 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/prototype/src/camera.h	Thu Jun 28 06:05:50 2012 +0300
     3.3 @@ -0,0 +1,69 @@
     3.4 +#ifndef CAMERA_H_
     3.5 +#define CAMERA_H_
     3.6 +
     3.7 +#include "vmath/vmath.h"
     3.8 +
     3.9 +class Camera {
    3.10 +protected:
    3.11 +	mutable struct {
    3.12 +		bool valid;
    3.13 +		Matrix4x4 mat;
    3.14 +	} mcache, mcache_inv;
    3.15 +
    3.16 +	virtual void calc_matrix(Matrix4x4 *mat) const = 0;
    3.17 +	virtual void calc_inv_matrix(Matrix4x4 *mat) const;
    3.18 +
    3.19 +	void inval_cache() { mcache.valid = mcache_inv.valid = false; }
    3.20 +	void set_glmat(const Matrix4x4 &m) const;
    3.21 +
    3.22 +public:
    3.23 +	Camera();
    3.24 +	virtual ~Camera();
    3.25 +
    3.26 +	const Matrix4x4 &matrix() const;
    3.27 +	const Matrix4x4 &inv_matrix() const;
    3.28 +
    3.29 +	void use() const;
    3.30 +	void use_inverse() const;
    3.31 +
    3.32 +	// these do nothing, override to provide input handling
    3.33 +	virtual void input_move(float x, float y, float z);
    3.34 +	virtual void input_rotate(float x, float y, float z);
    3.35 +	virtual void input_zoom(float factor);
    3.36 +};
    3.37 +
    3.38 +class OrbitCamera : public Camera {
    3.39 +private:
    3.40 +	float theta, phi, rad;
    3.41 +
    3.42 +	void calc_matrix(Matrix4x4 *mat) const;
    3.43 +	void calc_inv_matrix(Matrix4x4 *mat) const;
    3.44 +
    3.45 +public:
    3.46 +	OrbitCamera();
    3.47 +	virtual ~OrbitCamera();
    3.48 +
    3.49 +	void input_rotate(float x, float y, float z);
    3.50 +	void input_zoom(float factor);
    3.51 +};
    3.52 +
    3.53 +class FlyCamera : public Camera {
    3.54 +private:
    3.55 +	Vector3 pos;
    3.56 +	Quaternion rot;
    3.57 +
    3.58 +	void calc_matrix(Matrix4x4 *mat) const;
    3.59 +	//void calc_inv_matrix(Matrix4x4 *mat) const;
    3.60 +
    3.61 +public:
    3.62 +	FlyCamera();
    3.63 +
    3.64 +	const Vector3 &get_position() const;
    3.65 +	const Quaternion &get_rotation() const;
    3.66 +
    3.67 +	void input_move(float x, float y, float z);
    3.68 +	void input_rotate(float x, float y, float z);
    3.69 +};
    3.70 +
    3.71 +
    3.72 +#endif	// CAMERA_H_
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/prototype/src/level.cc	Thu Jun 28 06:05:50 2012 +0300
     4.3 @@ -0,0 +1,114 @@
     4.4 +#include <stdio.h>
     4.5 +#include <string.h>
     4.6 +#include "opengl.h"
     4.7 +#include "level.h"
     4.8 +#include "tile.h"
     4.9 +
    4.10 +Level::Level()
    4.11 +{
    4.12 +	cell_size = 1.0;
    4.13 +
    4.14 +	cells = 0;
    4.15 +	xsz = ysz = 0;
    4.16 +}
    4.17 +
    4.18 +Level::~Level()
    4.19 +{
    4.20 +	delete [] cells;
    4.21 +}
    4.22 +
    4.23 +bool Level::load(const char *fname)
    4.24 +{
    4.25 +	xsz = ysz = 64;
    4.26 +
    4.27 +	cells = new GridCell*[xsz * ysz];
    4.28 +	memset(cells, 0, xsz * ysz * sizeof *cells);
    4.29 +
    4.30 +	GridCell *g = new GridCell;
    4.31 +	g->add_tile(new Tile);
    4.32 +	cells[ysz / 2 * xsz + xsz / 2] = g;
    4.33 +
    4.34 +	return true;
    4.35 +}
    4.36 +
    4.37 +bool Level::save(const char *fname) const
    4.38 +{
    4.39 +	return false;
    4.40 +}
    4.41 +
    4.42 +const GridCell *Level::get_cell(int x, int y) const
    4.43 +{
    4.44 +	if(x < 0 || x >= xsz || y < 0 || y >= ysz) {
    4.45 +		return 0;
    4.46 +	}
    4.47 +	return cells[y * xsz + x];
    4.48 +}
    4.49 +
    4.50 +Vector3 Level::get_cell_pos(int x, int y) const
    4.51 +{
    4.52 +	float posx = (x - xsz / 2) * cell_size;
    4.53 +	float posy = (y - ysz / 2) * cell_size;
    4.54 +	return Vector3(posx, 0, posy);
    4.55 +}
    4.56 +
    4.57 +void Level::draw() const
    4.58 +{
    4.59 +	glMatrixMode(GL_MODELVIEW);
    4.60 +
    4.61 +	draw_grid();
    4.62 +
    4.63 +	for(int i=0; i<ysz; i++) {
    4.64 +		for(int j=0; j<xsz; j++) {
    4.65 +			const GridCell *cell = get_cell(j, i);
    4.66 +			if(cell) {
    4.67 +				Vector3 pos = get_cell_pos(j, i);
    4.68 +				glPushMatrix();
    4.69 +				glTranslatef(pos.x, pos.y, pos.z);
    4.70 +				glScalef(cell_size, cell_size, cell_size);
    4.71 +				cell->draw();
    4.72 +				glPopMatrix();
    4.73 +			}
    4.74 +		}
    4.75 +	}
    4.76 +}
    4.77 +
    4.78 +void Level::draw_grid() const
    4.79 +{
    4.80 +	float xlen = xsz * cell_size;
    4.81 +	float ylen = ysz * cell_size;
    4.82 +
    4.83 +	glPushAttrib(GL_ENABLE_BIT);
    4.84 +	glDisable(GL_LIGHTING);
    4.85 +
    4.86 +	glBegin(GL_LINES);
    4.87 +	glColor3f(0.4, 0.4, 0.4);
    4.88 +
    4.89 +	float y = -ylen / 2.0 - cell_size / 2.0;
    4.90 +	for(int i=0; i<ysz; i++) {
    4.91 +		glVertex3f(-xlen / 2.0, 0, y);
    4.92 +		glVertex3f(xlen / 2.0, 0, y);
    4.93 +		y += cell_size;
    4.94 +	}
    4.95 +
    4.96 +	float x = -xlen / 2.0 - cell_size / 2.0;
    4.97 +	for(int i=0; i<xsz; i++) {
    4.98 +		glVertex3f(x, 0, -ylen / 2.0);
    4.99 +		glVertex3f(x, 0, ylen / 2.0);
   4.100 +		x += cell_size;
   4.101 +	}
   4.102 +	glEnd();
   4.103 +
   4.104 +	glPopAttrib();
   4.105 +}
   4.106 +
   4.107 +void GridCell::add_tile(const Tile *tile)
   4.108 +{
   4.109 +	tiles.push_back(tile);
   4.110 +}
   4.111 +
   4.112 +void GridCell::draw() const
   4.113 +{
   4.114 +	for(size_t i=0; i<tiles.size(); i++) {
   4.115 +		tiles[i]->draw();
   4.116 +	}
   4.117 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/prototype/src/level.h	Thu Jun 28 06:05:50 2012 +0300
     5.3 @@ -0,0 +1,44 @@
     5.4 +#ifndef LEVEL_H_
     5.5 +#define LEVEL_H_
     5.6 +
     5.7 +#include <vector>
     5.8 +#include "vmath/vmath.h"
     5.9 +
    5.10 +class GridCell;
    5.11 +class Tile;
    5.12 +
    5.13 +class Level {
    5.14 +private:
    5.15 +	// cells are stored as a linear array of pointers to GridCells
    5.16 +	// null pointers mean unpopulated cells.
    5.17 +	GridCell **cells;
    5.18 +	int xsz, ysz;
    5.19 +	float cell_size;
    5.20 +
    5.21 +	void draw_grid() const;
    5.22 +
    5.23 +public:
    5.24 +	Level();
    5.25 +	~Level();
    5.26 +
    5.27 +	bool load(const char *fname);
    5.28 +	bool save(const char *fname) const;
    5.29 +
    5.30 +	const GridCell *get_cell(int x, int y) const;
    5.31 +	Vector3 get_cell_pos(int x, int y) const;
    5.32 +
    5.33 +	void draw() const;
    5.34 +};
    5.35 +
    5.36 +class GridCell {
    5.37 +private:
    5.38 +	// each grid-cell might contain multiple tiles.
    5.39 +	std::vector<const Tile*> tiles;
    5.40 +
    5.41 +public:
    5.42 +	void add_tile(const Tile *tile);
    5.43 +
    5.44 +	void draw() const;
    5.45 +};
    5.46 +
    5.47 +#endif	// LEVEL_H_
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/prototype/src/main.cc	Thu Jun 28 06:05:50 2012 +0300
     6.3 @@ -0,0 +1,105 @@
     6.4 +#include <stdio.h>
     6.5 +#include <stdlib.h>
     6.6 +#include <assert.h>
     6.7 +#include "opengl.h"
     6.8 +#include "level.h"
     6.9 +#include "camera.h"
    6.10 +
    6.11 +void disp();
    6.12 +void reshape(int x, int y);
    6.13 +void keyb(unsigned char key, int x, int y);
    6.14 +void mouse(int bn, int state, int x, int y);
    6.15 +void motion(int x, int y);
    6.16 +
    6.17 +static Level *level;
    6.18 +static OrbitCamera cam;
    6.19 +
    6.20 +int main(int argc, char **argv)
    6.21 +{
    6.22 +	glutInit(&argc, argv);
    6.23 +	glutInitWindowSize(800, 600);
    6.24 +	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
    6.25 +	glutCreateWindow("prototype");
    6.26 +
    6.27 +	glutDisplayFunc(disp);
    6.28 +	glutReshapeFunc(reshape);
    6.29 +	glutKeyboardFunc(keyb);
    6.30 +	glutMouseFunc(mouse);
    6.31 +	glutMotionFunc(motion);
    6.32 +
    6.33 +	glewInit();
    6.34 +
    6.35 +	glEnable(GL_LIGHTING);
    6.36 +	glEnable(GL_LIGHT0);
    6.37 +	float ldir[] = {-1, 1, 2, 0};
    6.38 +	glLightfv(GL_LIGHT0, GL_POSITION, ldir);
    6.39 +	glEnable(GL_NORMALIZE);
    6.40 +
    6.41 +	glEnable(GL_DEPTH_TEST);
    6.42 +	glEnable(GL_CULL_FACE);
    6.43 +	glEnable(GL_MULTISAMPLE);
    6.44 +
    6.45 +	level = new Level;
    6.46 +	if(!level->load("foobar")) {
    6.47 +		return 1;
    6.48 +	}
    6.49 +
    6.50 +	glutMainLoop();
    6.51 +}
    6.52 +
    6.53 +void disp()
    6.54 +{
    6.55 +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    6.56 +
    6.57 +	glMatrixMode(GL_MODELVIEW);
    6.58 +	glLoadIdentity();
    6.59 +	cam.use();
    6.60 +
    6.61 +	level->draw();
    6.62 +
    6.63 +	glutSwapBuffers();
    6.64 +	assert(glGetError() == GL_NO_ERROR);
    6.65 +}
    6.66 +
    6.67 +void reshape(int x, int y)
    6.68 +{
    6.69 +	glViewport(0, 0, x, y);
    6.70 +	glMatrixMode(GL_PROJECTION);
    6.71 +	glLoadIdentity();
    6.72 +	gluPerspective(45.0, (float)x / (float)y, 1.0, 1000.0);
    6.73 +}
    6.74 +
    6.75 +void keyb(unsigned char key, int x, int y)
    6.76 +{
    6.77 +	switch(key) {
    6.78 +	case 27:
    6.79 +		exit(0);
    6.80 +	}
    6.81 +}
    6.82 +
    6.83 +static int prev_x, prev_y;
    6.84 +static bool bnstate[32];
    6.85 +
    6.86 +void mouse(int bn, int state, int x, int y)
    6.87 +{
    6.88 +	prev_x = x;
    6.89 +	prev_y = y;
    6.90 +	bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN;
    6.91 +}
    6.92 +
    6.93 +void motion(int x, int y)
    6.94 +{
    6.95 +	int dx = x - prev_x;
    6.96 +	int dy = y - prev_y;
    6.97 +	prev_x = x;
    6.98 +	prev_y = y;
    6.99 +
   6.100 +	if(bnstate[0]) {
   6.101 +		cam.input_rotate(dx * 0.01, dy * 0.01, 0);
   6.102 +		glutPostRedisplay();
   6.103 +	}
   6.104 +	if(bnstate[2]) {
   6.105 +		cam.input_zoom(dy * 0.1);
   6.106 +		glutPostRedisplay();
   6.107 +	}
   6.108 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/prototype/src/opengl.h	Thu Jun 28 06:05:50 2012 +0300
     7.3 @@ -0,0 +1,12 @@
     7.4 +#ifndef OPENGL_H_
     7.5 +#define OPENGL_H_
     7.6 +
     7.7 +#include <GL/glew.h>
     7.8 +
     7.9 +#ifndef __APPLE__
    7.10 +#include <GL/glut.h>
    7.11 +#else
    7.12 +#include <GLUT/glut.h>
    7.13 +#endif
    7.14 +
    7.15 +#endif	/* OPENGL_H_ */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/prototype/src/tile.cc	Thu Jun 28 06:05:50 2012 +0300
     8.3 @@ -0,0 +1,23 @@
     8.4 +#include <stdio.h>
     8.5 +#include "opengl.h"
     8.6 +#include "tile.h"
     8.7 +
     8.8 +bool Tile::load(const char *fname)
     8.9 +{
    8.10 +	return true;
    8.11 +}
    8.12 +
    8.13 +void Tile::draw() const
    8.14 +{
    8.15 +	float color[] = {1, 0, 0, 1};
    8.16 +	float white[] = {1, 1, 1, 1};
    8.17 +
    8.18 +	glPushAttrib(GL_LIGHTING_BIT);
    8.19 +
    8.20 +	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
    8.21 +	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
    8.22 +	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0);
    8.23 +	glutSolidSphere(0.5, 16, 8);
    8.24 +
    8.25 +	glPopAttrib();
    8.26 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/prototype/src/tile.h	Thu Jun 28 06:05:50 2012 +0300
     9.3 @@ -0,0 +1,11 @@
     9.4 +#ifndef TILE_H_
     9.5 +#define TILE_H_
     9.6 +
     9.7 +class Tile {
     9.8 +public:
     9.9 +	bool load(const char *fname);
    9.10 +
    9.11 +	void draw() const;
    9.12 +};
    9.13 +
    9.14 +#endif	// TILE_H_
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/prototype/vmath/basis.cc	Thu Jun 28 06:05:50 2012 +0300
    10.3 @@ -0,0 +1,63 @@
    10.4 +#include "basis.h"
    10.5 +#include "vmath.h"
    10.6 +
    10.7 +Basis::Basis()
    10.8 +{
    10.9 +	i = Vector3(1, 0, 0);
   10.10 +	j = Vector3(0, 1, 0);
   10.11 +	k = Vector3(0, 0, 1);
   10.12 +}
   10.13 +
   10.14 +Basis::Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k)
   10.15 +{
   10.16 +	this->i = i;
   10.17 +	this->j = j;
   10.18 +	this->k = k;
   10.19 +}
   10.20 +
   10.21 +Basis::Basis(const Vector3 &dir, bool left_handed)
   10.22 +{
   10.23 +	k = dir;
   10.24 +	j = Vector3(0, 1, 0);
   10.25 +	i = cross_product(j, k);
   10.26 +	j = cross_product(k, i);
   10.27 +}
   10.28 +
   10.29 +/** Rotate with euler angles */
   10.30 +void Basis::rotate(scalar_t x, scalar_t y, scalar_t z) {
   10.31 +	Matrix4x4 RotMat;
   10.32 +	RotMat.set_rotation(Vector3(x, y, z));
   10.33 +	i.transform(RotMat);
   10.34 +	j.transform(RotMat);
   10.35 +	k.transform(RotMat);
   10.36 +}
   10.37 +
   10.38 +/** Rotate by axis-angle specification */
   10.39 +void Basis::rotate(const Vector3 &axis, scalar_t angle) {
   10.40 +	Quaternion q;
   10.41 +	q.set_rotation(axis, angle);
   10.42 +	i.transform(q);
   10.43 +	j.transform(q);
   10.44 +	k.transform(q);
   10.45 +}
   10.46 +
   10.47 +/** Rotate with a 4x4 matrix */
   10.48 +void Basis::rotate(const Matrix4x4 &mat) {
   10.49 +	i.transform(mat);
   10.50 +	j.transform(mat);
   10.51 +	k.transform(mat);
   10.52 +}
   10.53 +
   10.54 +/** Rotate with a quaternion */
   10.55 +void Basis::rotate(const Quaternion &quat) {
   10.56 +	i.transform(quat);
   10.57 +	j.transform(quat);
   10.58 +	k.transform(quat);
   10.59 +}
   10.60 +
   10.61 +/** Extract a rotation matrix from the orthogonal basis */
   10.62 +Matrix3x3 Basis::create_rotation_matrix() const {
   10.63 +	return Matrix3x3(	i.x, j.x, k.x,
   10.64 +						i.y, j.y, k.y,
   10.65 +						i.z, j.z, k.z);
   10.66 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/prototype/vmath/basis.h	Thu Jun 28 06:05:50 2012 +0300
    11.3 @@ -0,0 +1,57 @@
    11.4 +/*
    11.5 +libvmath - a vector math library
    11.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    11.7 +
    11.8 +This program is free software: you can redistribute it and/or modify
    11.9 +it under the terms of the GNU Lesser General Public License as published
   11.10 +by the Free Software Foundation, either version 3 of the License, or
   11.11 +(at your option) any later version.
   11.12 +
   11.13 +This program is distributed in the hope that it will be useful,
   11.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.16 +GNU Lesser General Public License for more details.
   11.17 +
   11.18 +You should have received a copy of the GNU Lesser General Public License
   11.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   11.20 +*/
   11.21 +
   11.22 +#ifndef VMATH_BASIS_H_
   11.23 +#define VMATH_BASIS_H_
   11.24 +
   11.25 +#include "vector.h"
   11.26 +#include "matrix.h"
   11.27 +
   11.28 +enum {
   11.29 +	LEFT_HANDED,
   11.30 +	RIGHT_HANDED
   11.31 +};
   11.32 +
   11.33 +#ifdef __cplusplus
   11.34 +extern "C" {
   11.35 +#endif	/* __cplusplus */
   11.36 +
   11.37 +void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k);
   11.38 +void basis_matrix_dir(mat4_t res, vec3_t dir);
   11.39 +
   11.40 +#ifdef __cplusplus
   11.41 +}	/* extern "C" */
   11.42 +
   11.43 +class Basis {
   11.44 +public:
   11.45 +	Vector3 i, j, k;
   11.46 +
   11.47 +	Basis();
   11.48 +	Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k);
   11.49 +	Basis(const Vector3 &dir, bool left_handed = true);
   11.50 +
   11.51 +	void rotate(scalar_t x, scalar_t y, scalar_t z);
   11.52 +	void rotate(const Vector3 &axis, scalar_t angle);
   11.53 +	void rotate(const Matrix4x4 &mat);
   11.54 +	void rotate(const Quaternion &quat);
   11.55 +
   11.56 +	Matrix3x3 create_rotation_matrix() const;
   11.57 +};
   11.58 +#endif	/* __cplusplus */
   11.59 +
   11.60 +#endif	/* VMATH_BASIS_H_ */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/prototype/vmath/basis_c.c	Thu Jun 28 06:05:50 2012 +0300
    12.3 @@ -0,0 +1,37 @@
    12.4 +/*
    12.5 +libvmath - a vector math library
    12.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    12.7 +
    12.8 +This program is free software: you can redistribute it and/or modify
    12.9 +it under the terms of the GNU Lesser General Public License as published
   12.10 +by the Free Software Foundation, either version 3 of the License, or
   12.11 +(at your option) any later version.
   12.12 +
   12.13 +This program is distributed in the hope that it will be useful,
   12.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.16 +GNU Lesser General Public License for more details.
   12.17 +
   12.18 +You should have received a copy of the GNU Lesser General Public License
   12.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   12.20 +*/
   12.21 +
   12.22 +#include "basis.h"
   12.23 +#include "matrix.h"
   12.24 +
   12.25 +void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k)
   12.26 +{
   12.27 +	m4_identity(res);
   12.28 +	m4_set_column(res, v4_cons(i.x, i.y, i.z, 1.0), 0);
   12.29 +	m4_set_column(res, v4_cons(j.x, j.y, j.z, 1.0), 1);
   12.30 +	m4_set_column(res, v4_cons(k.x, k.y, k.z, 1.0), 2);
   12.31 +}
   12.32 +
   12.33 +void basis_matrix_dir(mat4_t res, vec3_t dir)
   12.34 +{
   12.35 +	vec3_t k = v3_normalize(dir);
   12.36 +	vec3_t j = {0, 1, 0};
   12.37 +	vec3_t i = v3_cross(j, k);
   12.38 +	j = v3_cross(k, i);
   12.39 +	basis_matrix(res, i, j, k);
   12.40 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/prototype/vmath/geom.c	Thu Jun 28 06:05:50 2012 +0300
    13.3 @@ -0,0 +1,150 @@
    13.4 +/*
    13.5 +libvmath - a vector math library
    13.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    13.7 +
    13.8 +This program is free software: you can redistribute it and/or modify
    13.9 +it under the terms of the GNU Lesser General Public License as published
   13.10 +by the Free Software Foundation, either version 3 of the License, or
   13.11 +(at your option) any later version.
   13.12 +
   13.13 +This program is distributed in the hope that it will be useful,
   13.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.16 +GNU Lesser General Public License for more details.
   13.17 +
   13.18 +You should have received a copy of the GNU Lesser General Public License
   13.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   13.20 +*/
   13.21 +
   13.22 +
   13.23 +#include <math.h>
   13.24 +#include "geom.h"
   13.25 +#include "vector.h"
   13.26 +
   13.27 +plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d)
   13.28 +{
   13.29 +	plane_t p;
   13.30 +	p.norm.x = nx;
   13.31 +	p.norm.y = ny;
   13.32 +	p.norm.z = nz;
   13.33 +	p.d = d;
   13.34 +	return p;
   13.35 +}
   13.36 +
   13.37 +plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2)
   13.38 +{
   13.39 +	vec3_t a, b, norm;
   13.40 +
   13.41 +	a = v3_sub(v1, v0);
   13.42 +	b = v3_sub(v2, v0);
   13.43 +	norm = v3_cross(a, b);
   13.44 +	norm = v3_normalize(norm);
   13.45 +
   13.46 +	return plane_ptnorm(v0, norm);
   13.47 +}
   13.48 +
   13.49 +plane_t plane_ptnorm(vec3_t pt, vec3_t normal)
   13.50 +{
   13.51 +	plane_t plane;
   13.52 +
   13.53 +	plane.norm = normal;
   13.54 +	plane.d = v3_dot(pt, normal);
   13.55 +
   13.56 +	return plane;
   13.57 +}
   13.58 +
   13.59 +plane_t plane_invert(plane_t p)
   13.60 +{
   13.61 +	p.norm = v3_neg(p.norm);
   13.62 +	p.d = -p.d;
   13.63 +	return p;
   13.64 +}
   13.65 +
   13.66 +scalar_t plane_signed_dist(plane_t plane, vec3_t pt)
   13.67 +{
   13.68 +	vec3_t pp = plane_point(plane);
   13.69 +	vec3_t pptopt = v3_sub(pt, pp);
   13.70 +	return v3_dot(pptopt, plane.norm);
   13.71 +}
   13.72 +
   13.73 +scalar_t plane_dist(plane_t plane, vec3_t pt)
   13.74 +{
   13.75 +	return fabs(plane_signed_dist(plane, pt));
   13.76 +}
   13.77 +
   13.78 +vec3_t plane_point(plane_t plane)
   13.79 +{
   13.80 +	return v3_scale(plane.norm, plane.d);
   13.81 +}
   13.82 +
   13.83 +int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos)
   13.84 +{
   13.85 +	vec3_t pt, orig_to_pt;
   13.86 +	scalar_t ndotdir;
   13.87 +
   13.88 +	pt = plane_point(plane);
   13.89 +	ndotdir = v3_dot(plane.norm, ray.dir);
   13.90 +
   13.91 +	if(fabs(ndotdir) < 1e-7) {
   13.92 +		return 0;
   13.93 +	}
   13.94 +
   13.95 +	if(pos) {
   13.96 +		orig_to_pt = v3_sub(pt, ray.origin);
   13.97 +		*pos = v3_dot(plane.norm, orig_to_pt) / ndotdir;
   13.98 +	}
   13.99 +	return 1;
  13.100 +}
  13.101 +
  13.102 +sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad)
  13.103 +{
  13.104 +	sphere_t sph;
  13.105 +	sph.pos.x = x;
  13.106 +	sph.pos.y = y;
  13.107 +	sph.pos.z = z;
  13.108 +	sph.rad = rad;
  13.109 +	return sph;
  13.110 +}
  13.111 +
  13.112 +int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos)
  13.113 +{
  13.114 +	scalar_t a, b, c, d, sqrt_d, t1, t2, t;
  13.115 +
  13.116 +	a = v3_dot(ray.dir, ray.dir);
  13.117 +	b = 2.0 * ray.dir.x * (ray.origin.x - sph.pos.x) +
  13.118 +		2.0 * ray.dir.y * (ray.origin.y - sph.pos.y) +
  13.119 +		2.0 * ray.dir.z * (ray.origin.z - sph.pos.z);
  13.120 +	c = v3_dot(sph.pos, sph.pos) + v3_dot(ray.origin, ray.origin) +
  13.121 +		2.0 * v3_dot(v3_neg(sph.pos), ray.origin) - sph.rad * sph.rad;
  13.122 +
  13.123 +	d = b * b - 4.0 * a * c;
  13.124 +	if(d < 0.0) {
  13.125 +		return 0;
  13.126 +	}
  13.127 +
  13.128 +	sqrt_d = sqrt(d);
  13.129 +	t1 = (-b + sqrt_d) / (2.0 * a);
  13.130 +	t2 = (-b - sqrt_d) / (2.0 * a);
  13.131 +
  13.132 +	if(t1 < 1e-7 || t1 > 1.0) {
  13.133 +		t1 = t2;
  13.134 +	}
  13.135 +	if(t2 < 1e-7 || t2 > 1.0) {
  13.136 +		t2 = t1;
  13.137 +	}
  13.138 +	t = t1 < t2 ? t1 : t2;
  13.139 +
  13.140 +	if(t < 1e-7 || t > 1.0) {
  13.141 +		return 0;
  13.142 +	}
  13.143 +
  13.144 +	if(pos) {
  13.145 +		*pos = t;
  13.146 +	}
  13.147 +	return 1;
  13.148 +}
  13.149 +
  13.150 +int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad)
  13.151 +{
  13.152 +	return -1;
  13.153 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/prototype/vmath/geom.h	Thu Jun 28 06:05:50 2012 +0300
    14.3 @@ -0,0 +1,72 @@
    14.4 +/*
    14.5 +libvmath - a vector math library
    14.6 +Copyright (C) 2004-2012 John Tsiombikas <nuclear@member.fsf.org>
    14.7 +
    14.8 +This program is free software: you can redistribute it and/or modify
    14.9 +it under the terms of the GNU Lesser General Public License as published
   14.10 +by the Free Software Foundation, either version 3 of the License, or
   14.11 +(at your option) any later version.
   14.12 +
   14.13 +This program is distributed in the hope that it will be useful,
   14.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.16 +GNU Lesser General Public License for more details.
   14.17 +
   14.18 +You should have received a copy of the GNU Lesser General Public License
   14.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   14.20 +*/
   14.21 +#ifndef LIBVMATH_GEOM_H_
   14.22 +#define LIBVMATH_GEOM_H_
   14.23 +
   14.24 +#include "vector.h"
   14.25 +#include "ray.h"
   14.26 +
   14.27 +typedef struct {
   14.28 +	vec3_t norm;
   14.29 +	scalar_t d;
   14.30 +} plane_t;
   14.31 +
   14.32 +typedef struct {
   14.33 +	vec3_t pos;
   14.34 +	scalar_t rad;
   14.35 +} sphere_t;
   14.36 +
   14.37 +typedef struct {
   14.38 +	vec3_t min, max;
   14.39 +} aabox_t;
   14.40 +
   14.41 +#ifdef __cplusplus
   14.42 +extern "C" {
   14.43 +#endif
   14.44 +
   14.45 +/* planes are good... you need planes, yes you do */
   14.46 +plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d);
   14.47 +plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2);
   14.48 +plane_t plane_ptnorm(vec3_t pt, vec3_t normal);
   14.49 +
   14.50 +plane_t plane_invert(plane_t p);
   14.51 +
   14.52 +scalar_t plane_signed_dist(plane_t plane, vec3_t pt);
   14.53 +scalar_t plane_dist(plane_t plane, vec3_t pt);
   14.54 +vec3_t plane_point(plane_t plane);
   14.55 +
   14.56 +int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos);
   14.57 +
   14.58 +/* spheres always come in handy */
   14.59 +sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad);
   14.60 +
   14.61 +int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos);
   14.62 +int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad);
   14.63 +
   14.64 +#ifdef __cplusplus
   14.65 +}
   14.66 +
   14.67 +/* TODO
   14.68 +class Plane : public plane_t {
   14.69 +public:
   14.70 +};
   14.71 +*/
   14.72 +
   14.73 +#endif
   14.74 +
   14.75 +#endif	/* LIBVMATH_GEOM_H_ */
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/prototype/vmath/matrix.cc	Thu Jun 28 06:05:50 2012 +0300
    15.3 @@ -0,0 +1,743 @@
    15.4 +#include <cstdio>
    15.5 +#include <cmath>
    15.6 +#include "matrix.h"
    15.7 +#include "vector.h"
    15.8 +#include "quat.h"
    15.9 +
   15.10 +using namespace std;
   15.11 +
   15.12 +// ----------- Matrix3x3 --------------
   15.13 +
   15.14 +Matrix3x3 Matrix3x3::identity = Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1);
   15.15 +
   15.16 +Matrix3x3::Matrix3x3()
   15.17 +{
   15.18 +	*this = identity;
   15.19 +}
   15.20 +
   15.21 +Matrix3x3::Matrix3x3(	scalar_t m11, scalar_t m12, scalar_t m13,
   15.22 +						scalar_t m21, scalar_t m22, scalar_t m23,
   15.23 +						scalar_t m31, scalar_t m32, scalar_t m33)
   15.24 +{
   15.25 +	m[0][0] = m11; m[0][1] = m12; m[0][2] = m13;
   15.26 +	m[1][0] = m21; m[1][1] = m22; m[1][2] = m23;
   15.27 +	m[2][0] = m31; m[2][1] = m32; m[2][2] = m33;
   15.28 +}
   15.29 +
   15.30 +Matrix3x3::Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec)
   15.31 +{
   15.32 +	set_row_vector(ivec, 0);
   15.33 +	set_row_vector(jvec, 1);
   15.34 +	set_row_vector(kvec, 2);
   15.35 +}
   15.36 +
   15.37 +Matrix3x3::Matrix3x3(const mat3_t cmat)
   15.38 +{
   15.39 +	memcpy(m, cmat, sizeof(mat3_t));
   15.40 +}
   15.41 +
   15.42 +Matrix3x3::Matrix3x3(const Matrix4x4 &mat4x4)
   15.43 +{
   15.44 +	for(int i=0; i<3; i++) {
   15.45 +		for(int j=0; j<3; j++) {
   15.46 +			m[i][j] = mat4x4[i][j];
   15.47 +		}
   15.48 +	}
   15.49 +}
   15.50 +
   15.51 +Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2)
   15.52 +{
   15.53 +	Matrix3x3 res;
   15.54 +	const scalar_t *op1 = m1.m[0], *op2 = m2.m[0];
   15.55 +	scalar_t *dest = res.m[0];
   15.56 +
   15.57 +	for(int i=0; i<9; i++) {
   15.58 +		*dest++ = *op1++ + *op2++;
   15.59 +	}
   15.60 +	return res;
   15.61 +}
   15.62 +
   15.63 +Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2)
   15.64 +{
   15.65 +	Matrix3x3 res;
   15.66 +	const scalar_t *op1 = m1.m[0], *op2 = m2.m[0];
   15.67 +	scalar_t *dest = res.m[0];
   15.68 +
   15.69 +	for(int i=0; i<9; i++) {
   15.70 +		*dest++ = *op1++ - *op2++;
   15.71 +	}
   15.72 +	return res;
   15.73 +}
   15.74 +
   15.75 +Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2)
   15.76 +{
   15.77 +	Matrix3x3 res;
   15.78 +	for(int i=0; i<3; i++) {
   15.79 +		for(int j=0; j<3; j++) {
   15.80 +			res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j];
   15.81 +		}
   15.82 +	}
   15.83 +	return res;
   15.84 +}
   15.85 +
   15.86 +void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2)
   15.87 +{
   15.88 +	scalar_t *op1 = m1.m[0];
   15.89 +	const scalar_t *op2 = m2.m[0];
   15.90 +
   15.91 +	for(int i=0; i<9; i++) {
   15.92 +		*op1++ += *op2++;
   15.93 +	}
   15.94 +}
   15.95 +
   15.96 +void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2)
   15.97 +{
   15.98 +	scalar_t *op1 = m1.m[0];
   15.99 +	const scalar_t *op2 = m2.m[0];
  15.100 +
  15.101 +	for(int i=0; i<9; i++) {
  15.102 +		*op1++ -= *op2++;
  15.103 +	}
  15.104 +}
  15.105 +
  15.106 +void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2)
  15.107 +{
  15.108 +	Matrix3x3 res;
  15.109 +	for(int i=0; i<3; i++) {
  15.110 +		for(int j=0; j<3; j++) {
  15.111 +			res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j];
  15.112 +		}
  15.113 +	}
  15.114 +	memcpy(m1.m, res.m, 9 * sizeof(scalar_t));
  15.115 +}
  15.116 +
  15.117 +Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar)
  15.118 +{
  15.119 +	Matrix3x3 res;
  15.120 +	const scalar_t *mptr = mat.m[0];
  15.121 +	scalar_t *dptr = res.m[0];
  15.122 +
  15.123 +	for(int i=0; i<9; i++) {
  15.124 +		*dptr++ = *mptr++ * scalar;
  15.125 +	}
  15.126 +	return res;
  15.127 +}
  15.128 +
  15.129 +Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat)
  15.130 +{
  15.131 +	Matrix3x3 res;
  15.132 +	const scalar_t *mptr = mat.m[0];
  15.133 +	scalar_t *dptr = res.m[0];
  15.134 +
  15.135 +	for(int i=0; i<9; i++) {
  15.136 +		*dptr++ = *mptr++ * scalar;
  15.137 +	}
  15.138 +	return res;
  15.139 +}
  15.140 +
  15.141 +void operator *=(Matrix3x3 &mat, scalar_t scalar)
  15.142 +{
  15.143 +	scalar_t *mptr = mat.m[0];
  15.144 +
  15.145 +	for(int i=0; i<9; i++) {
  15.146 +		*mptr++ *= scalar;
  15.147 +	}
  15.148 +}
  15.149 +
  15.150 +void Matrix3x3::translate(const Vector2 &trans)
  15.151 +{
  15.152 +	Matrix3x3 tmat(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1);
  15.153 +	*this *= tmat;
  15.154 +}
  15.155 +
  15.156 +void Matrix3x3::set_translation(const Vector2 &trans)
  15.157 +{
  15.158 +	*this = Matrix3x3(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1);
  15.159 +}
  15.160 +
  15.161 +void Matrix3x3::rotate(scalar_t angle)
  15.162 +{
  15.163 +	scalar_t cos_a = cos(angle);
  15.164 +	scalar_t sin_a = sin(angle);
  15.165 +	Matrix3x3 rmat(	cos_a,	-sin_a,		0,
  15.166 +					sin_a,	cos_a,		0,
  15.167 +					0,		0,			1);
  15.168 +	*this *= rmat;
  15.169 +}
  15.170 +
  15.171 +void Matrix3x3::set_rotation(scalar_t angle)
  15.172 +{
  15.173 +	scalar_t cos_a = cos(angle);
  15.174 +	scalar_t sin_a = sin(angle);
  15.175 +	*this = Matrix3x3(cos_a, -sin_a, 0, sin_a, cos_a, 0, 0, 0, 1);
  15.176 +}
  15.177 +
  15.178 +void Matrix3x3::rotate(const Vector3 &euler_angles)
  15.179 +{
  15.180 +	Matrix3x3 xrot, yrot, zrot;
  15.181 +
  15.182 +	xrot = Matrix3x3(	1,			0,					0,
  15.183 +						0,	cos(euler_angles.x),	-sin(euler_angles.x),
  15.184 +						0,	sin(euler_angles.x),	cos(euler_angles.x));
  15.185 +
  15.186 +	yrot = Matrix3x3(	cos(euler_angles.y),	0,	sin(euler_angles.y),
  15.187 +								0,				1,				0,
  15.188 +						-sin(euler_angles.y),	0,	cos(euler_angles.y));
  15.189 +
  15.190 +	zrot = Matrix3x3(	cos(euler_angles.z),	-sin(euler_angles.z),	0,
  15.191 +						sin(euler_angles.z),	cos(euler_angles.z),	0,
  15.192 +								0,						0,				1);
  15.193 +
  15.194 +	*this *= xrot * yrot * zrot;
  15.195 +}
  15.196 +
  15.197 +void Matrix3x3::set_rotation(const Vector3 &euler_angles)
  15.198 +{
  15.199 +	Matrix3x3 xrot, yrot, zrot;
  15.200 +
  15.201 +	xrot = Matrix3x3(	1,			0,					0,
  15.202 +						0,	cos(euler_angles.x),	-sin(euler_angles.x),
  15.203 +						0,	sin(euler_angles.x),	cos(euler_angles.x));
  15.204 +
  15.205 +	yrot = Matrix3x3(	cos(euler_angles.y),	0,	sin(euler_angles.y),
  15.206 +								0,				1,				0,
  15.207 +						-sin(euler_angles.y),	0,	cos(euler_angles.y));
  15.208 +
  15.209 +	zrot = Matrix3x3(	cos(euler_angles.z),	-sin(euler_angles.z),	0,
  15.210 +						sin(euler_angles.z),	cos(euler_angles.z),	0,
  15.211 +								0,						0,				1);
  15.212 +
  15.213 +	*this = xrot * yrot * zrot;
  15.214 +}
  15.215 +
  15.216 +void Matrix3x3::rotate(const Vector3 &axis, scalar_t angle)
  15.217 +{
  15.218 +	scalar_t sina = (scalar_t)sin(angle);
  15.219 +	scalar_t cosa = (scalar_t)cos(angle);
  15.220 +	scalar_t invcosa = 1-cosa;
  15.221 +	scalar_t nxsq = axis.x * axis.x;
  15.222 +	scalar_t nysq = axis.y * axis.y;
  15.223 +	scalar_t nzsq = axis.z * axis.z;
  15.224 +
  15.225 +	Matrix3x3 xform;
  15.226 +	xform.m[0][0] = nxsq + (1-nxsq) * cosa;
  15.227 +	xform.m[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
  15.228 +	xform.m[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
  15.229 +
  15.230 +	xform.m[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
  15.231 +	xform.m[1][1] = nysq + (1-nysq) * cosa;
  15.232 +	xform.m[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
  15.233 +
  15.234 +	xform.m[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
  15.235 +	xform.m[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
  15.236 +	xform.m[2][2] = nzsq + (1-nzsq) * cosa;
  15.237 +
  15.238 +	*this *= xform;
  15.239 +}
  15.240 +
  15.241 +void Matrix3x3::set_rotation(const Vector3 &axis, scalar_t angle)
  15.242 +{
  15.243 +	scalar_t sina = (scalar_t)sin(angle);
  15.244 +	scalar_t cosa = (scalar_t)cos(angle);
  15.245 +	scalar_t invcosa = 1-cosa;
  15.246 +	scalar_t nxsq = axis.x * axis.x;
  15.247 +	scalar_t nysq = axis.y * axis.y;
  15.248 +	scalar_t nzsq = axis.z * axis.z;
  15.249 +
  15.250 +	reset_identity();
  15.251 +	m[0][0] = nxsq + (1-nxsq) * cosa;
  15.252 +	m[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
  15.253 +	m[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
  15.254 +	m[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
  15.255 +	m[1][1] = nysq + (1-nysq) * cosa;
  15.256 +	m[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
  15.257 +	m[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
  15.258 +	m[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
  15.259 +	m[2][2] = nzsq + (1-nzsq) * cosa;
  15.260 +}
  15.261 +
  15.262 +void Matrix3x3::scale(const Vector3 &scale_vec)
  15.263 +{
  15.264 +	Matrix3x3 smat(	scale_vec.x, 0, 0,
  15.265 +					0, scale_vec.y, 0,
  15.266 +					0, 0, scale_vec.z);
  15.267 +	*this *= smat;
  15.268 +}
  15.269 +
  15.270 +void Matrix3x3::set_scaling(const Vector3 &scale_vec)
  15.271 +{
  15.272 +	*this = Matrix3x3(	scale_vec.x, 0, 0,
  15.273 +						0, scale_vec.y, 0,
  15.274 +						0, 0, scale_vec.z);
  15.275 +}
  15.276 +
  15.277 +void Matrix3x3::set_column_vector(const Vector3 &vec, unsigned int col_index)
  15.278 +{
  15.279 +	m[0][col_index] = vec.x;
  15.280 +	m[1][col_index] = vec.y;
  15.281 +	m[2][col_index] = vec.z;
  15.282 +}
  15.283 +
  15.284 +void Matrix3x3::set_row_vector(const Vector3 &vec, unsigned int row_index)
  15.285 +{
  15.286 +	m[row_index][0] = vec.x;
  15.287 +	m[row_index][1] = vec.y;
  15.288 +	m[row_index][2] = vec.z;
  15.289 +}
  15.290 +
  15.291 +Vector3 Matrix3x3::get_column_vector(unsigned int col_index) const
  15.292 +{
  15.293 +	return Vector3(m[0][col_index], m[1][col_index], m[2][col_index]);
  15.294 +}
  15.295 +
  15.296 +Vector3 Matrix3x3::get_row_vector(unsigned int row_index) const
  15.297 +{
  15.298 +	return Vector3(m[row_index][0], m[row_index][1], m[row_index][2]);
  15.299 +}
  15.300 +
  15.301 +void Matrix3x3::transpose()
  15.302 +{
  15.303 +	Matrix3x3 tmp = *this;
  15.304 +	for(int i=0; i<3; i++) {
  15.305 +		for(int j=0; j<3; j++) {
  15.306 +			m[i][j] = tmp[j][i];
  15.307 +		}
  15.308 +	}
  15.309 +}
  15.310 +
  15.311 +Matrix3x3 Matrix3x3::transposed() const
  15.312 +{
  15.313 +	Matrix3x3 res;
  15.314 +	for(int i=0; i<3; i++) {
  15.315 +		for(int j=0; j<3; j++) {
  15.316 +			res[i][j] = m[j][i];
  15.317 +		}
  15.318 +	}
  15.319 +	return res;
  15.320 +}
  15.321 +
  15.322 +scalar_t Matrix3x3::determinant() const
  15.323 +{
  15.324 +	return	m[0][0] * (m[1][1]*m[2][2] - m[1][2]*m[2][1]) -
  15.325 +			m[0][1] * (m[1][0]*m[2][2] - m[1][2]*m[2][0]) +
  15.326 +			m[0][2] * (m[1][0]*m[2][1] - m[1][1]*m[2][0]);
  15.327 +}
  15.328 +
  15.329 +Matrix3x3 Matrix3x3::inverse() const
  15.330 +{
  15.331 +	// TODO: implement 3x3 inverse
  15.332 +	return *this;
  15.333 +}
  15.334 +
  15.335 +ostream &operator <<(ostream &out, const Matrix3x3 &mat)
  15.336 +{
  15.337 +	for(int i=0; i<3; i++) {
  15.338 +		char str[100];
  15.339 +		sprintf(str, "[ %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2]);
  15.340 +		out << str;
  15.341 +	}
  15.342 +	return out;
  15.343 +}
  15.344 +
  15.345 +
  15.346 +
  15.347 +/* ----------------- Matrix4x4 implementation --------------- */
  15.348 +
  15.349 +Matrix4x4 Matrix4x4::identity = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
  15.350 +
  15.351 +Matrix4x4::Matrix4x4()
  15.352 +{
  15.353 +	*this = identity;
  15.354 +}
  15.355 +
  15.356 +Matrix4x4::Matrix4x4(	scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14,
  15.357 +						scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24,
  15.358 +						scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34,
  15.359 +						scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44)
  15.360 +{
  15.361 +	m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14;
  15.362 +	m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24;
  15.363 +	m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34;
  15.364 +	m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44;
  15.365 +}
  15.366 +
  15.367 +Matrix4x4::Matrix4x4(const mat4_t cmat)
  15.368 +{
  15.369 +	memcpy(m, cmat, sizeof(mat4_t));
  15.370 +}
  15.371 +
  15.372 +Matrix4x4::Matrix4x4(const Matrix3x3 &mat3x3)
  15.373 +{
  15.374 +	reset_identity();
  15.375 +	for(int i=0; i<3; i++) {
  15.376 +		for(int j=0; j<3; j++) {
  15.377 +			m[i][j] = mat3x3[i][j];
  15.378 +		}
  15.379 +	}
  15.380 +}
  15.381 +
  15.382 +Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2)
  15.383 +{
  15.384 +	Matrix4x4 res;
  15.385 +	const scalar_t *op1 = m1.m[0], *op2 = m2.m[0];
  15.386 +	scalar_t *dest = res.m[0];
  15.387 +
  15.388 +	for(int i=0; i<16; i++) {
  15.389 +		*dest++ = *op1++ + *op2++;
  15.390 +	}
  15.391 +	return res;
  15.392 +}
  15.393 +
  15.394 +Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2)
  15.395 +{
  15.396 +	Matrix4x4 res;
  15.397 +	const scalar_t *op1 = m1.m[0], *op2 = m2.m[0];
  15.398 +	scalar_t *dest = res.m[0];
  15.399 +
  15.400 +	for(int i=0; i<16; i++) {
  15.401 +		*dest++ = *op1++ - *op2++;
  15.402 +	}
  15.403 +	return res;
  15.404 +}
  15.405 +
  15.406 +/*
  15.407 +Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2) {
  15.408 +	Matrix4x4 res;
  15.409 +
  15.410 +	for(int i=0; i<4; i++) {
  15.411 +		for(int j=0; j<4; j++) {
  15.412 +			res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j];
  15.413 +		}
  15.414 +	}
  15.415 +
  15.416 +	return res;
  15.417 +}
  15.418 +*/
  15.419 +
  15.420 +void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2)
  15.421 +{
  15.422 +	scalar_t *op1 = m1.m[0];
  15.423 +	const scalar_t *op2 = m2.m[0];
  15.424 +
  15.425 +	for(int i=0; i<16; i++) {
  15.426 +		*op1++ += *op2++;
  15.427 +	}
  15.428 +}
  15.429 +
  15.430 +void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2)
  15.431 +{
  15.432 +	scalar_t *op1 = m1.m[0];
  15.433 +	const scalar_t *op2 = m2.m[0];
  15.434 +
  15.435 +	for(int i=0; i<16; i++) {
  15.436 +		*op1++ -= *op2++;
  15.437 +	}
  15.438 +}
  15.439 +
  15.440 +void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2)
  15.441 +{
  15.442 +	Matrix4x4 res;
  15.443 +	for(int i=0; i<4; i++) {
  15.444 +		for(int j=0; j<4; j++) {
  15.445 +			res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j];
  15.446 +		}
  15.447 +	}
  15.448 +	memcpy(m1.m, res.m, 16 * sizeof(scalar_t));
  15.449 +}
  15.450 +
  15.451 +Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar)
  15.452 +{
  15.453 +	Matrix4x4 res;
  15.454 +	const scalar_t *mptr = mat.m[0];
  15.455 +	scalar_t *dptr = res.m[0];
  15.456 +
  15.457 +	for(int i=0; i<16; i++) {
  15.458 +		*dptr++ = *mptr++ * scalar;
  15.459 +	}
  15.460 +	return res;
  15.461 +}
  15.462 +
  15.463 +Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat)
  15.464 +{
  15.465 +	Matrix4x4 res;
  15.466 +	const scalar_t *mptr = mat.m[0];
  15.467 +	scalar_t *dptr = res.m[0];
  15.468 +
  15.469 +	for(int i=0; i<16; i++) {
  15.470 +		*dptr++ = *mptr++ * scalar;
  15.471 +	}
  15.472 +	return res;
  15.473 +}
  15.474 +
  15.475 +void operator *=(Matrix4x4 &mat, scalar_t scalar)
  15.476 +{
  15.477 +	scalar_t *mptr = mat.m[0];
  15.478 +
  15.479 +	for(int i=0; i<16; i++) {
  15.480 +		*mptr++ *= scalar;
  15.481 +	}
  15.482 +}
  15.483 +
  15.484 +void Matrix4x4::translate(const Vector3 &trans)
  15.485 +{
  15.486 +	Matrix4x4 tmat(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1);
  15.487 +	*this *= tmat;
  15.488 +}
  15.489 +
  15.490 +void Matrix4x4::set_translation(const Vector3 &trans)
  15.491 +{
  15.492 +	*this = Matrix4x4(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1);
  15.493 +}
  15.494 +
  15.495 +void Matrix4x4::rotate(const Vector3 &euler_angles)
  15.496 +{
  15.497 +	Matrix3x3 xrot, yrot, zrot;
  15.498 +
  15.499 +	xrot = Matrix3x3(	1,			0,					0,
  15.500 +						0,	cos(euler_angles.x),	-sin(euler_angles.x),
  15.501 +						0,	sin(euler_angles.x),	cos(euler_angles.x));
  15.502 +
  15.503 +	yrot = Matrix3x3(	cos(euler_angles.y),	0,	sin(euler_angles.y),
  15.504 +								0,				1,				0,
  15.505 +						-sin(euler_angles.y),	0,	cos(euler_angles.y));
  15.506 +
  15.507 +	zrot = Matrix3x3(	cos(euler_angles.z),	-sin(euler_angles.z),	0,
  15.508 +						sin(euler_angles.z),	cos(euler_angles.z),	0,
  15.509 +								0,						0,				1);
  15.510 +
  15.511 +	*this *= Matrix4x4(xrot * yrot * zrot);
  15.512 +}
  15.513 +
  15.514 +void Matrix4x4::set_rotation(const Vector3 &euler_angles)
  15.515 +{
  15.516 +	Matrix3x3 xrot, yrot, zrot;
  15.517 +
  15.518 +	xrot = Matrix3x3(	1,			0,					0,
  15.519 +						0,	cos(euler_angles.x),	-sin(euler_angles.x),
  15.520 +						0,	sin(euler_angles.x),	cos(euler_angles.x));
  15.521 +
  15.522 +	yrot = Matrix3x3(	cos(euler_angles.y),	0,	sin(euler_angles.y),
  15.523 +								0,				1,				0,
  15.524 +						-sin(euler_angles.y),	0,	cos(euler_angles.y));
  15.525 +
  15.526 +	zrot = Matrix3x3(	cos(euler_angles.z),	-sin(euler_angles.z),	0,
  15.527 +						sin(euler_angles.z),	cos(euler_angles.z),	0,
  15.528 +								0,						0,				1);
  15.529 +
  15.530 +	*this = Matrix4x4(xrot * yrot * zrot);
  15.531 +}
  15.532 +
  15.533 +void Matrix4x4::rotate(const Vector3 &axis, scalar_t angle)
  15.534 +{
  15.535 +	scalar_t sina = (scalar_t)sin(angle);
  15.536 +	scalar_t cosa = (scalar_t)cos(angle);
  15.537 +	scalar_t invcosa = 1-cosa;
  15.538 +	scalar_t nxsq = axis.x * axis.x;
  15.539 +	scalar_t nysq = axis.y * axis.y;
  15.540 +	scalar_t nzsq = axis.z * axis.z;
  15.541 +
  15.542 +	Matrix3x3 xform;
  15.543 +	xform[0][0] = nxsq + (1-nxsq) * cosa;
  15.544 +	xform[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
  15.545 +	xform[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
  15.546 +	xform[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
  15.547 +	xform[1][1] = nysq + (1-nysq) * cosa;
  15.548 +	xform[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
  15.549 +	xform[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
  15.550 +	xform[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
  15.551 +	xform[2][2] = nzsq + (1-nzsq) * cosa;
  15.552 +
  15.553 +	*this *= Matrix4x4(xform);
  15.554 +}
  15.555 +
  15.556 +void Matrix4x4::set_rotation(const Vector3 &axis, scalar_t angle)
  15.557 +{
  15.558 +	scalar_t sina = (scalar_t)sin(angle);
  15.559 +	scalar_t cosa = (scalar_t)cos(angle);
  15.560 +	scalar_t invcosa = 1-cosa;
  15.561 +	scalar_t nxsq = axis.x * axis.x;
  15.562 +	scalar_t nysq = axis.y * axis.y;
  15.563 +	scalar_t nzsq = axis.z * axis.z;
  15.564 +
  15.565 +	reset_identity();
  15.566 +	m[0][0] = nxsq + (1-nxsq) * cosa;
  15.567 +	m[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
  15.568 +	m[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
  15.569 +	m[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
  15.570 +	m[1][1] = nysq + (1-nysq) * cosa;
  15.571 +	m[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
  15.572 +	m[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
  15.573 +	m[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
  15.574 +	m[2][2] = nzsq + (1-nzsq) * cosa;
  15.575 +}
  15.576 +
  15.577 +void Matrix4x4::scale(const Vector4 &scale_vec)
  15.578 +{
  15.579 +	Matrix4x4 smat(	scale_vec.x, 0, 0, 0,
  15.580 +					0, scale_vec.y, 0, 0,
  15.581 +					0, 0, scale_vec.z, 0,
  15.582 +					0, 0, 0, scale_vec.w);
  15.583 +	*this *= smat;
  15.584 +}
  15.585 +
  15.586 +void Matrix4x4::set_scaling(const Vector4 &scale_vec)
  15.587 +{
  15.588 +	*this = Matrix4x4(	scale_vec.x, 0, 0, 0,
  15.589 +						0, scale_vec.y, 0, 0,
  15.590 +						0, 0, scale_vec.z, 0,
  15.591 +						0, 0, 0, scale_vec.w);
  15.592 +}
  15.593 +
  15.594 +void Matrix4x4::set_column_vector(const Vector4 &vec, unsigned int col_index)
  15.595 +{
  15.596 +	m[0][col_index] = vec.x;
  15.597 +	m[1][col_index] = vec.y;
  15.598 +	m[2][col_index] = vec.z;
  15.599 +	m[3][col_index] = vec.w;
  15.600 +}
  15.601 +
  15.602 +void Matrix4x4::set_row_vector(const Vector4 &vec, unsigned int row_index)
  15.603 +{
  15.604 +	m[row_index][0] = vec.x;
  15.605 +	m[row_index][1] = vec.y;
  15.606 +	m[row_index][2] = vec.z;
  15.607 +	m[row_index][3] = vec.w;
  15.608 +}
  15.609 +
  15.610 +Vector4 Matrix4x4::get_column_vector(unsigned int col_index) const
  15.611 +{
  15.612 +	return Vector4(m[0][col_index], m[1][col_index], m[2][col_index], m[3][col_index]);
  15.613 +}
  15.614 +
  15.615 +Vector4 Matrix4x4::get_row_vector(unsigned int row_index) const
  15.616 +{
  15.617 +	return Vector4(m[row_index][0], m[row_index][1], m[row_index][2], m[row_index][3]);
  15.618 +}
  15.619 +
  15.620 +void Matrix4x4::transpose()
  15.621 +{
  15.622 +	Matrix4x4 tmp = *this;
  15.623 +	for(int i=0; i<4; i++) {
  15.624 +		for(int j=0; j<4; j++) {
  15.625 +			m[i][j] = tmp[j][i];
  15.626 +		}
  15.627 +	}
  15.628 +}
  15.629 +
  15.630 +Matrix4x4 Matrix4x4::transposed() const
  15.631 +{
  15.632 +	Matrix4x4 res;
  15.633 +	for(int i=0; i<4; i++) {
  15.634 +		for(int j=0; j<4; j++) {
  15.635 +			res[i][j] = m[j][i];
  15.636 +		}
  15.637 +	}
  15.638 +	return res;
  15.639 +}
  15.640 +
  15.641 +scalar_t Matrix4x4::determinant() const
  15.642 +{
  15.643 +	scalar_t det11 =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  15.644 +						(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
  15.645 +						(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
  15.646 +
  15.647 +	scalar_t det12 =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  15.648 +						(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  15.649 +						(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
  15.650 +
  15.651 +	scalar_t det13 =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
  15.652 +						(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  15.653 +						(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  15.654 +
  15.655 +	scalar_t det14 =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
  15.656 +						(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
  15.657 +						(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  15.658 +
  15.659 +	return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14;
  15.660 +}
  15.661 +
  15.662 +
  15.663 +Matrix4x4 Matrix4x4::adjoint() const
  15.664 +{
  15.665 +	Matrix4x4 coef;
  15.666 +
  15.667 +	coef.m[0][0] =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  15.668 +					(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
  15.669 +					(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
  15.670 +	coef.m[0][1] =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  15.671 +					(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  15.672 +					(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
  15.673 +	coef.m[0][2] =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
  15.674 +					(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  15.675 +					(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  15.676 +	coef.m[0][3] =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
  15.677 +					(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
  15.678 +					(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  15.679 +
  15.680 +	coef.m[1][0] =	(m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  15.681 +					(m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
  15.682 +					(m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
  15.683 +	coef.m[1][1] =	(m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  15.684 +					(m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  15.685 +					(m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
  15.686 +	coef.m[1][2] =	(m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
  15.687 +					(m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  15.688 +					(m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  15.689 +	coef.m[1][3] =	(m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
  15.690 +					(m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
  15.691 +					(m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  15.692 +
  15.693 +	coef.m[2][0] =	(m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
  15.694 +					(m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) +
  15.695 +					(m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2]));
  15.696 +	coef.m[2][1] =	(m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
  15.697 +					(m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
  15.698 +					(m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2]));
  15.699 +	coef.m[2][2] =	(m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) -
  15.700 +					(m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
  15.701 +					(m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
  15.702 +	coef.m[2][3] =	(m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) -
  15.703 +					(m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) +
  15.704 +					(m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
  15.705 +
  15.706 +	coef.m[3][0] =	(m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
  15.707 +					(m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) +
  15.708 +					(m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]));
  15.709 +	coef.m[3][1] =	(m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
  15.710 +					(m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
  15.711 +					(m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2]));
  15.712 +	coef.m[3][2] =	(m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) -
  15.713 +					(m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
  15.714 +					(m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
  15.715 +	coef.m[3][3] =	(m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) -
  15.716 +					(m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) +
  15.717 +					(m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
  15.718 +
  15.719 +	coef.transpose();
  15.720 +
  15.721 +	for(int i=0; i<4; i++) {
  15.722 +		for(int j=0; j<4; j++) {
  15.723 +			coef.m[i][j] = j%2 ? -coef.m[i][j] : coef.m[i][j];
  15.724 +			if(i%2) coef.m[i][j] = -coef.m[i][j];
  15.725 +		}
  15.726 +	}
  15.727 +
  15.728 +	return coef;
  15.729 +}
  15.730 +
  15.731 +Matrix4x4 Matrix4x4::inverse() const
  15.732 +{
  15.733 +	Matrix4x4 adj = adjoint();
  15.734 +
  15.735 +	return adj * (1.0f / determinant());
  15.736 +}
  15.737 +
  15.738 +ostream &operator <<(ostream &out, const Matrix4x4 &mat)
  15.739 +{
  15.740 +	for(int i=0; i<4; i++) {
  15.741 +		char str[100];
  15.742 +		sprintf(str, "[ %12.5f %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2], (float)mat.m[i][3]);
  15.743 +		out << str;
  15.744 +	}
  15.745 +	return out;
  15.746 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/prototype/vmath/matrix.h	Thu Jun 28 06:05:50 2012 +0300
    16.3 @@ -0,0 +1,206 @@
    16.4 +/*
    16.5 +libvmath - a vector math library
    16.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    16.7 +
    16.8 +This program is free software: you can redistribute it and/or modify
    16.9 +it under the terms of the GNU Lesser General Public License as published
   16.10 +by the Free Software Foundation, either version 3 of the License, or
   16.11 +(at your option) any later version.
   16.12 +
   16.13 +This program is distributed in the hope that it will be useful,
   16.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.16 +GNU Lesser General Public License for more details.
   16.17 +
   16.18 +You should have received a copy of the GNU Lesser General Public License
   16.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   16.20 +*/
   16.21 +
   16.22 +#ifndef VMATH_MATRIX_H_
   16.23 +#define VMATH_MATRIX_H_
   16.24 +
   16.25 +#include <stdio.h>
   16.26 +#include "vmath_types.h"
   16.27 +
   16.28 +#ifdef __cplusplus
   16.29 +extern "C" {
   16.30 +#endif	/* __cplusplus */
   16.31 +
   16.32 +/* C matrix 3x3 functions */
   16.33 +static inline void m3_identity(mat3_t m);
   16.34 +static inline void m3_cons(mat3_t m,
   16.35 +		scalar_t m11, scalar_t m12, scalar_t m13,
   16.36 +		scalar_t m21, scalar_t m22, scalar_t m23,
   16.37 +		scalar_t m31, scalar_t m32, scalar_t m33);
   16.38 +static inline void m3_copy(mat3_t dest, mat3_t src);
   16.39 +void m3_to_m4(mat4_t dest, mat3_t src);
   16.40 +
   16.41 +void m3_print(FILE *fp, mat3_t m);
   16.42 +
   16.43 +/* C matrix 4x4 functions */
   16.44 +static inline void m4_identity(mat4_t m);
   16.45 +static inline void m4_cons(mat4_t m,
   16.46 +		scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14,
   16.47 +		scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24,
   16.48 +		scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34,
   16.49 +		scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44);
   16.50 +static inline void m4_copy(mat4_t dest, mat4_t src);
   16.51 +void m4_to_m3(mat3_t dest, mat4_t src);
   16.52 +
   16.53 +static inline void m4_mult(mat4_t res, mat4_t m1, mat4_t m2);
   16.54 +
   16.55 +void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z);
   16.56 +void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z);
   16.57 +void m4_rotate_x(mat4_t m, scalar_t angle);
   16.58 +void m4_rotate_y(mat4_t m, scalar_t angle);
   16.59 +void m4_rotate_z(mat4_t m, scalar_t angle);
   16.60 +void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z);
   16.61 +void m4_rotate_quat(mat4_t m, quat_t q);
   16.62 +void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z);
   16.63 +static inline void m4_set_column(mat4_t m, vec4_t v, int idx);
   16.64 +static inline void m4_set_row(mat4_t m, vec4_t v, int idx);
   16.65 +
   16.66 +void m4_transpose(mat4_t res, mat4_t m);
   16.67 +scalar_t m4_determinant(mat4_t m);
   16.68 +void m4_adjoint(mat4_t res, mat4_t m);
   16.69 +void m4_inverse(mat4_t res, mat4_t m);
   16.70 +
   16.71 +void m4_print(FILE *fp, mat4_t m);
   16.72 +
   16.73 +#ifdef __cplusplus
   16.74 +}
   16.75 +
   16.76 +/* when included from C++ source files, also define the matrix classes */
   16.77 +#include <iostream>
   16.78 +
   16.79 +/** 3x3 matrix */
   16.80 +class Matrix3x3 {
   16.81 +private:
   16.82 +	scalar_t m[3][3];
   16.83 +
   16.84 +public:
   16.85 +
   16.86 +	static Matrix3x3 identity;
   16.87 +
   16.88 +	Matrix3x3();
   16.89 +	Matrix3x3(	scalar_t m11, scalar_t m12, scalar_t m13,
   16.90 +				scalar_t m21, scalar_t m22, scalar_t m23,
   16.91 +				scalar_t m31, scalar_t m32, scalar_t m33);
   16.92 +	Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec);
   16.93 +	Matrix3x3(const mat3_t cmat);
   16.94 +
   16.95 +	Matrix3x3(const Matrix4x4 &mat4x4);
   16.96 +
   16.97 +	/* binary operations matrix (op) matrix */
   16.98 +	friend Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2);
   16.99 +	friend Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2);
  16.100 +	friend Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2);
  16.101 +
  16.102 +	friend void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2);
  16.103 +	friend void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2);
  16.104 +	friend void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2);
  16.105 +
  16.106 +	/* binary operations matrix (op) scalar and scalar (op) matrix */
  16.107 +	friend Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar);
  16.108 +	friend Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat);
  16.109 +
  16.110 +	friend void operator *=(Matrix3x3 &mat, scalar_t scalar);
  16.111 +
  16.112 +	inline scalar_t *operator [](int index);
  16.113 +	inline const scalar_t *operator [](int index) const;
  16.114 +
  16.115 +	inline void reset_identity();
  16.116 +
  16.117 +	void translate(const Vector2 &trans);
  16.118 +	void set_translation(const Vector2 &trans);
  16.119 +
  16.120 +	void rotate(scalar_t angle);						/* 2d rotation */
  16.121 +	void rotate(const Vector3 &euler_angles);			/* 3d rotation with euler angles */
  16.122 +	void rotate(const Vector3 &axis, scalar_t angle);	/* 3d axis/angle rotation */
  16.123 +	void set_rotation(scalar_t angle);
  16.124 +	void set_rotation(const Vector3 &euler_angles);
  16.125 +	void set_rotation(const Vector3 &axis, scalar_t angle);
  16.126 +
  16.127 +	void scale(const Vector3 &scale_vec);
  16.128 +	void set_scaling(const Vector3 &scale_vec);
  16.129 +
  16.130 +	void set_column_vector(const Vector3 &vec, unsigned int col_index);
  16.131 +	void set_row_vector(const Vector3 &vec, unsigned int row_index);
  16.132 +	Vector3 get_column_vector(unsigned int col_index) const;
  16.133 +	Vector3 get_row_vector(unsigned int row_index) const;
  16.134 +
  16.135 +	void transpose();
  16.136 +	Matrix3x3 transposed() const;
  16.137 +	scalar_t determinant() const;
  16.138 +	Matrix3x3 inverse() const;
  16.139 +
  16.140 +	friend std::ostream &operator <<(std::ostream &out, const Matrix3x3 &mat);
  16.141 +};
  16.142 +
  16.143 +/** 4x4 matrix */
  16.144 +class Matrix4x4 {
  16.145 +private:
  16.146 +	scalar_t m[4][4];
  16.147 +
  16.148 +public:
  16.149 +
  16.150 +	static Matrix4x4 identity;
  16.151 +
  16.152 +	Matrix4x4();
  16.153 +	Matrix4x4(	scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14,
  16.154 +				scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24,
  16.155 +				scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34,
  16.156 +				scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44);
  16.157 +	Matrix4x4(const mat4_t cmat);
  16.158 +
  16.159 +	Matrix4x4(const Matrix3x3 &mat3x3);
  16.160 +
  16.161 +	/* binary operations matrix (op) matrix */
  16.162 +	friend Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2);
  16.163 +	friend Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2);
  16.164 +	friend Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2);
  16.165 +
  16.166 +	friend void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2);
  16.167 +	friend void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2);
  16.168 +	friend inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2);
  16.169 +
  16.170 +	/* binary operations matrix (op) scalar and scalar (op) matrix */
  16.171 +	friend Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar);
  16.172 +	friend Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat);
  16.173 +
  16.174 +	friend void operator *=(Matrix4x4 &mat, scalar_t scalar);
  16.175 +
  16.176 +	inline scalar_t *operator [](int index);
  16.177 +	inline const scalar_t *operator [](int index) const;
  16.178 +
  16.179 +	inline void reset_identity();
  16.180 +
  16.181 +	void translate(const Vector3 &trans);
  16.182 +	void set_translation(const Vector3 &trans);
  16.183 +
  16.184 +	void rotate(const Vector3 &euler_angles);			/* 3d rotation with euler angles */
  16.185 +	void rotate(const Vector3 &axis, scalar_t angle);	/* 3d axis/angle rotation */
  16.186 +	void set_rotation(const Vector3 &euler_angles);
  16.187 +	void set_rotation(const Vector3 &axis, scalar_t angle);
  16.188 +
  16.189 +	void scale(const Vector4 &scale_vec);
  16.190 +	void set_scaling(const Vector4 &scale_vec);
  16.191 +
  16.192 +	void set_column_vector(const Vector4 &vec, unsigned int col_index);
  16.193 +	void set_row_vector(const Vector4 &vec, unsigned int row_index);
  16.194 +	Vector4 get_column_vector(unsigned int col_index) const;
  16.195 +	Vector4 get_row_vector(unsigned int row_index) const;
  16.196 +
  16.197 +	void transpose();
  16.198 +	Matrix4x4 transposed() const;
  16.199 +	scalar_t determinant() const;
  16.200 +	Matrix4x4 adjoint() const;
  16.201 +	Matrix4x4 inverse() const;
  16.202 +
  16.203 +	friend std::ostream &operator <<(std::ostream &out, const Matrix4x4 &mat);
  16.204 +};
  16.205 +#endif	/* __cplusplus */
  16.206 +
  16.207 +#include "matrix.inl"
  16.208 +
  16.209 +#endif	/* VMATH_MATRIX_H_ */
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/prototype/vmath/matrix.inl	Thu Jun 28 06:05:50 2012 +0300
    17.3 @@ -0,0 +1,165 @@
    17.4 +/*
    17.5 +libvmath - a vector math library
    17.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    17.7 +
    17.8 +This program is free software: you can redistribute it and/or modify
    17.9 +it under the terms of the GNU Lesser General Public License as published
   17.10 +by the Free Software Foundation, either version 3 of the License, or
   17.11 +(at your option) any later version.
   17.12 +
   17.13 +This program is distributed in the hope that it will be useful,
   17.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.16 +GNU Lesser General Public License for more details.
   17.17 +
   17.18 +You should have received a copy of the GNU Lesser General Public License
   17.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   17.20 +*/
   17.21 +
   17.22 +#include <string.h>
   17.23 +
   17.24 +#ifdef __cplusplus
   17.25 +extern "C" {
   17.26 +#endif	/* __cplusplus */
   17.27 +
   17.28 +/* C matrix 3x3 functions */
   17.29 +static inline void m3_identity(mat3_t m)
   17.30 +{
   17.31 +	static const mat3_t id = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
   17.32 +	memcpy(m, id, sizeof id);
   17.33 +}
   17.34 +
   17.35 +static inline void m3_cons(mat3_t m,
   17.36 +		scalar_t m11, scalar_t m12, scalar_t m13,
   17.37 +		scalar_t m21, scalar_t m22, scalar_t m23,
   17.38 +		scalar_t m31, scalar_t m32, scalar_t m33)
   17.39 +{
   17.40 +	m[0][0] = m11; m[0][1] = m12; m[0][2] = m13;
   17.41 +	m[1][0] = m21; m[1][1] = m22; m[1][2] = m23;
   17.42 +	m[2][0] = m31; m[2][1] = m32; m[2][2] = m33;
   17.43 +}
   17.44 +
   17.45 +static inline void m3_copy(mat3_t dest, mat3_t src)
   17.46 +{
   17.47 +	memcpy(dest, src, sizeof(mat3_t));
   17.48 +}
   17.49 +
   17.50 +
   17.51 +/* C matrix 4x4 functions */
   17.52 +static inline void m4_identity(mat4_t m)
   17.53 +{
   17.54 +	static const mat4_t id = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
   17.55 +	memcpy(m, id, sizeof id);
   17.56 +}
   17.57 +
   17.58 +static inline void m4_cons(mat4_t m,
   17.59 +		scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14,
   17.60 +		scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24,
   17.61 +		scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34,
   17.62 +		scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44)
   17.63 +{
   17.64 +	m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14;
   17.65 +	m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24;
   17.66 +	m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34;
   17.67 +	m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44;
   17.68 +}
   17.69 +
   17.70 +static inline void m4_copy(mat4_t dest, mat4_t src)
   17.71 +{
   17.72 +	memcpy(dest, src, sizeof(mat4_t));
   17.73 +}
   17.74 +
   17.75 +static inline void m4_mult(mat4_t res, mat4_t m1, mat4_t m2)
   17.76 +{
   17.77 +	res[0][0] = m1[0][0] * m2[0][0] + m1[0][1] * m2[1][0] + m1[0][2] * m2[2][0] + m1[0][3] * m2[3][0];
   17.78 +	res[0][1] = m1[0][0] * m2[0][1] + m1[0][1] * m2[1][1] + m1[0][2] * m2[2][1] + m1[0][3] * m2[3][1];
   17.79 +	res[0][2] = m1[0][0] * m2[0][2] + m1[0][1] * m2[1][2] + m1[0][2] * m2[2][2] + m1[0][3] * m2[3][2];
   17.80 +	res[0][3] = m1[0][0] * m2[0][3] + m1[0][1] * m2[1][3] + m1[0][2] * m2[2][3] + m1[0][3] * m2[3][3];
   17.81 +
   17.82 +	res[1][0] = m1[1][0] * m2[0][0] + m1[1][1] * m2[1][0] + m1[1][2] * m2[2][0] + m1[1][3] * m2[3][0];
   17.83 +	res[1][1] = m1[1][0] * m2[0][1] + m1[1][1] * m2[1][1] + m1[1][2] * m2[2][1] + m1[1][3] * m2[3][1];
   17.84 +	res[1][2] = m1[1][0] * m2[0][2] + m1[1][1] * m2[1][2] + m1[1][2] * m2[2][2] + m1[1][3] * m2[3][2];
   17.85 +	res[1][3] = m1[1][0] * m2[0][3] + m1[1][1] * m2[1][3] + m1[1][2] * m2[2][3] + m1[1][3] * m2[3][3];
   17.86 +
   17.87 +	res[2][0] = m1[2][0] * m2[0][0] + m1[2][1] * m2[1][0] + m1[2][2] * m2[2][0] + m1[2][3] * m2[3][0];
   17.88 +	res[2][1] = m1[2][0] * m2[0][1] + m1[2][1] * m2[1][1] + m1[2][2] * m2[2][1] + m1[2][3] * m2[3][1];
   17.89 +	res[2][2] = m1[2][0] * m2[0][2] + m1[2][1] * m2[1][2] + m1[2][2] * m2[2][2] + m1[2][3] * m2[3][2];
   17.90 +	res[2][3] = m1[2][0] * m2[0][3] + m1[2][1] * m2[1][3] + m1[2][2] * m2[2][3] + m1[2][3] * m2[3][3];
   17.91 +
   17.92 +	res[3][0] = m1[3][0] * m2[0][0] + m1[3][1] * m2[1][0] + m1[3][2] * m2[2][0] + m1[3][3] * m2[3][0];
   17.93 +	res[3][1] = m1[3][0] * m2[0][1] + m1[3][1] * m2[1][1] + m1[3][2] * m2[2][1] + m1[3][3] * m2[3][1];
   17.94 +	res[3][2] = m1[3][0] * m2[0][2] + m1[3][1] * m2[1][2] + m1[3][2] * m2[2][2] + m1[3][3] * m2[3][2];
   17.95 +	res[3][3] = m1[3][0] * m2[0][3] + m1[3][1] * m2[1][3] + m1[3][2] * m2[2][3] + m1[3][3] * m2[3][3];
   17.96 +}
   17.97 +
   17.98 +static inline void m4_set_column(mat4_t m, vec4_t v, int idx)
   17.99 +{
  17.100 +	m[0][idx] = v.x;
  17.101 +	m[1][idx] = v.y;
  17.102 +	m[2][idx] = v.z;
  17.103 +	m[3][idx] = v.w;
  17.104 +}
  17.105 +
  17.106 +static inline void m4_set_row(mat4_t m, vec4_t v, int idx)
  17.107 +{
  17.108 +	m[idx][0] = v.x;
  17.109 +	m[idx][1] = v.y;
  17.110 +	m[idx][2] = v.z;
  17.111 +	m[idx][3] = v.w;
  17.112 +}
  17.113 +
  17.114 +#ifdef __cplusplus
  17.115 +}	/* extern "C" */
  17.116 +
  17.117 +
  17.118 +/* unrolled to hell and inline */
  17.119 +inline Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2) {
  17.120 +	Matrix4x4 res;
  17.121 +
  17.122 +	res.m[0][0] = m1.m[0][0] * m2.m[0][0] + m1.m[0][1] * m2.m[1][0] + m1.m[0][2] * m2.m[2][0] + m1.m[0][3] * m2.m[3][0];
  17.123 +	res.m[0][1] = m1.m[0][0] * m2.m[0][1] + m1.m[0][1] * m2.m[1][1] + m1.m[0][2] * m2.m[2][1] + m1.m[0][3] * m2.m[3][1];
  17.124 +	res.m[0][2] = m1.m[0][0] * m2.m[0][2] + m1.m[0][1] * m2.m[1][2] + m1.m[0][2] * m2.m[2][2] + m1.m[0][3] * m2.m[3][2];
  17.125 +	res.m[0][3] = m1.m[0][0] * m2.m[0][3] + m1.m[0][1] * m2.m[1][3] + m1.m[0][2] * m2.m[2][3] + m1.m[0][3] * m2.m[3][3];
  17.126 +
  17.127 +	res.m[1][0] = m1.m[1][0] * m2.m[0][0] + m1.m[1][1] * m2.m[1][0] + m1.m[1][2] * m2.m[2][0] + m1.m[1][3] * m2.m[3][0];
  17.128 +	res.m[1][1] = m1.m[1][0] * m2.m[0][1] + m1.m[1][1] * m2.m[1][1] + m1.m[1][2] * m2.m[2][1] + m1.m[1][3] * m2.m[3][1];
  17.129 +	res.m[1][2] = m1.m[1][0] * m2.m[0][2] + m1.m[1][1] * m2.m[1][2] + m1.m[1][2] * m2.m[2][2] + m1.m[1][3] * m2.m[3][2];
  17.130 +	res.m[1][3] = m1.m[1][0] * m2.m[0][3] + m1.m[1][1] * m2.m[1][3] + m1.m[1][2] * m2.m[2][3] + m1.m[1][3] * m2.m[3][3];
  17.131 +
  17.132 +	res.m[2][0] = m1.m[2][0] * m2.m[0][0] + m1.m[2][1] * m2.m[1][0] + m1.m[2][2] * m2.m[2][0] + m1.m[2][3] * m2.m[3][0];
  17.133 +	res.m[2][1] = m1.m[2][0] * m2.m[0][1] + m1.m[2][1] * m2.m[1][1] + m1.m[2][2] * m2.m[2][1] + m1.m[2][3] * m2.m[3][1];
  17.134 +	res.m[2][2] = m1.m[2][0] * m2.m[0][2] + m1.m[2][1] * m2.m[1][2] + m1.m[2][2] * m2.m[2][2] + m1.m[2][3] * m2.m[3][2];
  17.135 +	res.m[2][3] = m1.m[2][0] * m2.m[0][3] + m1.m[2][1] * m2.m[1][3] + m1.m[2][2] * m2.m[2][3] + m1.m[2][3] * m2.m[3][3];
  17.136 +
  17.137 +	res.m[3][0] = m1.m[3][0] * m2.m[0][0] + m1.m[3][1] * m2.m[1][0] + m1.m[3][2] * m2.m[2][0] + m1.m[3][3] * m2.m[3][0];
  17.138 +	res.m[3][1] = m1.m[3][0] * m2.m[0][1] + m1.m[3][1] * m2.m[1][1] + m1.m[3][2] * m2.m[2][1] + m1.m[3][3] * m2.m[3][1];
  17.139 +	res.m[3][2] = m1.m[3][0] * m2.m[0][2] + m1.m[3][1] * m2.m[1][2] + m1.m[3][2] * m2.m[2][2] + m1.m[3][3] * m2.m[3][2];
  17.140 +	res.m[3][3] = m1.m[3][0] * m2.m[0][3] + m1.m[3][1] * m2.m[1][3] + m1.m[3][2] * m2.m[2][3] + m1.m[3][3] * m2.m[3][3];
  17.141 +
  17.142 +	return res;
  17.143 +}
  17.144 +
  17.145 +inline scalar_t *Matrix3x3::operator [](int index) {
  17.146 +	return m[index];
  17.147 +}
  17.148 +
  17.149 +inline const scalar_t *Matrix3x3::operator [](int index) const {
  17.150 +	return m[index];
  17.151 +}
  17.152 +
  17.153 +inline void Matrix3x3::reset_identity() {
  17.154 +	memcpy(this->m, identity.m, 9 * sizeof(scalar_t));
  17.155 +}
  17.156 +
  17.157 +inline scalar_t *Matrix4x4::operator [](int index) {
  17.158 +	return m[index];
  17.159 +}
  17.160 +
  17.161 +inline const scalar_t *Matrix4x4::operator [](int index) const {
  17.162 +	return m[index];
  17.163 +}
  17.164 +
  17.165 +inline void Matrix4x4::reset_identity() {
  17.166 +	memcpy(this->m, identity.m, 16 * sizeof(scalar_t));
  17.167 +}
  17.168 +#endif	/* __cplusplus */
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/prototype/vmath/matrix_c.c	Thu Jun 28 06:05:50 2012 +0300
    18.3 @@ -0,0 +1,265 @@
    18.4 +/*
    18.5 +libvmath - a vector math library
    18.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    18.7 +
    18.8 +This program is free software: you can redistribute it and/or modify
    18.9 +it under the terms of the GNU Lesser General Public License as published
   18.10 +by the Free Software Foundation, either version 3 of the License, or
   18.11 +(at your option) any later version.
   18.12 +
   18.13 +This program is distributed in the hope that it will be useful,
   18.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.16 +GNU Lesser General Public License for more details.
   18.17 +
   18.18 +You should have received a copy of the GNU Lesser General Public License
   18.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   18.20 +*/
   18.21 +
   18.22 +
   18.23 +#include <stdio.h>
   18.24 +#include "matrix.h"
   18.25 +#include "vector.h"
   18.26 +#include "quat.h"
   18.27 +
   18.28 +void m3_to_m4(mat4_t dest, mat3_t src)
   18.29 +{
   18.30 +	int i, j;
   18.31 +
   18.32 +	memset(dest, 0, sizeof(mat4_t));
   18.33 +	for(i=0; i<3; i++) {
   18.34 +		for(j=0; j<3; j++) {
   18.35 +			dest[i][j] = src[i][j];
   18.36 +		}
   18.37 +	}
   18.38 +	dest[3][3] = 1.0;
   18.39 +}
   18.40 +
   18.41 +void m3_print(FILE *fp, mat3_t m)
   18.42 +{
   18.43 +	int i;
   18.44 +	for(i=0; i<3; i++) {
   18.45 +		fprintf(fp, "[ %12.5f %12.5f %12.5f ]\n", (float)m[i][0], (float)m[i][1], (float)m[i][2]);
   18.46 +	}
   18.47 +}
   18.48 +
   18.49 +/* C matrix 4x4 functions */
   18.50 +void m4_to_m3(mat3_t dest, mat4_t src)
   18.51 +{
   18.52 +	int i, j;
   18.53 +	for(i=0; i<3; i++) {
   18.54 +		for(j=0; j<3; j++) {
   18.55 +			dest[i][j] = src[i][j];
   18.56 +		}
   18.57 +	}
   18.58 +}
   18.59 +
   18.60 +void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z)
   18.61 +{
   18.62 +	mat4_t tm;
   18.63 +	m4_identity(tm);
   18.64 +	tm[0][3] = x;
   18.65 +	tm[1][3] = y;
   18.66 +	tm[2][3] = z;
   18.67 +	m4_mult(m, m, tm);
   18.68 +}
   18.69 +
   18.70 +void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z)
   18.71 +{
   18.72 +	m4_rotate_x(m, x);
   18.73 +	m4_rotate_y(m, y);
   18.74 +	m4_rotate_z(m, z);
   18.75 +}
   18.76 +
   18.77 +void m4_rotate_x(mat4_t m, scalar_t angle)
   18.78 +{
   18.79 +	mat4_t rm;
   18.80 +	m4_identity(rm);
   18.81 +	rm[1][1] = cos(angle); rm[1][2] = -sin(angle);
   18.82 +	rm[2][1] = sin(angle); rm[2][2] = cos(angle);
   18.83 +	m4_mult(m, m, rm);
   18.84 +}
   18.85 +
   18.86 +void m4_rotate_y(mat4_t m, scalar_t angle)
   18.87 +{
   18.88 +	mat4_t rm;
   18.89 +	m4_identity(rm);
   18.90 +	rm[0][0] = cos(angle); rm[0][2] = sin(angle);
   18.91 +	rm[2][0] = -sin(angle); rm[2][2] = cos(angle);
   18.92 +	m4_mult(m, m, rm);
   18.93 +}
   18.94 +
   18.95 +void m4_rotate_z(mat4_t m, scalar_t angle)
   18.96 +{
   18.97 +	mat4_t rm;
   18.98 +	m4_identity(rm);
   18.99 +	rm[0][0] = cos(angle); rm[0][1] = -sin(angle);
  18.100 +	rm[1][0] = sin(angle); rm[1][1] = cos(angle);
  18.101 +	m4_mult(m, m, rm);
  18.102 +}
  18.103 +
  18.104 +void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z)
  18.105 +{
  18.106 +	mat4_t xform;
  18.107 +	scalar_t sina = sin(angle);
  18.108 +	scalar_t cosa = cos(angle);
  18.109 +	scalar_t one_minus_cosa = 1.0 - cosa;
  18.110 +	scalar_t nxsq = x * x;
  18.111 +	scalar_t nysq = y * y;
  18.112 +	scalar_t nzsq = z * z;
  18.113 +
  18.114 +	m4_identity(xform);
  18.115 +	xform[0][0] = nxsq + (1.0 - nxsq) * cosa;
  18.116 +	xform[0][1] = x * y * one_minus_cosa - z * sina;
  18.117 +	xform[0][2] = x * z * one_minus_cosa + y * sina;
  18.118 +	xform[1][0] = x * y * one_minus_cosa + z * sina;
  18.119 +	xform[1][1] = nysq + (1.0 - nysq) * cosa;
  18.120 +	xform[1][2] = y * z * one_minus_cosa - x * sina;
  18.121 +	xform[2][0] = x * z * one_minus_cosa - y * sina;
  18.122 +	xform[2][1] = y * z * one_minus_cosa + x * sina;
  18.123 +	xform[2][2] = nzsq + (1.0 - nzsq) * cosa;
  18.124 +
  18.125 +	m4_mult(m, m, xform);
  18.126 +}
  18.127 +
  18.128 +void m4_rotate_quat(mat4_t m, quat_t q)
  18.129 +{
  18.130 +	mat4_t rm;
  18.131 +	quat_to_mat4(rm, q);
  18.132 +	m4_mult(m, m, rm);
  18.133 +}
  18.134 +
  18.135 +void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z)
  18.136 +{
  18.137 +	mat4_t sm;
  18.138 +	m4_identity(sm);
  18.139 +	sm[0][0] = x;
  18.140 +	sm[1][1] = y;
  18.141 +	sm[2][2] = z;
  18.142 +	m4_mult(m, m, sm);
  18.143 +}
  18.144 +
  18.145 +void m4_transpose(mat4_t res, mat4_t m)
  18.146 +{
  18.147 +	int i, j;
  18.148 +	mat4_t tmp;
  18.149 +	m4_copy(tmp, m);
  18.150 +
  18.151 +	for(i=0; i<4; i++) {
  18.152 +		for(j=0; j<4; j++) {
  18.153 +			res[i][j] = tmp[j][i];
  18.154 +		}
  18.155 +	}
  18.156 +}
  18.157 +
  18.158 +scalar_t m4_determinant(mat4_t m)
  18.159 +{
  18.160 +	scalar_t det11 =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  18.161 +						(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
  18.162 +						(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
  18.163 +
  18.164 +	scalar_t det12 =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  18.165 +						(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  18.166 +						(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
  18.167 +
  18.168 +	scalar_t det13 =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
  18.169 +						(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  18.170 +						(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  18.171 +
  18.172 +	scalar_t det14 =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
  18.173 +						(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
  18.174 +						(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  18.175 +
  18.176 +	return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14;
  18.177 +}
  18.178 +
  18.179 +void m4_adjoint(mat4_t res, mat4_t m)
  18.180 +{
  18.181 +	int i, j;
  18.182 +	mat4_t coef;
  18.183 +
  18.184 +	coef[0][0] =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  18.185 +					(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
  18.186 +					(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
  18.187 +	coef[0][1] =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  18.188 +					(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  18.189 +					(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
  18.190 +	coef[0][2] =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
  18.191 +					(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  18.192 +					(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  18.193 +	coef[0][3] =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
  18.194 +					(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
  18.195 +					(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  18.196 +
  18.197 +	coef[1][0] =	(m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  18.198 +					(m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
  18.199 +					(m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
  18.200 +	coef[1][1] =	(m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
  18.201 +					(m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  18.202 +					(m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
  18.203 +	coef[1][2] =	(m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
  18.204 +					(m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
  18.205 +					(m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  18.206 +	coef[1][3] =	(m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
  18.207 +					(m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
  18.208 +					(m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
  18.209 +
  18.210 +	coef[2][0] =	(m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
  18.211 +					(m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) +
  18.212 +					(m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2]));
  18.213 +	coef[2][1] =	(m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
  18.214 +					(m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
  18.215 +					(m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2]));
  18.216 +	coef[2][2] =	(m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) -
  18.217 +					(m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
  18.218 +					(m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
  18.219 +	coef[2][3] =	(m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) -
  18.220 +					(m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) +
  18.221 +					(m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
  18.222 +
  18.223 +	coef[3][0] =	(m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
  18.224 +					(m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) +
  18.225 +					(m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]));
  18.226 +	coef[3][1] =	(m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
  18.227 +					(m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
  18.228 +					(m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2]));
  18.229 +	coef[3][2] =	(m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) -
  18.230 +					(m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
  18.231 +					(m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
  18.232 +	coef[3][3] =	(m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) -
  18.233 +					(m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) +
  18.234 +					(m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
  18.235 +
  18.236 +	m4_transpose(res, coef);
  18.237 +
  18.238 +	for(i=0; i<4; i++) {
  18.239 +		for(j=0; j<4; j++) {
  18.240 +			res[i][j] = j % 2 ? -res[i][j] : res[i][j];
  18.241 +			if(i % 2) res[i][j] = -res[i][j];
  18.242 +		}
  18.243 +	}
  18.244 +}
  18.245 +
  18.246 +void m4_inverse(mat4_t res, mat4_t m)
  18.247 +{
  18.248 +	int i, j;
  18.249 +	mat4_t adj;
  18.250 +	scalar_t det;
  18.251 +
  18.252 +	m4_adjoint(adj, m);
  18.253 +	det = m4_determinant(m);
  18.254 +	
  18.255 +	for(i=0; i<4; i++) {
  18.256 +		for(j=0; j<4; j++) {
  18.257 +			res[i][j] = adj[i][j] / det;
  18.258 +		}
  18.259 +	}
  18.260 +}
  18.261 +
  18.262 +void m4_print(FILE *fp, mat4_t m)
  18.263 +{
  18.264 +	int i;
  18.265 +	for(i=0; i<4; i++) {
  18.266 +		fprintf(fp, "[ %12.5f %12.5f %12.5f %12.5f ]\n", (float)m[i][0], (float)m[i][1], (float)m[i][2], (float)m[i][3]);
  18.267 +	}
  18.268 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/prototype/vmath/quat.cc	Thu Jun 28 06:05:50 2012 +0300
    19.3 @@ -0,0 +1,159 @@
    19.4 +#include "quat.h"
    19.5 +
    19.6 +Quaternion::Quaternion() {
    19.7 +	s = 1.0;
    19.8 +	v.x = v.y = v.z = 0.0;
    19.9 +}
   19.10 +
   19.11 +Quaternion::Quaternion(scalar_t s, const Vector3 &v) {
   19.12 +	this->s = s;
   19.13 +	this->v = v;
   19.14 +}
   19.15 +
   19.16 +Quaternion::Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z) {
   19.17 +	v.x = x;
   19.18 +	v.y = y;
   19.19 +	v.z = z;
   19.20 +	this->s = s;
   19.21 +}
   19.22 +
   19.23 +Quaternion::Quaternion(const Vector3 &axis, scalar_t angle) {
   19.24 +	set_rotation(axis, angle);
   19.25 +}
   19.26 +
   19.27 +Quaternion::Quaternion(const quat_t &quat)
   19.28 +{
   19.29 +	v.x = quat.x;
   19.30 +	v.y = quat.y;
   19.31 +	v.z = quat.z;
   19.32 +	s = quat.w;
   19.33 +}
   19.34 +
   19.35 +Quaternion Quaternion::operator +(const Quaternion &quat) const {
   19.36 +	return Quaternion(s + quat.s, v + quat.v);
   19.37 +}
   19.38 +
   19.39 +Quaternion Quaternion::operator -(const Quaternion &quat) const {
   19.40 +	return Quaternion(s - quat.s, v - quat.v);
   19.41 +}
   19.42 +
   19.43 +Quaternion Quaternion::operator -() const {
   19.44 +	return Quaternion(-s, -v);
   19.45 +}
   19.46 +
   19.47 +/** Quaternion Multiplication:
   19.48 + * Q1*Q2 = [s1*s2 - v1.v2,  s1*v2 + s2*v1 + v1(x)v2]
   19.49 + */
   19.50 +Quaternion Quaternion::operator *(const Quaternion &quat) const {
   19.51 +	Quaternion newq;
   19.52 +	newq.s = s * quat.s - dot_product(v, quat.v);
   19.53 +	newq.v = quat.v * s + v * quat.s + cross_product(v, quat.v);
   19.54 +	return newq;
   19.55 +}
   19.56 +
   19.57 +void Quaternion::operator +=(const Quaternion &quat) {
   19.58 +	*this = Quaternion(s + quat.s, v + quat.v);
   19.59 +}
   19.60 +
   19.61 +void Quaternion::operator -=(const Quaternion &quat) {
   19.62 +	*this = Quaternion(s - quat.s, v - quat.v);
   19.63 +}
   19.64 +
   19.65 +void Quaternion::operator *=(const Quaternion &quat) {
   19.66 +	*this = *this * quat;
   19.67 +}
   19.68 +
   19.69 +void Quaternion::reset_identity() {
   19.70 +	s = 1.0;
   19.71 +	v.x = v.y = v.z = 0.0;
   19.72 +}
   19.73 +
   19.74 +Quaternion Quaternion::conjugate() const {
   19.75 +	return Quaternion(s, -v);
   19.76 +}
   19.77 +
   19.78 +scalar_t Quaternion::length() const {
   19.79 +	return (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s);
   19.80 +}
   19.81 +
   19.82 +/** Q * ~Q = ||Q||^2 */
   19.83 +scalar_t Quaternion::length_sq() const {
   19.84 +	return v.x*v.x + v.y*v.y + v.z*v.z + s*s;
   19.85 +}
   19.86 +
   19.87 +void Quaternion::normalize() {
   19.88 +	scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s);
   19.89 +	v.x /= len;
   19.90 +	v.y /= len;
   19.91 +	v.z /= len;
   19.92 +	s /= len;
   19.93 +}
   19.94 +
   19.95 +Quaternion Quaternion::normalized() const {
   19.96 +	Quaternion nq = *this;
   19.97 +	scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s);
   19.98 +	nq.v.x /= len;
   19.99 +	nq.v.y /= len;
  19.100 +	nq.v.z /= len;
  19.101 +	nq.s /= len;
  19.102 +	return nq;
  19.103 +}
  19.104 +
  19.105 +/** Quaternion Inversion: Q^-1 = ~Q / ||Q||^2 */
  19.106 +Quaternion Quaternion::inverse() const {
  19.107 +	Quaternion inv = conjugate();
  19.108 +	scalar_t lensq = length_sq();
  19.109 +	inv.v /= lensq;
  19.110 +	inv.s /= lensq;
  19.111 +
  19.112 +	return inv;
  19.113 +}
  19.114 +
  19.115 +
  19.116 +void Quaternion::set_rotation(const Vector3 &axis, scalar_t angle) {
  19.117 +	scalar_t half_angle = angle / 2.0;
  19.118 +	s = cos(half_angle);
  19.119 +	v = axis * sin(half_angle);
  19.120 +}
  19.121 +
  19.122 +void Quaternion::rotate(const Vector3 &axis, scalar_t angle) {
  19.123 +	Quaternion q;
  19.124 +	scalar_t half_angle = angle / 2.0;
  19.125 +	q.s = cos(half_angle);
  19.126 +	q.v = axis * sin(half_angle);
  19.127 +
  19.128 +	*this *= q;
  19.129 +}
  19.130 +
  19.131 +void Quaternion::rotate(const Quaternion &q) {
  19.132 +	*this = q * *this * q.conjugate();
  19.133 +}
  19.134 +
  19.135 +Matrix3x3 Quaternion::get_rotation_matrix() const {
  19.136 +	return Matrix3x3(	1.0 - 2.0 * v.y*v.y - 2.0 * v.z*v.z,	2.0 * v.x * v.y + 2.0 * s * v.z,		2.0 * v.z * v.x - 2.0 * s * v.y,
  19.137 +						2.0 * v.x * v.y - 2.0 * s * v.z,		1.0 - 2.0 * v.x*v.x - 2.0 * v.z*v.z,	2.0 * v.y * v.z + 2.0 * s * v.x,
  19.138 +						2.0 * v.z * v.x + 2.0 * s * v.y,		2.0 * v.y * v.z - 2.0 * s * v.x,		1.0 - 2.0 * v.x*v.x - 2.0 * v.y*v.y);
  19.139 +}
  19.140 +
  19.141 +
  19.142 +/** Spherical linear interpolation (slerp) */
  19.143 +Quaternion slerp(const Quaternion &q1, const Quaternion &q2, scalar_t t) {
  19.144 +	scalar_t angle = acos(q1.s * q2.s + q1.v.x * q2.v.x + q1.v.y * q2.v.y + q1.v.z * q2.v.z);
  19.145 +	scalar_t a = sin((1.0f - t) * angle);
  19.146 +	scalar_t b = sin(t * angle);
  19.147 +	scalar_t c = sin(angle);
  19.148 +
  19.149 +	scalar_t x = (q1.v.x * a + q2.v.x * b) / c;
  19.150 +	scalar_t y = (q1.v.y * a + q2.v.y * b) / c;
  19.151 +	scalar_t z = (q1.v.z * a + q2.v.z * b) / c;
  19.152 +	scalar_t s = (q1.s * a + q2.s * b) / c;
  19.153 +
  19.154 +	return Quaternion(s, Vector3(x, y, z)).normalized();
  19.155 +}
  19.156 +	
  19.157 +
  19.158 +
  19.159 +std::ostream &operator <<(std::ostream &out, const Quaternion &q) {
  19.160 +	out << "(" << q.s << ", " << q.v << ")";
  19.161 +	return out;
  19.162 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/prototype/vmath/quat.h	Thu Jun 28 06:05:50 2012 +0300
    20.3 @@ -0,0 +1,119 @@
    20.4 +/*
    20.5 +libvmath - a vector math library
    20.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    20.7 +
    20.8 +This program is free software: you can redistribute it and/or modify
    20.9 +it under the terms of the GNU Lesser General Public License as published
   20.10 +by the Free Software Foundation, either version 3 of the License, or
   20.11 +(at your option) any later version.
   20.12 +
   20.13 +This program is distributed in the hope that it will be useful,
   20.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.16 +GNU Lesser General Public License for more details.
   20.17 +
   20.18 +You should have received a copy of the GNU Lesser General Public License
   20.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   20.20 +*/
   20.21 +
   20.22 +#ifndef VMATH_QUATERNION_H_
   20.23 +#define VMATH_QUATERNION_H_
   20.24 +
   20.25 +#include <stdio.h>
   20.26 +#include "vmath_types.h"
   20.27 +#include "vector.h"
   20.28 +
   20.29 +#ifdef __cplusplus
   20.30 +extern "C" {
   20.31 +#endif	/* __cplusplus */
   20.32 +
   20.33 +#define quat_cons(s, x, y, z)	v4_cons(x, y, z, s)
   20.34 +#define quat_vec(q)				v3_cons((q).x, (q).y, (q).z)
   20.35 +#define quat_s(q)				((q).w)
   20.36 +#define quat_identity()			quat_cons(1.0, 0.0, 0.0, 0.0)
   20.37 +void quat_print(FILE *fp, quat_t q);
   20.38 +
   20.39 +#define quat_add		v4_add
   20.40 +#define quat_sub		v4_sub
   20.41 +#define quat_neg		v4_neg
   20.42 +
   20.43 +static inline quat_t quat_mul(quat_t q1, quat_t q2);
   20.44 +
   20.45 +static inline quat_t quat_conjugate(quat_t q);
   20.46 +
   20.47 +#define quat_length		v4_length
   20.48 +#define quat_length_sq	v4_length_sq
   20.49 +
   20.50 +#define quat_normalize	v4_normalize
   20.51 +static inline quat_t quat_inverse(quat_t q);
   20.52 +
   20.53 +quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z);
   20.54 +quat_t quat_rotate_quat(quat_t q, quat_t rotq);
   20.55 +
   20.56 +static inline void quat_to_mat3(mat3_t res, quat_t q);
   20.57 +static inline void quat_to_mat4(mat4_t res, quat_t q);
   20.58 +
   20.59 +#define quat_lerp quat_slerp
   20.60 +quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t);
   20.61 +
   20.62 +
   20.63 +#ifdef __cplusplus
   20.64 +}	/* extern "C" */
   20.65 +
   20.66 +#include <iostream>
   20.67 +
   20.68 +/* Quaternion */
   20.69 +class Quaternion {
   20.70 +public:
   20.71 +	scalar_t s;
   20.72 +	Vector3 v;
   20.73 +
   20.74 +	Quaternion();
   20.75 +	Quaternion(scalar_t s, const Vector3 &v);
   20.76 +	Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z);
   20.77 +	Quaternion(const Vector3 &axis, scalar_t angle);
   20.78 +	Quaternion(const quat_t &quat);
   20.79 +
   20.80 +	Quaternion operator +(const Quaternion &quat) const;
   20.81 +	Quaternion operator -(const Quaternion &quat) const;
   20.82 +	Quaternion operator -() const;
   20.83 +	Quaternion operator *(const Quaternion &quat) const;
   20.84 +
   20.85 +	void operator +=(const Quaternion &quat);
   20.86 +	void operator -=(const Quaternion &quat);
   20.87 +	void operator *=(const Quaternion &quat);
   20.88 +
   20.89 +	void reset_identity();
   20.90 +
   20.91 +	Quaternion conjugate() const;
   20.92 +
   20.93 +	scalar_t length() const;
   20.94 +	scalar_t length_sq() const;
   20.95 +
   20.96 +	void normalize();
   20.97 +	Quaternion normalized() const;
   20.98 +
   20.99 +	Quaternion inverse() const;
  20.100 +
  20.101 +	void set_rotation(const Vector3 &axis, scalar_t angle);
  20.102 +	void rotate(const Vector3 &axis, scalar_t angle);
  20.103 +	/* note: this is a totally different operation from the above
  20.104 +	 * this treats the quaternion as signifying direction and rotates
  20.105 +	 * it by a rotation quaternion by rot * q * rot'
  20.106 +	 */
  20.107 +	void rotate(const Quaternion &q);
  20.108 +
  20.109 +	Matrix3x3 get_rotation_matrix() const;
  20.110 +
  20.111 +	friend Quaternion slerp(const Quaternion &q1, const Quaternion &q2, scalar_t t);
  20.112 +
  20.113 +	friend std::ostream &operator <<(std::ostream &out, const Quaternion &q);
  20.114 +};
  20.115 +
  20.116 +Quaternion slerp(const Quaternion &q1, const Quaternion &q2, scalar_t t);
  20.117 +inline Quaternion lerp(const Quaternion &q1, const Quaternion &q2, scalar_t t);
  20.118 +#endif	/* __cplusplus */
  20.119 +
  20.120 +#include "quat.inl"
  20.121 +
  20.122 +#endif	/* VMATH_QUATERNION_H_ */
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/prototype/vmath/quat.inl	Thu Jun 28 06:05:50 2012 +0300
    21.3 @@ -0,0 +1,81 @@
    21.4 +/*
    21.5 +libvmath - a vector math library
    21.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    21.7 +
    21.8 +This program is free software: you can redistribute it and/or modify
    21.9 +it under the terms of the GNU Lesser General Public License as published
   21.10 +by the Free Software Foundation, either version 3 of the License, or
   21.11 +(at your option) any later version.
   21.12 +
   21.13 +This program is distributed in the hope that it will be useful,
   21.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.16 +GNU Lesser General Public License for more details.
   21.17 +
   21.18 +You should have received a copy of the GNU Lesser General Public License
   21.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   21.20 +*/
   21.21 +
   21.22 +#include "vector.h"
   21.23 +#include "matrix.h"
   21.24 +
   21.25 +#ifdef __cplusplus
   21.26 +extern "C" {
   21.27 +#endif	/* __cplusplus */
   21.28 +
   21.29 +static inline quat_t quat_mul(quat_t q1, quat_t q2)
   21.30 +{
   21.31 +	quat_t res;
   21.32 +	vec3_t v1 = quat_vec(q1);
   21.33 +	vec3_t v2 = quat_vec(q2);
   21.34 +
   21.35 +	res.w = q1.w * q2.w - v3_dot(v1, v2);
   21.36 +	/* resvec = v2 * q1 + v1 * q2 + cross(v1, v2) */
   21.37 +	res.x = v2.x * q1.w + v1.x * q2.w + (v1.y * v2.z - v1.z * v2.y);
   21.38 +	res.y = v2.y * q1.w + v1.y * q2.w + (v1.z * v2.x - v1.x * v2.z);
   21.39 +	res.z = v2.z * q1.w + v1.z * q2.w + (v1.x * v2.y - v1.y * v2.x);
   21.40 +	return res;
   21.41 +}
   21.42 +
   21.43 +static inline quat_t quat_conjugate(quat_t q)
   21.44 +{
   21.45 +	q.x = -q.x;
   21.46 +	q.y = -q.y;
   21.47 +	q.z = -q.z;
   21.48 +	return q;
   21.49 +}
   21.50 +
   21.51 +static inline quat_t quat_inverse(quat_t q)
   21.52 +{
   21.53 +	scalar_t lensq = quat_length_sq(q);
   21.54 +	q = quat_conjugate(q);
   21.55 +	q.x /= lensq;
   21.56 +	q.y /= lensq;
   21.57 +	q.z /= lensq;
   21.58 +	q.w /= lensq;
   21.59 +	return q;
   21.60 +}
   21.61 +
   21.62 +static inline void quat_to_mat3(mat3_t res, quat_t q)
   21.63 +{
   21.64 +	m3_cons(res, 1.0 - 2.0 * q.y*q.y - 2.0 * q.z*q.z, 2.0 * q.x * q.y + 2.0 * q.w * q.z,   2.0 * q.z * q.x - 2.0 * q.w * q.y,
   21.65 +				 2.0 * q.x * q.y - 2.0 * q.w * q.z,   1.0 - 2.0 * q.x*q.x - 2.0 * q.z*q.z, 2.0 * q.y * q.z + 2.0 * q.w * q.x,
   21.66 +				 2.0 * q.z * q.x + 2.0 * q.w * q.y,   2.0 * q.y * q.z - 2.0 * q.w * q.x,   1.0 - 2.0 * q.x*q.x - 2.0 * q.y*q.y);
   21.67 +}
   21.68 +
   21.69 +static inline void quat_to_mat4(mat4_t res, quat_t q)
   21.70 +{
   21.71 +	m4_cons(res, 1.0 - 2.0 * q.y*q.y - 2.0 * q.z*q.z, 2.0 * q.x * q.y + 2.0 * q.w * q.z,   2.0 * q.z * q.x - 2.0 * q.w * q.y,   0,
   21.72 +				 2.0 * q.x * q.y - 2.0 * q.w * q.z,   1.0 - 2.0 * q.x*q.x - 2.0 * q.z*q.z, 2.0 * q.y * q.z + 2.0 * q.w * q.x,   0,
   21.73 +				 2.0 * q.z * q.x + 2.0 * q.w * q.y,   2.0 * q.y * q.z - 2.0 * q.w * q.x,   1.0 - 2.0 * q.x*q.x - 2.0 * q.y*q.y, 0,
   21.74 +				 0, 0, 0, 1);
   21.75 +}
   21.76 +
   21.77 +#ifdef __cplusplus
   21.78 +}	/* extern "C" */
   21.79 +
   21.80 +inline Quaternion lerp(const Quaternion &a, const Quaternion &b, scalar_t t)
   21.81 +{
   21.82 +	return slerp(a, b, t);
   21.83 +}
   21.84 +#endif	/* __cplusplus */
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/prototype/vmath/quat_c.c	Thu Jun 28 06:05:50 2012 +0300
    22.3 @@ -0,0 +1,61 @@
    22.4 +/*
    22.5 +libvmath - a vector math library
    22.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    22.7 +
    22.8 +This program is free software: you can redistribute it and/or modify
    22.9 +it under the terms of the GNU Lesser General Public License as published
   22.10 +by the Free Software Foundation, either version 3 of the License, or
   22.11 +(at your option) any later version.
   22.12 +
   22.13 +This program is distributed in the hope that it will be useful,
   22.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22.16 +GNU Lesser General Public License for more details.
   22.17 +
   22.18 +You should have received a copy of the GNU Lesser General Public License
   22.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   22.20 +*/
   22.21 +
   22.22 +
   22.23 +#include <stdio.h>
   22.24 +#include <math.h>
   22.25 +#include "quat.h"
   22.26 +
   22.27 +void quat_print(FILE *fp, quat_t q)
   22.28 +{
   22.29 +	fprintf(fp, "([ %.4f %.4f %.4f ] %.4f)", q.x, q.y, q.z, q.w);
   22.30 +}
   22.31 +
   22.32 +quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z)
   22.33 +{
   22.34 +	quat_t rq;
   22.35 +	scalar_t half_angle = angle * 0.5;
   22.36 +	scalar_t sin_half = sin(half_angle);
   22.37 +
   22.38 +	rq.w = cos(half_angle);
   22.39 +	rq.x = x * sin_half;
   22.40 +	rq.y = y * sin_half;
   22.41 +	rq.z = z * sin_half;
   22.42 +
   22.43 +	return quat_mul(q, rq);
   22.44 +}
   22.45 +
   22.46 +quat_t quat_rotate_quat(quat_t q, quat_t rotq)
   22.47 +{
   22.48 +	return quat_mul(quat_mul(rotq, q), quat_conjugate(rotq));
   22.49 +}
   22.50 +
   22.51 +quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t)
   22.52 +{
   22.53 +	quat_t res;
   22.54 +	scalar_t angle = acos(q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z);
   22.55 +	scalar_t a = sin((1.0f - t) * angle);
   22.56 +	scalar_t b = sin(t * angle);
   22.57 +	scalar_t c = sin(angle);
   22.58 +
   22.59 +	res.x = (q1.x * a + q2.x * b) / c;
   22.60 +	res.y = (q1.y * a + q2.y * b) / c;
   22.61 +	res.z = (q1.z * a + q2.z * b) / c;
   22.62 +	res.w = (q1.w * a + q2.w * b) / c;
   22.63 +	return quat_normalize(res);
   22.64 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/prototype/vmath/ray.cc	Thu Jun 28 06:05:50 2012 +0300
    23.3 @@ -0,0 +1,66 @@
    23.4 +#include "ray.h"
    23.5 +#include "vector.h"
    23.6 +
    23.7 +scalar_t Ray::env_ior = 1.0;
    23.8 +
    23.9 +Ray::Ray() {
   23.10 +	ior = env_ior;
   23.11 +	energy = 1.0;
   23.12 +	time = 0;
   23.13 +	iter = 0;
   23.14 +}
   23.15 +
   23.16 +Ray::Ray(const Vector3 &origin, const Vector3 &dir) {
   23.17 +	this->origin = origin;
   23.18 +	this->dir = dir;
   23.19 +	ior = env_ior;
   23.20 +	energy = 1.0;
   23.21 +	time = 0;
   23.22 +	iter = 0;
   23.23 +}
   23.24 +
   23.25 +void Ray::transform(const Matrix4x4 &xform) {
   23.26 +	Matrix4x4 upper;
   23.27 +	Vector3 dir;
   23.28 +
   23.29 +	upper = xform;
   23.30 +	upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0;
   23.31 +	upper[3][3] = 1.0;
   23.32 +
   23.33 +	dir = (this->dir - origin).transformed(upper);
   23.34 +	origin.transform(xform);
   23.35 +	this->dir = dir + origin;
   23.36 +}
   23.37 +
   23.38 +Ray Ray::transformed(const Matrix4x4 &xform) const {
   23.39 +	Ray foo = *this;
   23.40 +	foo.transform(xform);
   23.41 +	return foo;
   23.42 +}
   23.43 +
   23.44 +void Ray::enter(scalar_t new_ior) {
   23.45 +	ior = new_ior;
   23.46 +	ior_stack.push(ior);
   23.47 +}
   23.48 +
   23.49 +void Ray::leave() {
   23.50 +	if(ior_stack.empty()) {
   23.51 +		//std::cerr << "empty ior stack?\n";
   23.52 +		return;
   23.53 +	}
   23.54 +	ior_stack.pop();
   23.55 +	ior = ior_stack.empty() ? env_ior : ior_stack.top();
   23.56 +}
   23.57 +
   23.58 +scalar_t Ray::calc_ior(bool entering, scalar_t mat_ior) const
   23.59 +{
   23.60 +	scalar_t from_ior = this->ior;
   23.61 +
   23.62 +	if(entering) {
   23.63 +		return from_ior / mat_ior;
   23.64 +	}
   23.65 +
   23.66 +	Ray tmp = *this;
   23.67 +	tmp.leave();
   23.68 +	return from_ior / tmp.ior;
   23.69 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/prototype/vmath/ray.h	Thu Jun 28 06:05:50 2012 +0300
    24.3 @@ -0,0 +1,73 @@
    24.4 +/*
    24.5 +libvmath - a vector math library
    24.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    24.7 +
    24.8 +This program is free software: you can redistribute it and/or modify
    24.9 +it under the terms of the GNU Lesser General Public License as published
   24.10 +by the Free Software Foundation, either version 3 of the License, or
   24.11 +(at your option) any later version.
   24.12 +
   24.13 +This program is distributed in the hope that it will be useful,
   24.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   24.16 +GNU Lesser General Public License for more details.
   24.17 +
   24.18 +You should have received a copy of the GNU Lesser General Public License
   24.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   24.20 +*/
   24.21 +
   24.22 +#ifndef VMATH_RAY_H_
   24.23 +#define VMATH_RAY_H_
   24.24 +
   24.25 +#include "matrix.h"
   24.26 +#include "vector.h"
   24.27 +
   24.28 +typedef struct {
   24.29 +	vec3_t origin, dir;
   24.30 +} ray_t;
   24.31 +
   24.32 +#ifdef __cplusplus
   24.33 +extern "C" {
   24.34 +#endif	/* __cplusplus */
   24.35 +
   24.36 +static inline ray_t ray_cons(vec3_t origin, vec3_t dir);
   24.37 +ray_t ray_transform(ray_t r, mat4_t m);
   24.38 +
   24.39 +#ifdef __cplusplus
   24.40 +}	/* __cplusplus */
   24.41 +
   24.42 +#include <stack>
   24.43 +
   24.44 +class Ray {
   24.45 +private:
   24.46 +	std::stack<scalar_t> ior_stack;
   24.47 +
   24.48 +public:
   24.49 +	/* enviornmental index of refraction, normally 1.0 */
   24.50 +	static scalar_t env_ior;
   24.51 +	
   24.52 +	Vector3 origin, dir;
   24.53 +	scalar_t energy;
   24.54 +	int iter;
   24.55 +	scalar_t ior;
   24.56 +	long time;
   24.57 +
   24.58 +	Ray();
   24.59 +	Ray(const Vector3 &origin, const Vector3 &dir);
   24.60 +
   24.61 +	void transform(const Matrix4x4 &xform);
   24.62 +	Ray transformed(const Matrix4x4 &xform) const;
   24.63 +
   24.64 +	void enter(scalar_t new_ior);
   24.65 +	void leave();
   24.66 +
   24.67 +	scalar_t calc_ior(bool entering, scalar_t mat_ior = 1.0) const;
   24.68 +};
   24.69 +
   24.70 +inline Ray reflect_ray(const Ray &inray, const Vector3 &norm);
   24.71 +inline Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t ior, bool entering, scalar_t ray_mag = -1.0);
   24.72 +#endif	/* __cplusplus */
   24.73 +
   24.74 +#include "ray.inl"
   24.75 +
   24.76 +#endif	/* VMATH_RAY_H_ */
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/prototype/vmath/ray.inl	Thu Jun 28 06:05:50 2012 +0300
    25.3 @@ -0,0 +1,70 @@
    25.4 +/*
    25.5 +libvmath - a vector math library
    25.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    25.7 +
    25.8 +This program is free software: you can redistribute it and/or modify
    25.9 +it under the terms of the GNU Lesser General Public License as published
   25.10 +by the Free Software Foundation, either version 3 of the License, or
   25.11 +(at your option) any later version.
   25.12 +
   25.13 +This program is distributed in the hope that it will be useful,
   25.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   25.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   25.16 +GNU Lesser General Public License for more details.
   25.17 +
   25.18 +You should have received a copy of the GNU Lesser General Public License
   25.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   25.20 +*/
   25.21 +
   25.22 +#ifdef __cplusplus
   25.23 +extern "C" {
   25.24 +#endif	/* __cplusplus */
   25.25 +
   25.26 +static inline ray_t ray_cons(vec3_t origin, vec3_t dir)
   25.27 +{
   25.28 +	ray_t r;
   25.29 +	r.origin = origin;
   25.30 +	r.dir = dir;
   25.31 +	return r;
   25.32 +}
   25.33 +
   25.34 +#ifdef __cplusplus
   25.35 +}
   25.36 +
   25.37 +inline Ray reflect_ray(const Ray &inray, const Vector3 &norm)
   25.38 +{
   25.39 +	Ray ray = inray;
   25.40 +	ray.iter--;
   25.41 +	ray.dir = ray.dir.reflection(norm);
   25.42 +	return ray;
   25.43 +}
   25.44 +
   25.45 +inline Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t mat_ior, bool entering, scalar_t ray_mag)
   25.46 +{
   25.47 +	Ray ray = inray;
   25.48 +	ray.iter--;
   25.49 +
   25.50 +	scalar_t ior = ray.calc_ior(entering, mat_ior);
   25.51 +	
   25.52 +	if(entering) {
   25.53 +		ray.enter(mat_ior);
   25.54 +	} else {
   25.55 +		ray.leave();
   25.56 +	}
   25.57 +
   25.58 +	if(ray_mag < 0.0) {
   25.59 +		ray_mag = ray.dir.length();
   25.60 +	}
   25.61 +	ray.dir = (ray.dir / ray_mag).refraction(norm, ior) * ray_mag;
   25.62 +
   25.63 +	/* check TIR */
   25.64 +	if(dot_product(ray.dir, norm) > 0.0) {
   25.65 +		if(entering) {
   25.66 +			ray.leave();
   25.67 +		} else {
   25.68 +			ray.enter(mat_ior);
   25.69 +		}
   25.70 +	}
   25.71 +	return ray;
   25.72 +}
   25.73 +#endif	/* __cplusplus */
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/prototype/vmath/ray_c.c	Thu Jun 28 06:05:50 2012 +0300
    26.3 @@ -0,0 +1,36 @@
    26.4 +/*
    26.5 +libvmath - a vector math library
    26.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    26.7 +
    26.8 +This program is free software: you can redistribute it and/or modify
    26.9 +it under the terms of the GNU Lesser General Public License as published
   26.10 +by the Free Software Foundation, either version 3 of the License, or
   26.11 +(at your option) any later version.
   26.12 +
   26.13 +This program is distributed in the hope that it will be useful,
   26.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   26.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   26.16 +GNU Lesser General Public License for more details.
   26.17 +
   26.18 +You should have received a copy of the GNU Lesser General Public License
   26.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   26.20 +*/
   26.21 +
   26.22 +#include "ray.h"
   26.23 +#include "vector.h"
   26.24 +
   26.25 +ray_t ray_transform(ray_t r, mat4_t xform)
   26.26 +{
   26.27 +	mat4_t upper;
   26.28 +	vec3_t dir;
   26.29 +
   26.30 +	m4_copy(upper, xform);
   26.31 +	upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0;
   26.32 +	upper[3][3] = 1.0;
   26.33 +
   26.34 +	dir = v3_sub(r.dir, r.origin);
   26.35 +	dir = v3_transform(dir, upper);
   26.36 +	r.origin = v3_transform(r.origin, xform);
   26.37 +	r.dir = v3_add(dir, r.origin);
   26.38 +	return r;
   26.39 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/prototype/vmath/sphvec.cc	Thu Jun 28 06:05:50 2012 +0300
    27.3 @@ -0,0 +1,27 @@
    27.4 +#include "sphvec.h"
    27.5 +#include "vector.h"
    27.6 +
    27.7 +/* theta: 0 <= theta <= 2pi, the angle around Y axis.
    27.8 + * phi: 0 <= phi <= pi, the angle from Y axis.
    27.9 + * r: radius.
   27.10 + */
   27.11 +SphVector::SphVector(scalar_t theta, scalar_t phi, scalar_t r) {
   27.12 +	this->theta = theta;
   27.13 +	this->phi = phi;
   27.14 +	this->r = r;
   27.15 +}
   27.16 +
   27.17 +/* Constructs a spherical coordinate vector from a cartesian vector */
   27.18 +SphVector::SphVector(const Vector3 &cvec) {
   27.19 +	*this = cvec;
   27.20 +}
   27.21 +
   27.22 +/* Assignment operator that converts cartesian to spherical coords */
   27.23 +SphVector &SphVector::operator =(const Vector3 &cvec) {
   27.24 +	r = cvec.length();
   27.25 +	//theta = atan2(cvec.y, cvec.x);
   27.26 +	theta = atan2(cvec.z, cvec.x);
   27.27 +	//phi = acos(cvec.z / r);
   27.28 +	phi = acos(cvec.y / r);
   27.29 +	return *this;
   27.30 +}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/prototype/vmath/sphvec.h	Thu Jun 28 06:05:50 2012 +0300
    28.3 @@ -0,0 +1,36 @@
    28.4 +/*
    28.5 +libvmath - a vector math library
    28.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    28.7 +
    28.8 +This program is free software: you can redistribute it and/or modify
    28.9 +it under the terms of the GNU Lesser General Public License as published
   28.10 +by the Free Software Foundation, either version 3 of the License, or
   28.11 +(at your option) any later version.
   28.12 +
   28.13 +This program is distributed in the hope that it will be useful,
   28.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.16 +GNU Lesser General Public License for more details.
   28.17 +
   28.18 +You should have received a copy of the GNU Lesser General Public License
   28.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   28.20 +*/
   28.21 +
   28.22 +#ifndef VMATH_SPHVEC_H_
   28.23 +#define VMATH_SPHVEC_H_
   28.24 +
   28.25 +#include "vmath_types.h"
   28.26 +
   28.27 +#ifdef __cplusplus
   28.28 +/* Vector in spherical coordinates */
   28.29 +class SphVector {
   28.30 +public:
   28.31 +	scalar_t theta, phi, r;
   28.32 +
   28.33 +	SphVector(scalar_t theta = 0.0, scalar_t phi = 0.0, scalar_t r = 1.0);
   28.34 +	SphVector(const Vector3 &cvec);
   28.35 +	SphVector &operator =(const Vector3 &cvec);
   28.36 +};
   28.37 +#endif	/* __cplusplus */
   28.38 +
   28.39 +#endif	/* VMATH_SPHVEC_H_ */
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/prototype/vmath/vector.cc	Thu Jun 28 06:05:50 2012 +0300
    29.3 @@ -0,0 +1,326 @@
    29.4 +#include "vector.h"
    29.5 +#include "vmath.h"
    29.6 +
    29.7 +// ---------- Vector2 -----------
    29.8 +
    29.9 +Vector2::Vector2(scalar_t x, scalar_t y)
   29.10 +{
   29.11 +	this->x = x;
   29.12 +	this->y = y;
   29.13 +}
   29.14 +
   29.15 +Vector2::Vector2(const vec2_t &vec)
   29.16 +{
   29.17 +	x = vec.x;
   29.18 +	y = vec.y;
   29.19 +}
   29.20 +
   29.21 +Vector2::Vector2(const Vector3 &vec)
   29.22 +{
   29.23 +	x = vec.x;
   29.24 +	y = vec.y;
   29.25 +}
   29.26 +
   29.27 +Vector2::Vector2(const Vector4 &vec)
   29.28 +{
   29.29 +	x = vec.x;
   29.30 +	y = vec.y;
   29.31 +}
   29.32 +
   29.33 +void Vector2::normalize()
   29.34 +{
   29.35 +	scalar_t len = length();
   29.36 +	x /= len;
   29.37 +	y /= len;
   29.38 +}
   29.39 +
   29.40 +Vector2 Vector2::normalized() const
   29.41 +{
   29.42 +	scalar_t len = length();
   29.43 +	return Vector2(x / len, y / len);
   29.44 +}
   29.45 +
   29.46 +void Vector2::transform(const Matrix3x3 &mat)
   29.47 +{
   29.48 +	scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2];
   29.49 +	y = mat[1][0] * x + mat[1][1] * y + mat[1][2];
   29.50 +	x = nx;
   29.51 +}
   29.52 +
   29.53 +Vector2 Vector2::transformed(const Matrix3x3 &mat) const
   29.54 +{
   29.55 +	Vector2 vec;
   29.56 +	vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2];
   29.57 +	vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2];
   29.58 +	return vec;
   29.59 +}
   29.60 +
   29.61 +void Vector2::rotate(scalar_t angle)
   29.62 +{
   29.63 +	*this = Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y);
   29.64 +}
   29.65 +
   29.66 +Vector2 Vector2::rotated(scalar_t angle) const
   29.67 +{
   29.68 +	return Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y);
   29.69 +}
   29.70 +
   29.71 +Vector2 Vector2::reflection(const Vector2 &normal) const
   29.72 +{
   29.73 +	return 2.0 * dot_product(*this, normal) * normal - *this;
   29.74 +}
   29.75 +
   29.76 +Vector2 Vector2::refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const
   29.77 +{
   29.78 +	// quick and dirty implementation :)
   29.79 +	Vector3 v3refr = Vector3(this->x, this->y, 1.0).refraction(Vector3(this->x, this->y, 1), src_ior, dst_ior);
   29.80 +	return Vector2(v3refr.x, v3refr.y);
   29.81 +}
   29.82 +
   29.83 +std::ostream &operator <<(std::ostream &out, const Vector2 &vec)
   29.84 +{
   29.85 +	out << "[" << vec.x << " " << vec.y << "]";
   29.86 +	return out;
   29.87 +}
   29.88 +
   29.89 +
   29.90 +
   29.91 +// --------- Vector3 ----------
   29.92 +
   29.93 +Vector3::Vector3(scalar_t x, scalar_t y, scalar_t z)
   29.94 +{
   29.95 +	this->x = x;
   29.96 +	this->y = y;
   29.97 +	this->z = z;
   29.98 +}
   29.99 +
  29.100 +Vector3::Vector3(const vec3_t &vec)
  29.101 +{
  29.102 +	x = vec.x;
  29.103 +	y = vec.y;
  29.104 +	z = vec.z;
  29.105 +}
  29.106 +
  29.107 +Vector3::Vector3(const Vector2 &vec)
  29.108 +{
  29.109 +	x = vec.x;
  29.110 +	y = vec.y;
  29.111 +	z = 1;
  29.112 +}
  29.113 +
  29.114 +Vector3::Vector3(const Vector4 &vec)
  29.115 +{
  29.116 +	x = vec.x;
  29.117 +	y = vec.y;
  29.118 +	z = vec.z;
  29.119 +}
  29.120 +
  29.121 +Vector3::Vector3(const SphVector &sph)
  29.122 +{
  29.123 +	*this = sph;
  29.124 +}
  29.125 +
  29.126 +Vector3 &Vector3::operator =(const SphVector &sph)
  29.127 +{
  29.128 +	x = sph.r * cos(sph.theta) * sin(sph.phi);
  29.129 +	z = sph.r * sin(sph.theta) * sin(sph.phi);
  29.130 +	y = sph.r * cos(sph.phi);
  29.131 +	return *this;
  29.132 +}
  29.133 +
  29.134 +void Vector3::normalize()
  29.135 +{
  29.136 +	scalar_t len = length();
  29.137 +	x /= len;
  29.138 +	y /= len;
  29.139 +	z /= len;
  29.140 +}
  29.141 +
  29.142 +Vector3 Vector3::normalized() const
  29.143 +{
  29.144 +	scalar_t len = length();
  29.145 +	return Vector3(x / len, y / len, z / len);
  29.146 +}
  29.147 +
  29.148 +Vector3 Vector3::reflection(const Vector3 &normal) const
  29.149 +{
  29.150 +	return 2.0 * dot_product(*this, normal) * normal - *this;
  29.151 +}
  29.152 +
  29.153 +Vector3 Vector3::refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const
  29.154 +{
  29.155 +	return refraction(normal, src_ior / dst_ior);
  29.156 +}
  29.157 +
  29.158 +Vector3 Vector3::refraction(const Vector3 &normal, scalar_t ior) const
  29.159 +{
  29.160 +	scalar_t cos_inc = dot_product(*this, -normal);
  29.161 +
  29.162 +	scalar_t radical = 1.0 + SQ(ior) * (SQ(cos_inc) - 1.0);
  29.163 +
  29.164 +	if(radical < 0.0) {		// total internal reflection
  29.165 +		return -reflection(normal);
  29.166 +	}
  29.167 +
  29.168 +	scalar_t beta = ior * cos_inc - sqrt(radical);
  29.169 +
  29.170 +	return *this * ior + normal * beta;
  29.171 +}
  29.172 +
  29.173 +void Vector3::transform(const Matrix3x3 &mat)
  29.174 +{
  29.175 +	scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z;
  29.176 +	scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z;
  29.177 +	z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z;
  29.178 +	x = nx;
  29.179 +	y = ny;
  29.180 +}
  29.181 +
  29.182 +Vector3 Vector3::transformed(const Matrix3x3 &mat) const
  29.183 +{
  29.184 +	Vector3 vec;
  29.185 +	vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z;
  29.186 +	vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z;
  29.187 +	vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z;
  29.188 +	return vec;
  29.189 +}
  29.190 +
  29.191 +void Vector3::transform(const Matrix4x4 &mat)
  29.192 +{
  29.193 +	scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3];
  29.194 +	scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3];
  29.195 +	z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3];
  29.196 +	x = nx;
  29.197 +	y = ny;
  29.198 +}
  29.199 +
  29.200 +Vector3 Vector3::transformed(const Matrix4x4 &mat) const
  29.201 +{
  29.202 +	Vector3 vec;
  29.203 +	vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3];
  29.204 +	vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3];
  29.205 +	vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3];
  29.206 +	return vec;
  29.207 +}
  29.208 +
  29.209 +void Vector3::transform(const Quaternion &quat)
  29.210 +{
  29.211 +	Quaternion vq(0.0f, *this);
  29.212 +	vq = quat * vq * quat.inverse();
  29.213 +	*this = vq.v;
  29.214 +}
  29.215 +
  29.216 +Vector3 Vector3::transformed(const Quaternion &quat) const
  29.217 +{
  29.218 +	Quaternion vq(0.0f, *this);
  29.219 +	vq = quat * vq * quat.inverse();
  29.220 +	return vq.v;
  29.221 +}
  29.222 +
  29.223 +void Vector3::rotate(const Vector3 &euler)
  29.224 +{
  29.225 +	Matrix4x4 rot;
  29.226 +	rot.set_rotation(euler);
  29.227 +	transform(rot);
  29.228 +}
  29.229 +
  29.230 +Vector3 Vector3::rotated(const Vector3 &euler) const
  29.231 +{
  29.232 +	Matrix4x4 rot;
  29.233 +	rot.set_rotation(euler);
  29.234 +	return transformed(rot);
  29.235 +}
  29.236 +
  29.237 +std::ostream &operator <<(std::ostream &out, const Vector3 &vec)
  29.238 +{
  29.239 +	out << "[" << vec.x << " " << vec.y << " " << vec.z << "]";
  29.240 +	return out;
  29.241 +}
  29.242 +
  29.243 +
  29.244 +// -------------- Vector4 --------------
  29.245 +Vector4::Vector4(scalar_t x, scalar_t y, scalar_t z, scalar_t w)
  29.246 +{
  29.247 +	this->x = x;
  29.248 +	this->y = y;
  29.249 +	this->z = z;
  29.250 +	this->w = w;
  29.251 +}
  29.252 +
  29.253 +Vector4::Vector4(const vec4_t &vec)
  29.254 +{
  29.255 +	x = vec.x;
  29.256 +	y = vec.y;
  29.257 +	z = vec.z;
  29.258 +	w = vec.w;
  29.259 +}
  29.260 +
  29.261 +Vector4::Vector4(const Vector2 &vec)
  29.262 +{
  29.263 +	x = vec.x;
  29.264 +	y = vec.y;
  29.265 +	z = 1;
  29.266 +	w = 1;
  29.267 +}
  29.268 +
  29.269 +Vector4::Vector4(const Vector3 &vec)
  29.270 +{
  29.271 +	x = vec.x;
  29.272 +	y = vec.y;
  29.273 +	z = vec.z;
  29.274 +	w = 1;
  29.275 +}
  29.276 +
  29.277 +void Vector4::normalize()
  29.278 +{
  29.279 +	scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w);
  29.280 +	x /= len;
  29.281 +	y /= len;
  29.282 +	z /= len;
  29.283 +	w /= len;
  29.284 +}
  29.285 +
  29.286 +Vector4 Vector4::normalized() const
  29.287 +{
  29.288 +	scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w);
  29.289 +	return Vector4(x / len, y / len, z / len, w / len);
  29.290 +}
  29.291 +
  29.292 +void Vector4::transform(const Matrix4x4 &mat)
  29.293 +{
  29.294 +	scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w;
  29.295 +	scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w;
  29.296 +	scalar_t nz = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w;
  29.297 +	w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w;
  29.298 +	x = nx;
  29.299 +	y = ny;
  29.300 +	z = nz;
  29.301 +}
  29.302 +
  29.303 +Vector4 Vector4::transformed(const Matrix4x4 &mat) const
  29.304 +{
  29.305 +	Vector4 vec;
  29.306 +	vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w;
  29.307 +	vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w;
  29.308 +	vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w;
  29.309 +	vec.w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w;
  29.310 +	return vec;
  29.311 +}
  29.312 +
  29.313 +// TODO: implement 4D vector reflection
  29.314 +Vector4 Vector4::reflection(const Vector4 &normal) const
  29.315 +{
  29.316 +	return *this;
  29.317 +}
  29.318 +
  29.319 +// TODO: implement 4D vector refraction
  29.320 +Vector4 Vector4::refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const
  29.321 +{
  29.322 +	return *this;
  29.323 +}
  29.324 +
  29.325 +std::ostream &operator <<(std::ostream &out, const Vector4 &vec)
  29.326 +{
  29.327 +	out << "[" << vec.x << " " << vec.y << " " << vec.z << " " << vec.w << "]";
  29.328 +	return out;
  29.329 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/prototype/vmath/vector.h	Thu Jun 28 06:05:50 2012 +0300
    30.3 @@ -0,0 +1,292 @@
    30.4 +/*
    30.5 +libvmath - a vector math library
    30.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    30.7 +
    30.8 +This program is free software: you can redistribute it and/or modify
    30.9 +it under the terms of the GNU Lesser General Public License as published
   30.10 +by the Free Software Foundation, either version 3 of the License, or
   30.11 +(at your option) any later version.
   30.12 +
   30.13 +This program is distributed in the hope that it will be useful,
   30.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   30.16 +GNU Lesser General Public License for more details.
   30.17 +
   30.18 +You should have received a copy of the GNU Lesser General Public License
   30.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   30.20 +*/
   30.21 +
   30.22 +#ifndef VMATH_VECTOR_H_
   30.23 +#define VMATH_VECTOR_H_
   30.24 +
   30.25 +#include <stdio.h>
   30.26 +#include "vmath_types.h"
   30.27 +
   30.28 +#ifdef __cplusplus
   30.29 +extern "C" {
   30.30 +#endif	/* __cplusplus */
   30.31 +
   30.32 +/* C 2D vector functions */
   30.33 +static inline vec2_t v2_cons(scalar_t x, scalar_t y);
   30.34 +static inline void v2_print(FILE *fp, vec2_t v);
   30.35 +
   30.36 +static inline vec2_t v2_add(vec2_t v1, vec2_t v2);
   30.37 +static inline vec2_t v2_sub(vec2_t v1, vec2_t v2);
   30.38 +static inline vec2_t v2_scale(vec2_t v, scalar_t s);
   30.39 +static inline scalar_t v2_dot(vec2_t v1, vec2_t v2);
   30.40 +static inline scalar_t v2_length(vec2_t v);
   30.41 +static inline scalar_t v2_length_sq(vec2_t v);
   30.42 +static inline vec2_t v2_normalize(vec2_t v);
   30.43 +
   30.44 +static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t);
   30.45 +
   30.46 +/* C 3D vector functions */
   30.47 +static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z);
   30.48 +static inline void v3_print(FILE *fp, vec3_t v);
   30.49 +
   30.50 +static inline vec3_t v3_add(vec3_t v1, vec3_t v2);
   30.51 +static inline vec3_t v3_sub(vec3_t v1, vec3_t v2);
   30.52 +static inline vec3_t v3_neg(vec3_t v);
   30.53 +static inline vec3_t v3_mul(vec3_t v1, vec3_t v2);
   30.54 +static inline vec3_t v3_scale(vec3_t v1, scalar_t s);
   30.55 +static inline scalar_t v3_dot(vec3_t v1, vec3_t v2);
   30.56 +static inline vec3_t v3_cross(vec3_t v1, vec3_t v2);
   30.57 +static inline scalar_t v3_length(vec3_t v);
   30.58 +static inline scalar_t v3_length_sq(vec3_t v);
   30.59 +static inline vec3_t v3_normalize(vec3_t v);
   30.60 +static inline vec3_t v3_transform(vec3_t v, mat4_t m);
   30.61 +
   30.62 +static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z);
   30.63 +static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z);
   30.64 +static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q);
   30.65 +
   30.66 +static inline vec3_t v3_reflect(vec3_t v, vec3_t n);
   30.67 +
   30.68 +static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t);
   30.69 +
   30.70 +/* C 4D vector functions */
   30.71 +static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w);
   30.72 +static inline void v4_print(FILE *fp, vec4_t v);
   30.73 +
   30.74 +static inline vec4_t v4_add(vec4_t v1, vec4_t v2);
   30.75 +static inline vec4_t v4_sub(vec4_t v1, vec4_t v2);
   30.76 +static inline vec4_t v4_neg(vec4_t v);
   30.77 +static inline vec4_t v4_mul(vec4_t v1, vec4_t v2);
   30.78 +static inline vec4_t v4_scale(vec4_t v, scalar_t s);
   30.79 +static inline scalar_t v4_dot(vec4_t v1, vec4_t v2);
   30.80 +static inline scalar_t v4_length(vec4_t v);
   30.81 +static inline scalar_t v4_length_sq(vec4_t v);
   30.82 +static inline vec4_t v4_normalize(vec4_t v);
   30.83 +static inline vec4_t v4_transform(vec4_t v, mat4_t m);
   30.84 +
   30.85 +#ifdef __cplusplus
   30.86 +}	/* extern "C" */
   30.87 +
   30.88 +/* when included from C++ source files, also define the vector classes */
   30.89 +#include <iostream>
   30.90 +
   30.91 +/** 2D Vector */
   30.92 +class Vector2 {
   30.93 +public:
   30.94 +	scalar_t x, y;
   30.95 +
   30.96 +	Vector2(scalar_t x = 0.0, scalar_t y = 0.0);
   30.97 +	Vector2(const vec2_t &vec);
   30.98 +	Vector2(const Vector3 &vec);
   30.99 +	Vector2(const Vector4 &vec);
  30.100 +
  30.101 +	inline scalar_t &operator [](int elem);
  30.102 +	inline const scalar_t &operator [](int elem) const;
  30.103 +
  30.104 +	inline scalar_t length() const;
  30.105 +	inline scalar_t length_sq() const;
  30.106 +	void normalize();
  30.107 +	Vector2 normalized() const;
  30.108 +
  30.109 +	void transform(const Matrix3x3 &mat);
  30.110 +	Vector2 transformed(const Matrix3x3 &mat) const;
  30.111 +
  30.112 +	void rotate(scalar_t angle);
  30.113 +	Vector2 rotated(scalar_t angle) const;
  30.114 +
  30.115 +	Vector2 reflection(const Vector2 &normal) const;
  30.116 +	Vector2 refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const;
  30.117 +};
  30.118 +
  30.119 +/* unary operations */
  30.120 +inline Vector2 operator -(const Vector2 &vec);
  30.121 +
  30.122 +/* binary vector (op) vector operations */
  30.123 +inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2);
  30.124 +
  30.125 +inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2);
  30.126 +inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2);
  30.127 +inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2);
  30.128 +inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2);
  30.129 +inline bool operator ==(const Vector2 &v1, const Vector2 &v2);
  30.130 +
  30.131 +inline void operator +=(Vector2 &v1, const Vector2 &v2);
  30.132 +inline void operator -=(Vector2 &v1, const Vector2 &v2);
  30.133 +inline void operator *=(Vector2 &v1, const Vector2 &v2);
  30.134 +inline void operator /=(Vector2 &v1, const Vector2 &v2);
  30.135 +
  30.136 +/* binary vector (op) scalar and scalar (op) vector operations */
  30.137 +inline Vector2 operator +(const Vector2 &vec, scalar_t scalar);
  30.138 +inline Vector2 operator +(scalar_t scalar, const Vector2 &vec);
  30.139 +inline Vector2 operator -(const Vector2 &vec, scalar_t scalar);
  30.140 +inline Vector2 operator *(const Vector2 &vec, scalar_t scalar);
  30.141 +inline Vector2 operator *(scalar_t scalar, const Vector2 &vec);
  30.142 +inline Vector2 operator /(const Vector2 &vec, scalar_t scalar);
  30.143 +
  30.144 +inline void operator +=(Vector2 &vec, scalar_t scalar);
  30.145 +inline void operator -=(Vector2 &vec, scalar_t scalar);
  30.146 +inline void operator *=(Vector2 &vec, scalar_t scalar);
  30.147 +inline void operator /=(Vector2 &vec, scalar_t scalar);
  30.148 +
  30.149 +std::ostream &operator <<(std::ostream &out, const Vector2 &vec);
  30.150 +
  30.151 +inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t);
  30.152 +inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1,
  30.153 +		const Vector2 &v2, const Vector2 &v3, scalar_t t);
  30.154 +
  30.155 +/* 3D Vector */
  30.156 +class Vector3 {
  30.157 +public:
  30.158 +	scalar_t x, y, z;
  30.159 +
  30.160 +	Vector3(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0);
  30.161 +	Vector3(const vec3_t &vec);
  30.162 +	Vector3(const Vector2 &vec);
  30.163 +	Vector3(const Vector4 &vec);
  30.164 +	Vector3(const SphVector &sph);
  30.165 +
  30.166 +	Vector3 &operator =(const SphVector &sph);
  30.167 +
  30.168 +	inline scalar_t &operator [](int elem);
  30.169 +	inline const scalar_t &operator [](int elem) const;
  30.170 +
  30.171 +	inline scalar_t length() const;
  30.172 +	inline scalar_t length_sq() const;
  30.173 +	void normalize();
  30.174 +	Vector3 normalized() const;
  30.175 +
  30.176 +	void transform(const Matrix3x3 &mat);
  30.177 +	Vector3 transformed(const Matrix3x3 &mat) const;
  30.178 +	void transform(const Matrix4x4 &mat);
  30.179 +	Vector3 transformed(const Matrix4x4 &mat) const;
  30.180 +	void transform(const Quaternion &quat);
  30.181 +	Vector3 transformed(const Quaternion &quat) const;
  30.182 +
  30.183 +	void rotate(const Vector3 &euler);
  30.184 +	Vector3 rotated(const Vector3 &euler) const;
  30.185 +
  30.186 +	Vector3 reflection(const Vector3 &normal) const;
  30.187 +	Vector3 refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const;
  30.188 +	Vector3 refraction(const Vector3 &normal, scalar_t ior) const;
  30.189 +};
  30.190 +
  30.191 +/* unary operations */
  30.192 +inline Vector3 operator -(const Vector3 &vec);
  30.193 +
  30.194 +/* binary vector (op) vector operations */
  30.195 +inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2);
  30.196 +inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2);
  30.197 +
  30.198 +inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2);
  30.199 +inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2);
  30.200 +inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2);
  30.201 +inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2);
  30.202 +inline bool operator ==(const Vector3 &v1, const Vector3 &v2);
  30.203 +
  30.204 +inline void operator +=(Vector3 &v1, const Vector3 &v2);
  30.205 +inline void operator -=(Vector3 &v1, const Vector3 &v2);
  30.206 +inline void operator *=(Vector3 &v1, const Vector3 &v2);
  30.207 +inline void operator /=(Vector3 &v1, const Vector3 &v2);
  30.208 +
  30.209 +/* binary vector (op) scalar and scalar (op) vector operations */
  30.210 +inline Vector3 operator +(const Vector3 &vec, scalar_t scalar);
  30.211 +inline Vector3 operator +(scalar_t scalar, const Vector3 &vec);
  30.212 +inline Vector3 operator -(const Vector3 &vec, scalar_t scalar);
  30.213 +inline Vector3 operator *(const Vector3 &vec, scalar_t scalar);
  30.214 +inline Vector3 operator *(scalar_t scalar, const Vector3 &vec);
  30.215 +inline Vector3 operator /(const Vector3 &vec, scalar_t scalar);
  30.216 +
  30.217 +inline void operator +=(Vector3 &vec, scalar_t scalar);
  30.218 +inline void operator -=(Vector3 &vec, scalar_t scalar);
  30.219 +inline void operator *=(Vector3 &vec, scalar_t scalar);
  30.220 +inline void operator /=(Vector3 &vec, scalar_t scalar);
  30.221 +
  30.222 +std::ostream &operator <<(std::ostream &out, const Vector3 &vec);
  30.223 +
  30.224 +inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t);
  30.225 +inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1,
  30.226 +		const Vector3 &v2, const Vector3 &v3, scalar_t t);
  30.227 +
  30.228 +/* 4D Vector */
  30.229 +class Vector4 {
  30.230 +public:
  30.231 +	scalar_t x, y, z, w;
  30.232 +
  30.233 +	Vector4(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0, scalar_t w = 0.0);
  30.234 +	Vector4(const vec4_t &vec);
  30.235 +	Vector4(const Vector2 &vec);
  30.236 +	Vector4(const Vector3 &vec);
  30.237 +
  30.238 +	inline scalar_t &operator [](int elem);
  30.239 +	inline const scalar_t &operator [](int elem) const;
  30.240 +
  30.241 +	inline scalar_t length() const;
  30.242 +	inline scalar_t length_sq() const;
  30.243 +	void normalize();
  30.244 +	Vector4 normalized() const;
  30.245 +
  30.246 +	void transform(const Matrix4x4 &mat);
  30.247 +	Vector4 transformed(const Matrix4x4 &mat) const;
  30.248 +
  30.249 +	Vector4 reflection(const Vector4 &normal) const;
  30.250 +	Vector4 refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const;
  30.251 +};
  30.252 +
  30.253 +
  30.254 +/* unary operations */
  30.255 +inline Vector4 operator -(const Vector4 &vec);
  30.256 +
  30.257 +/* binary vector (op) vector operations */
  30.258 +inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2);
  30.259 +inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3);
  30.260 +
  30.261 +inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2);
  30.262 +inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2);
  30.263 +inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2);
  30.264 +inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2);
  30.265 +inline bool operator ==(const Vector4 &v1, const Vector4 &v2);
  30.266 +
  30.267 +inline void operator +=(Vector4 &v1, const Vector4 &v2);
  30.268 +inline void operator -=(Vector4 &v1, const Vector4 &v2);
  30.269 +inline void operator *=(Vector4 &v1, const Vector4 &v2);
  30.270 +inline void operator /=(Vector4 &v1, const Vector4 &v2);
  30.271 +
  30.272 +/* binary vector (op) scalar and scalar (op) vector operations */
  30.273 +inline Vector4 operator +(const Vector4 &vec, scalar_t scalar);
  30.274 +inline Vector4 operator +(scalar_t scalar, const Vector4 &vec);
  30.275 +inline Vector4 operator -(const Vector4 &vec, scalar_t scalar);
  30.276 +inline Vector4 operator *(const Vector4 &vec, scalar_t scalar);
  30.277 +inline Vector4 operator *(scalar_t scalar, const Vector4 &vec);
  30.278 +inline Vector4 operator /(const Vector4 &vec, scalar_t scalar);
  30.279 +
  30.280 +inline void operator +=(Vector4 &vec, scalar_t scalar);
  30.281 +inline void operator -=(Vector4 &vec, scalar_t scalar);
  30.282 +inline void operator *=(Vector4 &vec, scalar_t scalar);
  30.283 +inline void operator /=(Vector4 &vec, scalar_t scalar);
  30.284 +
  30.285 +std::ostream &operator <<(std::ostream &out, const Vector4 &vec);
  30.286 +
  30.287 +inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t);
  30.288 +inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1,
  30.289 +		const Vector4 &v2, const Vector4 &v3, scalar_t t);
  30.290 +
  30.291 +#endif	/* __cplusplus */
  30.292 +
  30.293 +#include "vector.inl"
  30.294 +
  30.295 +#endif	/* VMATH_VECTOR_H_ */
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/prototype/vmath/vector.inl	Thu Jun 28 06:05:50 2012 +0300
    31.3 @@ -0,0 +1,761 @@
    31.4 +/*
    31.5 +libvmath - a vector math library
    31.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    31.7 +
    31.8 +This program is free software: you can redistribute it and/or modify
    31.9 +it under the terms of the GNU Lesser General Public License as published
   31.10 +by the Free Software Foundation, either version 3 of the License, or
   31.11 +(at your option) any later version.
   31.12 +
   31.13 +This program is distributed in the hope that it will be useful,
   31.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   31.16 +GNU Lesser General Public License for more details.
   31.17 +
   31.18 +You should have received a copy of the GNU Lesser General Public License
   31.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   31.20 +*/
   31.21 +
   31.22 +#include <math.h>
   31.23 +
   31.24 +#ifdef __cplusplus
   31.25 +extern "C" {
   31.26 +#endif	/* __cplusplus */
   31.27 +
   31.28 +/* C 2D vector functions */
   31.29 +static inline vec2_t v2_cons(scalar_t x, scalar_t y)
   31.30 +{
   31.31 +	vec2_t v;
   31.32 +	v.x = x;
   31.33 +	v.y = y;
   31.34 +	return v;
   31.35 +}
   31.36 +
   31.37 +static inline void v2_print(FILE *fp, vec2_t v)
   31.38 +{
   31.39 +	fprintf(fp, "[ %.4f %.4f ]", v.x, v.y);
   31.40 +}
   31.41 +
   31.42 +static inline vec2_t v2_add(vec2_t v1, vec2_t v2)
   31.43 +{
   31.44 +	vec2_t res;
   31.45 +	res.x = v1.x + v2.x;
   31.46 +	res.y = v1.y + v2.y;
   31.47 +	return res;
   31.48 +}
   31.49 +
   31.50 +static inline vec2_t v2_sub(vec2_t v1, vec2_t v2)
   31.51 +{
   31.52 +	vec2_t res;
   31.53 +	res.x = v1.x - v2.x;
   31.54 +	res.y = v1.y - v2.y;
   31.55 +	return res;
   31.56 +}
   31.57 +
   31.58 +static inline vec2_t v2_scale(vec2_t v, scalar_t s)
   31.59 +{
   31.60 +	vec2_t res;
   31.61 +	res.x = v.x * s;
   31.62 +	res.y = v.y * s;
   31.63 +	return res;
   31.64 +}
   31.65 +
   31.66 +static inline scalar_t v2_dot(vec2_t v1, vec2_t v2)
   31.67 +{
   31.68 +	return v1.x * v2.x + v1.y * v2.y;
   31.69 +}
   31.70 +
   31.71 +static inline scalar_t v2_length(vec2_t v)
   31.72 +{
   31.73 +	return sqrt(v.x * v.x + v.y * v.y);
   31.74 +}
   31.75 +
   31.76 +static inline scalar_t v2_length_sq(vec2_t v)
   31.77 +{
   31.78 +	return v.x * v.x + v.y * v.y;
   31.79 +}
   31.80 +
   31.81 +static inline vec2_t v2_normalize(vec2_t v)
   31.82 +{
   31.83 +	scalar_t len = (scalar_t)sqrt(v.x * v.x + v.y * v.y);
   31.84 +	v.x /= len;
   31.85 +	v.y /= len;
   31.86 +	return v;
   31.87 +}
   31.88 +
   31.89 +static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t)
   31.90 +{
   31.91 +	vec2_t res;
   31.92 +	res.x = v1.x + (v2.x - v1.x) * t;
   31.93 +	res.y = v1.y + (v2.y - v1.y) * t;
   31.94 +	return res;
   31.95 +}
   31.96 +
   31.97 +
   31.98 +/* C 3D vector functions */
   31.99 +static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z)
  31.100 +{
  31.101 +	vec3_t v;
  31.102 +	v.x = x;
  31.103 +	v.y = y;
  31.104 +	v.z = z;
  31.105 +	return v;
  31.106 +}
  31.107 +
  31.108 +static inline void v3_print(FILE *fp, vec3_t v)
  31.109 +{
  31.110 +	fprintf(fp, "[ %.4f %.4f %.4f ]", v.x, v.y, v.z);
  31.111 +}
  31.112 +
  31.113 +static inline vec3_t v3_add(vec3_t v1, vec3_t v2)
  31.114 +{
  31.115 +	v1.x += v2.x;
  31.116 +	v1.y += v2.y;
  31.117 +	v1.z += v2.z;
  31.118 +	return v1;
  31.119 +}
  31.120 +
  31.121 +static inline vec3_t v3_sub(vec3_t v1, vec3_t v2)
  31.122 +{
  31.123 +	v1.x -= v2.x;
  31.124 +	v1.y -= v2.y;
  31.125 +	v1.z -= v2.z;
  31.126 +	return v1;
  31.127 +}
  31.128 +
  31.129 +static inline vec3_t v3_neg(vec3_t v)
  31.130 +{
  31.131 +	v.x = -v.x;
  31.132 +	v.y = -v.y;
  31.133 +	v.z = -v.z;
  31.134 +	return v;
  31.135 +}
  31.136 +
  31.137 +static inline vec3_t v3_mul(vec3_t v1, vec3_t v2)
  31.138 +{
  31.139 +	v1.x *= v2.x;
  31.140 +	v1.y *= v2.y;
  31.141 +	v1.z *= v2.z;
  31.142 +	return v1;
  31.143 +}
  31.144 +
  31.145 +static inline vec3_t v3_scale(vec3_t v1, scalar_t s)
  31.146 +{
  31.147 +	v1.x *= s;
  31.148 +	v1.y *= s;
  31.149 +	v1.z *= s;
  31.150 +	return v1;
  31.151 +}
  31.152 +
  31.153 +static inline scalar_t v3_dot(vec3_t v1, vec3_t v2)
  31.154 +{
  31.155 +	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
  31.156 +}
  31.157 +
  31.158 +static inline vec3_t v3_cross(vec3_t v1, vec3_t v2)
  31.159 +{
  31.160 +	vec3_t v;
  31.161 +	v.x = v1.y * v2.z - v1.z * v2.y;
  31.162 +	v.y = v1.z * v2.x - v1.x * v2.z;
  31.163 +	v.z = v1.x * v2.y - v1.y * v2.x;
  31.164 +	return v;
  31.165 +}
  31.166 +
  31.167 +static inline scalar_t v3_length(vec3_t v)
  31.168 +{
  31.169 +	return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
  31.170 +}
  31.171 +
  31.172 +static inline scalar_t v3_length_sq(vec3_t v)
  31.173 +{
  31.174 +	return v.x * v.x + v.y * v.y + v.z * v.z;
  31.175 +}
  31.176 +
  31.177 +static inline vec3_t v3_normalize(vec3_t v)
  31.178 +{
  31.179 +	scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
  31.180 +	v.x /= len;
  31.181 +	v.y /= len;
  31.182 +	v.z /= len;
  31.183 +	return v;
  31.184 +}
  31.185 +
  31.186 +static inline vec3_t v3_transform(vec3_t v, mat4_t m)
  31.187 +{
  31.188 +	vec3_t res;
  31.189 +	res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3];
  31.190 +	res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3];
  31.191 +	res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3];
  31.192 +	return res;
  31.193 +}
  31.194 +
  31.195 +static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z)
  31.196 +{
  31.197 +	void m4_rotate(mat4_t, scalar_t, scalar_t, scalar_t);
  31.198 +
  31.199 +	mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
  31.200 +	m4_rotate(m, x, y, z);
  31.201 +	return v3_transform(v, m);
  31.202 +}
  31.203 +
  31.204 +static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z)
  31.205 +{
  31.206 +	void m4_rotate_axis(mat4_t, scalar_t, scalar_t, scalar_t, scalar_t);
  31.207 +
  31.208 +	mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
  31.209 +	m4_rotate_axis(m, angle, x, y, z);
  31.210 +	return v3_transform(v, m);
  31.211 +}
  31.212 +
  31.213 +static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q)
  31.214 +{
  31.215 +	quat_t quat_rotate_quat(quat_t, quat_t);
  31.216 +
  31.217 +	quat_t vq = v4_cons(v.x, v.y, v.z, 0.0);
  31.218 +	quat_t res = quat_rotate_quat(vq, q);
  31.219 +	return v3_cons(res.x, res.y, res.z);
  31.220 +}
  31.221 +
  31.222 +static inline vec3_t v3_reflect(vec3_t v, vec3_t n)
  31.223 +{
  31.224 +	scalar_t dot = v3_dot(v, n);
  31.225 +	return v3_sub(v3_scale(n, dot * 2.0), v);
  31.226 +}
  31.227 +
  31.228 +static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t)
  31.229 +{
  31.230 +	v1.x += (v2.x - v1.x) * t;
  31.231 +	v1.y += (v2.y - v1.y) * t;
  31.232 +	v1.z += (v2.z - v1.z) * t;
  31.233 +	return v1;
  31.234 +}
  31.235 +
  31.236 +/* C 4D vector functions */
  31.237 +static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w)
  31.238 +{
  31.239 +	vec4_t v;
  31.240 +	v.x = x;
  31.241 +	v.y = y;
  31.242 +	v.z = z;
  31.243 +	v.w = w;
  31.244 +	return v;
  31.245 +}
  31.246 +
  31.247 +static inline void v4_print(FILE *fp, vec4_t v)
  31.248 +{
  31.249 +	fprintf(fp, "[ %.4f %.4f %.4f %.4f ]", v.x, v.y, v.z, v.w);
  31.250 +}
  31.251 +
  31.252 +static inline vec4_t v4_add(vec4_t v1, vec4_t v2)
  31.253 +{
  31.254 +	v1.x += v2.x;
  31.255 +	v1.y += v2.y;
  31.256 +	v1.z += v2.z;
  31.257 +	v1.w += v2.w;
  31.258 +	return v1;
  31.259 +}
  31.260 +
  31.261 +static inline vec4_t v4_sub(vec4_t v1, vec4_t v2)
  31.262 +{
  31.263 +	v1.x -= v2.x;
  31.264 +	v1.y -= v2.y;
  31.265 +	v1.z -= v2.z;
  31.266 +	v1.w -= v2.w;
  31.267 +	return v1;
  31.268 +}
  31.269 +
  31.270 +static inline vec4_t v4_neg(vec4_t v)
  31.271 +{
  31.272 +	v.x = -v.x;
  31.273 +	v.y = -v.y;
  31.274 +	v.z = -v.z;
  31.275 +	v.w = -v.w;
  31.276 +	return v;
  31.277 +}
  31.278 +
  31.279 +static inline vec4_t v4_mul(vec4_t v1, vec4_t v2)
  31.280 +{
  31.281 +	v1.x *= v2.x;
  31.282 +	v1.y *= v2.y;
  31.283 +	v1.z *= v2.z;
  31.284 +	v1.w *= v2.w;
  31.285 +	return v1;
  31.286 +}
  31.287 +
  31.288 +static inline vec4_t v4_scale(vec4_t v, scalar_t s)
  31.289 +{
  31.290 +	v.x *= s;
  31.291 +	v.y *= s;
  31.292 +	v.z *= s;
  31.293 +	v.w *= s;
  31.294 +	return v;
  31.295 +}
  31.296 +
  31.297 +static inline scalar_t v4_dot(vec4_t v1, vec4_t v2)
  31.298 +{
  31.299 +	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
  31.300 +}
  31.301 +
  31.302 +static inline scalar_t v4_length(vec4_t v)
  31.303 +{
  31.304 +	return sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
  31.305 +}
  31.306 +
  31.307 +static inline scalar_t v4_length_sq(vec4_t v)
  31.308 +{
  31.309 +	return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
  31.310 +}
  31.311 +
  31.312 +static inline vec4_t v4_normalize(vec4_t v)
  31.313 +{
  31.314 +	scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
  31.315 +	v.x /= len;
  31.316 +	v.y /= len;
  31.317 +	v.z /= len;
  31.318 +	v.w /= len;
  31.319 +	return v;
  31.320 +}
  31.321 +
  31.322 +static inline vec4_t v4_transform(vec4_t v, mat4_t m)
  31.323 +{
  31.324 +	vec4_t res;
  31.325 +	res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w;
  31.326 +	res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w;
  31.327 +	res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w;
  31.328 +	res.w = m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w;
  31.329 +	return res;
  31.330 +}
  31.331 +
  31.332 +#ifdef __cplusplus
  31.333 +}	/* extern "C" */
  31.334 +
  31.335 +
  31.336 +/* --------------- C++ part -------------- */
  31.337 +
  31.338 +inline scalar_t &Vector2::operator [](int elem) {
  31.339 +	return elem ? y : x;
  31.340 +}
  31.341 +
  31.342 +inline const scalar_t &Vector2::operator [](int elem) const {
  31.343 +	return elem ? y : x;
  31.344 +}
  31.345 +
  31.346 +inline Vector2 operator -(const Vector2 &vec) {
  31.347 +	return Vector2(-vec.x, -vec.y);
  31.348 +}
  31.349 +
  31.350 +inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2) {
  31.351 +	return v1.x * v2.x + v1.y * v2.y;
  31.352 +}
  31.353 +
  31.354 +inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2) {
  31.355 +	return Vector2(v1.x + v2.x, v1.y + v2.y);
  31.356 +}
  31.357 +
  31.358 +inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2) {
  31.359 +	return Vector2(v1.x - v2.x, v1.y - v2.y);
  31.360 +}
  31.361 +
  31.362 +inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2) {
  31.363 +	return Vector2(v1.x * v2.x, v1.y * v2.y);
  31.364 +}
  31.365 +
  31.366 +inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2) {
  31.367 +	return Vector2(v1.x / v2.x, v1.y / v2.y);
  31.368 +}
  31.369 +
  31.370 +inline bool operator ==(const Vector2 &v1, const Vector2 &v2) {
  31.371 +	return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.x) < XSMALL_NUMBER);
  31.372 +}
  31.373 +
  31.374 +inline void operator +=(Vector2 &v1, const Vector2 &v2) {
  31.375 +	v1.x += v2.x;
  31.376 +	v1.y += v2.y;
  31.377 +}
  31.378 +
  31.379 +inline void operator -=(Vector2 &v1, const Vector2 &v2) {
  31.380 +	v1.x -= v2.x;
  31.381 +	v1.y -= v2.y;
  31.382 +}
  31.383 +
  31.384 +inline void operator *=(Vector2 &v1, const Vector2 &v2) {
  31.385 +	v1.x *= v2.x;
  31.386 +	v1.y *= v2.y;
  31.387 +}
  31.388 +
  31.389 +inline void operator /=(Vector2 &v1, const Vector2 &v2) {
  31.390 +	v1.x /= v2.x;
  31.391 +	v1.y /= v2.y;
  31.392 +}
  31.393 +
  31.394 +inline Vector2 operator +(const Vector2 &vec, scalar_t scalar) {
  31.395 +	return Vector2(vec.x + scalar, vec.y + scalar);
  31.396 +}
  31.397 +
  31.398 +inline Vector2 operator +(scalar_t scalar, const Vector2 &vec) {
  31.399 +	return Vector2(vec.x + scalar, vec.y + scalar);
  31.400 +}
  31.401 +
  31.402 +inline Vector2 operator -(scalar_t scalar, const Vector2 &vec) {
  31.403 +	return Vector2(vec.x - scalar, vec.y - scalar);
  31.404 +}
  31.405 +
  31.406 +inline Vector2 operator *(const Vector2 &vec, scalar_t scalar) {
  31.407 +	return Vector2(vec.x * scalar, vec.y * scalar);
  31.408 +}
  31.409 +
  31.410 +inline Vector2 operator *(scalar_t scalar, const Vector2 &vec) {
  31.411 +	return Vector2(vec.x * scalar, vec.y * scalar);
  31.412 +}
  31.413 +
  31.414 +inline Vector2 operator /(const Vector2 &vec, scalar_t scalar) {
  31.415 +	return Vector2(vec.x / scalar, vec.y / scalar);
  31.416 +}
  31.417 +
  31.418 +inline void operator +=(Vector2 &vec, scalar_t scalar) {
  31.419 +	vec.x += scalar;
  31.420 +	vec.y += scalar;
  31.421 +}
  31.422 +
  31.423 +inline void operator -=(Vector2 &vec, scalar_t scalar) {
  31.424 +	vec.x -= scalar;
  31.425 +	vec.y -= scalar;
  31.426 +}
  31.427 +
  31.428 +inline void operator *=(Vector2 &vec, scalar_t scalar) {
  31.429 +	vec.x *= scalar;
  31.430 +	vec.y *= scalar;
  31.431 +}
  31.432 +
  31.433 +inline void operator /=(Vector2 &vec, scalar_t scalar) {
  31.434 +	vec.x /= scalar;
  31.435 +	vec.y /= scalar;
  31.436 +}
  31.437 +
  31.438 +inline scalar_t Vector2::length() const {
  31.439 +	return sqrt(x*x + y*y);
  31.440 +}
  31.441 +
  31.442 +inline scalar_t Vector2::length_sq() const {
  31.443 +	return x*x + y*y;
  31.444 +}
  31.445 +
  31.446 +inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t)
  31.447 +{
  31.448 +	return a + (b - a) * t;
  31.449 +}
  31.450 +
  31.451 +inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1,
  31.452 +		const Vector2 &v2, const Vector2 &v3, scalar_t t)
  31.453 +{
  31.454 +	scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
  31.455 +	scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
  31.456 +	scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
  31.457 +	return Vector2(x, y);
  31.458 +}
  31.459 +
  31.460 +
  31.461 +/* ------------- Vector3 -------------- */
  31.462 +
  31.463 +inline scalar_t &Vector3::operator [](int elem) {
  31.464 +	return elem ? (elem == 1 ? y : z) : x;
  31.465 +}
  31.466 +
  31.467 +inline const scalar_t &Vector3::operator [](int elem) const {
  31.468 +	return elem ? (elem == 1 ? y : z) : x;
  31.469 +}
  31.470 +
  31.471 +/* unary operations */
  31.472 +inline Vector3 operator -(const Vector3 &vec) {
  31.473 +	return Vector3(-vec.x, -vec.y, -vec.z);
  31.474 +}
  31.475 +
  31.476 +/* binary vector (op) vector operations */
  31.477 +inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2) {
  31.478 +	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
  31.479 +}
  31.480 +
  31.481 +inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2) {
  31.482 +	return Vector3(v1.y * v2.z - v1.z * v2.y,  v1.z * v2.x - v1.x * v2.z,  v1.x * v2.y - v1.y * v2.x);
  31.483 +}
  31.484 +
  31.485 +
  31.486 +inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2) {
  31.487 +	return Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
  31.488 +}
  31.489 +
  31.490 +inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2) {
  31.491 +	return Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
  31.492 +}
  31.493 +
  31.494 +inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2) {
  31.495 +	return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
  31.496 +}
  31.497 +
  31.498 +inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2) {
  31.499 +	return Vector3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);
  31.500 +}
  31.501 +
  31.502 +inline bool operator ==(const Vector3 &v1, const Vector3 &v2) {
  31.503 +	return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.y) < XSMALL_NUMBER) && (fabs(v1.z - v2.z) < XSMALL_NUMBER);
  31.504 +}
  31.505 +
  31.506 +inline void operator +=(Vector3 &v1, const Vector3 &v2) {
  31.507 +	v1.x += v2.x;
  31.508 +	v1.y += v2.y;
  31.509 +	v1.z += v2.z;
  31.510 +}
  31.511 +
  31.512 +inline void operator -=(Vector3 &v1, const Vector3 &v2) {
  31.513 +	v1.x -= v2.x;
  31.514 +	v1.y -= v2.y;
  31.515 +	v1.z -= v2.z;
  31.516 +}
  31.517 +
  31.518 +inline void operator *=(Vector3 &v1, const Vector3 &v2) {
  31.519 +	v1.x *= v2.x;
  31.520 +	v1.y *= v2.y;
  31.521 +	v1.z *= v2.z;
  31.522 +}
  31.523 +
  31.524 +inline void operator /=(Vector3 &v1, const Vector3 &v2) {
  31.525 +	v1.x /= v2.x;
  31.526 +	v1.y /= v2.y;
  31.527 +	v1.z /= v2.z;
  31.528 +}
  31.529 +/* binary vector (op) scalar and scalar (op) vector operations */
  31.530 +inline Vector3 operator +(const Vector3 &vec, scalar_t scalar) {
  31.531 +	return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar);
  31.532 +}
  31.533 +
  31.534 +inline Vector3 operator +(scalar_t scalar, const Vector3 &vec) {
  31.535 +	return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar);
  31.536 +}
  31.537 +
  31.538 +inline Vector3 operator -(const Vector3 &vec, scalar_t scalar) {
  31.539 +	return Vector3(vec.x - scalar, vec.y - scalar, vec.z - scalar);
  31.540 +}
  31.541 +
  31.542 +inline Vector3 operator *(const Vector3 &vec, scalar_t scalar) {
  31.543 +	return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
  31.544 +}
  31.545 +
  31.546 +inline Vector3 operator *(scalar_t scalar, const Vector3 &vec) {
  31.547 +	return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar);
  31.548 +}
  31.549 +
  31.550 +inline Vector3 operator /(const Vector3 &vec, scalar_t scalar) {
  31.551 +	return Vector3(vec.x / scalar, vec.y / scalar, vec.z / scalar);
  31.552 +}
  31.553 +
  31.554 +inline void operator +=(Vector3 &vec, scalar_t scalar) {
  31.555 +	vec.x += scalar;
  31.556 +	vec.y += scalar;
  31.557 +	vec.z += scalar;
  31.558 +}
  31.559 +
  31.560 +inline void operator -=(Vector3 &vec, scalar_t scalar) {
  31.561 +	vec.x -= scalar;
  31.562 +	vec.y -= scalar;
  31.563 +	vec.z -= scalar;
  31.564 +}
  31.565 +
  31.566 +inline void operator *=(Vector3 &vec, scalar_t scalar) {
  31.567 +	vec.x *= scalar;
  31.568 +	vec.y *= scalar;
  31.569 +	vec.z *= scalar;
  31.570 +}
  31.571 +
  31.572 +inline void operator /=(Vector3 &vec, scalar_t scalar) {
  31.573 +	vec.x /= scalar;
  31.574 +	vec.y /= scalar;
  31.575 +	vec.z /= scalar;
  31.576 +}
  31.577 +
  31.578 +inline scalar_t Vector3::length() const {
  31.579 +	return sqrt(x*x + y*y + z*z);
  31.580 +}
  31.581 +inline scalar_t Vector3::length_sq() const {
  31.582 +	return x*x + y*y + z*z;
  31.583 +}
  31.584 +
  31.585 +inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t) {
  31.586 +	return a + (b - a) * t;
  31.587 +}
  31.588 +
  31.589 +inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1,
  31.590 +		const Vector3 &v2, const Vector3 &v3, scalar_t t)
  31.591 +{
  31.592 +	scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
  31.593 +	scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
  31.594 +	scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
  31.595 +	scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t);
  31.596 +	return Vector3(x, y, z);
  31.597 +}
  31.598 +
  31.599 +/* ----------- Vector4 ----------------- */
  31.600 +
  31.601 +inline scalar_t &Vector4::operator [](int elem) {
  31.602 +	return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x;
  31.603 +}
  31.604 +
  31.605 +inline const scalar_t &Vector4::operator [](int elem) const {
  31.606 +	return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x;
  31.607 +}
  31.608 +
  31.609 +inline Vector4 operator -(const Vector4 &vec) {
  31.610 +	return Vector4(-vec.x, -vec.y, -vec.z, -vec.w);
  31.611 +}
  31.612 +
  31.613 +inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2) {
  31.614 +	return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
  31.615 +}
  31.616 +
  31.617 +inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3) {
  31.618 +	scalar_t a, b, c, d, e, f;       /* Intermediate Values */
  31.619 +    Vector4 result;
  31.620 +
  31.621 +    /* Calculate intermediate values. */
  31.622 +    a = (v2.x * v3.y) - (v2.y * v3.x);
  31.623 +    b = (v2.x * v3.z) - (v2.z * v3.x);
  31.624 +    c = (v2.x * v3.w) - (v2.w * v3.x);
  31.625 +    d = (v2.y * v3.z) - (v2.z * v3.y);
  31.626 +    e = (v2.y * v3.w) - (v2.w * v3.y);
  31.627 +    f = (v2.z * v3.w) - (v2.w * v3.z);
  31.628 +
  31.629 +    /* Calculate the result-vector components. */
  31.630 +    result.x =   (v1.y * f) - (v1.z * e) + (v1.w * d);
  31.631 +    result.y = - (v1.x * f) + (v1.z * c) - (v1.w * b);
  31.632 +    result.z =   (v1.x * e) - (v1.y * c) + (v1.w * a);
  31.633 +    result.w = - (v1.x * d) + (v1.y * b) - (v1.z * a);
  31.634 +    return result;
  31.635 +}
  31.636 +
  31.637 +inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2) {
  31.638 +	return Vector4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
  31.639 +}
  31.640 +
  31.641 +inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2) {
  31.642 +	return Vector4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
  31.643 +}
  31.644 +
  31.645 +inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2) {
  31.646 +	return Vector4(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w);
  31.647 +}
  31.648 +
  31.649 +inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2) {
  31.650 +	return Vector4(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w);
  31.651 +}
  31.652 +
  31.653 +inline bool operator ==(const Vector4 &v1, const Vector4 &v2) {
  31.654 +	return	(fabs(v1.x - v2.x) < XSMALL_NUMBER) &&
  31.655 +			(fabs(v1.y - v2.y) < XSMALL_NUMBER) &&
  31.656 +			(fabs(v1.z - v2.z) < XSMALL_NUMBER) &&
  31.657 +			(fabs(v1.w - v2.w) < XSMALL_NUMBER);
  31.658 +}
  31.659 +
  31.660 +inline void operator +=(Vector4 &v1, const Vector4 &v2) {
  31.661 +	v1.x += v2.x;
  31.662 +	v1.y += v2.y;
  31.663 +	v1.z += v2.z;
  31.664 +	v1.w += v2.w;
  31.665 +}
  31.666 +
  31.667 +inline void operator -=(Vector4 &v1, const Vector4 &v2) {
  31.668 +	v1.x -= v2.x;
  31.669 +	v1.y -= v2.y;
  31.670 +	v1.z -= v2.z;
  31.671 +	v1.w -= v2.w;
  31.672 +}
  31.673 +
  31.674 +inline void operator *=(Vector4 &v1, const Vector4 &v2) {
  31.675 +	v1.x *= v2.x;
  31.676 +	v1.y *= v2.y;
  31.677 +	v1.z *= v2.z;
  31.678 +	v1.w *= v2.w;
  31.679 +}
  31.680 +
  31.681 +inline void operator /=(Vector4 &v1, const Vector4 &v2) {
  31.682 +	v1.x /= v2.x;
  31.683 +	v1.y /= v2.y;
  31.684 +	v1.z /= v2.z;
  31.685 +	v1.w /= v2.w;
  31.686 +}
  31.687 +
  31.688 +/* binary vector (op) scalar and scalar (op) vector operations */
  31.689 +inline Vector4 operator +(const Vector4 &vec, scalar_t scalar) {
  31.690 +	return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar);
  31.691 +}
  31.692 +
  31.693 +inline Vector4 operator +(scalar_t scalar, const Vector4 &vec) {
  31.694 +	return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar);
  31.695 +}
  31.696 +
  31.697 +inline Vector4 operator -(const Vector4 &vec, scalar_t scalar) {
  31.698 +	return Vector4(vec.x - scalar, vec.y - scalar, vec.z - scalar, vec.w - scalar);
  31.699 +}
  31.700 +
  31.701 +inline Vector4 operator *(const Vector4 &vec, scalar_t scalar) {
  31.702 +	return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar);
  31.703 +}
  31.704 +
  31.705 +inline Vector4 operator *(scalar_t scalar, const Vector4 &vec) {
  31.706 +	return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar);
  31.707 +}
  31.708 +
  31.709 +inline Vector4 operator /(const Vector4 &vec, scalar_t scalar) {
  31.710 +	return Vector4(vec.x / scalar, vec.y / scalar, vec.z / scalar, vec.w / scalar);
  31.711 +}
  31.712 +
  31.713 +inline void operator +=(Vector4 &vec, scalar_t scalar) {
  31.714 +	vec.x += scalar;
  31.715 +	vec.y += scalar;
  31.716 +	vec.z += scalar;
  31.717 +	vec.w += scalar;
  31.718 +}
  31.719 +
  31.720 +inline void operator -=(Vector4 &vec, scalar_t scalar) {
  31.721 +	vec.x -= scalar;
  31.722 +	vec.y -= scalar;
  31.723 +	vec.z -= scalar;
  31.724 +	vec.w -= scalar;
  31.725 +}
  31.726 +
  31.727 +inline void operator *=(Vector4 &vec, scalar_t scalar) {
  31.728 +	vec.x *= scalar;
  31.729 +	vec.y *= scalar;
  31.730 +	vec.z *= scalar;
  31.731 +	vec.w *= scalar;
  31.732 +}
  31.733 +
  31.734 +inline void operator /=(Vector4 &vec, scalar_t scalar) {
  31.735 +	vec.x /= scalar;
  31.736 +	vec.y /= scalar;
  31.737 +	vec.z /= scalar;
  31.738 +	vec.w /= scalar;
  31.739 +}
  31.740 +
  31.741 +inline scalar_t Vector4::length() const {
  31.742 +	return sqrt(x*x + y*y + z*z + w*w);
  31.743 +}
  31.744 +inline scalar_t Vector4::length_sq() const {
  31.745 +	return x*x + y*y + z*z + w*w;
  31.746 +}
  31.747 +
  31.748 +inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t)
  31.749 +{
  31.750 +	return v0 + (v1 - v0) * t;
  31.751 +}
  31.752 +
  31.753 +inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1,
  31.754 +		const Vector4 &v2, const Vector4 &v3, scalar_t t)
  31.755 +{
  31.756 +	scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t);
  31.757 +	scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t);
  31.758 +	scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t);
  31.759 +	scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t);
  31.760 +	scalar_t w = spline(v0.w, v1.w, v2.w, v3.w, t);
  31.761 +	return Vector4(x, y, z, w);
  31.762 +}
  31.763 +
  31.764 +#endif	/* __cplusplus */
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/prototype/vmath/vmath.c	Thu Jun 28 06:05:50 2012 +0300
    32.3 @@ -0,0 +1,335 @@
    32.4 +/*
    32.5 +libvmath - a vector math library
    32.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    32.7 +
    32.8 +This program is free software: you can redistribute it and/or modify
    32.9 +it under the terms of the GNU Lesser General Public License as published
   32.10 +by the Free Software Foundation, either version 3 of the License, or
   32.11 +(at your option) any later version.
   32.12 +
   32.13 +This program is distributed in the hope that it will be useful,
   32.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   32.16 +GNU Lesser General Public License for more details.
   32.17 +
   32.18 +You should have received a copy of the GNU Lesser General Public License
   32.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   32.20 +*/
   32.21 +
   32.22 +#include <stdlib.h>
   32.23 +#include <math.h>
   32.24 +#include "vmath.h"
   32.25 +
   32.26 +/** Numerical calculation of integrals using simpson's rule */
   32.27 +scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples)
   32.28 +{
   32.29 +	int i;
   32.30 +	scalar_t h = (high - low) / (scalar_t)samples;
   32.31 +	scalar_t sum = 0.0;
   32.32 +
   32.33 +	for(i=0; i<samples+1; i++) {
   32.34 +		scalar_t y = f((scalar_t)i * h + low);
   32.35 +		sum += ((!i || i == samples) ? y : ((i % 2) ? 4.0 * y : 2.0 * y)) * (h / 3.0);
   32.36 +	}
   32.37 +	return sum;
   32.38 +}
   32.39 +
   32.40 +/** Gaussuan function */
   32.41 +scalar_t gaussian(scalar_t x, scalar_t mean, scalar_t sdev)
   32.42 +{
   32.43 +	scalar_t exponent = -SQ(x - mean) / (2.0 * SQ(sdev));
   32.44 +	return 1.0 - -pow(M_E, exponent) / (sdev * sqrt(TWO_PI));
   32.45 +}
   32.46 +
   32.47 +
   32.48 +/** b-spline approximation */
   32.49 +scalar_t bspline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t)
   32.50 +{
   32.51 +	vec4_t tmp;
   32.52 +	scalar_t tsq = t * t;
   32.53 +
   32.54 +	static mat4_t bspline_mat = {
   32.55 +		{-1,  3, -3,  1},
   32.56 +		{3, -6,  3,  0},
   32.57 +		{-3,  0,  3,  0},
   32.58 +		{1,  4,  1,  0}
   32.59 +	};
   32.60 +
   32.61 +	tmp = v4_scale(v4_transform(v4_cons(a, b, c, d), bspline_mat), 1.0 / 6.0);
   32.62 +	return v4_dot(v4_cons(tsq * t, tsq, t, 1.0), tmp);
   32.63 +}
   32.64 +
   32.65 +/** Catmull-rom spline interpolation */
   32.66 +scalar_t spline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t) {
   32.67 +	vec4_t tmp;
   32.68 +	scalar_t tsq = t * t;
   32.69 +
   32.70 +	static mat4_t crspline_mat = {
   32.71 +		{-1,  3, -3,  1},
   32.72 +		{2, -5,  4, -1},
   32.73 +		{-1,  0,  1,  0},
   32.74 +		{0,  2,  0,  0}
   32.75 +	};
   32.76 +
   32.77 +	tmp = v4_scale(v4_transform(v4_cons(a, b, c, d), crspline_mat), 0.5);
   32.78 +	return v4_dot(v4_cons(tsq * t, tsq, t, 1.0), tmp);
   32.79 +}
   32.80 +
   32.81 +/** Bezier interpolation */
   32.82 +scalar_t bezier(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t)
   32.83 +{
   32.84 +	scalar_t omt, omt3, t3, f;
   32.85 +	t3 = t * t * t;
   32.86 +	omt = 1.0f - t;
   32.87 +	omt3 = omt * omt * omt;
   32.88 +	f = 3 * t * omt;
   32.89 +
   32.90 +	return (a * omt3) + (b * f * omt) + (c * f * t) + (d * t3);
   32.91 +}
   32.92 +
   32.93 +/* ---- Ken Perlin's implementation of noise ---- */
   32.94 +
   32.95 +#define B	0x100
   32.96 +#define BM	0xff
   32.97 +#define N	0x1000
   32.98 +#define NP	12   /* 2^N */
   32.99 +#define NM	0xfff
  32.100 +
  32.101 +#define s_curve(t) (t * t * (3.0f - 2.0f * t))
  32.102 +
  32.103 +#define setup(elem, b0, b1, r0, r1) \
  32.104 +	do {							\
  32.105 +		scalar_t t = elem + N;		\
  32.106 +		b0 = ((int)t) & BM;			\
  32.107 +		b1 = (b0 + 1) & BM;			\
  32.108 +		r0 = t - (int)t;			\
  32.109 +		r1 = r0 - 1.0f;				\
  32.110 +	} while(0)
  32.111 +
  32.112 +
  32.113 +static int perm[B + B + 2];			/* permuted index from g_n onto themselves */
  32.114 +static vec3_t grad3[B + B + 2];		/* 3D random gradients */
  32.115 +static vec2_t grad2[B + B + 2];		/* 2D random gradients */
  32.116 +static scalar_t grad1[B + B + 2];	/* 1D random ... slopes */
  32.117 +static int tables_valid;
  32.118 +
  32.119 +static void init_noise()
  32.120 +{
  32.121 +	int i;
  32.122 +
  32.123 +	/* calculate random gradients */
  32.124 +	for(i=0; i<B; i++) {
  32.125 +		perm[i] = i;	/* .. and initialize permutation mapping to identity */
  32.126 +
  32.127 +		grad1[i] = (scalar_t)((rand() % (B + B)) - B) / B;
  32.128 +
  32.129 +		grad2[i].x = (scalar_t)((rand() % (B + B)) - B) / B;
  32.130 +		grad2[i].y = (scalar_t)((rand() % (B + B)) - B) / B;
  32.131 +		grad2[i] = v2_normalize(grad2[i]);
  32.132 +
  32.133 +		grad3[i].x = (scalar_t)((rand() % (B + B)) - B) / B;
  32.134 +		grad3[i].y = (scalar_t)((rand() % (B + B)) - B) / B;
  32.135 +		grad3[i].z = (scalar_t)((rand() % (B + B)) - B) / B;
  32.136 +		grad3[i] = v3_normalize(grad3[i]);
  32.137 +	}
  32.138 +
  32.139 +	/* permute indices by swapping them randomly */
  32.140 +	for(i=0; i<B; i++) {
  32.141 +		int rand_idx = rand() % B;
  32.142 +
  32.143 +		int tmp = perm[i];
  32.144 +		perm[i] = perm[rand_idx];
  32.145 +		perm[rand_idx] = tmp;
  32.146 +	}
  32.147 +
  32.148 +	/* fill up the rest of the arrays by duplicating the existing gradients */
  32.149 +	/* and permutations */
  32.150 +	for(i=0; i<B+2; i++) {
  32.151 +		perm[B + i] = perm[i];
  32.152 +		grad1[B + i] = grad1[i];
  32.153 +		grad2[B + i] = grad2[i];
  32.154 +		grad3[B + i] = grad3[i];
  32.155 +	}
  32.156 +}
  32.157 +
  32.158 +scalar_t noise1(scalar_t x)
  32.159 +{
  32.160 +	int bx0, bx1;
  32.161 +	scalar_t rx0, rx1, sx, u, v;
  32.162 +
  32.163 +	if(!tables_valid) {
  32.164 +		init_noise();
  32.165 +		tables_valid = 1;
  32.166 +	}
  32.167 +
  32.168 +	setup(x, bx0, bx1, rx0, rx1);
  32.169 +	sx = s_curve(rx0);
  32.170 +	u = rx0 * grad1[perm[bx0]];
  32.171 +	v = rx1 * grad1[perm[bx1]];
  32.172 +
  32.173 +	return lerp(u, v, sx);
  32.174 +}
  32.175 +
  32.176 +scalar_t noise2(scalar_t x, scalar_t y)
  32.177 +{
  32.178 +	int i, j, b00, b10, b01, b11;
  32.179 +	int bx0, bx1, by0, by1;
  32.180 +	scalar_t rx0, rx1, ry0, ry1;
  32.181 +	scalar_t sx, sy, u, v, a, b;
  32.182 +
  32.183 +	if(!tables_valid) {
  32.184 +		init_noise();
  32.185 +		tables_valid = 1;
  32.186 +	}
  32.187 +
  32.188 +	setup(x, bx0, bx1, rx0, rx1);
  32.189 +	setup(y, by0, by1, ry0, ry1);
  32.190 +
  32.191 +	i = perm[bx0];
  32.192 +	j = perm[bx1];
  32.193 +
  32.194 +	b00 = perm[i + by0];
  32.195 +	b10 = perm[j + by0];
  32.196 +	b01 = perm[i + by1];
  32.197 +	b11 = perm[j + by1];
  32.198 +
  32.199 +	/* calculate hermite inteprolating factors */
  32.200 +	sx = s_curve(rx0);
  32.201 +	sy = s_curve(ry0);
  32.202 +
  32.203 +	/* interpolate along the left edge */
  32.204 +	u = v2_dot(grad2[b00], v2_cons(rx0, ry0));
  32.205 +	v = v2_dot(grad2[b10], v2_cons(rx1, ry0));
  32.206 +	a = lerp(u, v, sx);
  32.207 +
  32.208 +	/* interpolate along the right edge */
  32.209 +	u = v2_dot(grad2[b01], v2_cons(rx0, ry1));
  32.210 +	v = v2_dot(grad2[b11], v2_cons(rx1, ry1));
  32.211 +	b = lerp(u, v, sx);
  32.212 +
  32.213 +	/* interpolate between them */
  32.214 +	return lerp(a, b, sy);
  32.215 +}
  32.216 +
  32.217 +scalar_t noise3(scalar_t x, scalar_t y, scalar_t z)
  32.218 +{
  32.219 +	int i, j;
  32.220 +	int bx0, bx1, by0, by1, bz0, bz1;
  32.221 +	int b00, b10, b01, b11;
  32.222 +	scalar_t rx0, rx1, ry0, ry1, rz0, rz1;
  32.223 +	scalar_t sx, sy, sz;
  32.224 +	scalar_t u, v, a, b, c, d;
  32.225 +
  32.226 +	if(!tables_valid) {
  32.227 +		init_noise();
  32.228 +		tables_valid = 1;
  32.229 +	}
  32.230 +
  32.231 +	setup(x, bx0, bx1, rx0, rx1);
  32.232 +	setup(y, by0, by1, ry0, ry1);
  32.233 +	setup(z, bz0, bz1, rz0, rz1);
  32.234 +
  32.235 +	i = perm[bx0];
  32.236 +	j = perm[bx1];
  32.237 +
  32.238 +	b00 = perm[i + by0];
  32.239 +	b10 = perm[j + by0];
  32.240 +	b01 = perm[i + by1];
  32.241 +	b11 = perm[j + by1];
  32.242 +
  32.243 +	/* calculate hermite interpolating factors */
  32.244 +	sx = s_curve(rx0);
  32.245 +	sy = s_curve(ry0);
  32.246 +	sz = s_curve(rz0);
  32.247 +
  32.248 +	/* interpolate along the top slice of the cell */
  32.249 +	u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz0));
  32.250 +	v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz0));
  32.251 +	a = lerp(u, v, sx);
  32.252 +
  32.253 +	u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz0));
  32.254 +	v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz0));
  32.255 +	b = lerp(u, v, sx);
  32.256 +
  32.257 +	c = lerp(a, b, sy);
  32.258 +
  32.259 +	/* interpolate along the bottom slice of the cell */
  32.260 +	u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz1));
  32.261 +	v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz1));
  32.262 +	a = lerp(u, v, sx);
  32.263 +
  32.264 +	u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz1));
  32.265 +	v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz1));
  32.266 +	b = lerp(u, v, sx);
  32.267 +
  32.268 +	d = lerp(a, b, sy);
  32.269 +
  32.270 +	/* interpolate between slices */
  32.271 +	return lerp(c, d, sz);
  32.272 +}
  32.273 +
  32.274 +scalar_t fbm1(scalar_t x, int octaves)
  32.275 +{
  32.276 +	int i;
  32.277 +	scalar_t res = 0.0f, freq = 1.0f;
  32.278 +	for(i=0; i<octaves; i++) {
  32.279 +		res += noise1(x * freq) / freq;
  32.280 +		freq *= 2.0f;
  32.281 +	}
  32.282 +	return res;
  32.283 +}
  32.284 +
  32.285 +scalar_t fbm2(scalar_t x, scalar_t y, int octaves)
  32.286 +{
  32.287 +	int i;
  32.288 +	scalar_t res = 0.0f, freq = 1.0f;
  32.289 +	for(i=0; i<octaves; i++) {
  32.290 +		res += noise2(x * freq, y * freq) / freq;
  32.291 +		freq *= 2.0f;
  32.292 +	}
  32.293 +	return res;
  32.294 +}
  32.295 +
  32.296 +scalar_t fbm3(scalar_t x, scalar_t y, scalar_t z, int octaves)
  32.297 +{
  32.298 +	int i;
  32.299 +	scalar_t res = 0.0f, freq = 1.0f;
  32.300 +	for(i=0; i<octaves; i++) {
  32.301 +		res += noise3(x * freq, y * freq, z * freq) / freq;
  32.302 +		freq *= 2.0f;
  32.303 +	}
  32.304 +	return res;
  32.305 +}
  32.306 +
  32.307 +scalar_t turbulence1(scalar_t x, int octaves)
  32.308 +{
  32.309 +	int i;
  32.310 +	scalar_t res = 0.0f, freq = 1.0f;
  32.311 +	for(i=0; i<octaves; i++) {
  32.312 +		res += fabs(noise1(x * freq) / freq);
  32.313 +		freq *= 2.0f;
  32.314 +	}
  32.315 +	return res;
  32.316 +}
  32.317 +
  32.318 +scalar_t turbulence2(scalar_t x, scalar_t y, int octaves)
  32.319 +{
  32.320 +	int i;
  32.321 +	scalar_t res = 0.0f, freq = 1.0f;
  32.322 +	for(i=0; i<octaves; i++) {
  32.323 +		res += fabs(noise2(x * freq, y * freq) / freq);
  32.324 +		freq *= 2.0f;
  32.325 +	}
  32.326 +	return res;
  32.327 +}
  32.328 +
  32.329 +scalar_t turbulence3(scalar_t x, scalar_t y, scalar_t z, int octaves)
  32.330 +{
  32.331 +	int i;
  32.332 +	scalar_t res = 0.0f, freq = 1.0f;
  32.333 +	for(i=0; i<octaves; i++) {
  32.334 +		res += fabs(noise3(x * freq, y * freq, z * freq) / freq);
  32.335 +		freq *= 2.0f;
  32.336 +	}
  32.337 +	return res;
  32.338 +}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/prototype/vmath/vmath.h	Thu Jun 28 06:05:50 2012 +0300
    33.3 @@ -0,0 +1,92 @@
    33.4 +/*
    33.5 +libvmath - a vector math library
    33.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    33.7 +
    33.8 +This program is free software: you can redistribute it and/or modify
    33.9 +it under the terms of the GNU Lesser General Public License as published
   33.10 +by the Free Software Foundation, either version 3 of the License, or
   33.11 +(at your option) any later version.
   33.12 +
   33.13 +This program is distributed in the hope that it will be useful,
   33.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33.16 +GNU Lesser General Public License for more details.
   33.17 +
   33.18 +You should have received a copy of the GNU Lesser General Public License
   33.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   33.20 +*/
   33.21 +
   33.22 +#ifndef VMATH_H_
   33.23 +#define VMATH_H_
   33.24 +
   33.25 +#include <math.h>
   33.26 +#include "vmath_types.h"
   33.27 +
   33.28 +#ifndef M_PI
   33.29 +#define M_PI	PI
   33.30 +#endif
   33.31 +
   33.32 +#ifndef M_E
   33.33 +#define M_E				2.718281828459045
   33.34 +#endif
   33.35 +
   33.36 +#define PI				3.141592653589793
   33.37 +#define HALF_PI			1.570796326794897
   33.38 +#define QUARTER_PI		0.785398163397448
   33.39 +#define TWO_PI			6.283185307179586
   33.40 +
   33.41 +
   33.42 +#define RAD_TO_DEG(a) ((((scalar_t)a) * 360.0) / TWO_PI)
   33.43 +#define DEG_TO_RAD(a) (((scalar_t)a) * (PI / 180.0))
   33.44 +
   33.45 +#define SQ(x) ((x) * (x))
   33.46 +
   33.47 +#define MIN(a, b)	((a) < (b) ? (a) : (b))
   33.48 +#define MAX(a, b)	((a) > (b) ? (a) : (b))
   33.49 +
   33.50 +#ifndef __GNUC__
   33.51 +#define round(x)	((x) >= 0 ? (x) + 0.5 : (x) - 0.5)
   33.52 +#endif
   33.53 +
   33.54 +#ifdef __cplusplus
   33.55 +extern "C" {
   33.56 +#endif	/* __cplusplus */
   33.57 +
   33.58 +static inline scalar_t frand(scalar_t range);
   33.59 +static inline vec3_t sphrand(scalar_t rad);
   33.60 +
   33.61 +scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples);
   33.62 +scalar_t gaussian(scalar_t x, scalar_t mean, scalar_t sdev);
   33.63 +
   33.64 +static inline scalar_t lerp(scalar_t a, scalar_t b, scalar_t t);
   33.65 +
   33.66 +scalar_t bspline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t);
   33.67 +scalar_t spline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t);
   33.68 +scalar_t bezier(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t);
   33.69 +
   33.70 +scalar_t noise1(scalar_t x);
   33.71 +scalar_t noise2(scalar_t x, scalar_t y);
   33.72 +scalar_t noise3(scalar_t x, scalar_t y, scalar_t z);
   33.73 +
   33.74 +scalar_t fbm1(scalar_t x, int octaves);
   33.75 +scalar_t fbm2(scalar_t x, scalar_t y, int octaves);
   33.76 +scalar_t fbm3(scalar_t x, scalar_t y, scalar_t z, int octaves);
   33.77 +
   33.78 +scalar_t turbulence1(scalar_t x, int octaves);
   33.79 +scalar_t turbulence2(scalar_t x, scalar_t y, int octaves);
   33.80 +scalar_t turbulence3(scalar_t x, scalar_t y, scalar_t z, int octaves);
   33.81 +
   33.82 +#ifdef __cplusplus
   33.83 +}
   33.84 +#endif	/* __cplusplus */
   33.85 +
   33.86 +#include "vmath.inl"
   33.87 +
   33.88 +#include "vector.h"
   33.89 +#include "matrix.h"
   33.90 +#include "quat.h"
   33.91 +#include "sphvec.h"
   33.92 +#include "ray.h"
   33.93 +#include "geom.h"
   33.94 +
   33.95 +#endif	/* VMATH_H_ */
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/prototype/vmath/vmath.inl	Thu Jun 28 06:05:50 2012 +0300
    34.3 @@ -0,0 +1,47 @@
    34.4 +/*
    34.5 +libvmath - a vector math library
    34.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    34.7 +
    34.8 +This program is free software: you can redistribute it and/or modify
    34.9 +it under the terms of the GNU Lesser General Public License as published
   34.10 +by the Free Software Foundation, either version 3 of the License, or
   34.11 +(at your option) any later version.
   34.12 +
   34.13 +This program is distributed in the hope that it will be useful,
   34.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   34.16 +GNU Lesser General Public License for more details.
   34.17 +
   34.18 +You should have received a copy of the GNU Lesser General Public License
   34.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   34.20 +*/
   34.21 +
   34.22 +#include <stdlib.h>
   34.23 +
   34.24 +/** Generates a random number in [0, range) */
   34.25 +static inline scalar_t frand(scalar_t range)
   34.26 +{
   34.27 +	return range * (scalar_t)rand() / (scalar_t)RAND_MAX;
   34.28 +}
   34.29 +
   34.30 +/** Generates a random vector on the surface of a sphere */
   34.31 +static inline vec3_t sphrand(scalar_t rad)
   34.32 +{
   34.33 +	scalar_t u = (scalar_t)rand() / RAND_MAX;
   34.34 +	scalar_t v = (scalar_t)rand() / RAND_MAX;
   34.35 +
   34.36 +	scalar_t theta = 2.0 * M_PI * u;
   34.37 +	scalar_t phi = acos(2.0 * v - 1.0);
   34.38 +
   34.39 +	vec3_t res;
   34.40 +	res.x = rad * cos(theta) * sin(phi);
   34.41 +	res.y = rad * sin(theta) * sin(phi);
   34.42 +	res.z = rad * cos(phi);
   34.43 +	return res;
   34.44 +}
   34.45 +
   34.46 +/** linear interpolation */
   34.47 +static inline scalar_t lerp(scalar_t a, scalar_t b, scalar_t t)
   34.48 +{
   34.49 +	return a + (b - a) * t;
   34.50 +}
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/prototype/vmath/vmath_config.h	Thu Jun 28 06:05:50 2012 +0300
    35.3 @@ -0,0 +1,19 @@
    35.4 +#ifndef VMATH_CONFIG_H_
    35.5 +#define VMATH_CONFIG_H_
    35.6 +
    35.7 +#if (__STDC_VERSION__ < 199999)
    35.8 +#if defined(__GNUC__) || defined(_MSC_VER)
    35.9 +#define inline __inline
   35.10 +#else
   35.11 +#define inline
   35.12 +
   35.13 +#ifdef VECTOR_H_
   35.14 +#warning "compiling vector operations without inline, performance might suffer"
   35.15 +#endif	/* VECTOR_H_ */
   35.16 +
   35.17 +#endif	/* gcc/msvc */
   35.18 +#endif	/* not C99 */
   35.19 +
   35.20 +#define SINGLE_PRECISION_MATH
   35.21 +
   35.22 +#endif	/* VMATH_CONFIG_H_ */
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/prototype/vmath/vmath_types.h	Thu Jun 28 06:05:50 2012 +0300
    36.3 @@ -0,0 +1,58 @@
    36.4 +/*
    36.5 +libvmath - a vector math library
    36.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org>
    36.7 +
    36.8 +This program is free software: you can redistribute it and/or modify
    36.9 +it under the terms of the GNU Lesser General Public License as published
   36.10 +by the Free Software Foundation, either version 3 of the License, or
   36.11 +(at your option) any later version.
   36.12 +
   36.13 +This program is distributed in the hope that it will be useful,
   36.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   36.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   36.16 +GNU Lesser General Public License for more details.
   36.17 +
   36.18 +You should have received a copy of the GNU Lesser General Public License
   36.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   36.20 +*/
   36.21 +
   36.22 +#ifndef VMATH_TYPES_H_
   36.23 +#define VMATH_TYPES_H_
   36.24 +
   36.25 +#include "vmath_config.h"
   36.26 +
   36.27 +#define SMALL_NUMBER	1.e-4
   36.28 +#define XSMALL_NUMBER	1.e-8
   36.29 +#define ERROR_MARGIN	1.e-6
   36.30 +
   36.31 +
   36.32 +#ifdef SINGLE_PRECISION_MATH
   36.33 +typedef float scalar_t;
   36.34 +#else
   36.35 +typedef double scalar_t;
   36.36 +#endif	/* floating point precision */
   36.37 +
   36.38 +/* vectors */
   36.39 +typedef struct { scalar_t x, y; } vec2_t;
   36.40 +typedef struct { scalar_t x, y, z; } vec3_t;
   36.41 +typedef struct { scalar_t x, y, z, w; } vec4_t;
   36.42 +
   36.43 +/* quaternions */
   36.44 +typedef vec4_t quat_t;
   36.45 +
   36.46 +/* matrices */
   36.47 +typedef scalar_t mat3_t[3][3];
   36.48 +typedef scalar_t mat4_t[4][4];
   36.49 +
   36.50 +
   36.51 +#ifdef __cplusplus
   36.52 +class Vector2;
   36.53 +class Vector3;
   36.54 +class Vector4;
   36.55 +class Quaternion;
   36.56 +class Matrix3x3;
   36.57 +class Matrix4x4;
   36.58 +class SphVector;
   36.59 +#endif	/* __cplusplus */
   36.60 +
   36.61 +#endif	/* VMATH_TYPES_H_ */