Panagiotis Christopoulos Charitos 16 éve
commit
066599a308
100 módosított fájl, 27828 hozzáadás és 0 törlés
  1. 292 0
      src/main.cpp
  2. 32 0
      src/math/axisang.h
  3. 93 0
      src/math/axisang.inl.h
  4. 42 0
      src/math/euler.h
  5. 123 0
      src/math/euler.inl.h
  6. 15 0
      src/math/forward_decls.h
  7. 19 0
      src/math/gmath.h
  8. 14 0
      src/math/m_dflt_header.h
  9. 46 0
      src/math/m_misc.h
  10. 142 0
      src/math/m_misc.inl.h
  11. 92 0
      src/math/mat3.h
  12. 618 0
      src/math/mat3.inl.h
  13. 90 0
      src/math/mat4.h
  14. 649 0
      src/math/mat4.inl.h
  15. 57 0
      src/math/quat.h
  16. 277 0
      src/math/quat.inl.h
  17. 68 0
      src/math/vec2.h
  18. 222 0
      src/math/vec2.inl.h
  19. 84 0
      src/math/vec3.h
  20. 321 0
      src/math/vec3.inl.h
  21. 66 0
      src/math/vec4.h
  22. 234 0
      src/math/vec4.inl.h
  23. 66 0
      src/old_src/2009-5-11/animation.cbp
  24. 222 0
      src/old_src/2009-5-11/assets.cpp
  25. 47 0
      src/old_src/2009-5-11/assets.h
  26. 194 0
      src/old_src/2009-5-11/camera.cpp
  27. 75 0
      src/old_src/2009-5-11/camera.h
  28. 2044 0
      src/old_src/2009-5-11/collision.cpp
  29. 325 0
      src/old_src/2009-5-11/collision.h
  30. 110 0
      src/old_src/2009-5-11/common.cpp
  31. 100 0
      src/old_src/2009-5-11/common.h
  32. 63 0
      src/old_src/2009-5-11/engine_class.h
  33. 463 0
      src/old_src/2009-5-11/geometry.cpp
  34. 54 0
      src/old_src/2009-5-11/geometry.h
  35. 71 0
      src/old_src/2009-5-11/handlers.cpp
  36. 27 0
      src/old_src/2009-5-11/handlers.h
  37. 235 0
      src/old_src/2009-5-11/hud.cpp
  38. 20 0
      src/old_src/2009-5-11/hud.h
  39. 104 0
      src/old_src/2009-5-11/input.cpp
  40. 27 0
      src/old_src/2009-5-11/input.h
  41. 60 0
      src/old_src/2009-5-11/lights.cpp
  42. 98 0
      src/old_src/2009-5-11/lights.h
  43. 232 0
      src/old_src/2009-5-11/main_animation.cpp
  44. 231 0
      src/old_src/2009-5-11/main_deffered.cpp
  45. 364 0
      src/old_src/2009-5-11/main_particles.cpp
  46. 270 0
      src/old_src/2009-5-11/main_project_txtr.cpp
  47. 274 0
      src/old_src/2009-5-11/main_projection_test.cpp
  48. 287 0
      src/old_src/2009-5-11/main_shadows.cpp
  49. 93 0
      src/old_src/2009-5-11/material.cpp
  50. 48 0
      src/old_src/2009-5-11/material.h
  51. 2273 0
      src/old_src/2009-5-11/math.cpp
  52. 476 0
      src/old_src/2009-5-11/math.h
  53. 1012 0
      src/old_src/2009-5-11/memory.cpp
  54. 59 0
      src/old_src/2009-5-11/memory.h
  55. 643 0
      src/old_src/2009-5-11/model.cpp
  56. 206 0
      src/old_src/2009-5-11/model.h
  57. 139 0
      src/old_src/2009-5-11/particles.cbp
  58. 212 0
      src/old_src/2009-5-11/particles.cpp
  59. 79 0
      src/old_src/2009-5-11/particles.h
  60. 131 0
      src/old_src/2009-5-11/primitives.cpp
  61. 88 0
      src/old_src/2009-5-11/primitives.h
  62. 322 0
      src/old_src/2009-5-11/r_deferred.cpp
  63. 403 0
      src/old_src/2009-5-11/renderer.cpp
  64. 61 0
      src/old_src/2009-5-11/renderer.h
  65. 1000 0
      src/old_src/2009-5-11/scanner.cpp
  66. 104 0
      src/old_src/2009-5-11/scanner.h
  67. 213 0
      src/old_src/2009-5-11/scene.cpp
  68. 55 0
      src/old_src/2009-5-11/scene.h
  69. 307 0
      src/old_src/2009-5-11/shaders.cpp
  70. 65 0
      src/old_src/2009-5-11/shaders.h
  71. 97 0
      src/old_src/2009-5-11/skybox.cpp
  72. 35 0
      src/old_src/2009-5-11/skybox.h
  73. 30 0
      src/old_src/2009-5-11/spatial.cpp
  74. 24 0
      src/old_src/2009-5-11/spatial.h
  75. 319 0
      src/old_src/2009-5-11/texture.cpp
  76. 57 0
      src/old_src/2009-5-11/texture.h
  77. 2036 0
      src/old_src/collision.cpp
  78. 325 0
      src/old_src/collision.h
  79. 261 0
      src/old_src/deferred shading, calculate fragpos from depth/light_pass_generic.frag
  80. 10 0
      src/old_src/deferred shading, calculate fragpos from depth/light_pass_generic.vert
  81. 17 0
      src/old_src/deferred shading, calculate fragpos from depth/light_pass_point.shdr
  82. 18 0
      src/old_src/deferred shading, calculate fragpos from depth/light_pass_proj_nos.shdr
  83. 18 0
      src/old_src/deferred shading, calculate fragpos from depth/light_pass_proj_s.shdr
  84. 75 0
      src/old_src/deferred shading, calculate fragpos from depth/mat_pass_generic.frag
  85. 32 0
      src/old_src/deferred shading, calculate fragpos from depth/mat_pass_generic.vert
  86. 525 0
      src/old_src/deferred shading, calculate fragpos from depth/r_deferred.cpp
  87. 393 0
      src/old_src/geometry.cpp
  88. 40 0
      src/old_src/geometry.h
  89. 70 0
      src/old_src/gl_wapper.h
  90. 232 0
      src/old_src/main_animation.cpp
  91. 464 0
      src/old_src/main_dualparabolic.cpp
  92. 194 0
      src/old_src/main_normalmaping.cpp
  93. 190 0
      src/old_src/main_parallax.cpp
  94. 364 0
      src/old_src/main_particles.cpp
  95. 270 0
      src/old_src/main_project_txtr.cpp
  96. 274 0
      src/old_src/main_projection_test.cpp
  97. 287 0
      src/old_src/main_shadows.cpp
  98. 2365 0
      src/old_src/math.cpp
  99. 488 0
      src/old_src/math.h
  100. 670 0
      src/old_src/model.cpp

+ 292 - 0
src/main.cpp

@@ -0,0 +1,292 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include <typeinfo>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "gmath.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "mesh.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "smodel.h"
+#include "spatial.h"
+#include "material.h"
+#include "resource.h"
+#include "scene.h"
+#include "scanner.h"
+#include "skybox.h"
+#include "map.h"
+#include "model.h"
+#include "shader_parser.h"
+
+camera_t main_cam;
+
+
+mesh_t imp, mcube, floor__, sarge;
+
+smodel_t mdl;
+
+skeleton_anim_t walk_anim;
+
+point_light_t point_lights[10];
+spot_light_t projlights[2];
+
+map_t map;
+
+class sphere_t: public mesh_t
+{
+	public:
+		sphere_t()
+		{
+			translation_lspace = vec3_t( 0.0, 0.0, 0.0 );
+			scale_lspace = 2.5;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( transformation_wspace );
+
+			//r::dbg::RenderSphere( 1.0, 16.0 );
+			r::dbg::RenderCube( false, 1.0 );
+
+			glPopMatrix();
+		}
+
+		void RenderDepth()
+		{
+			glPushMatrix();
+			r::MultMatrix( transformation_wspace );
+
+			//r::dbg::RenderSphere( 1.0, 16.0 );
+			r::dbg::RenderCube( false, 1.0 );
+
+			glPopMatrix();
+		}
+} sphere;
+
+
+
+/*
+=======================================================================================================================================
+Init                                                                                                                                  =
+=======================================================================================================================================
+*/
+void Init()
+{
+	#if defined( _DEBUG_ )
+		PRINT( "Engine initializing (Debug)..." );
+	#else
+		PRINT( "Engine initializing (Release)..." );
+	#endif
+	srand( unsigned(time(NULL)) );
+	MathSanityChecks();
+
+	hndl::InitWindow( r::w, r::h, "AnKi Engine" );
+	uint ticks = hndl::GetTicks();
+
+	r::Init();
+	hud::Init();
+
+
+	main_cam = camera_t( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 100.0 );
+	main_cam.MoveLocalY( 3.0 );
+	main_cam.MoveLocalZ( 5.7 );
+	main_cam.MoveLocalX( -0.3 );
+//	main_cam.translation_lspace = vec3_t(2.0, 2.0, 0.0);
+//	main_cam.RotateLocalY( ToRad(75) );
+//	main_cam.RotateLocalX( ToRad(-30) );
+	main_cam.camera_data_user_class_t::SetName("main_cam");
+
+	point_lights[0].SetSpecularColor( vec3_t( 0.4, 0.4, 0.4) );
+	point_lights[0].SetDiffuseColor( vec3_t( 1.0, 0.0, 0.0)*1 );
+	point_lights[0].translation_lspace = vec3_t( -1.0, 2.4, 1.0 );
+	point_lights[0].radius = 2.0;
+	point_lights[1].SetSpecularColor( vec3_t( 0.0, 0.0, 1.0)*4 );
+	point_lights[1].SetDiffuseColor( vec3_t( 3.0, 0.1, 0.1) );
+	point_lights[1].translation_lspace = vec3_t( 2.5, 1.4, 1.0 );
+	point_lights[1].radius = 3.0;
+	projlights[0].camera.SetAll( ToRad(60), ToRad(60), 0.1, 20.0 );
+	projlights[0].texture = rsrc::textures.Load( "gfx/lights/flashlight.tga" );
+	projlights[0].texture->TexParameter( GL_TEXTURE_MAX_ANISOTROPY_EXT, 0 );
+	projlights[0].SetSpecularColor( vec3_t( 1.0, 1.0, 1.0) );
+	projlights[0].SetDiffuseColor( vec3_t( 1.0, 1.0, 1.0)*3.0 );
+	projlights[0].translation_lspace = vec3_t( 1.3, 4.3, 3.0 );
+	projlights[0].rotation_lspace.RotateYAxis(ToRad(20));
+	projlights[0].rotation_lspace.RotateXAxis(ToRad(-30));
+	projlights[0].casts_shadow = true;
+
+//	projlights[0].translation_lspace = vec3_t( 2.36, 1.14, 9.70 );
+//	projlights[0].rotation_lspace = euler_t( ToRad(-27.13), ToRad(38.13), ToRad(18.28) );
+
+	projlights[1].camera.SetAll( ToRad(60), ToRad(60), 0.1, 20.0 );
+	projlights[1].texture = rsrc::textures.Load( "gfx/lights/impflash.tga" );
+	projlights[1].SetSpecularColor( vec3_t( 1.0, 1.0, 0.0) );
+	projlights[1].SetDiffuseColor( vec3_t( 1.0, 1.0, 1.0) );
+	projlights[1].translation_lspace = vec3_t( -2.3, 6.3, 2.9 );
+	projlights[1].rotation_lspace.RotateYAxis(ToRad(-20));
+	projlights[1].rotation_lspace.RotateXAxis(ToRad(-70));
+	projlights[1].casts_shadow = true;
+
+	/*imp.Load( "models/imp/imp.mesh" );
+	//imp.Load( "maps/temple/column.mesh" );
+	imp.translation_lspace = vec3_t( 0.0, 2.11, 0.0 );
+	imp.scale_lspace = 0.7;
+	imp.rotation_lspace.RotateXAxis( -PI/2 );*/
+
+	mcube.Load( "meshes/horse/horse.mesh" );
+	mcube.translation_lspace = vec3_t( -2, 0, 1 );
+	mcube.scale_lspace = 0.5;
+	mcube.rotation_lspace.RotateXAxis(ToRad(-90));
+
+	/*floor__.Load( "maps/temple/floor.mesh" );
+	floor__.translation_lspace = vec3_t(0.0, -0.2, 0.0);*/
+
+	sarge.Load( "meshes/sarge/sarge.mesh" );
+	sarge.scale_lspace = 0.1;
+	sarge.RotateLocalX(ToRad(-90));
+	sarge.translation_lspace = vec3_t(0, -2.8, 1.0);
+
+	mdl.Init( rsrc::model_datas.Load( "models/imp/imp.smdl" ) );
+	mdl.translation_lspace = vec3_t( 0.0, 2.11, 0.0 );
+	mdl.scale_lspace = 0.7;
+	mdl.rotation_lspace.RotateXAxis( -PI/2 );
+	walk_anim.Load( "models/imp/walk.imp.anim" );
+	mdl.Play( &walk_anim, 0, 0.8, smodel_t::START_IMMEDIATELY );
+
+	sphere.material = rsrc::materials.Load( "materials/volfog.mtl" );
+
+	scene::smodels.Register( &mdl );
+	scene::meshes.Register( &sarge );
+	//scene::Register( &imp );
+	scene::meshes.Register( &mcube );
+	scene::cameras.Register( &main_cam );
+	scene::lights.Register( &point_lights[0] );
+	scene::lights.Register( &point_lights[1] );
+	scene::lights.Register( &projlights[0] );
+	scene::lights.Register( &projlights[1] );
+	scene::meshes.Register( &sphere );
+
+	//map.Load( "maps/temple/temple.map" );
+	//map.CreateOctree();
+
+
+	const char* skybox_fnames [] = { "textures/env/hellsky4_forward.tga", "textures/env/hellsky4_back.tga", "textures/env/hellsky4_left.tga",
+																	 "textures/env/hellsky4_right.tga", "textures/env/hellsky4_up.tga", "textures/env/hellsky4_down.tga" };
+	scene::skybox.Load( skybox_fnames );
+
+	PRINT( "Engine initialization ends (" << hndl::GetTicks()-ticks << ")" );
+}
+
+
+
+//=====================================================================================================================================
+// main                                                                                                                               =
+//=====================================================================================================================================
+int main( int /*argc*/, char* /*argv*/[] )
+{
+	Init();
+
+
+	//===================================================================================================================================
+	//                                                          MAIN LOOP                                                               =
+	//===================================================================================================================================
+	PRINT( "Entering main loop" );
+	int ticks = hndl::GetTicks();
+	do
+	{
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_2 ] ) mover = &point_lights[0];
+		if( i::keys[ SDLK_3 ] ) mover = &projlights[0];
+		if( i::keys[ SDLK_4 ] ) mover = &point_lights[1];
+		if( i::keys[ SDLK_5 ] ) mover = &projlights[1];
+		if( i::keys[ SDLK_m ] == 1 ) i::warp_mouse = !i::warp_mouse;
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( !i::warp_mouse )
+		{
+			if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+			if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+			if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+			if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		}
+		else
+		{
+			float accel = 44.0;
+			mover->RotateLocalX( ang * i::mouse_velocity.y * accel );
+			mover->RotateLocalY( -ang * i::mouse_velocity.x * accel );
+		}
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->scale_lspace += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->scale_lspace -= scale ;
+
+		if( i::keys[SDLK_k] ) main_cam.LookAtPoint( point_lights[0].translation_wspace );
+
+		mover->rotation_lspace.Reorthogonalize();
+
+
+		scene::InterpolateAllModels();
+		scene::UpdateAllWorldStuff();
+
+		r::Render( main_cam );
+
+
+
+		//map.octree.root->bounding_box.Render();
+
+		// print some debug stuff
+		hud::SetColor( vec4_t(1.0, 1.0, 1.0, 1.0) );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+		//hud::Print( "Movement keys: arrows,w,a,s,d,q,e,shift,space\nSelect objects: keys 1 to 5\n" );
+		hud::Printf( "Mover: Pos(%.2f %.2f %.2f) Angs(%.2f %.2f %.2f)", mover->translation_wspace.x, mover->translation_wspace.y, mover->translation_wspace.z,
+								 ToDegrees(euler_t(mover->rotation_wspace).x), ToDegrees(euler_t(mover->rotation_wspace).y), ToDegrees(euler_t(mover->rotation_wspace).z) );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		if( i::keys[SDLK_F12] == 1 ) r::TakeScreenshot("gfx/screenshot.jpg");
+
+		/*char str[128];
+		sprintf( str, "capt/%05d.jpg", r::frames_num );
+		r::TakeScreenshot(str);*/
+
+		// std stuff follow
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		//if( r::frames_num == 10 ) r::TakeScreenshot("gfx/screenshot.tga");
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+	PRINT( "Exiting main loop (" << hndl::GetTicks()-ticks << ")" );
+
+
+	PRINT( "Exiting..." );
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 32 - 0
src/math/axisang.h

@@ -0,0 +1,32 @@
+#ifndef _AXISANG_H_
+#define _AXISANG_H_
+
+#include "common.h"
+#include "forward_decls.h"
+
+
+namespace m {
+
+
+class axisang_t
+{
+	public:
+		// data members
+		float ang;
+		vec3_t axis;
+		// constructors & distructors
+		explicit axisang_t();
+		         axisang_t( const axisang_t& b );
+		explicit axisang_t( float rad, const vec3_t& axis_ );
+		explicit axisang_t( const quat_t& q );
+		explicit axisang_t( const mat3_t& m3 );
+};
+
+
+} // end namespace
+
+
+#include "axisang.inl.h"
+
+
+#endif

+ 93 - 0
src/math/axisang.inl.h

@@ -0,0 +1,93 @@
+#include "m_dflt_header.h"
+
+namespace m {
+
+
+// constructor []
+M_INLINE axisang_t::axisang_t()
+	: ang(0.0), axis()
+{}
+
+// constructor [axisang_t]
+M_INLINE axisang_t::axisang_t( const axisang_t& b )
+	: ang(b.ang), axis(b.axis)
+{}
+
+// constructor [float, axis]
+M_INLINE axisang_t::axisang_t( float rad, const vec3_t& axis_ )
+	: ang(rad), axis(axis_)
+{}
+
+// constructor [quat]
+M_INLINE axisang_t::axisang_t( const quat_t& q )
+{
+	ang = 2.0*acos( q.w );
+	float length = Sqrt( 1.0 - q.w*q.w );
+	if( IsZero(length) )
+		axis = vec3_t(0.0);
+	else
+	{
+		length = 1.0/length;
+		axis = vec3_t( q.x*length, q.y*length, q.z*length );
+	}
+}
+
+// constructor [mat3]
+M_INLINE axisang_t::axisang_t( const mat3_t& m3 )
+{
+	if( (fabs(m3(0,1)-m3(1,0))< EPSILON)  && (fabs(m3(0,2)-m3(2,0))< EPSILON)  && (fabs(m3(1,2)-m3(2,1))< EPSILON) )
+	{
+
+		if( (fabs(m3(0,1)+m3(1,0)) < 0.1 ) && (fabs(m3(0,2)+m3(2,0)) < 0.1) && (fabs(m3(1,2)+m3(2,1)) < 0.1) && (fabs(m3(0,0)+m3(1,1)+m3(2,2))-3) < 0.1 )
+		{
+			axis = vec3_t( 1.0, 0.0, 0.0 );
+			ang = 0.0;
+			return;
+		}
+
+		ang = PI;
+		axis.x = (m3(0,0)+1)/2;
+		if( axis.x > 0.0 )
+			axis.x = Sqrt(axis.x);
+		else
+			axis.x = 0;
+		axis.y = (m3(1,1)+1)/2;
+		if( axis.y > 0 )
+			axis.y = Sqrt(axis.y);
+		else
+			axis.y = 0;
+		axis.z = (m3(2,2)+1)/2;
+		if( axis.z > 0 )
+			axis.z = Sqrt(axis.z);
+		else
+			axis.z = 0.0;
+
+		bool xZero = ( fabs(axis.x)<EPSILON );
+		bool yZero = ( fabs(axis.y)<EPSILON );
+		bool zZero = ( fabs(axis.z)<EPSILON );
+		bool xyPositive = ( m3(0,1) > 0 );
+		bool xzPositive = ( m3(0,2) > 0 );
+		bool yzPositive = ( m3(1,2) > 0 );
+		if( xZero && !yZero && !zZero ){
+			if( !yzPositive ) axis.y = -axis.y;
+		}else if( yZero && !zZero ){
+			if( !xzPositive ) axis.z = -axis.z;
+		}else if (zZero){
+			if( !xyPositive ) axis.x = -axis.x;
+		}
+
+		return;
+	}
+
+	float s = Sqrt((m3(2,1) - m3(1,2))*(m3(2,1) - m3(1,2))+(m3(0,2) - m3(2,0))*(m3(0,2) - m3(2,0))+(m3(1,0) - m3(0,1))*(m3(1,0) - m3(0,1)));
+
+	if( fabs(s) < 0.001 ) s = 1;
+
+	ang = acos( ( m3(0,0) + m3(1,1) + m3(2,2) - 1)/2 );
+	axis.x= (m3(2,1) - m3(1,2))/s;
+	axis.y= (m3(0,2) - m3(2,0))/s;
+	axis.z= (m3(1,0) - m3(0,1))/s;
+}
+
+
+} // end namaspace

+ 42 - 0
src/math/euler.h

@@ -0,0 +1,42 @@
+#ifndef _EULER_H_
+#define _EULER_H_
+
+#include "common.h"
+#include "forward_decls.h"
+
+
+namespace m {
+
+
+class euler_t
+{
+	public:
+		// data members
+		float x, y, z;
+		// accessors
+		float& operator []( uint i );
+		float  operator []( uint i) const;
+		float& bank();
+		float  bank() const;
+		float& heading();
+		float  heading() const;
+		float& attitude();
+		float  attitude() const;
+		// constructors & distructors
+		explicit euler_t();
+		explicit euler_t( float x, float y, float z  );
+		         euler_t( const euler_t& b );
+		explicit euler_t( const quat_t& q );
+		explicit euler_t( const mat3_t& m3 );
+		// other
+		void Print() const;
+};
+
+
+} // end namespace
+
+
+#include "euler.inl.h"
+
+
+#endif

+ 123 - 0
src/math/euler.inl.h

@@ -0,0 +1,123 @@
+#include "m_dflt_header.h"
+
+
+namespace m {
+
+
+// accessors
+M_INLINE float& euler_t::operator []( uint i )
+{
+	return (&x)[i];
+}
+
+M_INLINE float euler_t::operator []( uint i) const
+{
+	return (&x)[i];
+}
+
+M_INLINE float& euler_t::bank()
+{
+	return x;
+}
+
+M_INLINE float euler_t::bank() const
+{
+	return x;
+}
+
+M_INLINE float& euler_t::heading()
+{
+	return y;
+}
+
+M_INLINE float euler_t::heading() const
+{
+	return y;
+}
+
+M_INLINE float& euler_t::attitude()
+{
+	return z;
+}
+
+M_INLINE float euler_t::attitude() const
+{
+	return z;
+}
+
+// constructor []
+M_INLINE euler_t::euler_t()
+	: x(0.0), y(0.0), z(0.0)
+{}
+
+// constructor [float, float, float]
+M_INLINE euler_t::euler_t( float x_, float y_, float z_ )
+	: x(x_), y(y_), z(z_)
+{}
+
+// constructor [euler]
+M_INLINE euler_t::euler_t( const euler_t& b )
+	: x(b.x), y(b.y), z(b.z)
+{}
+
+// constructor [quat]
+M_INLINE euler_t::euler_t( const quat_t& q )
+{
+	float test = q.x*q.y + q.z*q.w;
+	if( test > 0.499 )
+	{
+		heading() = 2.0 * atan2( q.x, q.w );
+		attitude() = PI/2.0;
+		bank() = 0.0;
+		return;
+	}
+	if( test < -0.499 )
+	{
+		heading() = -2.0 * atan2( q.x, q.w );
+		attitude() = -PI/2.0;
+		bank() = 0.0;
+		return;
+	}
+
+	float sqx = q.x*q.x;
+	float sqy = q.y*q.y;
+	float sqz = q.z*q.z;
+	heading() = atan2( 2.0*q.y*q.w-2.0*q.x*q.z, 1.0-2.0*sqy-2.0*sqz );
+	attitude() = asin( 2.0f*test );
+	bank() = atan2( 2.0*q.x*q.w-2.0*q.y*q.z, 1.0-2.0*sqx-2.0*sqz );
+}
+
+// constructor [mat3]
+M_INLINE euler_t::euler_t( const mat3_t& m3 )
+{
+	float cx, sx;
+	float cy, sy;
+	float cz, sz;
+
+	sy = m3(0,2);
+	cy = Sqrt( 1.0 - sy*sy );
+	// normal case
+	if ( !IsZero( cy ) )
+	{
+		float factor = 1.0/cy;
+		sx = -m3(1,2) * factor;
+		cx = m3(2,2) * factor;
+		sz = -m3(0,1) * factor;
+		cz = m3(0,0) * factor;
+	}
+	// x and z axes aligned
+	else
+	{
+		sz = 0.0;
+		cz = 1.0;
+		sx = m3(2,1);
+		cx = m3(1,1);
+	}
+
+	z = atan2f( sz, cz );
+	y = atan2f( sy, cy );
+	x = atan2f( sx, cx );
+}
+
+
+} // end namespace

+ 15 - 0
src/math/forward_decls.h

@@ -0,0 +1,15 @@
+#ifndef _FORWARD_DECLS_H_
+#define _FORWARD_DECLS_H_
+
+namespace m {
+	class vec2_t;
+	class vec3_t;
+	class vec4_t;
+	class quat_t;
+	class euler_t;
+	class axisang_t;
+	class mat3_t;
+	class mat4_t;
+}
+
+#endif

+ 19 - 0
src/math/gmath.h

@@ -0,0 +1,19 @@
+#ifndef _GMATH_H_
+#define _GMATH_H_
+
+
+#include <math.h>
+#include "vec2.h"
+#include "vec3.h"
+#include "vec4.h"
+#include "quat.h"
+#include "axisang.h"
+#include "euler.h"
+#include "mat3.h"
+#include "mat4.h"
+#include "m_misc.h"
+
+using namespace m;
+
+
+#endif

+ 14 - 0
src/math/m_dflt_header.h

@@ -0,0 +1,14 @@
+#include "vec2.h"
+#include "vec3.h"
+#include "vec4.h"
+#include "quat.h"
+#include "axisang.h"
+#include "euler.h"
+#include "mat3.h"
+#include "mat4.h"
+#include "m_misc.h"
+
+
+#ifndef M_INLINE
+	#define M_INLINE inline
+#endif

+ 46 - 0
src/math/m_misc.h

@@ -0,0 +1,46 @@
+#ifndef _M_MISC_H_
+#define _M_MISC_H_
+
+#include "common.h"
+#include "forward_decls.h"
+
+
+namespace m {
+
+
+const float PI = 3.14159265358979323846;
+const float EPSILON = 1.0e-6;
+
+
+void  MathSanityChecks();
+void  SinCos( float rad, float& sin_, float& cos_ );
+float InvSqrt( float f );
+float Sqrt( float f );
+float ToRad( float degrees );
+float ToDegrees( float rad );
+float Sin( float rad );
+float Cos( float rad );
+bool  IsZero( float f );
+float Max( float a, float b );
+float Min( float a, float b );
+
+
+/**
+ * CombineTransformations
+ * mat4(t0,r0,s0)*mat4(t1,r1,s1) == mat4(tf,rf,sf)
+ */
+void CombineTransformations( const vec3_t& t0, const mat3_t& r0, float s0,
+                                    const vec3_t& t1, const mat3_t& r1, float s1,
+                                    vec3_t& tf, mat3_t& rf, float& sf );
+
+/// CombineTransformations as the above but without scale
+void CombineTransformations( const vec3_t& t0, const mat3_t& r0, const vec3_t& t1, const mat3_t& r1, vec3_t& tf, mat3_t& rf);
+
+
+} // end namespace
+
+
+#include "m_misc.inl.h"
+
+
+#endif

+ 142 - 0
src/math/m_misc.inl.h

@@ -0,0 +1,142 @@
+#include "m_dflt_header.h"
+
+
+namespace m {
+
+
+// MathSanityChecks
+// test if the compiler keeps the correct sizes for the classes
+M_INLINE void MathSanityChecks()
+{
+	const int fs = sizeof(float); // float size
+	if( sizeof(vec2_t)!=fs*2 || sizeof(vec3_t)!=fs*3 || sizeof(vec4_t)!=fs*4 || sizeof(quat_t)!=fs*4 || sizeof(euler_t)!=fs*3 ||
+	    sizeof(mat3_t)!=fs*9 || sizeof(mat4_t)!=fs*16 )
+		FATAL("Your compiler does class alignment. Quiting");
+}
+
+
+// 1/sqrt(f)
+M_INLINE float InvSqrt( float f )
+{
+#if defined( _DEBUG_ )
+	return 1.0/sqrtf(f);
+#elif defined( _PLATFORM_WIN_ )
+	float fhalf = 0.5*f;
+	int i = *(int*)&f;
+	i = 0x5F3759DF - (i>>1);
+	f = *(float*)&i;
+	f *= 1.5 - fhalf*f*f;
+	return f;
+#elif defined( _PLATFORM_LINUX_ )
+	float fhalf = 0.5*f;
+	asm
+	(
+		"mov %1, %%eax;"
+		"sar %%eax;"
+		"mov $0x5F3759DF, %%ebx;"
+		"sub %%eax, %%ebx;"
+		"mov %%ebx, %0"
+		:"=g"(f)
+		:"g"(f)
+		:"%eax", "%ebx"
+	);
+	f *= 1.5 - fhalf*f*f;
+	return f;
+#else
+	#error "See file"
+#endif
+}
+
+
+// PolynomialSinQuadrant
+// used in SinCos
+#if !defined(_DEBUG_)
+M_INLINE static float PolynomialSinQuadrant(float a)
+{
+	return a * ( 1.0 + a * a * (-0.16666 + a * a * (0.0083143 - a * a * 0.00018542)));
+}
+#endif
+
+
+// Sine and Cosine
+M_INLINE void SinCos( float a, float& sina, float& cosa )
+{
+#ifdef _DEBUG_
+	sina = sin(a);
+	cosa = cos(a);
+#else
+	bool negative = false;
+	if (a < 0.0)
+	{
+		a = -a;
+		negative = true;
+	}
+	const float k_two_over_pi = 1.0 / (PI/2.0);
+	float float_a = k_two_over_pi * a;
+	int int_a = (int)float_a;
+
+	const float k_rational_half_pi = 201 / 128.0;
+	const float k_remainder_half_pi = 4.8382679e-4;
+
+	float_a = (a - k_rational_half_pi * int_a) - k_remainder_half_pi * int_a;
+
+	float float_a_minus_half_pi = (float_a - k_rational_half_pi) - k_remainder_half_pi;
+
+	switch( int_a & 3 )
+	{
+	case 0: // 0 - Pi/2
+		sina = PolynomialSinQuadrant(float_a);
+		cosa = PolynomialSinQuadrant(-float_a_minus_half_pi);
+		break;
+	case 1: // Pi/2 - Pi
+		sina = PolynomialSinQuadrant(-float_a_minus_half_pi);
+		cosa = PolynomialSinQuadrant(-float_a);
+		break;
+	case 2: // Pi - 3Pi/2
+		sina = PolynomialSinQuadrant(-float_a);
+		cosa = PolynomialSinQuadrant(float_a_minus_half_pi);
+		break;
+	case 3: // 3Pi/2 - 2Pi
+		sina = PolynomialSinQuadrant(float_a_minus_half_pi);
+		cosa = PolynomialSinQuadrant(float_a);
+		break;
+	};
+
+	if( negative )
+		sina = -sina;
+#endif
+}
+
+
+//=====================================================================================================================================
+// Small funcs                                                                                                                        =
+//=====================================================================================================================================
+M_INLINE float Sqrt( float f ) { return 1/InvSqrt(f); }
+M_INLINE float ToRad( float degrees ) { return degrees*(PI/180.0); }
+M_INLINE float ToDegrees( float rad ) { return rad*(180.0/PI); }
+M_INLINE float Sin( float rad ) { return sin(rad); }
+M_INLINE float Cos( float rad ) { return cos(rad); }
+M_INLINE bool  IsZero( float f ) { return ( fabs(f) < EPSILON ); }
+M_INLINE float Max( float a, float b ) { return (a>b) ? a : b; }
+M_INLINE float Min( float a, float b ) { return (a<b) ? a : b; }
+
+
+//  CombineTransformations
+//  mat4(t0,r0,s0)*mat4(t1,r1,s1) == mat4(tf,rf,sf)
+M_INLINE void CombineTransformations( const vec3_t& t0, const mat3_t& r0, float s0,
+                             const vec3_t& t1, const mat3_t& r1, float s1,
+                             vec3_t& tf, mat3_t& rf, float& sf )
+{
+	tf = t1.Transformed( t0, r0, s0 );
+	rf = r0 * r1;
+	sf = s0 * s1;
+}
+
+//  CombineTransformations as the above but without scale
+M_INLINE void CombineTransformations( const vec3_t& t0, const mat3_t& r0, const vec3_t& t1, const mat3_t& r1, vec3_t& tf, mat3_t& rf)
+{
+	tf = t1.Transformed( t0, r0 );
+	rf = r0 * r1;
+}
+
+} // end namespace

+ 92 - 0
src/math/mat3.h

@@ -0,0 +1,92 @@
+#ifndef _MAT3_H_
+#define _MAT3_H_
+
+#include "common.h"
+#include "forward_decls.h"
+
+
+namespace m {
+
+
+class mat3_t
+{
+	private:
+		// data members
+		union
+		{
+			float arr1[9];
+			float arr2[3][3];
+		};
+
+	public:
+		// accessors
+		float& operator ()( const uint i, const uint j );
+		const float& operator ()( const uint i, const uint j ) const;
+		float& operator []( const uint i);
+		const float& operator []( const uint i) const;
+		// constructors & distructors
+		explicit mat3_t() {};
+		explicit mat3_t( float f );
+		explicit mat3_t( float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22 );
+		explicit mat3_t( float arr [] );
+		         mat3_t( const mat3_t& b );
+		explicit mat3_t( const quat_t& q ); // 12 muls, 12 adds
+		explicit mat3_t( const euler_t& eu );
+		explicit mat3_t( const axisang_t& axisang );
+		// ops with mat3
+		mat3_t  operator + ( const mat3_t& b ) const;
+		mat3_t& operator +=( const mat3_t& b );
+		mat3_t  operator - ( const mat3_t& b ) const;
+		mat3_t& operator -=( const mat3_t& b );
+		mat3_t  operator * ( const mat3_t& b ) const; // 27 muls, 18 adds
+		mat3_t& operator *=( const mat3_t& b );
+		mat3_t  operator / ( const mat3_t& b ) const;
+		mat3_t& operator /=( const mat3_t& b );
+		// ops with float
+		mat3_t  operator + ( float f ) const;
+		mat3_t& operator +=( float f );
+		mat3_t  operator - ( float f ) const;
+		mat3_t& operator -=( float f );
+		mat3_t  operator * ( float f ) const;
+		mat3_t& operator *=( float f );
+		mat3_t  operator / ( float f ) const;
+		mat3_t& operator /=( float f );
+		// ops with others
+		vec3_t  operator * ( const vec3_t& b ) const;  // 9 muls, 6 adds
+		// comparision
+		bool operator ==( const mat3_t& b ) const;
+		bool operator !=( const mat3_t& b ) const;
+		// other
+		void   SetRows( const vec3_t& a, const vec3_t& b, const vec3_t& c );
+		void   SetRow( const uint i, const vec3_t& v );
+		void   GetRows( vec3_t& a, vec3_t& b, vec3_t& c ) const;
+		vec3_t GetRow( const uint i ) const;
+		void   SetColumns( const vec3_t& a, const vec3_t& b, const vec3_t& c );
+		void   SetColumn( const uint i, const vec3_t& v );
+		void   GetColumns( vec3_t& a, vec3_t& b, vec3_t& c ) const;
+		vec3_t GetColumn( const uint i ) const;
+		void   SetRotationX( float rad );
+		void   SetRotationY( float rad );
+		void   SetRotationZ( float rad );
+		void   RotateXAxis( float rad ); // it rotates "this" in the axis defined by the rotation AND not the world axis
+		void   RotateYAxis( float rad );
+		void   RotateZAxis( float rad );
+		void   Transpose();
+		mat3_t Transposed() const;
+		void   Reorthogonalize();
+		void   Print() const;
+		float  Det() const;
+		void   Invert();
+		mat3_t Inverted() const;		
+		static const mat3_t& GetZero();
+		static const mat3_t& GetIdentity();		
+};
+
+
+} // end namespace
+
+
+#include "mat3.inl.h"
+
+
+#endif

+ 618 - 0
src/math/mat3.inl.h

@@ -0,0 +1,618 @@
+#include "m_dflt_header.h"
+
+
+#define ME (*this)
+
+
+namespace m {
+
+// accessors
+M_INLINE float& mat3_t::operator ()( const uint i, const uint j )
+{
+	return arr2[i][j];
+}
+
+M_INLINE const float& mat3_t::operator ()( const uint i, const uint j ) const
+{
+	return arr2[i][j]; 
+}
+
+M_INLINE float& mat3_t::operator []( const uint i)
+{
+	return arr1[i];
+}
+
+M_INLINE const float& mat3_t::operator []( const uint i) const
+{
+	return arr1[i];
+}
+
+// constructor [float[]]
+M_INLINE mat3_t::mat3_t( float arr [] )
+{
+	for( int i=0; i<9; i++ )
+		ME[i] = arr[i];
+}
+
+// constructor [float...........float]
+M_INLINE mat3_t::mat3_t( float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22 )
+{
+	ME(0,0) = m00;
+	ME(0,1) = m01;
+	ME(0,2) = m02;
+	ME(1,0) = m10;
+	ME(1,1) = m11;
+	ME(1,2) = m12;
+	ME(2,0) = m20;
+	ME(2,1) = m21;
+	ME(2,2) = m22;
+}
+
+// constructor [mat3]
+M_INLINE mat3_t::mat3_t( const mat3_t& b )
+{
+	for( int i=0; i<9; i++ )
+		ME[i] = b[i];
+}
+
+// constructor [quat]
+M_INLINE mat3_t::mat3_t( const quat_t& q )
+{
+	DEBUG_ERR( !IsZero( 1.0f - q.Length()) ); // Not normalized quat
+
+	float xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
+
+	xs = q.x+q.x;
+	ys = q.y+q.y;
+	zs = q.z+q.z;
+	wx = q.w*xs;
+	wy = q.w*ys;
+	wz = q.w*zs;
+	xx = q.x*xs;
+	xy = q.x*ys;
+	xz = q.x*zs;
+	yy = q.y*ys;
+	yz = q.y*zs;
+	zz = q.z*zs;
+
+	ME(0,0) = 1.0 - (yy + zz);
+	ME(0,1) = xy - wz;
+	ME(0,2) = xz + wy;
+
+	ME(1,0) = xy + wz;
+	ME(1,1) = 1.0f - (xx + zz);
+	ME(1,2) = yz - wx;
+
+	ME(2,0) = xz - wy;
+	ME(2,1) = yz + wx;
+	ME(2,2) = 1.0 - (xx + yy);
+}
+
+// constructor [euler]
+M_INLINE mat3_t::mat3_t( const euler_t& e )
+{
+	float ch, sh, ca, sa, cb, sb;
+  SinCos( e.heading(), sh, ch );
+  SinCos( e.attitude(), sa, ca );
+  SinCos( e.bank(), sb, cb );
+
+  ME(0,0) = ch * ca;
+  ME(0,1) = sh*sb - ch*sa*cb;
+  ME(0,2) = ch*sa*sb + sh*cb;
+  ME(1,0) = sa;
+  ME(1,1) = ca*cb;
+  ME(1,2) = -ca*sb;
+  ME(2,0) = -sh*ca;
+  ME(2,1) = sh*sa*cb + ch*sb;
+  ME(2,2) = -sh*sa*sb + ch*cb;
+}
+
+// constructor [axisang]
+M_INLINE mat3_t::mat3_t( const axisang_t& axisang )
+{
+	DEBUG_ERR( !IsZero( 1.0-axisang.axis.Length() ) ); // Not normalized axis
+
+	float c, s;
+	SinCos( axisang.ang, s, c );
+	float t = 1.0 - c;
+
+	const vec3_t& axis = axisang.axis;
+	ME(0,0) = c + axis.x*axis.x*t;
+	ME(1,1) = c + axis.y*axis.y*t;
+	ME(2,2) = c + axis.z*axis.z*t;
+
+	float tmp1 = axis.x*axis.y*t;
+	float tmp2 = axis.z*s;
+	ME(1,0) = tmp1 + tmp2;
+	ME(0,1) = tmp1 - tmp2;
+	tmp1 = axis.x*axis.z*t;
+	tmp2 = axis.y*s;
+	ME(2,0) = tmp1 - tmp2;
+	ME(0,2) = tmp1 + tmp2;    tmp1 = axis.y*axis.z*t;
+	tmp2 = axis.x*s;
+	ME(2,1) = tmp1 + tmp2;
+	ME(1,2) = tmp1 - tmp2;
+}
+
+// constructor [float]
+M_INLINE mat3_t::mat3_t( float f )
+{
+	for( int i=0; i<9; i++ )
+			ME[i] = f;
+}
+
+// 3x3 + 3x3
+M_INLINE mat3_t mat3_t::operator +( const mat3_t& b ) const
+{
+	mat3_t c;
+	for( int i=0; i<9; i++ )
+		c[i] = ME[i] + b[i];
+	return c;
+}
+
+// 3x3 + 3x3 (self)
+M_INLINE mat3_t& mat3_t::operator +=( const mat3_t& b )
+{
+	for( int i=0; i<9; i++ )
+		ME[i] += b[i];
+	return ME;
+}
+
+// 3x3 - 3x3
+M_INLINE mat3_t mat3_t::operator -( const mat3_t& b ) const
+{
+	mat3_t c;
+	for( int i=0; i<9; i++ )
+		c[i] = ME[i] - b[i];
+	return c;
+}
+
+// 3x3 - 3x3 (self)
+M_INLINE mat3_t& mat3_t::operator -=( const mat3_t& b )
+{
+	for( int i=0; i<9; i++ )
+		ME[i] -= b[i];
+	return ME;
+}
+
+// 3x3 * 3x3
+M_INLINE mat3_t mat3_t::operator *( const mat3_t& b ) const
+{
+	mat3_t c;
+	c(0, 0) = ME(0, 0)*b(0, 0) + ME(0, 1)*b(1, 0) + ME(0, 2)*b(2, 0);
+	c(0, 1) = ME(0, 0)*b(0, 1) + ME(0, 1)*b(1, 1) + ME(0, 2)*b(2, 1);
+	c(0, 2) = ME(0, 0)*b(0, 2) + ME(0, 1)*b(1, 2) + ME(0, 2)*b(2, 2);
+	c(1, 0) = ME(1, 0)*b(0, 0) + ME(1, 1)*b(1, 0) + ME(1, 2)*b(2, 0);
+	c(1, 1) = ME(1, 0)*b(0, 1) + ME(1, 1)*b(1, 1) + ME(1, 2)*b(2, 1);
+	c(1, 2) = ME(1, 0)*b(0, 2) + ME(1, 1)*b(1, 2) + ME(1, 2)*b(2, 2);
+	c(2, 0) = ME(2, 0)*b(0, 0) + ME(2, 1)*b(1, 0) + ME(2, 2)*b(2, 0);
+	c(2, 1) = ME(2, 0)*b(0, 1) + ME(2, 1)*b(1, 1) + ME(2, 2)*b(2, 1);
+	c(2, 2) = ME(2, 0)*b(0, 2) + ME(2, 1)*b(1, 2) + ME(2, 2)*b(2, 2);
+	return c;
+}
+
+// 3x3 * 3x3 (self)
+M_INLINE mat3_t& mat3_t::operator *=( const mat3_t& b )
+{
+	ME = ME * b;
+	return ME;
+}
+
+// 3x3 * float
+M_INLINE mat3_t mat3_t::operator *( float f ) const
+{
+	mat3_t c;
+	for( uint i=0; i<9; i++ )
+		c[i] = ME[i] * f;
+	return c;
+}
+
+// 3x3 * float (self)
+M_INLINE mat3_t& mat3_t::operator *=( float f )
+{
+	for( uint i=0; i<9; i++ )
+		ME[i] *= f;
+	return ME;
+}
+
+// 3x3 * vec3 (cross products with rows)
+M_INLINE vec3_t mat3_t::operator *( const vec3_t& b ) const
+{
+	return vec3_t(
+		ME(0, 0)*b.x + ME(0, 1)*b.y + ME(0, 2)*b.z,
+		ME(1, 0)*b.x + ME(1, 1)*b.y + ME(1, 2)*b.z,
+		ME(2, 0)*b.x + ME(2, 1)*b.y + ME(2, 2)*b.z
+	);
+}
+
+// ==
+M_INLINE bool mat3_t::operator ==( const mat3_t& b ) const
+{
+	for( int i=0; i<9; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return false;
+	return true;
+}
+
+// !=
+M_INLINE bool mat3_t::operator !=( const mat3_t& b ) const
+{
+	for( int i=0; i<9; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return true;
+	return false;
+}
+
+// SetRows
+M_INLINE void mat3_t::SetRows( const vec3_t& a, const vec3_t& b, const vec3_t& c )
+{
+	ME(0,0) = a.x;
+	ME(0,1) = a.y;
+	ME(0,2) = a.z;
+	ME(1,0) = b.x;
+	ME(1,1) = b.y;
+	ME(1,2) = b.z;
+	ME(2,0) = c.x;
+	ME(2,1) = c.y;
+	ME(2,2) = c.z;
+}
+
+// SetColumns
+M_INLINE void mat3_t::SetColumns( const vec3_t& a, const vec3_t& b, const vec3_t& c )
+{
+	ME(0,0) = a.x;
+	ME(1,0) = a.y;
+	ME(2,0) = a.z;
+	ME(0,1) = b.x;
+	ME(1,1) = b.y;
+	ME(2,1) = b.z;
+	ME(0,2) = c.x;
+	ME(1,2) = c.y;
+	ME(2,2) = c.z;
+}
+
+// GetRows
+M_INLINE void mat3_t::GetRows( vec3_t& a, vec3_t& b, vec3_t& c ) const
+{
+	a.x = ME(0,0);
+	a.y = ME(0,1);
+	a.z = ME(0,2);
+	b.x = ME(1,0);
+	b.y = ME(1,1);
+	b.z = ME(1,2);
+	c.x = ME(2,0);
+	c.y = ME(2,1);
+	c.z = ME(2,2);
+}
+
+// GetColumns
+M_INLINE void mat3_t::GetColumns( vec3_t& a, vec3_t& b, vec3_t& c ) const
+{
+	a.x = ME(0,0);
+	a.y = ME(1,0);
+	a.z = ME(2,0);
+	b.x = ME(0,1);
+	b.y = ME(1,1);
+	b.z = ME(2,1);
+	c.x = ME(0,2);
+	c.y = ME(1,2);
+	c.z = ME(2,2);
+}
+
+// SetRow
+M_INLINE void mat3_t::SetRow( const uint i, const vec3_t& v )
+{
+	ME(i,0)=v.x;
+	ME(i,1)=v.y;
+	ME(i,2)=v.z;
+}
+
+// GetRow
+M_INLINE vec3_t mat3_t::GetRow( const uint i ) const
+{
+	return vec3_t( ME(i,0), ME(i,1), ME(i,2) );
+}
+
+// SetColumn
+M_INLINE void mat3_t::SetColumn( const uint i, const vec3_t& v )
+{
+	ME(0,i)=v.x;
+	ME(1,i)=v.y;
+	ME(2,i)=v.z;
+}
+
+// GetColumn
+M_INLINE vec3_t mat3_t::GetColumn( const uint i ) const
+{
+	return vec3_t( ME(0,i), ME(1,i), ME(2,i) );
+}
+
+// SetRotationX
+M_INLINE void mat3_t::SetRotationX( float rad )
+{
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	ME(0,0) = 1.0f;
+	ME(0,1) = 0.0f;
+	ME(0,2) = 0.0f;
+	ME(1,0) = 0.0f;
+	ME(1,1) = costheta;
+	ME(1,2) = -sintheta;
+	ME(2,0) = 0.0f;
+	ME(2,1) = sintheta;
+	ME(2,2) = costheta;
+}
+
+// SetRotationY
+M_INLINE void mat3_t::SetRotationY( float rad )
+{
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	ME(0,0) = costheta;
+	ME(0,1) = 0.0f;
+	ME(0,2) = sintheta;
+	ME(1,0) = 0.0f;
+	ME(1,1) = 1.0f;
+	ME(1,2) = 0.0f;
+	ME(2,0) = -sintheta;
+	ME(2,1) = 0.0f;
+	ME(2,2) = costheta;
+}
+
+// LoadRotationZ
+M_INLINE void mat3_t::SetRotationZ( float rad )
+{
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	ME(0,0) = costheta;
+	ME(0,1) = -sintheta;
+	ME(0,2) = 0.0f;
+	ME(1,0) = sintheta;
+	ME(1,1) = costheta;
+	ME(1,2) = 0.0f;
+	ME(2,0) = 0.0f;
+	ME(2,1) = 0.0f;
+	ME(2,2) = 1.0f;
+}
+
+// RotateXAxis
+/* the slow code is in comments and above the comments the optimized one
+If we analize the mat3 we can extract the 3 unit vectors rotated by the mat3. The 3 rotated vectors are in mat's colomns.
+This means that: mat3.colomn[0] == i*mat3. RotateXAxis() rotates rad angle not from i vector (aka x axis) but
+from the vector from colomn 0*/
+M_INLINE void mat3_t::RotateXAxis( float rad )
+{
+	float sina, cosa;
+	SinCos( rad, sina, cosa );
+
+	/*vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );*/
+
+	// z_axis = z_axis*cosa - y_axis*sina;
+	ME(0,2) = ME(0,2)*cosa - ME(0,1)*sina;
+	ME(1,2) = ME(1,2)*cosa - ME(1,1)*sina;
+	ME(2,2) = ME(2,2)*cosa - ME(2,1)*sina;
+
+	// z_axis.Normalize();
+	float len = InvSqrt( ME(0,2)*ME(0,2) + ME(1,2)*ME(1,2) + ME(2,2)*ME(2,2) );
+	ME(0,2) *= len;
+	ME(1,2) *= len;
+	ME(2,2) *= len;
+
+	// y_axis = z_axis * x_axis;
+	ME(0,1) = ME(1,2)*ME(2,0) - ME(2,2)*ME(1,0);
+	ME(1,1) = ME(2,2)*ME(0,0) - ME(0,2)*ME(2,0);
+	ME(2,1) = ME(0,2)*ME(1,0) - ME(1,2)*ME(0,0);
+
+	// y_axis.Normalize();
+	/*len = InvSqrt( ME(0,1)*ME(0,1) + ME(1,1)*ME(1,1) + ME(2,1)*ME(2,1) );
+	ME(0,1) *= len;
+	ME(1,1) *= len;
+	ME(2,1) *= len;*/
+
+	// SetColumns( x_axis, y_axis, z_axis );
+
+}
+
+// RotateYAxis
+M_INLINE void mat3_t::RotateYAxis( float rad )
+{
+	float sina, cosa;
+	SinCos( rad, sina, cosa );
+
+	/*vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );*/
+
+	// z_axis = z_axis*cosa + x_axis*sina;
+	ME(0,2) = ME(0,2)*cosa + ME(0,0)*sina;
+	ME(1,2) = ME(1,2)*cosa + ME(1,0)*sina;
+	ME(2,2) = ME(2,2)*cosa + ME(2,0)*sina;
+
+	// z_axis.Normalize();
+	float len = InvSqrt( ME(0,2)*ME(0,2) + ME(1,2)*ME(1,2) + ME(2,2)*ME(2,2) );
+	ME(0,2) *= len;
+	ME(1,2) *= len;
+	ME(2,2) *= len;
+
+	// x_axis = (z_axis*y_axis) * -1.0f;
+	ME(0,0) = ME(2,2)*ME(1,1) - ME(1,2)*ME(2,1);
+	ME(1,0) = ME(0,2)*ME(2,1) - ME(2,2)*ME(0,1);
+	ME(2,0) = ME(1,2)*ME(0,1) - ME(0,2)*ME(1,1);
+
+	// x_axis.Normalize();
+	/*len = InvSqrt( ME(0,0)*ME(0,0) + ME(1,0)*ME(1,0) + ME(2,0)*ME(2,0) );
+	ME(0,0) *= len;
+	ME(1,0) *= len;
+	ME(2,0) *= len;*/
+
+	// SetColumns( x_axis, y_axis, z_axis );
+}
+
+
+// RotateZAxis
+M_INLINE void mat3_t::RotateZAxis( float rad )
+{
+	float sina, cosa;
+	SinCos( rad, sina, cosa );
+
+	/*vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );*/
+
+	// x_axis = x_axis*cosa + y_axis*sina;
+	ME(0,0) = ME(0,0)*cosa + ME(0,1)*sina;
+	ME(1,0) = ME(1,0)*cosa + ME(1,1)*sina;
+	ME(2,0) = ME(2,0)*cosa + ME(2,1)*sina;
+
+	// x_axis.Normalize();
+	float len = InvSqrt( ME(0,0)*ME(0,0) + ME(1,0)*ME(1,0) + ME(2,0)*ME(2,0) );
+	ME(0,0) *= len;
+	ME(1,0) *= len;
+	ME(2,0) *= len;
+
+	// y_axis = z_axis*x_axis;
+	ME(0,1) = ME(1,2)*ME(2,0) - ME(2,2)*ME(1,0);
+	ME(1,1) = ME(2,2)*ME(0,0) - ME(0,2)*ME(2,0);
+	ME(2,1) = ME(0,2)*ME(1,0) - ME(1,2)*ME(0,0);
+
+	// y_axis.Normalize();
+	/*len = InvSqrt( ME(0,1)*ME(0,1) + ME(1,1)*ME(1,1) + ME(2,1)*ME(2,1) );
+	ME(0,1) *= len;
+	ME(1,1) *= len;
+	ME(2,1) *= len;*/
+
+	//SetColumns( x_axis, y_axis, z_axis );
+}
+
+// Transpose
+M_INLINE void mat3_t::Transpose()
+{
+	float temp = ME(0,1);
+	ME(0,1) = ME(1,0);
+	ME(1,0) = temp;
+	temp = ME(0,2);
+	ME(0,2) = ME(2,0);
+	ME(2,0) = temp;
+	temp = ME(1,2);
+	ME(1,2) = ME(2,1);
+	ME(2,1) = temp;
+}
+
+// Transposed
+M_INLINE mat3_t mat3_t::Transposed() const
+{
+	mat3_t m3;
+	m3[0] = ME[0];
+	m3[1] = ME[3];
+	m3[2] = ME[6];
+	m3[3] = ME[1];
+	m3[4] = ME[4];
+	m3[5] = ME[7];
+	m3[6] = ME[2];
+	m3[7] = ME[5];
+	m3[8] = ME[8];
+	return m3;
+}
+
+// Reorthogonalize
+M_INLINE void mat3_t::Reorthogonalize()
+{
+	// method 1: standard orthogonalization method
+	/*mat3_t correction_m3 =
+	(
+		(mat3_t::ident * 3.0f) -
+		(ME * ME.Transposed())
+	) * 0.5f;
+
+	ME = correction_m3 * ME;*/
+
+	// method 2: Gram-Schmidt method with a twist for z_axis
+	vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );
+
+	x_axis.Normalize();
+
+	y_axis = y_axis - ( x_axis * x_axis.Dot(y_axis) );
+	y_axis.Normalize();
+
+	z_axis = x_axis.Cross(y_axis);
+
+	SetColumns( x_axis, y_axis, z_axis );
+}
+
+// Print
+M_INLINE void mat3_t::Print() const
+{
+	for( int i=0; i<3; i++ )
+	{
+		for( int j=0; j<3; j++ )
+			cout << fixed << ME(i, j) << " ";
+		cout << endl;
+	}
+	cout << endl;
+}
+
+// Determinant
+M_INLINE float mat3_t::Det() const
+{
+	/* accurate method:
+	return ME(0, 0)*ME(1, 1)*ME(2, 2) + ME(0, 1)*ME(1, 2)*ME(2, 0) + ME(0, 2)*ME(1, 0)*ME(2, 1)
+	- ME(0, 0)*ME(1, 2)*ME(2, 1) - ME(0, 1)*ME(1, 0)*ME(2, 2) - ME(0, 2)*ME(1, 1)*ME(2, 0);*/
+	return ME(0, 0)*( ME(1, 1)*ME(2, 2) - ME(1, 2)*ME(2, 1) ) -
+	ME(0, 1)*( ME(1, 0)*ME(2, 2) - ME(1, 2)*ME(2, 0) ) +
+	ME(0, 2)*( ME(0, 1)*ME(2, 1) - ME(1, 1)*ME(2, 0) );
+}
+
+// Invert
+// using Gramer's method ( Inv(A) = ( 1/Det(A) ) * Adj(A)  )
+M_INLINE mat3_t mat3_t::Inverted() const
+{
+	mat3_t result;
+
+	// compute determinant
+	float cofactor0 = ME(1,1)*ME(2,2) - ME(1,2)*ME(2,1);
+	float cofactor3 = ME(0,2)*ME(2,1) - ME(0,1)*ME(2,2);
+	float cofactor6 = ME(0,1)*ME(1,2) - ME(0,2)*ME(1,1);
+	float det = ME(0,0)*cofactor0 + ME(1,0)*cofactor3 + ME(2,0)*cofactor6;
+
+	DEBUG_ERR( IsZero( det ) ); // Cannot invert det == 0
+
+	// create adjoint matrix and multiply by 1/det to get inverse
+	float invDet = 1.0f/det;
+	result(0,0) = invDet*cofactor0;
+	result(0,1) = invDet*cofactor3;
+	result(0,2) = invDet*cofactor6;
+
+	result(1,0) = invDet*(ME(1,2)*ME(2,0) - ME(1,0)*ME(2,2));
+	result(1,1) = invDet*(ME(0,0)*ME(2,2) - ME(0,2)*ME(2,0));
+	result(1,2) = invDet*(ME(0,2)*ME(1,0) - ME(0,0)*ME(1,2));
+
+	result(2,0) = invDet*(ME(1,0)*ME(2,1) - ME(1,1)*ME(2,0));
+	result(2,1) = invDet*(ME(0,1)*ME(2,0) - ME(0,0)*ME(2,1));
+	result(2,2) = invDet*(ME(0,0)*ME(1,1) - ME(0,1)*ME(1,0));
+
+	return result;
+}
+
+// Invert
+// see above
+M_INLINE void mat3_t::Invert()
+{
+	ME = Inverted();
+}
+
+// GetZero
+M_INLINE const mat3_t& mat3_t::GetZero()
+{
+	static mat3_t zero( 0.0 );
+	return zero;
+}
+
+// GetIdentity
+M_INLINE const mat3_t& mat3_t::GetIdentity()
+{
+	static mat3_t ident( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 );
+	return ident;
+}
+
+} // end namespace

+ 90 - 0
src/math/mat4.h

@@ -0,0 +1,90 @@
+#ifndef _MAT4_H_
+#define _MAT4_H_
+
+#include "common.h"
+#include "forward_decls.h"
+
+
+namespace m {
+
+
+class mat4_t
+{
+	private:
+		union
+		{
+			float arr1[16];
+			float arr2[4][4];
+		};
+
+	public:
+		// access to the data
+		float& operator ()( const uint i, const uint j );
+		const float& operator ()( const uint i, const uint j ) const;
+		float& operator []( const uint i);
+		const float& operator []( const uint i) const;
+		// constructors & distructors
+		explicit mat4_t() {}
+		explicit mat4_t( float f );
+		explicit mat4_t( float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33 );
+		explicit mat4_t( const float arr [] );
+		         mat4_t( const mat4_t& b );
+		explicit mat4_t( const mat3_t& m3 );
+		explicit mat4_t( const vec3_t& v );
+		explicit mat4_t( const vec4_t& v );
+		explicit mat4_t( const vec3_t& transl, const mat3_t& rot );
+		explicit mat4_t( const vec3_t& transl, const mat3_t& rot, float scale );
+		// ops with same type
+		mat4_t  operator + ( const mat4_t& b ) const;
+		mat4_t& operator +=( const mat4_t& b );
+		mat4_t  operator - ( const mat4_t& b ) const;
+		mat4_t& operator -=( const mat4_t& b );
+		mat4_t  operator * ( const mat4_t& b ) const;
+		mat4_t& operator *=( const mat4_t& b );
+		mat4_t  operator / ( const mat4_t& b ) const;
+		mat4_t& operator /=( const mat4_t& b );
+		// ops with float
+		mat4_t  operator + ( float f ) const;
+		mat4_t& operator +=( float f );
+		mat4_t  operator - ( float f ) const;
+		mat4_t& operator -=( float f );
+		mat4_t  operator * ( float f ) const;
+		mat4_t& operator *=( float f );
+		mat4_t  operator / ( float f ) const;
+		mat4_t& operator /=( float f );
+		// ops with other types
+		vec4_t  operator * ( const vec4_t& v4 ) const; // 16 muls, 12 adds
+		// comparision
+		bool operator ==( const mat4_t& b ) const;
+		bool operator !=( const mat4_t& b ) const;
+		// other
+		void   SetRows( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d );
+		void   SetRow( uint i, const vec4_t& v );
+		void   SetColumns( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d );
+		void   SetColumn( uint i, const vec4_t& v );
+		void   SetRotationPart( const mat3_t& m3 );
+		void   SetTranslationPart( const vec4_t& v4 );
+		mat3_t GetRotationPart() const;
+		void   SetTranslationPart( const vec3_t& v3 );
+		vec3_t GetTranslationPart() const;
+		void   Transpose();
+		mat4_t Transposed() const;
+		void   Print() const;
+		float  Det() const;
+		void   Invert();
+		mat4_t Inverted() const;
+		mat4_t Lerp( const mat4_t& b, float t ) const;
+		static mat4_t CombineTransformations( const mat4_t& m0, const mat4_t& m1 );  // 12 muls, 27 adds. Something like m4 = m0 * m1 ...
+		                                                                             // ...but without touching the 4rth row and allot faster
+		static const mat4_t& GetIdentity();
+		static const mat4_t& GetZero();
+};
+
+
+} // end namespace
+
+
+#include "mat4.inl.h"
+
+
+#endif

+ 649 - 0
src/math/mat4.inl.h

@@ -0,0 +1,649 @@
+#include "m_dflt_header.h"
+
+
+#define ME (*this)
+
+
+namespace m {
+
+// accessors
+M_INLINE float& mat4_t::operator ()( const uint i, const uint j )
+{
+	return arr2[i][j];
+}
+
+M_INLINE const float& mat4_t::operator ()( const uint i, const uint j ) const
+{
+	return arr2[i][j];
+}
+
+M_INLINE float& mat4_t::operator []( const uint i) 
+{ 
+	return arr1[i]; 
+}
+
+M_INLINE const float& mat4_t::operator []( const uint i) const 
+{ 
+	return arr1[i]; 
+}
+
+// constructor [mat4]
+M_INLINE mat4_t::mat4_t( const mat4_t& b )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] = b[i];
+}
+
+// constructor [float[]]
+M_INLINE mat4_t::mat4_t( const float arr_ [] )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] = arr_[i];
+}
+
+// constructor [float..........]
+M_INLINE mat4_t::mat4_t( float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33 )
+{
+	ME(0,0) = m00;
+	ME(0,1) = m01;
+	ME(0,2) = m02;
+	ME(0,3) = m03;
+	ME(1,0) = m10;
+	ME(1,1) = m11;
+	ME(1,2) = m12;
+	ME(1,3) = m13;
+	ME(2,0) = m20;
+	ME(2,1) = m21;
+	ME(2,2) = m22;
+	ME(2,3) = m23;
+	ME(3,0) = m30;
+	ME(3,1) = m31;
+	ME(3,2) = m32;
+	ME(3,3) = m33;
+}
+
+// constructor [mat3]
+M_INLINE mat4_t::mat4_t( const mat3_t& m3 )
+{
+	ME(0,0) = m3(0,0);
+	ME(0,1) = m3(0,1);
+	ME(0,2) = m3(0,2);
+	ME(1,0) = m3(1,0);
+	ME(1,1) = m3(1,1);
+	ME(1,2) = m3(1,2);
+	ME(2,0) = m3(2,0);
+	ME(2,1) = m3(2,1);
+	ME(2,2) = m3(2,2);
+	ME(3, 0) = ME(3, 1) = ME(3, 2) = ME(0, 3) = ME(1, 3) = ME(2, 3) = 0.0;
+	ME(3, 3) = 1.0;
+}
+
+// constructor [vec3]
+M_INLINE mat4_t::mat4_t( const vec3_t& v )
+{
+	ME(0, 0) = 1.0;
+	ME(0, 1) = 0.0;
+	ME(0, 2) = 0.0;
+	ME(0, 3) = v.x;
+	ME(1, 0) = 0.0;
+	ME(1, 1) = 1.0;
+	ME(1, 2) = 0.0;
+	ME(1, 3) = v.y;
+	ME(2, 0) = 0.0;
+	ME(2, 1) = 0.0;
+	ME(2, 2) = 1.0;
+	ME(2, 3) = v.z;
+	ME(3, 0) = 0.0;
+	ME(3, 1) = 0.0;
+	ME(3, 2) = 0.0;
+	ME(3, 3) = 1.0;
+}
+
+// constructor [vec4]
+M_INLINE mat4_t::mat4_t( const vec4_t& v )
+{
+	ME(0, 0) = 1.0;
+	ME(0, 1) = 0.0;
+	ME(0, 2) = 0.0;
+	ME(0, 3) = v.x;
+	ME(1, 0) = 0.0;
+	ME(1, 1) = 1.0;
+	ME(1, 2) = 0.0;
+	ME(1, 3) = v.y;
+	ME(2, 0) = 0.0;
+	ME(2, 1) = 0.0;
+	ME(2, 2) = 1.0;
+	ME(2, 3) = v.z;
+	ME(3, 0) = 0.0;
+	ME(3, 1) = 0.0;
+	ME(3, 2) = 0.0;
+	ME(3, 3) = v.w;
+}
+
+// constructor [vec3, mat3]
+M_INLINE mat4_t::mat4_t( const vec3_t& transl, const mat3_t& rot )
+{
+	SetRotationPart(rot);
+	SetTranslationPart(transl);
+	ME(3,0) = ME(3,1) = ME(3,2) = 0.0;
+	ME(3,3) = 1.0;
+}
+
+// constructor [vec3, mat3, float]
+M_INLINE mat4_t::mat4_t( const vec3_t& translate, const mat3_t& rotate, float scale )
+{
+	if( !IsZero( scale-1.0 ) )
+		SetRotationPart( rotate*scale );
+	else
+		SetRotationPart( rotate );
+
+	SetTranslationPart( translate );
+
+	ME(3,0) = ME(3,1) = ME(3,2) = 0.0;
+	ME(3,3) = 1.0;
+}
+
+// constructor [float]
+M_INLINE mat4_t::mat4_t( float f )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] = f;
+}
+
+// 4x4 + 4x4
+M_INLINE mat4_t mat4_t::operator +( const mat4_t& b ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] + b[i];
+	return c;
+}
+
+// 4x4 + 4x4 (self)
+M_INLINE mat4_t& mat4_t::operator +=( const mat4_t& b )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] += b[i];
+	return ME;
+}
+
+// 4x4 - 4x4
+M_INLINE mat4_t mat4_t::operator -( const mat4_t& b ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] - b[i];
+	return c;
+}
+
+// 4x4 - 4x4 (self)
+M_INLINE mat4_t& mat4_t::operator -=( const mat4_t& b )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] -= b[i];
+	return ME;
+}
+
+// 4x4 * 4x4
+M_INLINE mat4_t mat4_t::operator *( const mat4_t& b ) const
+{
+	mat4_t c;
+	c(0,0) = ME(0,0)*b(0,0) + ME(0,1)*b(1,0) + ME(0,2)*b(2,0) + ME(0,3)*b(3,0);
+	c(0,1) = ME(0,0)*b(0,1) + ME(0,1)*b(1,1) + ME(0,2)*b(2,1) + ME(0,3)*b(3,1);
+	c(0,2) = ME(0,0)*b(0,2) + ME(0,1)*b(1,2) + ME(0,2)*b(2,2) + ME(0,3)*b(3,2);
+	c(0,3) = ME(0,0)*b(0,3) + ME(0,1)*b(1,3) + ME(0,2)*b(2,3) + ME(0,3)*b(3,3);
+	c(1,0) = ME(1,0)*b(0,0) + ME(1,1)*b(1,0) + ME(1,2)*b(2,0) + ME(1,3)*b(3,0);
+	c(1,1) = ME(1,0)*b(0,1) + ME(1,1)*b(1,1) + ME(1,2)*b(2,1) + ME(1,3)*b(3,1);
+	c(1,2) = ME(1,0)*b(0,2) + ME(1,1)*b(1,2) + ME(1,2)*b(2,2) + ME(1,3)*b(3,2);
+	c(1,3) = ME(1,0)*b(0,3) + ME(1,1)*b(1,3) + ME(1,2)*b(2,3) + ME(1,3)*b(3,3);
+	c(2,0) = ME(2,0)*b(0,0) + ME(2,1)*b(1,0) + ME(2,2)*b(2,0) + ME(2,3)*b(3,0);
+	c(2,1) = ME(2,0)*b(0,1) + ME(2,1)*b(1,1) + ME(2,2)*b(2,1) + ME(2,3)*b(3,1);
+	c(2,2) = ME(2,0)*b(0,2) + ME(2,1)*b(1,2) + ME(2,2)*b(2,2) + ME(2,3)*b(3,2);
+	c(2,3) = ME(2,0)*b(0,3) + ME(2,1)*b(1,3) + ME(2,2)*b(2,3) + ME(2,3)*b(3,3);
+	c(3,0) = ME(3,0)*b(0,0) + ME(3,1)*b(1,0) + ME(3,2)*b(2,0) + ME(3,3)*b(3,0);
+	c(3,1) = ME(3,0)*b(0,1) + ME(3,1)*b(1,1) + ME(3,2)*b(2,1) + ME(3,3)*b(3,1);
+	c(3,2) = ME(3,0)*b(0,2) + ME(3,1)*b(1,2) + ME(3,2)*b(2,2) + ME(3,3)*b(3,2);
+	c(3,3) = ME(3,0)*b(0,3) + ME(3,1)*b(1,3) + ME(3,2)*b(2,3) + ME(3,3)*b(3,3);
+	return c;
+}
+
+// 4x4 * 4x4 (self)
+M_INLINE mat4_t& mat4_t::operator *=( const mat4_t& b )
+{
+	ME = ME * b;
+	return ME;
+}
+
+// ==
+M_INLINE bool mat4_t::operator ==( const mat4_t& b ) const
+{
+	for( int i=0; i<16; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return false;
+	return true;
+}
+
+// !=
+M_INLINE bool mat4_t::operator !=( const mat4_t& b ) const
+{
+	for( int i=0; i<16; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return true;
+	return false;
+}
+
+// 4x4 * vec4
+M_INLINE vec4_t mat4_t::operator *( const vec4_t& b ) const
+{
+	return vec4_t(
+		ME(0,0)*b.x + ME(0,1)*b.y + ME(0,2)*b.z + ME(0,3)*b.w,
+		ME(1,0)*b.x + ME(1,1)*b.y + ME(1,2)*b.z + ME(1,3)*b.w,
+		ME(2,0)*b.x + ME(2,1)*b.y + ME(2,2)*b.z + ME(2,3)*b.w,
+		ME(3,0)*b.x + ME(3,1)*b.y + ME(3,2)*b.z + ME(3,3)*b.w
+	);
+}
+
+// 4x4 + float
+M_INLINE mat4_t mat4_t::operator +( float f ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] + f;
+	return c;
+}
+
+// 4x4 + float (self)
+M_INLINE mat4_t& mat4_t::operator +=( float f )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] += f;
+	return ME;
+}
+
+// 4x4 - float
+M_INLINE mat4_t mat4_t::operator -( float f ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] - f;
+	return c;
+}
+
+// 4x4 - float (self)
+M_INLINE mat4_t& mat4_t::operator -=( float f )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] -= f;
+	return ME;
+}
+
+// 4x4 * scalar
+M_INLINE mat4_t mat4_t::operator *( float f ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] * f;
+	return c;
+}
+
+// 4x4 * scalar (self)
+M_INLINE mat4_t& mat4_t::operator *=( float f )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] *= f;
+	return ME;
+}
+
+// 4x4 / scalar
+M_INLINE mat4_t mat4_t::operator /( float f ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] / f;
+	return c;
+}
+
+// 4x4 / scalar (self)
+M_INLINE mat4_t& mat4_t::operator /=( float f )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] /= f;
+	return ME;
+}
+
+// SetRows
+M_INLINE void mat4_t::SetRows( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d )
+{
+	ME(0,0) = a.x;
+	ME(0,1) = a.y;
+	ME(0,2) = a.z;
+	ME(0,3) = a.w;
+	ME(1,0) = b.x;
+	ME(1,1) = b.y;
+	ME(1,2) = b.z;
+	ME(1,3) = b.w;
+	ME(2,0) = c.x;
+	ME(2,1) = c.y;
+	ME(2,2) = c.z;
+	ME(2,3) = c.w;
+	ME(3,0) = d.x;
+	ME(3,1) = d.y;
+	ME(3,2) = d.z;
+	ME(3,3) = d.w;
+}
+
+// SetRow
+M_INLINE void mat4_t::SetRow( uint i, const vec4_t& v )
+{
+	DEBUG_ERR( i > 3 );
+	ME(i,0) = v.x;
+	ME(i,1) = v.y;
+	ME(i,2) = v.z;
+	ME(i,3) = v.w;
+}
+
+// SetColumns
+M_INLINE void mat4_t::SetColumns( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d )
+{
+	ME(0,0) = a.x;
+	ME(1,0) = a.y;
+	ME(2,0) = a.z;
+	ME(3,0) = a.w;
+	ME(0,1) = b.x;
+	ME(1,1) = b.y;
+	ME(2,1) = b.z;
+	ME(3,1) = b.w;
+	ME(0,2) = c.x;
+	ME(1,2) = c.y;
+	ME(2,2) = c.z;
+	ME(3,2) = c.w;
+	ME(0,3) = d.x;
+	ME(1,3) = d.y;
+	ME(2,3) = d.z;
+	ME(3,3) = d.w;
+}
+
+// SetColumn
+M_INLINE void mat4_t::SetColumn( uint i, const vec4_t& v )
+{
+	DEBUG_ERR( i > 3 );
+	ME(0,i) = v.x;
+	ME(1,i) = v.y;
+	ME(2,i) = v.z;
+	ME(3,i) = v.w;
+}
+
+// Transpose
+M_INLINE void mat4_t::Transpose()
+{
+	float tmp = ME(0,1);
+	ME(0,1) = ME(1,0);
+	ME(1,0) = tmp;
+	tmp = ME(0,2);
+	ME(0,2) = ME(2,0);
+	ME(2,0) = tmp;
+	tmp = ME(0,3);
+	ME(0,3) = ME(3,0);
+	ME(3,0) = tmp;
+	tmp = ME(1,2);
+	ME(1,2) = ME(2,1);
+	ME(2,1) = tmp;
+	tmp = ME(1,3);
+	ME(1,3) = ME(3,1);
+	ME(3,1) = tmp;
+	tmp = ME(2,3);
+	ME(2,3) = ME(3,2);
+	ME(3,2) = tmp;
+}
+
+// Transposed
+// return the transposed
+M_INLINE mat4_t mat4_t::Transposed() const
+{
+	mat4_t m4;
+	m4[0] = ME[0];
+	m4[1] = ME[4];
+	m4[2] = ME[8];
+	m4[3] = ME[12];
+	m4[4] = ME[1];
+	m4[5] = ME[5];
+	m4[6] = ME[9];
+	m4[7] = ME[13];
+	m4[8] = ME[2];
+	m4[9] = ME[6];
+	m4[10] = ME[10];
+	m4[11] = ME[14];
+	m4[12] = ME[3];
+	m4[13] = ME[7];
+	m4[14] = ME[11];
+	m4[15] = ME[15];
+	return m4;
+}
+
+// SetRotationPart
+M_INLINE void mat4_t::SetRotationPart( const mat3_t& m3 )
+{
+	ME(0,0) = m3(0,0);
+	ME(0,1) = m3(0,1);
+	ME(0,2) = m3(0,2);
+	ME(1,0) = m3(1,0);
+	ME(1,1) = m3(1,1);
+	ME(1,2) = m3(1,2);
+	ME(2,0) = m3(2,0);
+	ME(2,1) = m3(2,1);
+	ME(2,2) = m3(2,2);
+}
+
+// GetRotationPart
+M_INLINE mat3_t mat4_t::GetRotationPart() const
+{
+	mat3_t m3;
+	m3(0,0) = ME(0,0);
+	m3(0,1) = ME(0,1);
+	m3(0,2) = ME(0,2);
+	m3(1,0) = ME(1,0);
+	m3(1,1) = ME(1,1);
+	m3(1,2) = ME(1,2);
+	m3(2,0) = ME(2,0);
+	m3(2,1) = ME(2,1);
+	m3(2,2) = ME(2,2);
+	return m3;
+}
+
+// SetTranslationPart
+M_INLINE void mat4_t::SetTranslationPart( const vec4_t& v )
+{
+	ME(0, 3) = v.x;
+	ME(1, 3) = v.y;
+	ME(2, 3) = v.z;
+	ME(3, 3) = v.w;
+}
+
+// SetTranslationPart
+M_INLINE void mat4_t::SetTranslationPart( const vec3_t& v )
+{
+	ME(0, 3) = v.x;
+	ME(1, 3) = v.y;
+	ME(2, 3) = v.z;
+}
+
+// GetTranslationPart
+M_INLINE vec3_t mat4_t::GetTranslationPart() const
+{
+	return vec3_t( ME(0, 3), ME(1, 3), ME(2, 3) );
+}
+
+// GetIdentity
+M_INLINE const mat4_t& mat4_t::GetIdentity()
+{
+	static mat4_t ident( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 );
+	return ident;
+}
+
+// GetZero
+M_INLINE const mat4_t& mat4_t::GetZero()
+{
+	static mat4_t zero( 0.0 );
+	return zero;
+}
+
+// Print
+M_INLINE void mat4_t::Print() const
+{
+	cout << fixed;
+	for( int i=0; i<4; i++ )
+	{
+		for( int j=0; j<4; j++ )
+		{
+			if( ME(i, j) < 0.0 )
+				cout << ME(i, j) << " ";
+			else
+				cout << " " << ME(i, j) << " ";
+		}
+		cout << endl;
+	}
+	cout << endl;
+}
+
+// Determinant
+M_INLINE float mat4_t::Det() const
+{
+	return
+	ME(0, 3)*ME(1, 2)*ME(2, 1)*ME(3, 0) - ME(0, 2)*ME(1, 3)*ME(2, 1)*ME(3, 0) -
+	ME(0, 3)*ME(1, 1)*ME(2, 2)*ME(3, 0) + ME(0, 1)*ME(1, 3)*ME(2, 2)*ME(3, 0) +
+	ME(0, 2)*ME(1, 1)*ME(2, 3)*ME(3, 0) - ME(0, 1)*ME(1, 2)*ME(2, 3)*ME(3, 0) -
+	ME(0, 3)*ME(1, 2)*ME(2, 0)*ME(3, 1) + ME(0, 2)*ME(1, 3)*ME(2, 0)*ME(3, 1) +
+	ME(0, 3)*ME(1, 0)*ME(2, 2)*ME(3, 1) - ME(0, 0)*ME(1, 3)*ME(2, 2)*ME(3, 1) -
+	ME(0, 2)*ME(1, 0)*ME(2, 3)*ME(3, 1) + ME(0, 0)*ME(1, 2)*ME(2, 3)*ME(3, 1) +
+	ME(0, 3)*ME(1, 1)*ME(2, 0)*ME(3, 2) - ME(0, 1)*ME(1, 3)*ME(2, 0)*ME(3, 2) -
+	ME(0, 3)*ME(1, 0)*ME(2, 1)*ME(3, 2) + ME(0, 0)*ME(1, 3)*ME(2, 1)*ME(3, 2) +
+	ME(0, 1)*ME(1, 0)*ME(2, 3)*ME(3, 2) - ME(0, 0)*ME(1, 1)*ME(2, 3)*ME(3, 2) -
+	ME(0, 2)*ME(1, 1)*ME(2, 0)*ME(3, 3) + ME(0, 1)*ME(1, 2)*ME(2, 0)*ME(3, 3) +
+	ME(0, 2)*ME(1, 0)*ME(2, 1)*ME(3, 3) - ME(0, 0)*ME(1, 2)*ME(2, 1)*ME(3, 3) -
+	ME(0, 1)*ME(1, 0)*ME(2, 2)*ME(3, 3) + ME(0, 0)*ME(1, 1)*ME(2, 2)*ME(3, 3);
+}
+
+// Invert
+M_INLINE void mat4_t::Invert()
+{
+	ME = Inverted();
+}
+
+// Inverted
+M_INLINE mat4_t mat4_t::Inverted() const
+{
+	float tmp[12];
+	float det;
+	const mat4_t& in = ME;
+
+	mat4_t m4;
+
+
+	tmp[0] = in(2,2) * in(3,3);
+	tmp[1] = in(3,2) * in(2,3);
+	tmp[2] = in(1,2) * in(3,3);
+	tmp[3] = in(3,2) * in(1,3);
+	tmp[4] = in(1,2) * in(2,3);
+	tmp[5] = in(2,2) * in(1,3);
+	tmp[6] = in(0,2) * in(3,3);
+	tmp[7] = in(3,2) * in(0,3);
+	tmp[8] = in(0,2) * in(2,3);
+	tmp[9] = in(2,2) * in(0,3);
+	tmp[10] = in(0,2) * in(1,3);
+	tmp[11] = in(1,2) * in(0,3);
+
+	m4(0,0) =  tmp[0]*in(1,1) + tmp[3]*in(2,1) + tmp[4]*in(3,1);
+	m4(0,0) -= tmp[1]*in(1,1) + tmp[2]*in(2,1) + tmp[5]*in(3,1);
+	m4(0,1) =  tmp[1]*in(0,1) + tmp[6]*in(2,1) + tmp[9]*in(3,1);
+	m4(0,1) -= tmp[0]*in(0,1) + tmp[7]*in(2,1) + tmp[8]*in(3,1);
+	m4(0,2) =  tmp[2]*in(0,1) + tmp[7]*in(1,1) + tmp[10]*in(3,1);
+	m4(0,2) -= tmp[3]*in(0,1) + tmp[6]*in(1,1) + tmp[11]*in(3,1);
+	m4(0,3) =  tmp[5]*in(0,1) + tmp[8]*in(1,1) + tmp[11]*in(2,1);
+	m4(0,3) -= tmp[4]*in(0,1) + tmp[9]*in(1,1) + tmp[10]*in(2,1);
+	m4(1,0) =  tmp[1]*in(1,0) + tmp[2]*in(2,0) + tmp[5]*in(3,0);
+	m4(1,0) -= tmp[0]*in(1,0) + tmp[3]*in(2,0) + tmp[4]*in(3,0);
+	m4(1,1) =  tmp[0]*in(0,0) + tmp[7]*in(2,0) + tmp[8]*in(3,0);
+	m4(1,1) -= tmp[1]*in(0,0) + tmp[6]*in(2,0) + tmp[9]*in(3,0);
+	m4(1,2) =  tmp[3]*in(0,0) + tmp[6]*in(1,0) + tmp[11]*in(3,0);
+	m4(1,2) -= tmp[2]*in(0,0) + tmp[7]*in(1,0) + tmp[10]*in(3,0);
+	m4(1,3) =  tmp[4]*in(0,0) + tmp[9]*in(1,0) + tmp[10]*in(2,0);
+	m4(1,3) -= tmp[5]*in(0,0) + tmp[8]*in(1,0) + tmp[11]*in(2,0);
+
+
+	tmp[0] = in(2,0)*in(3,1);
+	tmp[1] = in(3,0)*in(2,1);
+	tmp[2] = in(1,0)*in(3,1);
+	tmp[3] = in(3,0)*in(1,1);
+	tmp[4] = in(1,0)*in(2,1);
+	tmp[5] = in(2,0)*in(1,1);
+	tmp[6] = in(0,0)*in(3,1);
+	tmp[7] = in(3,0)*in(0,1);
+	tmp[8] = in(0,0)*in(2,1);
+	tmp[9] = in(2,0)*in(0,1);
+	tmp[10] = in(0,0)*in(1,1);
+	tmp[11] = in(1,0)*in(0,1);
+
+	m4(2,0) = tmp[0]*in(1,3) + tmp[3]*in(2,3) + tmp[4]*in(3,3);
+	m4(2,0)-= tmp[1]*in(1,3) + tmp[2]*in(2,3) + tmp[5]*in(3,3);
+	m4(2,1) = tmp[1]*in(0,3) + tmp[6]*in(2,3) + tmp[9]*in(3,3);
+	m4(2,1)-= tmp[0]*in(0,3) + tmp[7]*in(2,3) + tmp[8]*in(3,3);
+	m4(2,2) = tmp[2]*in(0,3) + tmp[7]*in(1,3) + tmp[10]*in(3,3);
+	m4(2,2)-= tmp[3]*in(0,3) + tmp[6]*in(1,3) + tmp[11]*in(3,3);
+	m4(2,3) = tmp[5]*in(0,3) + tmp[8]*in(1,3) + tmp[11]*in(2,3);
+	m4(2,3)-= tmp[4]*in(0,3) + tmp[9]*in(1,3) + tmp[10]*in(2,3);
+	m4(3,0) = tmp[2]*in(2,2) + tmp[5]*in(3,2) + tmp[1]*in(1,2);
+	m4(3,0)-= tmp[4]*in(3,2) + tmp[0]*in(1,2) + tmp[3]*in(2,2);
+	m4(3,1) = tmp[8]*in(3,2) + tmp[0]*in(0,2) + tmp[7]*in(2,2);
+	m4(3,1)-= tmp[6]*in(2,2) + tmp[9]*in(3,2) + tmp[1]*in(0,2);
+	m4(3,2) = tmp[6]*in(1,2) + tmp[11]*in(3,2) + tmp[3]*in(0,2);
+	m4(3,2)-= tmp[10]*in(3,2) + tmp[2]*in(0,2) + tmp[7]*in(1,2);
+	m4(3,3) = tmp[10]*in(2,2) + tmp[4]*in(0,2) + tmp[9]*in(1,2);
+	m4(3,3)-= tmp[8]*in(1,2) + tmp[11]*in(2,2) + tmp[5]*in(0,2);
+
+	det = ME(0,0)*m4(0,0)+ME(1,0)*m4(0,1)+ME(2,0)*m4(0,2)+ME(3,0)*m4(0,3);
+
+	DEBUG_ERR( IsZero( det ) ); // Cannot invert, det == 0
+	det = 1/det;
+	m4 *= det;
+	return m4;
+}
+
+// Lerp
+M_INLINE mat4_t mat4_t::Lerp( const mat4_t& b, float t ) const
+{
+	return (ME*(1.0-t))+(b*t);
+}
+
+// CombineTransformations
+M_INLINE mat4_t mat4_t::CombineTransformations( const mat4_t& m0, const mat4_t& m1 )
+{
+	/* the clean code is:
+	mat3_t rot = m0.GetRotationPart() * m1.GetRotationPart();  // combine the rotations
+	vec3_t tra = (m1.GetTranslationPart()).Transformed( m0.GetTranslationPart(), m0.GetRotationPart(), 1.0 );
+	return mat4_t( tra, rot );
+	and the optimized: */
+	DEBUG_ERR( !IsZero( m0(3,0)+m0(3,1)+m0(3,2)+m0(3,3)-1.0 ) ||
+	           !IsZero( m1(3,0)+m1(3,1)+m1(3,2)+m1(3,3)-1.0 ) ); // one of the 2 mat4 doesnt represent transformation
+
+	mat4_t m4;
+
+	m4(0, 0) = m0(0, 0)*m1(0, 0) + m0(0, 1)*m1(1, 0) + m0(0, 2)*m1(2, 0);
+	m4(0, 1) = m0(0, 0)*m1(0, 1) + m0(0, 1)*m1(1, 1) + m0(0, 2)*m1(2, 1);
+	m4(0, 2) = m0(0, 0)*m1(0, 2) + m0(0, 1)*m1(1, 2) + m0(0, 2)*m1(2, 2);
+	m4(1, 0) = m0(1, 0)*m1(0, 0) + m0(1, 1)*m1(1, 0) + m0(1, 2)*m1(2, 0);
+	m4(1, 1) = m0(1, 0)*m1(0, 1) + m0(1, 1)*m1(1, 1) + m0(1, 2)*m1(2, 1);
+	m4(1, 2) = m0(1, 0)*m1(0, 2) + m0(1, 1)*m1(1, 2) + m0(1, 2)*m1(2, 2);
+	m4(2, 0) = m0(2, 0)*m1(0, 0) + m0(2, 1)*m1(1, 0) + m0(2, 2)*m1(2, 0);
+	m4(2, 1) = m0(2, 0)*m1(0, 1) + m0(2, 1)*m1(1, 1) + m0(2, 2)*m1(2, 1);
+	m4(2, 2) = m0(2, 0)*m1(0, 2) + m0(2, 1)*m1(1, 2) + m0(2, 2)*m1(2, 2);
+
+	m4(0, 3) = m0(0, 0)*m1(0, 3) + m0(0, 1)*m1(1, 3) + m0(0, 2)*m1(2, 3) + m0(0, 3);
+	m4(1, 3) = m0(1, 0)*m1(0, 3) + m0(1, 1)*m1(1, 3) + m0(1, 2)*m1(2, 3) + m0(1, 3);
+	m4(2, 3) = m0(2, 0)*m1(0, 3) + m0(2, 1)*m1(1, 3) + m0(2, 2)*m1(2, 3) + m0(2, 3);
+
+	m4(3,0) = m4(3,1) = m4(3,2) = 0.0;
+	m4(3,3) = 1.0;
+
+	return m4;
+}
+
+
+} // end namespace

+ 57 - 0
src/math/quat.h

@@ -0,0 +1,57 @@
+#ifndef _QUAT_H_
+#define _QUAT_H_
+
+#include "common.h"
+#include "forward_decls.h"
+
+
+namespace m {
+
+
+class quat_t
+{
+	public:
+		// data members
+		float x, y, z, w;
+		static quat_t zero;
+		static quat_t ident;
+		// constructors & distructors
+		explicit quat_t();
+		explicit quat_t( float f );
+		explicit quat_t( float x, float y, float z, float w );
+		explicit quat_t( const vec2_t& v2, float z, float w );
+		explicit quat_t( const vec3_t& v3, float w );
+		explicit quat_t( const vec4_t& v4 );
+		         quat_t( const quat_t& b );
+		explicit quat_t( const mat3_t& m3 );
+		explicit quat_t( const euler_t& eu );
+		explicit quat_t( const axisang_t& axisang );
+		// ops with same
+		quat_t  operator * ( const quat_t& b ) const;
+		quat_t& operator *=( const quat_t& b );
+		// comparision
+		bool operator ==( const quat_t& b ) const;
+		bool operator !=( const quat_t& b ) const;
+		// other
+		void   CalcFrom2Vec3( const vec3_t& v0, const vec3_t& v1 ); // calculates the quat from v0 to v1
+		float  Length() const;
+		void   Invert();
+		void   Conjugate();
+		quat_t Conjugated() const;
+		void   Normalize();
+		quat_t Normalized() const;
+		void   Print() const;
+		float  Dot( const quat_t& b ) const;
+		quat_t Slerp( const quat_t& q1, float t ) const; // returns Slerp( this, q1, t )
+		quat_t Rotated( const quat_t& b ) const;
+		void   Rotate( const quat_t& b );
+};
+
+
+} // end namespace
+
+
+#include "quat.inl.h"
+
+
+#endif

+ 277 - 0
src/math/quat.inl.h

@@ -0,0 +1,277 @@
+#include "m_dflt_header.h"
+
+
+#define ME (*this)
+
+namespace m {
+
+
+// constructor []
+M_INLINE quat_t::quat_t()
+	: x(0.0), y(0.0), z(0.0), w(1.0)
+{}
+
+// constructor [float]
+M_INLINE quat_t::quat_t( float f )
+	: x(f), y(f), z(f), w(f)
+{}
+
+// constructor [float, float, float, float]
+M_INLINE quat_t::quat_t( float x_, float y_, float z_, float w_ )
+	: x(x_), y(y_), z(z_), w(w_)
+{}
+
+// constructor [vec2, float, float]
+M_INLINE quat_t::quat_t( const vec2_t& v2, float z_, float w_ )
+	: x(v2.x), y(v2.y), z(z_), w(w_)
+{}
+
+// constructor [vec3, float]
+M_INLINE quat_t::quat_t( const vec3_t& v3, float w_ )
+	: x(v3.x), y(v3.y), z(v3.z), w(w_)
+{}
+
+// constructor [vec4]
+M_INLINE quat_t::quat_t( const vec4_t& v4 )
+	: x(v4.x), y(v4.y), z(v4.z), w(v4.w)
+{}
+
+// constructor [quat]
+M_INLINE quat_t::quat_t( const quat_t& b )
+	: x(b.x), y(b.y), z(b.z), w(b.w)
+{}
+
+// constructor [mat3]
+M_INLINE quat_t::quat_t( const mat3_t& m3 )
+{
+	float trace = m3(0, 0) + m3(1, 1) + m3(2, 2) + 1.0;
+	if( trace > EPSILON )
+	{
+		float s = 0.5 * InvSqrt(trace);
+		w = 0.25 / s;
+		x = ( m3(2, 1) - m3(1, 2) ) * s;
+		y = ( m3(0, 2) - m3(2, 0) ) * s;
+		z = ( m3(1, 0) - m3(0, 1) ) * s;
+	}
+	else
+	{
+		if( m3(0, 0) > m3(1, 1) && m3(0, 0) > m3(2, 2) )
+		{
+			float s = 0.5 * InvSqrt( 1.0 + m3(0, 0) - m3(1, 1) - m3(2, 2) );
+			w = (m3(1, 2) - m3(2, 1) ) * s;
+			x = 0.25 / s;
+			y = (m3(0, 1) + m3(1, 0) ) * s;
+			z = (m3(0, 2) + m3(2, 0) ) * s;
+		}
+		else if( m3(1, 1) > m3(2, 2) )
+		{
+			float s = 0.5 * InvSqrt( 1.0 + m3(1, 1) - m3(0, 0) - m3(2, 2) );
+			w = (m3(0, 2) - m3(2, 0) ) * s;
+			x = (m3(0, 1) + m3(1, 0) ) * s;
+			y = 0.25 / s;
+			z = (m3(1, 2) + m3(2, 1) ) * s;
+		}
+		else
+		{
+			float s = 0.5 * InvSqrt( 1.0 + m3(2, 2) - m3(0, 0) - m3(1, 1) );
+			w = (m3(0, 1) - m3(1, 0) ) * s;
+			x = (m3(0, 2) + m3(2, 0) ) * s;
+			y = (m3(1, 2) + m3(2, 1) ) * s;
+			z = 0.25 / s;
+		}
+	}
+}
+
+// constructor [euler]
+M_INLINE quat_t::quat_t( const euler_t& eu )
+{
+	float cx, sx;
+	SinCos( eu.heading()*0.5, sx, cx );
+
+	float cy, sy;
+	SinCos( eu.attitude()*0.5, sy, cy );
+
+	float cz, sz;
+	SinCos( eu.bank()*0.5, sz, cz );
+
+	float cxcy = cx*cy;
+	float sxsy = sx*sy;
+	x = cxcy*sz + sxsy*cz;
+	y = sx*cy*cz + cx*sy*sz;
+	z = cx*sy*cz - sx*cy*sz;
+	w = cxcy*cz - sxsy*sz;
+}
+
+// constructor [euler]
+M_INLINE quat_t::quat_t( const axisang_t& axisang )
+{
+	float lengthsq = axisang.axis.LengthSquared();
+	if( IsZero( lengthsq ) )
+	{
+		ME = ident;
+		return;
+	}
+
+	float rad = axisang.ang * 0.5;
+
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	float scalefactor = sintheta * InvSqrt(lengthsq);
+
+	x = scalefactor * axisang.axis.x;
+	y = scalefactor * axisang.axis.y;
+	z = scalefactor * axisang.axis.z;
+	w = costheta;
+}
+
+// *
+M_INLINE quat_t quat_t::operator *( const quat_t& b ) const
+{
+	return quat_t(
+		 x * b.w + y * b.z - z * b.y + w * b.x,
+		-x * b.z + y * b.w + z * b.x + w * b.y,
+		 x * b.y - y * b.x + z * b.w + w * b.z,
+		-x * b.x - y * b.y - z * b.z + w * b.w
+	);
+}
+
+// *=
+M_INLINE quat_t& quat_t::operator *=( const quat_t& b )
+{
+	ME = ME * b;
+	return ME;
+}
+
+// ==
+M_INLINE bool quat_t::operator ==( const quat_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) && IsZero(w-b.w) ) ? true : false;
+}
+
+// !=
+M_INLINE bool quat_t::operator !=( const quat_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) && IsZero(w-b.w) ) ? false : true;
+}
+
+// Conjugate
+M_INLINE void quat_t::Conjugate()
+{
+	x = -x;
+	y = -y;
+	z = -z;
+}
+
+// Conjugated
+M_INLINE quat_t quat_t::Conjugated() const
+{
+	return quat_t( -x, -y, -z, w );
+}
+
+// Normalized
+M_INLINE quat_t quat_t::Normalized() const
+{
+	return quat_t( vec4_t(ME).Normalized() );
+}
+
+// Normalize
+M_INLINE void quat_t::Normalize()
+{
+	ME = Normalized();
+}
+
+// Length
+M_INLINE float quat_t::Length() const
+{
+	return Sqrt( w*w + x*x + y*y + z*z );
+}
+
+// Invert
+M_INLINE void quat_t::Invert()
+{
+	float norm = w*w + x*x + y*y + z*z;
+
+	DEBUG_ERR( IsZero(norm) ); // Norm is zero
+
+	float normi = 1.0 / norm;
+	ME = quat_t( -normi*x, -normi*y, -normi*z, normi*w );
+}
+
+// Print
+M_INLINE void quat_t::Print() const
+{
+	cout << fixed << "(w,x,y,z) = " << w << ' ' << x << ' ' << y << ' ' << z  << '\n' << endl;
+}
+
+// CalcFromVecVec
+M_INLINE void quat_t::CalcFrom2Vec3( const vec3_t& from, const vec3_t& to )
+{
+	vec3_t axis( from.Cross(to) );
+	ME = quat_t( axis.x, axis.y, axis.z, from.Dot(to) );
+	Normalize();
+	w += 1.0;
+
+	if( w <= EPSILON )
+	{
+		if( from.z*from.z > from.x*from.x )
+			ME = quat_t( 0.0, from.z, -from.y, 0.0 );
+		else
+			ME = quat_t( from.y, -from.x, 0.0, 0.0 );
+	}
+	Normalize();
+}
+
+// Rotated
+M_INLINE quat_t quat_t::Rotated( const quat_t& b ) const
+{
+	return ME * b;
+}
+
+// Rotate
+M_INLINE void quat_t::Rotate( const quat_t& b )
+{
+	ME = Rotated( b );
+}
+
+// Dot
+M_INLINE float quat_t::Dot( const quat_t& b ) const
+{
+	return w*b.w + x*b.x + y*b.y + z*b.z;
+}
+
+// SLERP
+M_INLINE quat_t quat_t::Slerp( const quat_t& q1_, float t ) const
+{
+	const quat_t& q0 = ME;
+	quat_t q1( q1_ );
+	float cos_half_theta = q0.w*q1.w + q0.x*q1.x + q0.y*q1.y + q0.z*q1.z;
+	if( cos_half_theta < 0.0 )
+	{
+		q1 = quat_t( -vec4_t(q1) ); // quat changes
+		cos_half_theta = -cos_half_theta;
+	}
+	if( fabs(cos_half_theta) >= 1.0f )
+	{
+		return quat_t( q0 );
+	}
+
+	float half_theta = acos( cos_half_theta );
+	float sin_half_theta = Sqrt(1.0 - cos_half_theta*cos_half_theta);
+
+	if( fabs(sin_half_theta) < 0.001 )
+	{
+		return quat_t( (vec4_t(q0) + vec4_t(q1))*0.5 );
+	}
+	float ratio_a = sin((1.0 - t) * half_theta) / sin_half_theta;
+	float ratio_b = sin(t * half_theta) / sin_half_theta;
+	vec4_t tmp, tmp1, sum;
+	tmp = vec4_t(q0)*ratio_a;
+	tmp1 = vec4_t(q1)*ratio_b;
+	sum = tmp + tmp1;
+	sum.Normalize();
+	return quat_t( sum );
+}
+
+
+} // end namespace

+ 68 - 0
src/math/vec2.h

@@ -0,0 +1,68 @@
+#ifndef _VEC2_H_
+#define _VEC2_H_
+
+#include "common.h"
+#include "forward_decls.h"
+
+
+namespace m {
+
+
+class vec2_t
+{
+	public:
+		// data members
+		float x, y;
+		static const vec2_t zero;
+		static const vec2_t one;
+		// accessors
+		float& operator []( uint i );
+		float  operator []( uint i ) const;
+		// constructors & distructors
+		explicit vec2_t();
+		explicit vec2_t( float f );
+		explicit vec2_t( float x, float y );
+		         vec2_t( const vec2_t& b );
+		explicit vec2_t( const vec3_t& v3 );
+		explicit vec2_t( const vec4_t& v4 );
+		// ops with same type
+		vec2_t  operator + ( const vec2_t& b ) const;
+		vec2_t& operator +=( const vec2_t& b );
+		vec2_t  operator - ( const vec2_t& b ) const;
+		vec2_t& operator -=( const vec2_t& b );
+		vec2_t  operator * ( const vec2_t& b ) const;
+		vec2_t& operator *=( const vec2_t& b );
+		vec2_t  operator / ( const vec2_t& b ) const;
+		vec2_t& operator /=( const vec2_t& b );
+		vec2_t  operator - () const;
+		// ops with float
+		vec2_t  operator + ( float f ) const;
+		vec2_t& operator +=( float f );
+		vec2_t  operator - ( float f ) const;
+		vec2_t& operator -=( float f );
+		vec2_t  operator * ( float f ) const;
+		vec2_t& operator *=( float f );
+		vec2_t  operator / ( float f ) const;
+		vec2_t& operator /=( float f );
+		// comparision
+		bool operator ==( const vec2_t& b ) const;
+		bool operator !=( const vec2_t& b ) const;
+		// other
+		static vec2_t GetZero();
+		static vec2_t GetOne();
+		float  Length() const;
+		void   SetZero();
+		void   Normalize();
+		vec2_t Normalized() const;
+		float  Dot( const vec2_t& b ) const;
+		void   Print() const;
+};
+
+
+} // end namespace
+
+
+#include "vec2.inl.h"
+
+
+#endif

+ 222 - 0
src/math/vec2.inl.h

@@ -0,0 +1,222 @@
+#include "m_dflt_header.h"
+
+
+#define ME (*this)
+
+namespace m {
+
+// accessors
+M_INLINE float& vec2_t::operator []( uint i )
+{
+	return (&x)[i];
+}
+
+M_INLINE float vec2_t::operator []( uint i ) const
+{
+	return (&x)[i];
+}
+
+// constructor []
+M_INLINE vec2_t::vec2_t()
+	: x(0.0), y(0.0)
+{}
+
+// constructor [float, float]
+M_INLINE vec2_t::vec2_t( float x_, float y_ )
+	: x(x_), y(y_)
+{}
+
+// constructor [float]
+M_INLINE vec2_t::vec2_t( float f ): x(f), y(f)
+{}
+
+// constructor [vec2]
+M_INLINE vec2_t::vec2_t( const vec2_t& b ): x(b.x), y(b.y)
+{}
+
+// constructor [vec3]
+M_INLINE vec2_t::vec2_t( const vec3_t& v3 ): x(v3.x), y(v3.y)
+{}
+
+// constructor [vec4]
+M_INLINE vec2_t::vec2_t( const vec4_t& v4 ): x(v4.x), y(v4.y)
+{}
+
+// +
+M_INLINE vec2_t vec2_t::operator +( const vec2_t& b ) const
+{
+	return vec2_t( x+b.x, y+b.y );
+}
+
+// +=
+M_INLINE vec2_t& vec2_t::operator +=( const vec2_t& b )
+{
+	x += b.x;
+	y += b.y;
+	return ME;
+}
+
+// -
+M_INLINE vec2_t vec2_t::operator -( const vec2_t& b ) const
+{
+	return vec2_t( x-b.x, y-b.y );
+}
+
+// -=
+M_INLINE vec2_t& vec2_t::operator -=( const vec2_t& b )
+{
+	x -= b.x;
+	y -= b.y;
+	return ME;
+}
+
+// *
+M_INLINE vec2_t vec2_t::operator *( const vec2_t& b ) const
+{
+	return vec2_t( x*b.x, y*b.y );
+}
+
+// *=
+M_INLINE vec2_t& vec2_t::operator *=( const vec2_t& b )
+{
+	x *= b.x;
+	y *= b.y;
+	return ME;
+}
+
+// /
+M_INLINE vec2_t vec2_t::operator /( const vec2_t& b ) const
+{
+	return vec2_t( x/b.x, y/b.y );
+}
+
+// /=
+M_INLINE vec2_t& vec2_t::operator /=( const vec2_t& b )
+{
+	x /= b.x;
+	y /= b.y;
+	return ME;
+}
+
+// negative
+M_INLINE vec2_t vec2_t::operator -() const
+{
+	return vec2_t( -x, -y );
+}
+
+// ==
+M_INLINE bool vec2_t::operator ==( const vec2_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) ) ? true : false;
+}
+
+// !=
+M_INLINE bool vec2_t::operator !=( const vec2_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) ) ? false : true;
+}
+
+// vec2 + float
+M_INLINE vec2_t vec2_t::operator +( float f ) const
+{
+	return ME + vec2_t(f);
+}
+
+// vec2 += float
+M_INLINE vec2_t& vec2_t::operator +=( float f )
+{
+	ME += vec2_t(f);
+	return ME;
+}
+
+// vec2 - float
+M_INLINE vec2_t vec2_t::operator -( float f ) const
+{
+	return ME - vec2_t(f);
+}
+
+// vec2 -= float
+M_INLINE vec2_t& vec2_t::operator -=( float f )
+{
+	ME -= vec2_t(f);
+	return ME;
+}
+
+// vec2 * float
+M_INLINE vec2_t vec2_t::operator *( float f ) const
+{
+	return ME * vec2_t(f);
+}
+
+// vec2 *= float
+M_INLINE vec2_t& vec2_t::operator *=( float f )
+{
+	ME *= vec2_t(f);
+	return ME;
+}
+
+// vec2 / float
+M_INLINE vec2_t vec2_t::operator /( float f ) const
+{
+	return ME / vec2_t(f);
+}
+
+// vec2 /= float
+M_INLINE vec2_t& vec2_t::operator /=( float f )
+{
+	ME /= vec2_t(f);
+	return ME;
+}
+
+// Length
+M_INLINE float vec2_t::Length() const
+{
+	return Sqrt( x*x + y*y );
+}
+
+// set to zero
+M_INLINE void vec2_t::SetZero()
+{
+	x = y = 0.0;
+}
+
+// Normalize
+M_INLINE void vec2_t::Normalize()
+{
+	ME *= InvSqrt( x*x + y*y );
+}
+
+// Normalized (return the normalized)
+M_INLINE vec2_t vec2_t::Normalized() const
+{
+	return ME * InvSqrt( x*x + y*y );
+}
+
+// Dot
+M_INLINE float vec2_t::Dot( const vec2_t& b ) const
+{
+	return x*b.x + y*b.y;
+}
+
+// GetZero
+M_INLINE vec2_t vec2_t::GetZero()
+{
+	return vec2_t(0.0);
+}
+
+// GetOne
+M_INLINE vec2_t vec2_t::GetOne()
+{
+	return vec2_t(1.0);
+}
+
+// Print
+M_INLINE void vec2_t::Print() const
+{
+	for( int i=0; i<2; i++ )
+		cout << fixed << ME[i] << ' ';
+	cout << "\n" << endl;
+}
+
+
+} // end namespace

+ 84 - 0
src/math/vec3.h

@@ -0,0 +1,84 @@
+#ifndef _VEC3_H_
+#define _VEC3_H_
+
+#include "common.h"
+#include "forward_decls.h"
+
+
+namespace m {
+
+
+class vec3_t
+{
+	public:
+		// data members
+		float x, y, z;
+		// accessors
+		float& operator []( uint i );
+		float  operator []( uint i ) const;
+		// constructors & distructors
+		explicit vec3_t();
+		explicit vec3_t( float f );
+		explicit vec3_t( float x, float y, float z );
+		explicit vec3_t( const vec2_t& v2, float z );
+		         vec3_t( const vec3_t& b );
+		explicit vec3_t( const vec4_t& v4 );
+		explicit vec3_t( const quat_t& q );
+		// ops with same type
+		vec3_t  operator + ( const vec3_t& b ) const;
+		vec3_t& operator +=( const vec3_t& b );
+		vec3_t  operator - ( const vec3_t& b ) const;
+		vec3_t& operator -=( const vec3_t& b );
+		vec3_t  operator * ( const vec3_t& b ) const;
+		vec3_t& operator *=( const vec3_t& b );
+		vec3_t  operator / ( const vec3_t& b ) const;
+		vec3_t& operator /=( const vec3_t& b );
+		vec3_t  operator - () const; // return the negative
+		// ops with float
+		vec3_t  operator + ( float f ) const;
+		vec3_t& operator +=( float f );
+		vec3_t  operator - ( float f ) const;
+		vec3_t& operator -=( float f );
+		vec3_t  operator * ( float f ) const;
+		vec3_t& operator *=( float f );
+		vec3_t  operator / ( float f ) const;
+		vec3_t& operator /=( float f );
+		// ops with other types
+		vec3_t  operator * ( const mat3_t& m3 ) const;
+		// comparision
+		bool operator ==( const vec3_t& b ) const;
+		bool operator !=( const vec3_t& b ) const;
+		// other
+		float  Dot( const vec3_t& b ) const;
+		vec3_t Cross( const vec3_t& b ) const;
+		float  Length() const;
+		float  LengthSquared() const;
+		float  DistanceSquared( const vec3_t& b ) const;
+		void   Normalize();
+		vec3_t Normalized() const;
+		vec3_t Project( const vec3_t& to_this ) const;
+		vec3_t Rotated( const quat_t& q ) const; // returns q * this * q.Conjucated() aka returns a rotated this. 21 muls, 12 adds
+		void   Rotate( const quat_t& q );
+		vec3_t Lerp( const vec3_t& v1, float t ) const; // return Lerp( this, v1, t )
+		void   Print() const;
+		// transformations. The faster way is by far the mat4 * vec3 or the Transformed( vec3_t, mat3_t )
+		vec3_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void   Transform( const vec3_t& translate, const mat3_t& rotate, float scale );
+		vec3_t Transformed( const vec3_t& translate, const mat3_t& rotate ) const;
+		void   Transform( const vec3_t& translate, const mat3_t& rotate );
+		vec3_t Transformed( const vec3_t& translate, const quat_t& rotate, float scale ) const;
+		void   Transform( const vec3_t& translate, const quat_t& rotate, float scale );
+		vec3_t Transformed( const vec3_t& translate, const quat_t& rotate ) const;
+		void   Transform( const vec3_t& translate, const quat_t& rotate );
+		vec3_t Transformed( const mat4_t& transform ) const;  // 9 muls, 9 adds
+		void   Transform( const mat4_t& transform );
+};
+
+
+} // end namespace
+
+
+#include "vec3.inl.h"
+
+
+#endif

+ 321 - 0
src/math/vec3.inl.h

@@ -0,0 +1,321 @@
+#include "m_dflt_header.h"
+
+
+#define ME (*this)
+
+
+namespace m {
+
+
+// accessors
+M_INLINE float& vec3_t::operator []( uint i )
+{
+	return (&x)[i];
+}
+
+M_INLINE float vec3_t::operator []( uint i ) const
+{
+	return (&x)[i];
+}
+
+// constructor []
+M_INLINE vec3_t::vec3_t()
+	: x(0.0), y(0.0), z(0.0)
+{}
+
+// constructor [float, float, float]
+M_INLINE vec3_t::vec3_t( float x_, float y_, float z_ )
+	: x(x_), y(y_), z(z_)
+{}
+
+// constructor [float]
+M_INLINE vec3_t::vec3_t( float f )
+	: x(f), y(f), z(f)
+{}
+
+// constructor [vec3]
+M_INLINE vec3_t::vec3_t( const vec3_t& b )
+	: x(b.x), y(b.y), z(b.z)
+{}
+
+// constructor [vec2, float]
+M_INLINE vec3_t::vec3_t( const vec2_t& v2, float z_ )
+	: x(v2.x), y(v2.y), z(z_)
+{}
+
+// constructor [vec4]
+M_INLINE vec3_t::vec3_t( const vec4_t& v4 )
+	: x(v4.x), y(v4.y), z(v4.z)
+{}
+
+// constructor [quat]
+M_INLINE vec3_t::vec3_t( const quat_t& q )
+	: x(q.x), y(q.y), z(q.z)
+{}
+
+// +
+M_INLINE vec3_t vec3_t::operator +( const vec3_t& b ) const
+{
+	return vec3_t( x+b.x, y+b.y, z+b.z );
+}
+
+// +=
+M_INLINE vec3_t& vec3_t::operator +=( const vec3_t& b )
+{
+	x += b.x;
+	y += b.y;
+	z += b.z;
+	return ME;
+}
+
+// -
+M_INLINE vec3_t vec3_t::operator -( const vec3_t& b ) const
+{
+	return vec3_t( x-b.x, y-b.y, z-b.z );
+}
+
+// -=
+M_INLINE vec3_t& vec3_t::operator -=( const vec3_t& b )
+{
+	x -= b.x;
+	y -= b.y;
+	z -= b.z;
+	return ME;
+}
+
+// *
+M_INLINE vec3_t vec3_t::operator *( const vec3_t& b ) const
+{
+	return vec3_t( x*b.x, y*b.y, z*b.z );
+}
+
+// *=
+M_INLINE vec3_t& vec3_t::operator *=( const vec3_t& b )
+{
+	x *= b.x;
+	y *= b.y;
+	z *= b.z;
+	return ME;
+}
+
+// /
+M_INLINE vec3_t vec3_t::operator /( const vec3_t& b ) const
+{
+	return vec3_t( x/b.x, y/b.y, z/b.z );
+}
+
+// /=
+M_INLINE vec3_t& vec3_t::operator /=( const vec3_t& b )
+{
+	x /= b.x;
+	y /= b.y;
+	z /= b.z;
+	return ME;
+}
+
+// negative
+M_INLINE vec3_t vec3_t::operator -() const
+{
+	return vec3_t( -x, -y, -z );
+}
+
+// ==
+M_INLINE bool vec3_t::operator ==( const vec3_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? true : false;
+}
+
+// !=
+M_INLINE bool vec3_t::operator !=( const vec3_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? false : true;
+}
+
+// vec3 + float
+M_INLINE vec3_t vec3_t::operator +( float f ) const
+{
+	return ME + vec3_t(f);
+}
+
+// vec3 += float
+M_INLINE vec3_t& vec3_t::operator +=( float f )
+{
+	ME += vec3_t(f);
+	return ME;
+}
+
+// vec3 - float
+M_INLINE vec3_t vec3_t::operator -( float f ) const
+{
+	return ME - vec3_t(f);
+}
+
+// vec3 -= float
+M_INLINE vec3_t& vec3_t::operator -=( float f )
+{
+	ME -= vec3_t(f);
+	return ME;
+}
+
+// vec3 * float
+M_INLINE vec3_t vec3_t::operator *( float f ) const
+{
+	return ME * vec3_t(f);
+}
+
+// vec3 *= float
+M_INLINE vec3_t& vec3_t::operator *=( float f )
+{
+	ME *= vec3_t(f);
+	return ME;
+}
+
+// vec3 / float
+M_INLINE vec3_t vec3_t::operator /( float f ) const
+{
+	return ME / vec3_t(f);
+}
+
+// vec3 /= float
+M_INLINE vec3_t& vec3_t::operator /=( float f )
+{
+	ME /= vec3_t(f);
+	return ME;
+}
+
+// Dot
+M_INLINE float vec3_t::Dot( const vec3_t& b ) const
+{
+	return x*b.x + y*b.y + z*b.z;
+}
+
+// cross prod
+M_INLINE vec3_t vec3_t::Cross( const vec3_t& b ) const
+{
+	return vec3_t( y*b.z-z*b.y, z*b.x-x*b.z, x*b.y-y*b.x );
+}
+
+// Length
+M_INLINE float vec3_t::Length() const
+{
+	return Sqrt( x*x + y*y + z*z );
+}
+
+// LengthSquared
+M_INLINE float vec3_t::LengthSquared() const
+{
+	return x*x + y*y + z*z;
+}
+
+// DistanceSquared
+M_INLINE float vec3_t::DistanceSquared( const vec3_t& b ) const
+{
+	return (ME-b).LengthSquared();
+}
+
+// Normalize
+M_INLINE void vec3_t::Normalize()
+{
+	ME *= InvSqrt( x*x + y*y + z*z );
+}
+
+// Normalized (return the normalized)
+M_INLINE vec3_t vec3_t::Normalized() const
+{
+	return ME * InvSqrt( x*x + y*y + z*z );
+}
+
+// Project
+M_INLINE vec3_t vec3_t::Project( const vec3_t& to_this ) const
+{
+	return to_this * ( ME.Dot(to_this)/(to_this.Dot(to_this)) );
+}
+
+// Rotated
+M_INLINE vec3_t vec3_t::Rotated( const quat_t& q ) const
+{
+	DEBUG_ERR( !IsZero(1.0f-q.Length()) ); // Not normalized quat
+
+	float vmult = 2.0f*(q.x*x + q.y*y + q.z*z);
+	float crossmult = 2.0*q.w;
+	float pmult = crossmult*q.w - 1.0;
+
+	return vec3_t( pmult*x + vmult*q.x + crossmult*(q.y*z - q.z*y),
+							   pmult*y + vmult*q.y + crossmult*(q.z*x - q.x*z),
+	               pmult*z + vmult*q.z + crossmult*(q.x*y - q.y*x) );
+}
+
+// Rotate
+M_INLINE void vec3_t::Rotate( const quat_t& q )
+{
+	ME = Rotated(q);
+}
+
+// Print
+M_INLINE void vec3_t::Print() const
+{
+	for( int i=0; i<3; i++ )
+		cout << fixed << ME[i] << " ";
+	cout << "\n" << endl;
+}
+
+// Lerp
+M_INLINE vec3_t vec3_t::Lerp( const vec3_t& v1, float t ) const
+{
+	return (ME*(1.0f-t))+(v1*t);
+}
+
+// Transformed [mat3]
+M_INLINE vec3_t vec3_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	return (rotate * (ME * scale)) + translate;
+}
+
+// Transform [mat3]
+M_INLINE void vec3_t::Transform( const vec3_t& translate, const mat3_t& rotate, float scale )
+{
+	ME = Transformed( translate, rotate, scale );
+}
+
+// Transformed [mat3] no scale
+M_INLINE vec3_t vec3_t::Transformed( const vec3_t& translate, const mat3_t& rotate ) const
+{
+	return (rotate * ME) + translate;
+}
+
+// Transform [mat3] no scale
+M_INLINE void vec3_t::Transform( const vec3_t& translate, const mat3_t& rotate )
+{
+	ME = Transformed( translate, rotate );
+}
+
+// Transformed [quat]
+M_INLINE vec3_t vec3_t::Transformed( const vec3_t& translate, const quat_t& rotate, float scale ) const
+{
+	return (ME * scale).Rotated(rotate) + translate;
+}
+
+// Transform [quat3] no scale
+M_INLINE void vec3_t::Transform( const vec3_t& translate, const quat_t& rotate, float scale )
+{
+	ME = Transformed( translate, rotate, scale );
+}
+
+// Transformed [mat4]
+M_INLINE vec3_t vec3_t::Transformed( const mat4_t& transform ) const
+{
+	return vec3_t(
+		transform(0,0)*x + transform(0,1)*y + transform(0,2)*z + transform(0,3),
+		transform(1,0)*x + transform(1,1)*y + transform(1,2)*z + transform(1,3),
+		transform(2,0)*x + transform(2,1)*y + transform(2,2)*z + transform(2,3)
+	);
+}
+
+// Transformed [mat4]
+M_INLINE void vec3_t::Transform( const mat4_t& transform )
+{
+	ME = Transformed( transform );
+}
+
+
+} // end namespace

+ 66 - 0
src/math/vec4.h

@@ -0,0 +1,66 @@
+#ifndef _VEC4_H_
+#define _VEC4_H_
+
+#include "common.h"
+#include "forward_decls.h"
+
+
+namespace m {
+
+
+class vec4_t
+{
+	public:
+		// data members
+		float x, y, z, w;
+		// accessors
+		float& operator []( uint i );
+		float  operator []( uint i ) const;
+		// constructors & distructors
+		explicit vec4_t();
+		explicit vec4_t( float f );
+		explicit vec4_t( float x, float y, float z, float w );
+		explicit vec4_t( const vec2_t& v2, float z, float w );
+		explicit vec4_t( const vec3_t& v3, float w );
+		         vec4_t( const vec4_t& b );
+		explicit vec4_t( const quat_t& q );
+		// ops with same
+		vec4_t  operator + ( const vec4_t& b ) const;
+		vec4_t& operator +=( const vec4_t& b );
+		vec4_t  operator - ( const vec4_t& b ) const;
+		vec4_t& operator -=( const vec4_t& b );
+		vec4_t  operator * ( const vec4_t& b ) const;
+		vec4_t& operator *=( const vec4_t& b );
+		vec4_t  operator / ( const vec4_t& b ) const;
+		vec4_t& operator /=( const vec4_t& b );
+		vec4_t  operator - () const;
+		// ops with float
+		vec4_t  operator + ( float f ) const;
+		vec4_t& operator +=( float f );
+		vec4_t  operator - ( float f ) const;
+		vec4_t& operator -=( float f );
+		vec4_t  operator * ( float f ) const;
+		vec4_t& operator *=( float f );
+		vec4_t  operator / ( float f ) const;
+		vec4_t& operator /=( float f );
+		// ops with other
+		vec4_t  operator * ( const mat4_t& m4 ) const;
+		// comparision
+		bool operator ==( const vec4_t& b ) const;
+		bool operator !=( const vec4_t& b ) const;
+		// other
+		float  Length() const;
+		vec4_t Normalized() const;
+		void   Normalize();
+		void   Print() const;
+		float  Dot( const vec4_t& b ) const;
+};
+
+
+} // end namespace
+
+
+#include "vec4.inl.h"
+
+
+#endif

+ 234 - 0
src/math/vec4.inl.h

@@ -0,0 +1,234 @@
+#include "m_dflt_header.h"
+
+
+#define ME (*this)
+
+
+namespace m {
+
+
+// accessors
+M_INLINE float& vec4_t::operator []( uint i )
+{
+	return (&x)[i];
+}
+
+M_INLINE float vec4_t::operator []( uint i ) const
+{
+	return (&x)[i];
+}
+
+// constructor []
+M_INLINE vec4_t::vec4_t()
+	: x(0.0), y(0.0), z(0.0), w(0.0)
+{}
+
+// constructor [float]
+M_INLINE vec4_t::vec4_t( float f )
+	: x(f), y(f), z(f), w(f)
+{}
+
+// constructor [float, float, float, float]
+M_INLINE vec4_t::vec4_t( float x_, float y_, float z_, float w_ )
+	: x(x_), y(y_), z(z_), w(w_)
+{}
+
+// constructor [vec2, float, float]
+M_INLINE vec4_t::vec4_t( const vec2_t& v2, float z_, float w_ )
+	: x(v2.x), y(v2.y), z(z_), w(w_)
+{}
+
+// constructor [vec3, float]
+M_INLINE vec4_t::vec4_t( const vec3_t& v3, float w_ )
+	: x(v3.x), y(v3.y), z(v3.z), w(w_)
+{}
+
+// constructor [vec4]
+M_INLINE vec4_t::vec4_t( const vec4_t& b )
+	: x(b.x), y(b.y), z(b.z), w(b.w)
+{}
+
+// constructor [quat]
+M_INLINE vec4_t::vec4_t( const quat_t& q )
+	: x(q.x), y(q.y), z(q.z), w(q.w)
+{}
+
+// +
+M_INLINE vec4_t vec4_t::operator +( const vec4_t& b ) const
+{
+	return vec4_t( x+b.x, y+b.y, z+b.z, w+b.w );
+}
+
+// +=
+M_INLINE vec4_t& vec4_t::operator +=( const vec4_t& b )
+{
+	x += b.x;
+	y += b.y;
+	z += b.z;
+	w += b.w;
+	return ME;
+}
+
+// -
+M_INLINE vec4_t vec4_t::operator -( const vec4_t& b ) const
+{
+	return vec4_t( x-b.x, y-b.y, z-b.z, w-b.w );
+}
+
+// -=
+M_INLINE vec4_t& vec4_t::operator -=( const vec4_t& b )
+{
+	x -= b.x;
+	y -= b.y;
+	z -= b.z;
+	w -= b.w;
+	return ME;
+}
+
+// *
+M_INLINE vec4_t vec4_t::operator *( const vec4_t& b ) const
+{
+	return vec4_t( x*b.x, y*b.y, z*b.z, w*b.w );
+}
+
+// *=
+M_INLINE vec4_t& vec4_t::operator *=( const vec4_t& b )
+{
+	x *= b.x;
+	y *= b.y;
+	z *= b.z;
+	w *= b.w;
+	return ME;
+}
+
+// /
+M_INLINE vec4_t vec4_t::operator /( const vec4_t& b ) const
+{
+	return vec4_t( x/b.x, y/b.y, z/b.z, w/b.w );
+}
+
+// /=
+M_INLINE vec4_t& vec4_t::operator /=( const vec4_t& b )
+{
+	x /= b.x;
+	y /= b.y;
+	z /= b.z;
+	w /= b.w;
+	return ME;
+}
+
+// negative
+M_INLINE vec4_t vec4_t::operator -() const
+{
+	return vec4_t( -x, -y, -z, -w );
+}
+
+// ==
+M_INLINE bool vec4_t::operator ==( const vec4_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) && IsZero(w-b.w) ) ? true : false;
+}
+
+// !=
+M_INLINE bool vec4_t::operator !=( const vec4_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) && IsZero(w-b.w) ) ? false : true;
+}
+
+// vec4 + float
+M_INLINE vec4_t vec4_t::operator +( float f ) const
+{
+	return ME + vec4_t(f);
+}
+
+// vec4 += float
+M_INLINE vec4_t& vec4_t::operator +=( float f )
+{
+	ME += vec4_t(f);
+	return ME;
+}
+
+// vec4 - float
+M_INLINE vec4_t vec4_t::operator -( float f ) const
+{
+	return ME - vec4_t(f);
+}
+
+// vec4 -= float
+M_INLINE vec4_t& vec4_t::operator -=( float f )
+{
+	ME -= vec4_t(f);
+	return ME;
+}
+
+// vec4 * float
+M_INLINE vec4_t vec4_t::operator *( float f ) const
+{
+	return ME * vec4_t(f);
+}
+
+// vec4 *= float
+M_INLINE vec4_t& vec4_t::operator *=( float f )
+{
+	ME *= vec4_t(f);
+	return ME;
+}
+
+// vec4 / float
+M_INLINE vec4_t vec4_t::operator /( float f ) const
+{
+	return ME / vec4_t(f);
+}
+
+// vec4 /= float
+M_INLINE vec4_t& vec4_t::operator /=( float f )
+{
+	ME /= vec4_t(f);
+	return ME;
+}
+
+// vec4 * mat4
+M_INLINE vec4_t vec4_t::operator *( const mat4_t& m4 ) const
+{
+	return vec4_t(
+		x*m4(0,0) + y*m4(1,0) + z*m4(2,0) + w*m4(3,0),
+		x*m4(0,1) + y*m4(1,1) + z*m4(2,1) + w*m4(3,1),
+		x*m4(0,2) + y*m4(1,2) + z*m4(2,2) + w*m4(3,2),
+		x*m4(0,3) + y*m4(1,3) + z*m4(2,3) + w*m4(3,3)
+	);
+}
+
+// Dot
+M_INLINE float vec4_t::Dot( const vec4_t& b ) const
+{
+	return x*b.x + y*b.y + z*b.z + w*b.w;
+}
+
+// Length
+M_INLINE float vec4_t::Length() const
+{
+	return Sqrt( x*x + y*y + z*z + w*w );
+}
+
+// Normalized
+M_INLINE vec4_t vec4_t::Normalized() const
+{
+	return ME * InvSqrt( x*x +y*y + z*z + w*w );
+}
+
+// Normalize
+M_INLINE void vec4_t::Normalize()
+{
+	ME = Normalized();
+}
+
+// Print
+M_INLINE void vec4_t::Print() const
+{
+	for( int i=0; i<4; i++ )
+		cout << fixed << ME[i] << " ";
+	cout << "\n" << endl;
+}
+
+
+} // end namespace

+ 66 - 0
src/old_src/2009-5-11/animation.cbp

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6" />
+	<Project>
+		<Option title="animation" />
+		<Option pch_mode="2" />
+		<Option compiler="gcc" />
+		<Build>
+			<Target title="Debug">
+				<Option output="bin/Debug/animation" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj/Debug/" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Compiler>
+					<Add option="-g" />
+				</Compiler>
+			</Target>
+			<Target title="Release">
+				<Option output="bin/Release/animation" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj/Release/" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Compiler>
+					<Add option="-O3" />
+				</Compiler>
+				<Linker>
+					<Add option="-s" />
+				</Linker>
+			</Target>
+		</Build>
+		<Compiler>
+			<Add option="-Wall" />
+		</Compiler>
+		<Linker>
+			<Add option="`sdl-config --libs`" />
+			<Add library="GL" />
+			<Add library="GLU" />
+		</Linker>
+		<Unit filename="camera.cpp" />
+		<Unit filename="camera.h" />
+		<Unit filename="handlers.cpp" />
+		<Unit filename="handlers.h" />
+		<Unit filename="input.cpp" />
+		<Unit filename="input.h" />
+		<Unit filename="local.cpp" />
+		<Unit filename="local.h" />
+		<Unit filename="main_animation.cpp" />
+		<Unit filename="math.cpp" />
+		<Unit filename="math.h" />
+		<Unit filename="model.cpp" />
+		<Unit filename="model.h" />
+		<Unit filename="primitives.h" />
+		<Unit filename="renderer.cpp" />
+		<Unit filename="renderer.h" />
+		<Unit filename="textout.cpp" />
+		<Unit filename="textout.h" />
+		<Unit filename="texture.cpp" />
+		<Unit filename="texture.h" />
+		<Extensions>
+			<code_completion />
+			<envvars />
+			<debugger />
+			<lib_finder disable_auto="1" />
+		</Extensions>
+	</Project>
+</CodeBlocks_project_file>

+ 222 - 0
src/old_src/2009-5-11/assets.cpp

@@ -0,0 +1,222 @@
+#include "assets.h"
+
+
+namespace ass {
+
+
+/**
+=======================================================================================================================================
+DATA OBJECTS                                                                                                                          =
+=======================================================================================================================================
+*/
+static vector<data_class_t*> assets; // ToDo: update the funcs
+
+static vector<texture_t*> textures;
+static vector<shader_prog_t*> shaders;
+static vector<material_t*> materials;
+static vector<mesh_data_t*> mesh_data;
+static vector<model_data_t*> model_data;
+
+
+/**
+=======================================================================================================================================
+TEMPLATE FUNCS                                                                                                                        =
+=======================================================================================================================================
+*/
+
+// Search (by name)
+template <typename type_t> type_t* Search( vector<type_t*>& vec, const char* name )
+{
+	typename vector<type_t*>::iterator it;
+	for( it=vec.begin(); it<vec.end(); it++ )
+	{
+		if( strcmp( name, (*it)->GetName() ) == 0 )
+			return *it;
+	}
+	return NULL;
+}
+
+// Search (by pointer)
+template <typename type_t> bool Search( vector<type_t*>& vec, type_t* x )
+{
+	typename vector<type_t*>::iterator it;
+	for( it=vec.begin(); it<vec.end(); it++ )
+	{
+		if( x == *it )
+			return true;
+	}
+	return false;
+}
+
+// Register
+template <typename type_t> void Register( vector<type_t*>& vec, type_t* x )
+{
+	DEBUG_ERR( Search<type_t>( vec, x ) ); // the obj must not be allready loaded
+
+	x->SetID( vec.size() );
+	vec.push_back( x );
+}
+
+// UnRegister
+template <typename type_t> void UnRegister( vector<type_t*>& vec, type_t* x )
+{
+	DEBUG_ERR( Search<type_t>( vec, x ) );
+
+	// decr the ids
+	typename vector<type_t*>::iterator it;
+	for( it=vec.begin()+x->GetID()+1; it<vec.end(); it++ )
+	{
+		(*it)->SetID( (*it)->GetID()-1 );
+	}
+
+	vec.erase( vec.begin() + x->GetID() );
+}
+
+// LoadDataClass
+template <typename type_t> type_t* LoadDataClass( vector<type_t*>& vec, const char* fname )
+{
+	char* name = CutPath(fname);
+	type_t* newt = Search<type_t>( vec, name );
+
+	// allready loaded
+	if( newt != NULL )
+	{
+		++newt->users_num;
+		return newt;
+	}
+
+	// not loaded
+	newt = new type_t;
+	newt->SetName( name );
+	if( !newt->Load( fname ) )
+	{
+		ERROR( "Cannot load \"" << fname << '\"' );
+		return NULL;
+	}
+	newt->users_num = 1;
+	Register<type_t>( vec, newt );
+	return newt;
+}
+
+// UnloadDataClass
+template <typename type_t> void UnloadDataClass( vector<type_t*>& vec, type_t* x )
+{
+	DEBUG_ERR( Search<type_t>( vec, x ) );
+	DEBUG_ERR( x->users_num < 1 );
+
+	--x->users_num;
+
+	if( x->users_num == 0 )
+	{
+		UnRegister<type_t>( vec, x );
+		delete x;
+	}
+}
+
+
+/*
+=======================================================================================================================================
+texture                                                                                                                               =
+=======================================================================================================================================
+*/
+texture_t* SearchTxtr( const char* name )
+{
+	return Search<texture_t>( textures, name );
+}
+
+texture_t* LoadTxtr( const char* name )
+{
+	return LoadDataClass<texture_t>( textures, name );
+}
+
+void UnLoadTxtr( texture_t* txtr )
+{
+	UnloadDataClass<texture_t>( textures, txtr );
+}
+
+
+/*
+=======================================================================================================================================
+material                                                                                                                              =
+=======================================================================================================================================
+*/
+material_t* SearchMat( const char* name )
+{
+	return Search<material_t>( materials, name );
+}
+
+material_t* LoadMat( const char* name )
+{
+	return LoadDataClass<material_t>( materials, name );
+}
+
+void UnLoadMat( material_t* mat )
+{
+	UnloadDataClass<material_t>( materials, mat );
+}
+
+
+/*
+=======================================================================================================================================
+shaders                                                                                                                               =
+=======================================================================================================================================
+*/
+shader_prog_t* SearchShdr( const char* name )
+{
+	return Search<shader_prog_t>( shaders, name );
+}
+
+shader_prog_t* LoadShdr( const char* name )
+{
+	return LoadDataClass<shader_prog_t>( shaders, name );
+}
+
+void UnLoadMat( shader_prog_t* x )
+{
+	UnloadDataClass<shader_prog_t>( shaders, x );
+}
+
+
+/*
+=======================================================================================================================================
+mesh data                                                                                                                             =
+=======================================================================================================================================
+*/
+mesh_data_t* SearchMeshD( const char* name )
+{
+	return Search<mesh_data_t>( mesh_data, name );
+}
+
+mesh_data_t* LoadMeshD( const char* name )
+{
+	return LoadDataClass<mesh_data_t>( mesh_data, name );
+}
+
+void UnLoadMeshD( mesh_data_t* x )
+{
+	UnloadDataClass<mesh_data_t>( mesh_data, x );
+}
+
+
+/*
+=======================================================================================================================================
+model data                                                                                                                            =
+=======================================================================================================================================
+*/
+model_data_t* SearchModelD( const char* name )
+{
+	return Search<model_data_t>( model_data, name );
+}
+
+model_data_t* LoadModelD( const char* name )
+{
+	return LoadDataClass<model_data_t>( model_data, name );
+}
+
+void UnLoadModelD( model_data_t* x )
+{
+	UnloadDataClass<model_data_t>( model_data, x );
+}
+
+
+} // end namespace

+ 47 - 0
src/old_src/2009-5-11/assets.h

@@ -0,0 +1,47 @@
+#ifndef _ASSETS_H_
+#define _ASSETS_H_
+
+#include "common.h"
+
+#include "texture.h"
+#include "material.h"
+#include "shaders.h"
+#include "geometry.h"
+#include "model.h"
+
+
+class texture_t;
+class material_t;
+class shader_prog_t;
+class mesh_data_t;
+class model_data_t;
+
+namespace ass {
+
+// texture
+extern texture_t* SearchTxtr( const char* name );
+extern texture_t* LoadTxtr( const char* filename );
+extern void UnLoadTxtr( texture_t* txtr );
+
+// material
+extern material_t* SearchMat( const char* name );
+extern material_t* LoadMat( const char* filename );
+extern void UnLoadMat( material_t* mat );
+
+// shaders
+extern shader_prog_t* SearchShdr( const char* name );
+extern shader_prog_t* LoadShdr( const char* filename );
+extern void UnLoadShdr( shader_prog_t* mat );
+
+// mesh data
+extern mesh_data_t* SearchMeshD( const char* name );
+extern mesh_data_t* LoadMeshD( const char* filename );
+extern void UnLoadMeshD( mesh_data_t* mesh );
+
+// model data
+extern model_data_t* SearchModelD( const char* name );
+extern model_data_t* LoadModelD( const char* filename );
+extern void UnLoadModelD( model_data_t* mesh );
+
+} // end namespace
+#endif

+ 194 - 0
src/old_src/2009-5-11/camera.cpp

@@ -0,0 +1,194 @@
+#include "camera.h"
+#include "renderer.h"
+
+
+
+/*
+=======================================================================================================================================
+RenderDebug                                                                                                                           =
+=======================================================================================================================================
+*/
+void camera_t::RenderDebug()
+{
+	glPushMatrix();
+	r::MultMatrix( world_transformation );
+
+	const float cam_len = 1.0;
+	float tmp0 = cam_len / tan( (PI - fovx)*0.5 ) + 0.001;
+	float tmp1 = cam_len * tan(fovy*0.5) + 0.001;
+
+	float points [][3] = {
+		{0.0, 0.0, 0.0}, // 0: eye point
+		{-tmp0, tmp1, -cam_len}, // 1: top left
+		{-tmp0, -tmp1, -cam_len}, // 2: bottom left
+		{tmp0, -tmp1, -cam_len}, // 3: bottom right
+		{tmp0, tmp1, -cam_len}, // 4: top right
+	};
+
+	glLineWidth( 2.0 );
+
+	r::SetGLState_Wireframe();
+
+	glColor3fv( &vec3_t(1.0,0.0,1.0)[0] );
+	glBegin( GL_LINES );
+		glVertex3fv( &points[0][0] );
+		glVertex3fv( &points[1][0] );
+		glVertex3fv( &points[0][0] );
+		glVertex3fv( &points[2][0] );
+		glVertex3fv( &points[0][0] );
+		glVertex3fv( &points[3][0] );
+		glVertex3fv( &points[0][0] );
+		glVertex3fv( &points[4][0] );
+	glEnd();
+
+	glBegin( GL_LINE_STRIP );
+		glVertex3fv( &points[1][0] );
+		glVertex3fv( &points[2][0] );
+		glVertex3fv( &points[3][0] );
+		glVertex3fv( &points[4][0] );
+		glVertex3fv( &points[1][0] );
+	glEnd();
+
+
+	glPopMatrix();
+}
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void camera_t::Render()
+{
+	if( !r::show_cameras ) return;
+	RenderDebug();
+}
+
+
+/*
+=======================================================================================================================================
+LookAtPoint                                                                                                                           =
+=======================================================================================================================================
+*/
+void camera_t::LookAtPoint( const vec3_t& point )
+{
+	const vec3_t& j = vec3_t( 0.0, 1.0, 0.0 );
+	vec3_t vdir = (point - local_translation).Normalized();
+	vec3_t vup = j - vdir * j.Dot(vdir);
+	vec3_t vside = vdir.Cross( vup );
+	local_rotation.SetColumns( vside, vup, -vdir );
+}
+
+
+/*
+=======================================================================================================================================
+CalcLSpaceFrustumPlanes                                                                                                               =
+=======================================================================================================================================
+*/
+void camera_t::CalcLSpaceFrustumPlanes()
+{
+	// right
+	lspace_frustum_planes[RIGHT] = plane_t( vec3_t( cos(PI - fovx/2), 0.0f, sin(fovx - PI/2) ), 0.0f );
+	// left
+	lspace_frustum_planes[LEFT] = plane_t( vec3_t( -cos(PI - fovx/2), 0.0f, sin(fovx - PI/2) ), 0.0f );
+	// top
+	lspace_frustum_planes[TOP] = plane_t( vec3_t( 0.0f, sin( (3*PI-fovy)*0.5 ), cos( (3*PI-fovy)*0.5 ) ), 0.0f );
+	// bottom
+	lspace_frustum_planes[BOTTOM] = plane_t( vec3_t( 0.0f, -sin( (3*PI-fovy)*0.5 ), cos( (3*PI-fovy)*0.5 ) ), 0.0f );
+	// near
+	lspace_frustum_planes[NEAR] = plane_t( vec3_t( 0.0f, 0.0f, -1.0f ), znear );
+	// far
+	lspace_frustum_planes[FAR] = plane_t( vec3_t( 0.0f, 0.0f, 1.0f ), -zfar );
+}
+
+
+/*
+=======================================================================================================================================
+UpdateWSpaceFrustumPlanes                                                                                                             =
+=======================================================================================================================================
+*/
+void camera_t::UpdateWSpaceFrustumPlanes()
+{
+	for( uint i=0; i<6; i++ )
+		wspace_frustum_planes[i] = lspace_frustum_planes[i].Transformed( world_translation, world_rotation, world_scale );
+}
+
+
+/*
+=======================================================================================================================================
+InsideFrustum                                                                                                                         =
+check if the volume is inside the frustum cliping planes                                                                              =
+=======================================================================================================================================
+*/
+bool camera_t::InsideFrustum( const bvolume_t& bvol )
+{
+	for( uint i=0; i<6; i++ )
+		if( bvol.PlaneTest( wspace_frustum_planes[i] ) < 0.0 )
+			return false;
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+UpdateProjectionMatrix                                                                                                                =
+=======================================================================================================================================
+*/
+void camera_t::UpdateProjectionMatrix()
+{
+	float f = 1.0f/tan( fovy*0.5f ); // f = cot(fovy/2)
+
+	projection_mat(0,0) = f*fovy/fovx; // = f/aspect_ratio;
+	projection_mat(0,1) = 0.0;
+	projection_mat(0,2) = 0.0;
+	projection_mat(0,3) = 0.0;
+	projection_mat(1,0) = 0.0;
+	projection_mat(1,1) = f;
+	projection_mat(1,2) = 0.0;
+	projection_mat(1,3) = 0.0;
+	projection_mat(2,0) = 0.0;
+	projection_mat(2,1) = 0.0;
+	projection_mat(2,2) = (zfar+znear) / (znear-zfar);
+	projection_mat(2,3) = (2.0f*zfar*znear) / (znear-zfar);
+	projection_mat(3,0) = 0.0;
+	projection_mat(3,1) = 0.0;
+	projection_mat(3,2) = -1.0f;
+	projection_mat(3,3) = 0.0;
+}
+
+
+/*
+=======================================================================================================================================
+UpdateViewMatrix                                                                                                                      =
+=======================================================================================================================================
+*/
+void camera_t::UpdateViewMatrix()
+{
+	/* The point at which the camera looks:
+	vec3_t viewpoint = local_translation + z_axis;
+	as we know the up vector, we can easily use gluLookAt:
+	gluLookAt( local_translation.x, local_translation.x, local_translation.z, z_axis.x, z_axis.y, z_axis.z, y_axis.x, y_axis.y, y_axis.z );
+	*/
+
+
+	// The view matrix is: Mview = camera.world_transform.Inverted(). Bus instead of inverting we do the following:
+	mat3_t cam_inverted_rot = world_rotation.Transposed();
+	vec3_t cam_inverted_tsl = -( cam_inverted_rot * world_translation );
+	view_mat = mat4_t( cam_inverted_tsl, cam_inverted_rot );
+}
+
+
+/*
+=======================================================================================================================================
+Update                                                                                                                                =
+=======================================================================================================================================
+*/
+void camera_t::Update()
+{
+	UpdateViewMatrix();
+	UpdateWSpaceFrustumPlanes();
+}
+
+
+

+ 75 - 0
src/old_src/2009-5-11/camera.h

@@ -0,0 +1,75 @@
+#ifndef _CAMERA_H_
+#define _CAMERA_H_
+
+#include "common.h"
+#include "primitives.h"
+#include "collision.h"
+
+class camera_runtime_class_t: public runtime_class_t {}; // for ambiguity reasons
+
+class camera_t: public object_t, public camera_runtime_class_t
+{
+	protected:
+		enum planes_e
+		{
+			LEFT,
+			RIGHT,
+			NEAR,
+			TOP,
+			BOTTOM,
+			FAR
+		};
+
+		// Fovx is the angle in the y axis (imagine the cam positioned in the default OGL pos)
+		// Note that fovx > fovy (most of the time) and aspect_ratio = fovx/fovy
+		// fovx and fovy in rad
+		float fovx, fovy;
+		float znear, zfar;
+
+		// the frustum planes in local and world space
+		plane_t lspace_frustum_planes[6];
+		plane_t wspace_frustum_planes[6];
+
+		// matrices
+		mat4_t projection_mat;
+		mat4_t view_mat;
+
+	public:
+		// constructors and destuctors
+		camera_t( float fovx_, float fovy_, float znear_, float zfar_ ): fovx(fovx_), fovy(fovy_), znear(znear_), zfar(zfar_)
+		{
+			CalcLSpaceFrustumPlanes();
+			UpdateWSpaceFrustumPlanes();
+			UpdateProjectionMatrix();
+		}
+		camera_t() {}
+		~camera_t() {}
+
+		// Sets & Gets
+		void SetFovX ( float fovx_ )  { fovx=fovx_; UpdateProjectionMatrix(); }
+		void SetFovY ( float fovy_ )  { fovy=fovy_; UpdateProjectionMatrix(); }
+		void SetZNear( float znear_ ) { znear=znear_; UpdateProjectionMatrix(); }
+		void SetZFar ( float zfar_ )  { zfar=zfar_; UpdateProjectionMatrix(); }
+		float GetFovX () const { return fovx; }
+		float GetFovY () const { return fovy; }
+		float GetZNear() const { return znear; }
+		float GetZFar () const { return zfar; }
+		const mat4_t& GetProjectionMatrix() const { return projection_mat; }
+		const mat4_t& GetViewMatrix() const { return view_mat; }
+
+		// misc
+		void LookAtPoint( const vec3_t& point );
+		void UpdateProjectionMatrix();
+		void UpdateViewMatrix();
+		void Update();
+		void RenderDebug();
+		void Render();
+
+		// frustum stuff
+		void CalcLSpaceFrustumPlanes();
+		void UpdateWSpaceFrustumPlanes();
+		bool InsideFrustum( const bvolume_t& vol );
+};
+
+
+#endif

+ 2044 - 0
src/old_src/2009-5-11/collision.cpp

@@ -0,0 +1,2044 @@
+#include "collision.h"
+#include "renderer.h"
+
+
+static int render_seperation_lock = 0;
+#define LOCK_RENDER_SEPERATION ++render_seperation_lock;
+#define UNLOCK_RENDER_SEPERATION --render_seperation_lock;
+#define RENDER_SEPERATION_TEST if(render_seperation_lock==0) RenderSeparationData( normal, impact_point, depth );
+
+
+/**
+=======================================================================================================================================
+misc                                                                                                                                  =
+=======================================================================================================================================
+*/
+static void RenderSeparationData( const vec3_t& normal, const vec3_t& impact_point, float depth )
+{
+	float con = 0.5f;
+	const vec3_t& i = impact_point;
+
+	r::SetGLState_Solid();
+	glLineWidth( 2.0f );
+	glBegin( GL_LINES );
+		glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+		glVertex3f( i.x-con, i.y, i.z );
+		glVertex3f( i.x+con, i.y, i.z );
+		glColor3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+		glVertex3f( i.x, i.y-con, i.z );
+		glVertex3f( i.x, i.y+con, i.z );
+		glColor3fv( &vec3_t( 0.0, 0.0, 1.0 )[0] );
+		glVertex3f( i.x, i.y, i.z-con );
+		glVertex3f( i.x, i.y, i.z+con );
+	glEnd();
+
+	glLineWidth( 6.0f );
+	glBegin( GL_LINES );
+		glColor3fv( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+		glVertex3fv( &((vec3_t&)impact_point)[0] );
+		glVertex3fv( &(impact_point+ normal*depth )[0] );
+	glEnd();
+}
+
+
+#define ABSTRACT_INTERSECTION_CODE \
+	switch( type ) \
+	{ \
+		case LINE_SEG: \
+			return Intersects( (const lineseg_t&)bv ); \
+		case RAY: \
+			return Intersects( (const ray_t&)bv ); \
+		case PLANE: \
+			return PlaneTest( (const plane_t&)bv ) == 0.0; \
+		case BSPHERE: \
+			return Intersects( (const bsphere_t&)bv ); \
+		case AABB: \
+			return Intersects( (const aabb_t&)bv ); \
+		case OBB: \
+			return Intersects( (const obb_t&)bv ); \
+	} \
+	return false;
+
+
+#define ABSTRACT_SEPERATION_CODE \
+	switch( type ) \
+	{ \
+		case BSPHERE: \
+			return SeperationTest( (const bsphere_t&)bv, normal, impact_point, depth ); \
+		case AABB: \
+			return SeperationTest( (const aabb_t&)bv, normal, impact_point, depth ); \
+		case OBB: \
+			return SeperationTest( (const obb_t&)bv, normal, impact_point, depth ); \
+	} \
+	return false;
+
+
+/**
+=======================================================================================================================================
+lineseg_t                                                                                                                             =
+=======================================================================================================================================
+*/
+
+/*
+=======================================================================================================================================
+DistanceSquared                                                                                                                       =
+seg - seg                                                                                                                             =
+=======================================================================================================================================
+*/
+float lineseg_t::DistanceSquared( const lineseg_t& ls, float& s_c, float& t_c ) const
+{
+	// compute intermediate parameters
+	vec3_t w0 = origin - ls.origin;
+	float a = dir.Dot( dir );
+	float b = dir.Dot( ls.dir );
+	float c = ls.dir.Dot( ls.dir );
+	float d = dir.Dot( w0 );
+	float e = ls.dir.Dot( w0 );
+
+	float denom = a*c - b*b;
+	// parameters to compute s_c, t_c
+	float sn, sd, tn, td;
+
+	// if denom is zero, try finding closest point on sl to origin0
+	if( IsZero(denom) )
+	{
+		// clamp s_c to 0
+		sd = td = c;
+		sn = 0.0f;
+		tn = e;
+	}
+	else
+	{
+		// clamp s_c within [0,1]
+		sd = td = denom;
+		sn = b*e - c*d;
+		tn = a*e - b*d;
+
+		// clamp s_c to 0
+		if (sn < 0.0f)
+		{
+			sn = 0.0f;
+			tn = e;
+			td = c;
+		}
+		// clamp s_c to 1
+		else if (sn > sd)
+		{
+			sn = sd;
+			tn = e + b;
+			td = c;
+		}
+	}
+
+	// clamp t_c within [0,1]
+	// clamp t_c to 0
+	if( tn < 0.0f )
+	{
+		t_c = 0.0f;
+		// clamp s_c to 0
+		if ( -d < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if ( -d > a )
+			s_c = 1.0f;
+		else
+			s_c = -d/a;
+	}
+	// clamp t_c to 1
+	else if( tn > td )
+	{
+		t_c = 1.0f;
+		// clamp s_c to 0
+		if( (-d+b) < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if( (-d+b) > a )
+			s_c = 1.0f;
+		else
+			s_c = (-d+b)/a;
+	}
+	else
+	{
+			t_c = tn/td;
+			s_c = sn/sd;
+	}
+
+	// compute difference vector and distance squared
+	vec3_t wc = w0 + dir*s_c - ls.dir*t_c;
+	return wc.Dot(wc);
+}
+
+
+/*
+=======================================================================================================================================
+DistanceSquared                                                                                                                       =
+seg - ray                                                                                                                             =
+=======================================================================================================================================
+*/
+float lineseg_t::DistanceSquared( const ray_t& ray, float& s_c, float& t_c ) const
+{
+	// compute intermediate parameters
+	vec3_t w0 = origin - ray.origin;
+	float a = dir.Dot( dir );
+	float b = dir.Dot( ray.dir );
+	float c = ray.dir.Dot( ray.dir );
+	float d = dir.Dot( w0 );
+	float e = ray.dir.Dot( w0 );
+
+	float denom = a*c - b*b;
+	// parameters to compute s_c, t_c
+	float sn, sd, tn, td;
+
+	// if denom is zero, try finding closest point on ME1 to origin0
+	if( IsZero(denom) )
+	{
+		// clamp s_c to 0
+		sd = td = c;
+		sn = 0.0f;
+		tn = e;
+	}
+	else
+	{
+		// clamp s_c within [0,1]
+		sd = td = denom;
+		sn = b*e - c*d;
+		tn = a*e - b*d;
+
+		// clamp s_c to 0
+		if (sn < 0.0f)
+		{
+			sn = 0.0f;
+			tn = e;
+			td = c;
+		}
+		// clamp s_c to 1
+		else if (sn > sd)
+		{
+			sn = sd;
+			tn = e + b;
+			td = c;
+		}
+	}
+
+	// clamp t_c within [0,+inf]
+	// clamp t_c to 0
+	if (tn < 0.0f)
+	{
+		t_c = 0.0f;
+		// clamp s_c to 0
+		if ( -d < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if ( -d > a )
+			s_c = 1.0f;
+		else
+			s_c = -d/a;
+	}
+	else
+	{
+		t_c = tn/td;
+		s_c = sn/sd;
+	}
+
+	// compute difference vector and distance squared
+	vec3_t wc = w0 + dir*s_c - ray.dir*t_c;
+	return wc.Dot(wc);
+}
+
+
+/*
+=======================================================================================================================================
+DistanceSquared                                                                                                                       =
+seg - point                                                                                                                           =
+=======================================================================================================================================
+*/
+float lineseg_t::DistanceSquared( const vec3_t& point, float& t_c ) const
+{
+	vec3_t w = point - origin;
+	float proj = w.Dot(dir);
+	// endpoint 0 is closest point
+	if ( proj <= 0 )
+	{
+		t_c = 0.0f;
+		return w.Dot(w);
+	}
+	else
+	{
+		float vsq = dir.Dot(dir);
+		// endpoint 1 is closest point
+		if ( proj >= vsq )
+		{
+			t_c = 1.0f;
+			return w.Dot(w) - 2.0f*proj + vsq;
+		}
+		// otherwise somewhere else in segment
+		else
+		{
+			t_c = proj/vsq;
+			return w.Dot(w) - t_c*proj;
+		}
+	}
+}
+
+
+/*
+=======================================================================================================================================
+ClosestPoints                                                                                                                         =
+seg - seg                                                                                                                             =
+=======================================================================================================================================
+*/
+void lineseg_t::ClosestPoints( const lineseg_t& segment1, vec3_t& point0, vec3_t& point1 ) const
+{
+  // compute intermediate parameters
+  vec3_t w0 = origin - segment1.origin;
+  float a = dir.Dot( dir );
+  float b = dir.Dot( segment1.dir );
+  float c = segment1.dir.Dot( segment1.dir );
+  float d = dir.Dot( w0 );
+  float e = segment1.dir.Dot( w0 );
+
+  float denom = a*c - b*b;
+  // parameters to compute s_c, t_c
+  float s_c, t_c;
+  float sn, sd, tn, td;
+
+  // if denom is zero, try finding closest point on segment1 to origin0
+  if( ::IsZero(denom) )
+  {
+		// clamp s_c to 0
+		sd = td = c;
+		sn = 0.0f;
+		tn = e;
+  }
+  else
+  {
+		// clamp s_c within [0,1]
+		sd = td = denom;
+		sn = b*e - c*d;
+		tn = a*e - b*d;
+
+		// clamp s_c to 0
+		if(sn < 0.0f)
+		{
+			sn = 0.0f;
+			tn = e;
+			td = c;
+		}
+		// clamp s_c to 1
+		else if(sn > sd)
+		{
+			sn = sd;
+			tn = e + b;
+			td = c;
+		}
+  }
+
+  // clamp t_c within [0,1]
+  // clamp t_c to 0
+  if(tn < 0.0f)
+  {
+		t_c = 0.0f;
+		// clamp s_c to 0
+		if( -d < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if( -d > a )
+			s_c = 1.0f;
+		else
+			s_c = -d/a;
+  }
+  // clamp t_c to 1
+  else if(tn > td)
+  {
+		t_c = 1.0f;
+		// clamp s_c to 0
+		if( (-d+b) < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if( (-d+b) > a )
+			s_c = 1.0f;
+		else
+			s_c = (-d+b)/a;
+  }
+  else
+  {
+     t_c = tn/td;
+     s_c = sn/sd;
+  }
+
+  // compute closest points
+  point0 = origin + dir*s_c;
+  point1 = segment1.origin + segment1.dir*t_c;
+
+}
+
+/*
+=======================================================================================================================================
+ClosestPoints                                                                                                                         =
+seg - ray                                                                                                                             =
+=======================================================================================================================================
+*/
+void lineseg_t::ClosestPoints( const ray_t& ray, vec3_t& point0, vec3_t& point1 ) const
+{
+	// compute intermediate parameters
+	vec3_t w0 = origin - ray.origin;
+	float a = dir.Dot( dir );
+	float b = dir.Dot( ray.dir );
+	float c = ray.dir.Dot( ray.dir );
+	float d = dir.Dot( w0 );
+	float e = ray.dir.Dot( w0 );
+
+	float denom = a*c - b*b;
+	// parameters to compute s_c, t_c
+	float s_c, t_c;
+	float sn, sd, tn, td;
+
+	// if denom is zero, try finding closest point on 1 to origin0
+	if( IsZero(denom) )
+	{
+		// clamp s_c to 0
+		sd = td = c;
+		sn = 0.0f;
+		tn = e;
+	}
+	else
+	{
+		// clamp s_c within [0,1]
+		sd = td = denom;
+		sn = b*e - c*d;
+		tn = a*e - b*d;
+
+		// clamp s_c to 0
+		if( sn < 0.0f )
+		{
+			sn = 0.0f;
+			tn = e;
+			td = c;
+		}
+		// clamp s_c to 1
+		else if( sn > sd )
+		{
+			sn = sd;
+			tn = e + b;
+			td = c;
+		}
+	}
+
+	// clamp t_c within [0,+inf]
+	// clamp t_c to 0
+	if( tn < 0.0f )
+	{
+		t_c = 0.0f;
+		// clamp s_c to 0
+		if( -d < 0.0f )
+		{
+			s_c = 0.0f;
+		}
+		// clamp s_c to 1
+		else if( -d > a )
+		{
+			s_c = 1.0f;
+		}
+		else
+		{
+			s_c = -d/a;
+		}
+	}
+	else
+	{
+		t_c = tn/td;
+		s_c = sn/sd;
+	}
+
+	// compute closest points
+	point0 = origin + dir*s_c;
+	point1 = ray.origin + ray.dir*t_c;
+
+}
+
+
+/*
+=======================================================================================================================================
+ClosestPoints                                                                                                                         =
+seg - point                                                                                                                           =
+=======================================================================================================================================
+*/
+vec3_t lineseg_t::ClosestPoints( const vec3_t& point ) const
+{
+    vec3_t w = point - origin;
+    float proj = w.Dot( dir );
+    // endpoint 0 is closest point
+    if( proj <= 0.0f )
+			return origin;
+    else
+    {
+			float vsq = dir.Dot(dir);
+			// endpoint 1 is closest point
+			if( proj >= vsq )
+				return origin + dir;
+			// else somewhere else in segment
+			else
+				return origin + dir*(proj/vsq);
+    }
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+lineseg_t lineseg_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale  ) const
+{
+	lineseg_t seg;
+
+	seg.origin = origin.Transformed( translate, rotate, scale );
+	seg.dir = rotate * (dir * scale);
+
+	return seg;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void lineseg_t::Render()
+{
+	vec3_t P1 = origin+dir;
+
+	r::SetGLState_Solid();
+
+	glColor3fv( &vec3_t(1.0f, 1.0f, 1.0f )[0] );
+	glBegin( GL_LINES );
+		glVertex3fv( &origin[0] );
+		glVertex3fv( &P1[0] );
+	glEnd();
+
+
+	glPointSize( 4.0f );
+	glBegin( GL_POINTS );
+		glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+		glVertex3fv( &origin[0] );
+		glColor3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+		glVertex3fv( &P1[0] );
+	glEnd();
+
+
+	r::SetGLState_WireframeDotted();
+	glDisable( GL_DEPTH_TEST );
+	glColor3fv( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+	glBegin( GL_LINES );
+		glVertex3fv( &origin[0] );
+		glVertex3fv( &(P1)[0] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+line - any                                                                                                                            =
+=======================================================================================================================================
+*/
+bool lineseg_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+line - sphere                                                                                                                         =
+=======================================================================================================================================
+*/
+bool lineseg_t::Intersects( const bsphere_t& sphere ) const
+{
+	return sphere.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+line - aabb                                                                                                                           =
+=======================================================================================================================================
+*/
+bool lineseg_t::Intersects( const aabb_t& box ) const
+{
+	return box.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+line - obb                                                                                                                            =
+=======================================================================================================================================
+*/
+bool lineseg_t::Intersects( const obb_t& obb ) const
+{
+	return obb.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+line - any                                                                                                                            =
+=======================================================================================================================================
+*/
+bool lineseg_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+
+/**
+=======================================================================================================================================
+ray_t                                                                                                                                 =
+=======================================================================================================================================
+*/
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+ray_t ray_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	ray_t ray;
+
+	mat4_t semi_transf( rotate*scale );
+
+	ray.dir = semi_transf * dir;
+	ray.dir.Normalize();
+
+	ray.origin = semi_transf * origin;
+	ray.origin += translate;
+
+	return ray;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void ray_t::Render()
+{
+	const float dist = 100.0f;
+	glColor3fv( &vec3_t( 1.0f, 1.0f, 0.0f )[0] );
+
+	// render a dotted without depth
+	r::SetGLState_WireframeDotted();
+	glDisable( GL_DEPTH_TEST );
+
+	glBegin( GL_LINES );
+		glVertex3fv( &origin[0] );
+		glVertex3fv( &(dir*dist+origin)[0] );
+	glEnd();
+
+	glPointSize( 4.0f );
+	glBegin( GL_POINTS );
+		glVertex3fv( &origin[0] );
+	glEnd();
+
+	// render with depth
+	r::SetGLState_Solid();
+	glBegin( GL_LINES );
+		glVertex3fv( &origin[0] );
+		glVertex3fv( &(dir*dist+origin)[0] );
+	glEnd();
+
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+ray - any                                                                                                                             =
+=======================================================================================================================================
+*/
+bool ray_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+ray - sphere                                                                                                                          =
+=======================================================================================================================================
+*/
+bool ray_t::Intersects( const bsphere_t& sphere ) const
+{
+	return sphere.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+ray - aabb                                                                                                                            =
+=======================================================================================================================================
+*/
+bool ray_t::Intersects( const aabb_t& box ) const
+{
+	return box.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+ray - obb                                                                                                                             =
+=======================================================================================================================================
+*/
+bool ray_t::Intersects( const obb_t& obb ) const
+{
+	return obb.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+ray - any                                                                                                                             =
+=======================================================================================================================================
+*/
+bool ray_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/**
+=======================================================================================================================================
+plane_t                                                                                                                               =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+from plane eqtuation                                                                                                                  =
+=======================================================================================================================================
+*/
+void plane_t::Set( float a, float b, float c, float d )
+{
+	// normalize for cheap distance checks
+	float lensq = a*a + b*b + c*c;
+	// length of normal had better not be zero
+	DEBUG_ERR( IsZero( lensq ) );
+
+	// recover gracefully
+	if ( IsZero( lensq ) )
+	{
+		normal = vec3_t( 1.0, 0.0, 0.0 );
+		offset = 0.0f;
+	}
+	else
+	{
+		float recip = InvSqrt(lensq);
+		normal = vec3_t( a*recip, b*recip, c*recip );
+		offset = d*recip;
+	}
+}
+
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+from 3 points                                                                                                                         =
+=======================================================================================================================================
+*/
+void plane_t::Set( const vec3_t& p0, const vec3_t& p1, const vec3_t& p2 )
+{
+	// get plane vectors
+	vec3_t u = p1 - p0;
+	vec3_t v = p2 - p0;
+
+	normal = u.Cross(v);
+
+	// length of normal had better not be zero
+	DEBUG_ERR( IsZero( normal.LengthSquared() ) );
+
+	normal.Normalize();
+	offset = normal.Dot(p0); // ToDo: correct??
+
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+plane_t plane_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	plane_t plane;
+
+	// the normal
+	plane.normal = rotate*normal;
+
+	// the offset
+	vec3_t new_trans = rotate.Transposed() * translate;
+	plane.offset = offset*scale + new_trans.Dot( normal );
+
+	return plane;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void plane_t::Render()
+{
+	glPushMatrix();
+
+	vec3_t translate( normal*offset );
+	mat3_t rotate( quat_t( vec3_t( 0.0, 0.0, 1.0 ), normal ) );
+	mat4_t transform( translate, rotate );
+	r::MultMatrix( transform );
+
+
+	r::SetGLState_AlphaSolid();
+	glColor4fv( &vec4_t(1.0f, 1.0f, 1.0f, 0.5f)[0] );
+
+	const float size = 10.0f;
+
+	glBegin( GL_QUADS );
+		glVertex3fv( &vec3_t(size, size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(-size, size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(-size, -size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(size, -size, 0.0f)[0] );
+	glEnd();
+
+	glColor4fv( &vec4_t(1.0f, 1.0f, 1.0f, 0.2f)[0] );
+	glBegin( GL_QUADS );
+		glVertex3fv( &vec3_t(size, -size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(-size, -size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(-size, size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(size, size, 0.0f)[0] );
+	glEnd();
+
+	glPopMatrix();
+
+	r::SetGLState_Solid();
+	glDisable( GL_DEPTH_TEST );
+	glColor3fv( &vec3_t(1, 1, 0)[0] );
+	glBegin( GL_LINES );
+		glVertex3fv( &(normal*offset)[0] );
+		glVertex3fv( &(normal*(offset+1))[0] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+plane - any                                                                                                                           =
+=======================================================================================================================================
+*/
+bool plane_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+plane - any                                                                                                                           =
+=======================================================================================================================================
+*/
+bool plane_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/**
+=======================================================================================================================================
+bounding sphere                                                                                                                       =
+=======================================================================================================================================
+*/
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+from a vec3 array                                                                                                                     =
+=======================================================================================================================================
+*/
+void bsphere_t::Set( const void* pointer, uint stride, int count )
+{
+	void* tmp_pointer = (void*)pointer;
+	vec3_t min( *(vec3_t*)tmp_pointer ),
+	       max( *(vec3_t*)tmp_pointer );
+
+	// for all the vec3 calc the max and min
+	for( int i=1; i<count; i++ )
+	{
+		tmp_pointer = (char*)tmp_pointer + stride;
+
+		const vec3_t& tmp = *((vec3_t*)tmp_pointer);
+
+		for( int j=0; j<3; j++ )
+		{
+			if( tmp[j] > max[j] )
+				max[j] = tmp[j];
+			else if( tmp[j] < min[j] )
+				min[j] = tmp[j];
+		}
+	}
+
+	center = (min+max) * 0.5; // average
+
+	tmp_pointer = (void*)pointer;
+	float max_dist = (*((vec3_t*)tmp_pointer) - center).LengthSquared(); // max distance between center and the vec3 arr
+	for( int i=1; i<count; i++ )
+	{
+		tmp_pointer = (char*)tmp_pointer + stride;
+
+		const vec3_t& vertco = *((vec3_t*)tmp_pointer);
+		float dist = (vertco - center).LengthSquared();
+		if( dist > max_dist )
+			max_dist = dist;
+	}
+
+	radius = Sqrt( max_dist );
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void bsphere_t::Render()
+{
+	glPushMatrix();
+
+	glTranslatef( center.x, center.y, center.z );
+
+	glColor4fv( &vec4_t(1.0, 1.0, 1.0, 0.2)[0] );
+
+	r::SetGLState_Wireframe();
+
+	r::RenderSphere( radius, 24 );
+
+	glPopMatrix();
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+bsphere_t bsphere_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	bsphere_t ret;
+
+	ret.center = ( rotate * (center * scale) ) + translate;
+	ret.radius = radius * scale;
+	return ret;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - any                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - sphere                                                                                                                       =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const bsphere_t& other ) const
+{
+	float tmp = radius + other.radius;
+	return (center-other.center).LengthSquared() <= tmp*tmp ;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - aabb                                                                                                                         =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const aabb_t& box ) const
+{
+	return box.Intersects(*this);
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - ray                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const ray_t& ray ) const
+{
+	vec3_t w( center - ray.origin );
+	const vec3_t& v = ray.dir;
+	float proj = v.Dot( w );
+	float wsq = w.LengthSquared();
+	float rsq = radius*radius;
+
+	if( proj < 0.0 && wsq > rsq )
+		return false;
+
+	float vsq = v.LengthSquared();
+
+	return (vsq*wsq - proj*proj <= vsq*rsq);
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - segment                                                                                                                      =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const lineseg_t& segment ) const
+{
+	const vec3_t& v = segment.dir;
+	vec3_t w0 = center - segment.origin;
+	float w0dv = w0.Dot( v );
+	float rsq = radius * radius;
+
+	if( w0dv < 0.0f ) // if the ang is >90
+		return w0.LengthSquared() <= rsq;
+
+	vec3_t w1 = w0 - v; // aka center - P1, where P1 = seg.origin + seg.dir
+	float w1dv = w1.Dot( v );
+
+	if( w1dv > 0.0f ) // if the ang is <90
+		return w1.LengthSquared() <= rsq;
+
+	vec3_t tmp = w0 - ( v * (w0.Dot(v) / v.LengthSquared()) ); // the big parenthesis is the projection of w0 to v
+	return tmp.LengthSquared() <= rsq;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - obb                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const obb_t& obb ) const
+{
+	return obb.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+PlaneTest                                                                                                                             =
+=======================================================================================================================================
+*/
+float bsphere_t::PlaneTest( const plane_t& plane ) const
+{
+	float dist = plane.Test( center );
+
+	if( dist > radius )
+		return dist-radius;
+	else if( -dist > radius )
+		return dist+radius;
+	else
+		return 0.0f;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+sphere - any                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+sphere - sphere                                                                                                                       =
+=======================================================================================================================================
+*/
+bool bsphere_t::SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	normal = sphere.center - center;
+	float rsum = radius + sphere.radius;
+	float distsq = normal.LengthSquared();
+
+	if( distsq <= rsum*rsum )
+	{
+		// calc the depth
+		float dist = Sqrt( distsq );
+		depth = rsum - dist;
+
+		normal.Normalize();
+
+		impact_point = ((center + normal*radius) + (sphere.center - normal*sphere.radius)) * 0.5f;
+
+		RENDER_SEPERATION_TEST
+
+		return true;
+	}
+
+	return false;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+sphere - aabb                                                                                                                         =
+=======================================================================================================================================
+*/
+bool bsphere_t::SeperationTest( const aabb_t& box, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	UNLOCK_RENDER_SEPERATION
+	bool test = box.SeperationTest( *this, normal, impact_point, depth );
+	LOCK_RENDER_SEPERATION
+	impact_point = impact_point + (normal*depth);
+	normal = -normal;
+
+	if( test ) RENDER_SEPERATION_TEST;
+
+	return test;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+sphere - obb                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	UNLOCK_RENDER_SEPERATION
+	bool test = obb.SeperationTest( *this, normal, impact_point, depth );
+	LOCK_RENDER_SEPERATION
+
+	if( !test ) return false;
+
+	impact_point = impact_point + (normal*depth);
+	normal = -normal;
+
+	RENDER_SEPERATION_TEST;
+	return true;
+}
+
+
+/**
+=======================================================================================================================================
+axis aligned bounding box                                                                                                             =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+Calc origin and radius from a vec3 array                                                                                              =
+=======================================================================================================================================
+*/
+void aabb_t::Set( const void* pointer, uint stride, int count )
+{
+	void* tmp_pointer = (void*)pointer;
+	min = *(vec3_t*)tmp_pointer;
+	max = *(vec3_t*)tmp_pointer;
+
+	// for all the vec3 calc the max and min
+	for( int i=1; i<count; i++ )
+	{
+		tmp_pointer = (char*)tmp_pointer + stride;
+
+		vec3_t tmp( *(vec3_t*)tmp_pointer );
+
+		for( int j=0; j<3; j++ )
+		{
+			if( tmp[j] > max[j] )
+				max[j] = tmp[j];
+			else if( tmp[j] < min[j] )
+				min[j] = tmp[j];
+		}
+	}
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+aabb_t aabb_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	aabb_t aabb;
+	aabb.min = min * scale;
+	aabb.max = max * scale;
+
+	aabb.min += translate;
+	aabb.max += translate;
+	return aabb;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void aabb_t::Render()
+{
+	glPushMatrix();
+
+	vec3_t sub( max-min );
+	vec3_t center( (max+min)*0.5f );
+
+
+	glTranslatef( center.x, center.y, center.z );
+	glScalef( sub.x, sub.y, sub.z );
+
+	r::SetGLState_Wireframe();
+	glColor3fv( &vec3_t( 1.0f, 1.0f, 1.0f )[0] );
+
+	r::RenderCube();
+
+	glPopMatrix();
+
+
+	glPointSize( 4.0f );
+	glBegin( GL_POINTS );
+		glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+		glVertex3fv( &min[0] );
+		glColor3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+		glVertex3fv( &max[0] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - any                                                                                                                            =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - aabb                                                                                                                           =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const aabb_t& other ) const
+{
+	// if separated in x direction
+	if( min.x > other.max.x || other.min.x > max.x )
+		return false;
+
+	// if separated in y direction
+	if( min.y > other.max.y || other.min.y > max.y )
+		return false;
+
+	// if separated in z direction
+	if( min.z > other.max.z || other.min.z > max.z )
+		return false;
+
+	// no separation, must be intersecting
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - sphere                                                                                                                         =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const bsphere_t& sphere ) const
+{
+	const vec3_t& c = sphere.center;
+
+	// find the box's closest point to the sphere
+	vec3_t cp;
+	for( uint i=0; i<3; i++ )
+	{
+		if( c[i] > max[i] ) // if the center is greater than the max then the closest point is the max
+			cp[i] = max[i];
+		else if( c[i] < min[i]  ) // relative to the above
+			cp[i] = min[i];
+		else           // the c lies between min and max
+			cp[i] = c[i];
+	}
+
+	float rsq = sphere.radius * sphere.radius;
+	vec3_t sub = c - cp; // if the c lies totaly inside the box then the sub is the zero,
+	                     //this means that the length is also zero and thus its always smaller than rsq
+
+	if( sub.LengthSquared() <= rsq ) return true;
+
+	return false;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - ray                                                                                                                            =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const ray_t& ray ) const
+{
+	float maxS = -FLT_MAX;
+	float minT = FLT_MAX;
+
+	// do tests against three sets of planes
+	for ( int i = 0; i < 3; ++i )
+	{
+		// ray is parallel to plane
+		if ( IsZero( ray.dir[i] ) )
+		{
+			// ray passes by box
+			if ( ray.origin[i] < min[i] || ray.origin[i] > max[i] )
+				return false;
+		}
+		else
+		{
+			// compute intersection parameters and sort
+			float s = (min[i] - ray.origin[i])/ray.dir[i];
+			float t = (max[i] - ray.origin[i])/ray.dir[i];
+			if ( s > t )
+			{
+				float temp = s;
+				s = t;
+				t = temp;
+			}
+
+			// adjust min and max values
+			if ( s > maxS )
+				maxS = s;
+			if ( t < minT )
+				minT = t;
+			// check for intersection failure
+			if ( minT < 0.0f || maxS > minT )
+				return false;
+		}
+	}
+
+	// done, have intersection
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - segment                                                                                                                        =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const lineseg_t& segment ) const
+{
+	float maxS = -FLT_MAX;
+	float minT = FLT_MAX;
+
+	// do tests against three sets of planes
+	for( int i = 0; i < 3; ++i )
+	{
+		// segment is parallel to plane
+		if( IsZero( segment.dir[i] ) )
+		{
+			// segment passes by box
+			if( (segment.origin)[i] < min[i] || (segment.origin)[i] > max[i] )
+				return false;
+		}
+		else
+		{
+			// compute intersection parameters and sort
+			float s = (min[i] - segment.origin[i])/segment.dir[i];
+			float t = (max[i] - segment.origin[i])/segment.dir[i];
+			if( s > t )
+			{
+				float temp = s;
+				s = t;
+				t = temp;
+			}
+
+			// adjust min and max values
+			if( s > maxS )
+				maxS = s;
+			if( t < minT )
+				minT = t;
+			// check for intersection failure
+			if( minT < 0.0f || maxS > 1.0f || maxS > minT )
+				return false;
+		}
+	}
+
+	// done, have intersection
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - obb                                                                                                                            =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const obb_t& obb ) const
+{
+	return obb.Intersects(*this);
+}
+
+
+/*
+=======================================================================================================================================
+PlaneTest                                                                                                                             =
+=======================================================================================================================================
+*/
+float aabb_t::PlaneTest( const plane_t& plane ) const
+{
+	vec3_t diag_min, diag_max;
+	// set min/max values for x,y,z direction
+	for( int i=0; i<3; i++ )
+	{
+		if( plane.normal[i] >= 0.0f )
+		{
+			diag_min[i] = min[i];
+			diag_max[i] = max[i];
+		}
+		else
+		{
+			diag_min[i] = max[i];
+			diag_max[i] = min[i];
+		}
+	}
+
+	// minimum on positive side of plane, box on positive side
+	float test = plane.Test( diag_min );
+	if ( test > 0.0f )
+		return test;
+
+	test = plane.Test( diag_max );
+	// min on non-positive side, max on non-negative side, intersection
+	if ( test >= 0.0f )
+		return 0.0f;
+	// max on negative side, box on negative side
+	else
+		return test;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+aabb - any                                                                                                                            =
+=======================================================================================================================================
+*/
+bool aabb_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+aabb - aabb                                                                                                                           =
+=======================================================================================================================================
+*/
+bool aabb_t::SeperationTest( const aabb_t& other, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	// calculete the closest points
+	for( uint i=0; i<3; i++ ) // for 3 axis
+	{
+		if( min[i] > other.max[i] || other.min[i] > max[i] )
+			return false;
+
+		const float& Am = min[i], AM = max[i], Bm = other.min[i], BM = other.max[i];
+
+		if( Bm < Am )
+		{
+			if( BM < Am ) // B is left and outside A
+				return false;
+			else
+				if( BM < AM ) // left
+				{
+					normal[i] = Am - BM;
+					impact_point[i] = (Am+BM) * 0.5f;
+				}
+				else // B overlaps A
+				{
+					float t0 = AM-Bm, t1 = BM-Am;
+					if( t0 < t1 )
+						normal[i] = t0;
+					else
+						normal[i] = -t1;
+
+					impact_point[i] = (Am+AM) * 0.5f;
+				}
+		}
+		else
+		{
+			if( Bm > AM ) // B is right and outside A
+				return false;
+			else
+				if( BM < AM ) // B totaly inside A
+				{
+					float t0 = BM-Am, t1 = AM-Bm;
+					if( t0 < t1 )
+						normal[i] = -t0;
+					else
+						normal[i] = t1;
+
+					impact_point[i] = (Bm+BM) * 0.5f;
+				}
+				else // right
+				{
+					normal[i] = AM - Bm;
+					impact_point[i] = (AM + Bm) * 0.5f;
+				}
+		}
+
+	}
+
+	vec3_t dist( fabs(normal.x), fabs(normal.y), fabs(normal.z) );
+	if( dist.x < dist.y && dist.x < dist.z )
+		normal = vec3_t( normal.x, 0.0f, 0.0f );
+	else if( dist.y < dist.z )
+		normal = vec3_t( 0.0f, normal.y, 0.0f );
+	else
+		normal = vec3_t( 0.0f, 0.0f, normal.z );
+
+	depth = normal.Length();
+
+	normal *= 1.0f/depth; // aka normal.Normalize()
+
+	RENDER_SEPERATION_TEST
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+aabb - sphere                                                                                                                         =
+=======================================================================================================================================
+*/
+bool aabb_t::SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	const vec3_t& c = sphere.center;
+	const float r = sphere.radius;
+	vec3_t cp; // closest point of box that its closer to the sphere's center
+
+	for( int i=0; i<3; i++ )
+	{
+		if( c[i] >= max[i] ) // if the center is greater than the max then the closest point is the max
+			cp[i] = max[i];
+		else if( c[i] <= min[i]  ) // relative to the above
+			cp[i] = min[i];
+		else           // the c lies between min and max
+			cp[i] = c[i];
+	}
+
+	vec3_t sub = c - cp; // if the c lies totaly inside the box then the sub is the zero,
+	                     //this means that the length is also zero and thus its always smaller than rsq
+
+	float sublsq = sub.LengthSquared();
+	if( sublsq > r*r ) return false; // if no collision leave before its too late
+
+	if( IsZero(sublsq) ) // this means that the closest point is coincide with the center so the center is totaly inside tha box. We have to revise the calcs
+	{
+		int n_axis = 0; // the axis that the normal will be
+		float min_d = FLT_MAX; // in the end of "for" the min_d holds the min projection dist of c to every cube's facet
+		float coord = 0.0;
+		for( int i=0; i<3; i++ )
+		{
+			// dist between c and max/min in the i axis
+			float dist_c_max = max[i]-c[i];
+			float dist_c_min = c[i]-min[i];
+
+			if( dist_c_max < min_d && dist_c_max < dist_c_min )
+			{
+				min_d = dist_c_max;
+				n_axis = i;
+				coord = max[i];
+			}
+			else if( dist_c_min < min_d )
+			{
+				min_d = dist_c_min;
+				n_axis = i;
+				coord = min[i];
+			}
+		}
+
+		float dif = coord - c[n_axis];
+
+		normal.SetZero();
+		normal[n_axis] = dif / min_d; // aka ... = (dif<0.0f) ? -1.0f : 1.0f;
+
+		depth = r + min_d;
+
+		impact_point = c-(normal*r);
+	}
+	// the c is outside the box
+	else
+	{
+		normal = c - cp;
+
+		depth = r - normal.Length();
+
+		normal.Normalize();
+
+		impact_point = c-(normal*r);
+	}
+
+	RENDER_SEPERATION_TEST
+
+	return true;
+}
+
+
+/**
+=======================================================================================================================================
+object oriented bounding box                                                                                                          =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+calc from a vec3 array                                                                                                                =
+=======================================================================================================================================
+*/
+void obb_t::Set( const void* pointer, uint stride, int count )
+{
+	void* tmp_pointer = (void*)pointer;
+	vec3_t min = *(vec3_t*)tmp_pointer;
+	vec3_t max = *(vec3_t*)tmp_pointer;
+
+	// for all the vec3 calc the max and min
+	for( int i=1; i<count; i++ )
+	{
+		tmp_pointer = (char*)tmp_pointer + stride;
+
+		vec3_t tmp( *(vec3_t*)tmp_pointer );
+
+		for( int j=0; j<3; j++ ) // for x y z
+		{
+			if( tmp[j] > max[j] )
+				max[j] = tmp[j];
+			else if( tmp[j] < min[j] )
+				min[j] = tmp[j];
+		}
+	}
+
+	// set the locals
+	center = (max+min)*0.5f;
+	rotation.SetIdent();
+	extends = max-center;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void obb_t::Render()
+{
+	glPushMatrix();
+
+	glTranslatef( center.x, center.y, center.z ); // translate
+	r::MultMatrix( mat4_t(rotation) ); // rotate
+	glScalef( extends.x, extends.y, extends.z ); // scale
+
+	r::SetGLState_Wireframe();
+	glColor3fv( &vec3_t(1.0f, 1.0f, 1.0f)[0] );
+
+	r::RenderCube( false, 2.0f );
+
+	glPopMatrix();
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+obb_t obb_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	obb_t res;
+
+	res.extends = extends * scale;
+	res.center = rotate*(center*scale) + translate;
+	res.rotation = rotate * rotation;
+
+	return res;
+}
+
+
+/*
+=======================================================================================================================================
+PlaneTest                                                                                                                             =
+=======================================================================================================================================
+*/
+float obb_t::PlaneTest( const plane_t& plane ) const
+{
+	vec3_t x_normal = rotation.Transposed() * plane.normal;
+	// maximum extent in direction of plane normal
+	float r = fabs(extends.x*x_normal.x)
+					+ fabs(extends.y*x_normal.y)
+					+ fabs(extends.z*x_normal.z);
+	// signed distance between box center and plane
+	float d = plane.Test(center);
+
+	// return signed distance
+	if( fabs(d) < r )
+		return 0.0f;
+	else if( d < 0.0f )
+		return d + r;
+	else
+		return d - r;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - any                                                                                                                             =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - obb                                                                                                                             =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const obb_t& other ) const
+{
+	// extent vectors
+	const vec3_t& a = extends;
+	const vec3_t& b = other.extends;
+
+	// test factors
+	float cTest, aTest, bTest;
+	bool parallelAxes = false;
+
+	// transpose of rotation of B relative to A, i.e. (R_b^T * R_a)^T
+	mat3_t Rt = rotation.Transposed() * other.rotation;
+
+	// absolute value of relative rotation matrix
+	mat3_t Rabs;
+	for( uint i = 0; i < 3; ++i )
+	{
+		for( uint j = 0; j < 3; ++j )
+		{
+			Rabs(i,j) = fabs( Rt(i,j ) );
+			// if magnitude of dot product between axes is close to one
+			if ( Rabs(i,j) + EPSILON >= 1.0f )
+			{
+				// then box A and box B have near-parallel axes
+				parallelAxes = true;
+			}
+		}
+	}
+
+	// relative translation (in A's frame)
+	vec3_t c = rotation.Transposed()*(other.center - center);
+
+	// separating axis A0
+	cTest = fabs(c.x);
+	aTest = a.x;
+	bTest = b.x*Rabs(0,0)+b.y*Rabs(0,1)+b.z*Rabs(0,2);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A1
+	cTest = fabs(c.y);
+	aTest = a.y;
+	bTest = b.x*Rabs(1,0)+b.y*Rabs(1,1)+b.z*Rabs(1,2);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A2
+	cTest = fabs(c.z);
+	aTest = a.z;
+	bTest = b.x*Rabs(2,0)+b.y*Rabs(2,1)+b.z*Rabs(2,2);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis B0
+	cTest = fabs( c.x*Rt(0,0) + c.y*Rt(1,0) + c.z*Rt(2,0) );
+	aTest = a.x*Rabs(0,0)+a.y*Rabs(1,0)+a.z*Rabs(2,0);
+	bTest = b.x;
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis B1
+	cTest = fabs( c.x*Rt(0,1) + c.y*Rt(1,1) + c.z*Rt(2,1) );
+	aTest = a.x*Rabs(0,1)+a.y*Rabs(1,1)+a.z*Rabs(2,1);
+	bTest = b.y;
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis B2
+	cTest = fabs( c.x*Rt(0,2) + c.y*Rt(1,2) + c.z*Rt(2,2) );
+	aTest = a.x*Rabs(0,2)+a.y*Rabs(1,2)+a.z*Rabs(2,2);
+	bTest = b.z;
+	if ( cTest > aTest + bTest ) return false;
+
+	// if the two boxes have parallel axes, we're done, intersection
+	if ( parallelAxes ) return true;
+
+	// separating axis A0 x B0
+	cTest = fabs(c.z*Rt(1,0)-c.y*Rt(2,0));
+	aTest = a.y*Rabs(2,0) + a.z*Rabs(1,0);
+	bTest = b.y*Rabs(0,2) + b.z*Rabs(0,1);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A0 x B1
+	cTest = fabs(c.z*Rt(1,1)-c.y*Rt(2,1));
+	aTest = a.y*Rabs(2,1) + a.z*Rabs(1,1);
+	bTest = b.x*Rabs(0,2) + b.z*Rabs(0,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A0 x B2
+	cTest = fabs(c.z*Rt(1,2)-c.y*Rt(2,2));
+	aTest = a.y*Rabs(2,2) + a.z*Rabs(1,2);
+	bTest = b.x*Rabs(0,1) + b.y*Rabs(0,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A1 x B0
+	cTest = fabs(c.x*Rt(2,0)-c.z*Rt(0,0));
+	aTest = a.x*Rabs(2,0) + a.z*Rabs(0,0);
+	bTest = b.y*Rabs(1,2) + b.z*Rabs(1,1);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A1 x B1
+	cTest = fabs(c.x*Rt(2,1)-c.z*Rt(0,1));
+	aTest = a.x*Rabs(2,1) + a.z*Rabs(0,1);
+	bTest = b.x*Rabs(1,2) + b.z*Rabs(1,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A1 x B2
+	cTest = fabs(c.x*Rt(2,2)-c.z*Rt(0,2));
+	aTest = a.x*Rabs(2,2) + a.z*Rabs(0,2);
+	bTest = b.x*Rabs(1,1) + b.y*Rabs(1,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A2 x B0
+	cTest = fabs(c.y*Rt(0,0)-c.x*Rt(1,0));
+	aTest = a.x*Rabs(1,0) + a.y*Rabs(0,0);
+	bTest = b.y*Rabs(2,2) + b.z*Rabs(2,1);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A2 x B1
+	cTest = fabs(c.y*Rt(0,1)-c.x*Rt(1,1));
+	aTest = a.x*Rabs(1,1) + a.y*Rabs(0,1);
+	bTest = b.x*Rabs(2,2) + b.z*Rabs(2,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A2 x B2
+	cTest = fabs(c.y*Rt(0,2)-c.x*Rt(1,2));
+	aTest = a.x*Rabs(1,2) + a.y*Rabs(0,2);
+	bTest = b.x*Rabs(2,1) + b.y*Rabs(2,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// all tests failed, have intersection
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - ray                                                                                                                             =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const ray_t& ray ) const
+{
+	aabb_t aabb_( -extends, extends );
+	ray_t newray;
+	mat3_t rottrans = rotation.Transposed();
+
+	newray.origin = rottrans * ( ray.origin - center );
+	newray.dir = rottrans * ray.dir;
+
+	return aabb_.Intersects( newray );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - segment                                                                                                                         =
+ToDo: not working good                                                                                                                =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const lineseg_t& segment ) const
+{
+	float maxS = -FLT_MAX;
+	float minT = FLT_MAX;
+
+	// compute difference vector
+	vec3_t diff = center - segment.origin;
+
+	// for each axis do
+	for( int i = 0; i < 3; ++i )
+	{
+		// get axis i
+		vec3_t axis = rotation.GetColumn( i );
+
+		// project relative vector onto axis
+		float e = axis.Dot( diff );
+		float f = segment.dir.Dot( axis );
+
+		// ray is parallel to plane
+		if( IsZero( f ) )
+		{
+			// ray passes by box
+			if( -e - extends[i] > 0.0f || -e + extends[i] > 0.0f )
+				return false;
+			continue;
+		}
+
+		float s = (e - extends[i])/f;
+		float t = (e + extends[i])/f;
+
+		// fix order
+		if( s > t )
+		{
+			float temp = s;
+			s = t;
+			t = temp;
+		}
+
+		// adjust min and max values
+		if( s > maxS )
+			maxS = s;
+		if( t < minT )
+			minT = t;
+
+		// check for intersection failure
+		if( minT < 0.0f || maxS > 1.0f || maxS > minT )
+			return false;
+	}
+
+	// done, have intersection
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - sphere                                                                                                                          =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const bsphere_t& sphere ) const
+{
+	aabb_t aabb_( -extends, extends ); // aabb_ is in "this" frame
+	vec3_t new_center = rotation.Transposed() * (sphere.center - center);
+	bsphere_t sphere_( new_center, sphere.radius ); // sphere1 to "this" fame
+
+	return aabb_.Intersects( sphere_ );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - aabb                                                                                                                            =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const aabb_t& aabb ) const
+{
+	vec3_t center_ = (aabb.max + aabb.min) * 0.5f;
+	vec3_t extends_ = (aabb.max - aabb.min) * 0.5f;
+	obb_t obb_( center_, mat3_t::ident, extends_ );
+
+	return Intersects( obb_ );
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+obb - any                                                                                                                             =
+=======================================================================================================================================
+*/
+bool obb_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+obb - sphere                                                                                                                          =
+=======================================================================================================================================
+*/
+bool obb_t::SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	aabb_t aabb_( -extends, extends ); // aabb_ is in "this" frame
+	vec3_t new_center = rotation.Transposed() * (sphere.center - center);
+	bsphere_t sphere_( new_center, sphere.radius ); // sphere_ to "this" fame
+
+	UNLOCK_RENDER_SEPERATION
+	bool test = aabb_.SeperationTest( sphere_, normal, impact_point, depth );
+	LOCK_RENDER_SEPERATION
+
+	if( !test ) return false;
+
+	impact_point = (rotation*impact_point) + center;
+	normal = rotation * normal;
+
+	RENDER_SEPERATION_TEST
+
+	return true;
+}
+
+
+
+
+
+
+

+ 325 - 0
src/old_src/2009-5-11/collision.h

@@ -0,0 +1,325 @@
+#ifndef _COLLISION_H_
+#define _COLLISION_H_
+
+/*
+Info on how seperation tests work.
+We have: bvolume1.SeperationTest( bvolume2, normal, impact_point, depth );
+This expresion returns the normal, impact_point and depth of the collision between bvolume1 and bvolume2.
+The normal shows the direction we have to move bvolume2 in order to seperate the 2 volumes. The depth shows the distance we have to
+move bvolume2 for the seperation. The impact_point is a point between inside the collision area.
+*/
+
+#include <float.h>
+#include "common.h"
+#include "math.h"
+
+class lineseg_t;
+class ray_t;
+class plane_t;
+class bsphere_t;
+class aabb_t;
+class obb_t;
+
+enum
+{
+	LINE_SEG,
+	RAY,
+	PLANE,
+	BSPHERE,
+	AABB,
+	OBB,
+	BVOLUMES_NUM
+};
+
+
+/*
+=======================================================================================================================================
+bvolume_t (A)                                                                                                                         =
+=======================================================================================================================================
+*/
+class bvolume_t
+{
+	public:
+		short type;
+
+		bvolume_t( short type_ ): type(type_) {}
+
+		virtual void Render() = 0;
+
+		//if the bounding volume intersects with the plane then returns 0, else the func returns the distance. If the distance is <0 then
+		//the b.v. lies behind the plane and if >0 then in front of it
+		virtual float PlaneTest( const plane_t& plane ) const = 0;
+
+		virtual bool Intersects( const bvolume_t& bv ) const = 0;
+		virtual bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const = 0;
+};
+
+
+/*
+=======================================================================================================================================
+line segment                                                                                                                          =
+=======================================================================================================================================
+*/
+class lineseg_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t origin; // P0
+		vec3_t dir;    // P1 = origin+dir so dir = P1-origin
+
+		// constructors & distructors
+		lineseg_t(): bvolume_t(LINE_SEG) {}
+		lineseg_t( const lineseg_t& b ): bvolume_t(LINE_SEG) { (*this)=b; }
+		lineseg_t( const vec3_t& origin_, const vec3_t& dir_ ): bvolume_t(LINE_SEG) { origin=origin_; dir=dir_; }
+
+		// operators
+		lineseg_t& operator =( const lineseg_t& b ) { origin=b.origin; dir=b.dir; return (*this); }
+
+		// std funcs
+		lineseg_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const { DEBUG_ERR("N.A."); return 0.0f; };
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const { DEBUG_ERR("N.A."); return false; };
+		bool Intersects( const lineseg_t& segment ) const { DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+
+		// other funcs
+		/**
+		1) If t_c<0 then outside the line segment and close to origin. If t_c>1 again outside the line segment and closer to dir.
+		If >0 or <1 then inside the segment
+		2) When we talk about distances we calc the distance between the point|line|ray etc and the P0 OR P1. For example the dist
+		between a point and P0 or P1 depending of t_c
+		*/
+		float  LengthSquared() const { return dir.LengthSquared(); }
+		float  Length() const { return dir.Length(); }
+		float  DistanceSquared( const lineseg_t& seg, float& s_c, float& t_c ) const;   // dist with another segment
+		float  DistanceSquared( const ray_t& ray, float& s_c, float& t_c ) const;       // with a ray
+		float  DistanceSquared( const vec3_t& point, float& t_c ) const;                // with a point.
+		void   ClosestPoints( const lineseg_t& seg, vec3_t& point0, vec3_t& point1 ) const; // closest points between this and another seg
+		void   ClosestPoints( const ray_t& ray, vec3_t& point0, vec3_t& point1 ) const;     // with a ray
+		vec3_t ClosestPoints( const vec3_t& point ) const;                                  // with a poin
+};
+
+
+/*
+=======================================================================================================================================
+ray                                                                                                                                   =
+=======================================================================================================================================
+*/
+class ray_t: bvolume_t
+{
+	public:
+		// data members
+		vec3_t origin;
+		vec3_t dir;
+
+		// constructors & distructors
+		ray_t(): bvolume_t(RAY) {}
+		ray_t( const ray_t& b ): bvolume_t(RAY) { (*this)=b; }
+		ray_t( const vec3_t& origin_, const vec3_t& dir_ ): bvolume_t(RAY), origin(origin_), dir(dir_) {}
+
+		// operators
+		ray_t& operator =( const ray_t& b ) { origin=b.origin; dir=b.dir; return (*this); }
+
+		// std funcs
+		ray_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const { DEBUG_ERR("N.A."); return 0.0f; };
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const { DEBUG_ERR("N.A."); return false; };
+		bool Intersects( const lineseg_t& segment ) const { DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+
+		// other funcs
+		float  DistanceSquared( const ray_t& ray, float& s_c, float& t_c ) const;   // this and another ray
+		void   ClosestPoints( const ray_t& ray, vec3_t& point0, vec3_t& point1 ) const;   // this and another ray
+		vec3_t ClosestPoint( const vec3_t& point ) const;                                 // this and point
+};
+
+
+/*
+=======================================================================================================================================
+plane                                                                                                                                 =
+=======================================================================================================================================
+*/
+class plane_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t normal;
+		float  offset;
+
+		// constructors & distructors
+		plane_t(): bvolume_t(PLANE) {}
+		plane_t( const plane_t& b ): bvolume_t(PLANE) { (*this)=b; }
+		plane_t( const vec3_t& normal_, float offset_ ): bvolume_t(PLANE), normal(normal_), offset(offset_) {}
+		plane_t( const vec3_t& p0, const vec3_t& p1, const vec3_t& p2 ): bvolume_t(PLANE) { Set(p0,p1,p2); }
+		plane_t( float a, float b, float c, float d ): bvolume_t(PLANE) { Set(a,b,c,d); }
+
+		// operators
+		plane_t& operator =( const plane_t& b ) { normal=b.normal; offset=b.offset; return (*this); }
+
+		// std funcs
+		plane_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const { DEBUG_ERR("N.A."); return 0.0f; };
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const { DEBUG_ERR("N.A."); return false; };
+		bool Intersects( const lineseg_t& segment ) const { DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const bsphere_t& sphere ) const{ DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const aabb_t& aabb ) const { DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const obb_t& obb ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+
+		// other funcs
+		void Set( const vec3_t& p0, const vec3_t& p1, const vec3_t& p2 ); // set the plane from 3 vectors
+		void Set( float a, float b, float c, float d ); // set from plane where plane equation is ax+by+cz+d
+
+		float Test( const vec3_t& point ) const { return normal.Dot(point) - offset; } // it gives the distance between the point and plane.
+		                                                                               // if >0 then the point lies in front of the plane,
+		                                                                               // if <0 then it is behind and if =0 then it is co-planar
+		float Distance( const vec3_t& point ) const { return fabs( Test(point) ); }
+		vec3_t ClosestPoint( const vec3_t& point ) const { return point - normal*Test(point); }; // returns the perpedicular of the point in
+		                                                                                         // this plane. Plane's normal and returned-point
+		                                                                                         // are perpedicular
+};
+
+
+/*
+=======================================================================================================================================
+bounding sphere                                                                                                                       =
+=======================================================================================================================================
+*/
+class bsphere_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t center;
+		float radius;
+
+		// constructors & distractor
+		bsphere_t(): bvolume_t(BSPHERE) {}
+		bsphere_t( const bsphere_t& other ): bvolume_t(BSPHERE) { (*this) = other; }
+		bsphere_t( const vec3_t& center_, float radius_ ): bvolume_t(BSPHERE), center(center_), radius(radius_) {}
+
+		// operators
+		bsphere_t& operator =( const bsphere_t& other ) { center=other.center; radius=other.radius; return (*this); }
+
+		// std funcs
+		bsphere_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const;
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const;
+		bool Intersects( const lineseg_t& segment ) const;
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+
+		// other funcs
+		void Set( const void* pointer, uint stride, int count );
+};
+
+
+/*
+=======================================================================================================================================
+axis aligned bounding box                                                                                                             =
+=======================================================================================================================================
+*/
+class aabb_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t min;
+		vec3_t max;
+
+		// constructors & destractor
+		aabb_t(): bvolume_t(AABB) {}
+		aabb_t( const aabb_t& other ): bvolume_t(AABB) { (*this) = other; }
+		aabb_t( const vec3_t& min_, const vec3_t& max_ ): bvolume_t(AABB), min(min_), max(max_) { DEBUG_ERR( max.x<min.x || max.y<min.y || max.z<min.z ) }
+
+		// operators
+		aabb_t& operator =( const aabb_t& other ) { min=other.min; max=other.max; return (*this); }
+
+		// std funcs
+		aabb_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const;
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const;
+		bool Intersects( const lineseg_t& segment ) const;
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("ToDo") return false; };
+
+		// other funcs
+		void Set( const void* pointer, uint stride, int count ); // set from vec3 array
+};
+
+
+/*
+=======================================================================================================================================
+object oriented bounding box                                                                                                          =
+=======================================================================================================================================
+*/
+class obb_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t center;
+		mat3_t rotation;
+		vec3_t extends;
+
+		// constructors & destractor
+		obb_t(): bvolume_t(OBB) {}
+		obb_t( const obb_t& other ): bvolume_t(OBB) { (*this)=other; }
+		obb_t( const vec3_t& c_, const mat3_t& r_, const vec3_t& e_ ): bvolume_t(OBB) { center=c_; rotation=r_; extends=e_; }
+
+		// operators
+		obb_t& operator =( const obb_t& other ) { center=other.center; rotation=other.rotation; extends=other.extends; return (*this); }
+
+		// std funcs
+		obb_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void  Render();
+		float PlaneTest( const plane_t& plane ) const;
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const;
+		bool Intersects( const lineseg_t& segment ) const;
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("ToDo") return false; };
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("ToDo") return false; };
+
+		// other funcs
+		void Set( const void* pointer, uint stride, int count ); // set from vec3 array
+};
+
+
+#endif

+ 110 - 0
src/old_src/2009-5-11/common.cpp

@@ -0,0 +1,110 @@
+#include "common.h"
+
+/*
+=======================================================================================================================================
+RandRange                                                                                                                             =
+=======================================================================================================================================
+*/
+int RandRange( int min, int max )
+{
+	return (rand() % (max-min+1)) + min ;
+}
+
+
+float RandRange( float min, float max )
+{
+	double d = max - min; // difference
+	if( d==0.0 ) return min;
+	// diferrense = mant * e^exp
+	int exp;
+	double mant = frexp( d, &exp );
+
+	int precision = 1000; // more accurate
+
+	mant *= precision;
+	double new_mant = rand() % (int)mant;
+	new_mant /= precision;
+
+	return min + (float)ldexp( new_mant, exp ); // return min + (new_mant * e^exp)
+}
+
+
+/*
+=======================================================================================================================================
+ReadFile                                                                                                                              =
+=======================================================================================================================================
+*/
+char* ReadFile( const char* filename )
+{
+	fstream file( filename, ios::in | ios::ate );
+  if ( !file.is_open() )
+  {
+		ERROR( "Canot open file " << filename );
+		return NULL;
+  }
+  char* memblock;
+  int size;
+	size = file.tellg();
+	memblock = new char [size+1];
+	file.seekg( 0, ios::beg );
+	file.read( memblock, size );
+	memblock[size] = '\0';
+	file.close();
+	return memblock;
+}
+
+
+/*
+=======================================================================================================================================
+CutPath                                                                                                                               =
+used only to cut the path from __FILE__ and return the actual file name                                                               =
+=======================================================================================================================================
+*/
+char* CutPath( const char* path )
+{
+	char* str = (char*)path + strlen(path) - 1;
+	for(;;)
+	{
+		if( (str-path)<=-1 || *str=='/' || *str=='\\'  )  break;
+		str--;
+	}
+	return str+1;
+}
+
+
+/*
+=======================================================================================================================================
+Benchmark stuff                                                                                                                       =
+=======================================================================================================================================
+*/
+clock_t bench_ms = 0;
+
+void StartBench()
+{
+	if( bench_ms )
+		ERROR( "Bench is allready running" );
+
+	bench_ms = clock();
+}
+
+clock_t StopBench()
+{
+	clock_t t = clock() - bench_ms;
+	bench_ms = 0;
+	return t/1000;
+}
+
+
+/*
+=======================================================================================================================================
+HudPrintMemInfo                                                                                                                       =
+=======================================================================================================================================
+*/
+void HudPrintMemInfo()
+{
+	/*hud::Printf( "==== Mem ===\n" );
+	hud::Printf( "Buffer:\nfree:%ldb total:%ldb\n", mem::free_size, mem::buffer_size );
+	hud::Printf( "Calls count:\n" );
+	hud::Printf( "m:%ld c:%ld r:%ld\nf:%ld n:%ld d:%ld\n", mem::malloc_called_num, mem::calloc_called_num, mem::realloc_called_num, mem::free_called_num, mem::new_called_num, mem::delete_called_num );*/
+}
+

+ 100 - 0
src/old_src/2009-5-11/common.h

@@ -0,0 +1,100 @@
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdio.h>
+#include <iostream>
+#include <iomanip>
+#include <time.h>
+#include <fstream>
+#include <math.h>
+#include <vector>
+#include "memory.h"
+
+using namespace std;
+
+/*
+=======================================================================================================================================
+misc types                                                                                                                            =
+=======================================================================================================================================
+*/
+#ifndef uint
+typedef unsigned int uint;
+#endif
+
+#ifndef ushort
+typedef unsigned short int ushort;
+#endif
+
+#ifndef ulong
+typedef unsigned long int ulong;
+#endif
+
+
+/*
+=======================================================================================================================================
+misc funcs                                                                                                                            =
+=======================================================================================================================================
+*/
+extern int   RandRange( int min, int max );
+extern float RandRange( float min, float max );
+extern char* ReadFile( const char* filename );
+extern char* CutPath( const char* path );
+extern void  StartBench();
+extern clock_t StopBench();
+
+
+/*
+=======================================================================================================================================
+MACROS                                                                                                                                =
+=======================================================================================================================================
+*/
+
+#define __FILENAME__ CutPath( __FILE__ )
+
+// General error macro
+#define GENERAL_ERR( x, y ) \
+	{cout << "-->" << x << " (" << __FILENAME__ << ":" << __LINE__ << " " << __FUNCTION__ << "): " << y << endl;} \
+
+// ERROR
+// in ERROR you can write something like this: ERROR( "tralala" << 10 << ' ' )
+#define ERROR( x ) GENERAL_ERR( "ERROR", x )
+
+// WARNING
+#define WARNING( x ) GENERAL_ERR( "WARNING", x );
+
+// FATAL ERROR
+#define FATAL( x ) { GENERAL_ERR( "FATAL", x << ". Bye!" ); exit( EXIT_FAILURE ); };
+
+// INFO
+#define INFO( x ) GENERAL_ERR( "INFO", x );
+
+// DEBUG_ERR
+#ifdef _DEBUG
+	#define DEBUG_ERR( x ) \
+		if( x ) { \
+			GENERAL_ERR( "DEBUG_ERR", "See file" ); \
+		}
+#else
+	#define DEBUG_ERR( x )
+#endif
+
+// code that executes on debug
+#ifdef _DEBUG
+	#define DEBUG_CODE( x ) {x}
+#else
+	#define DEBUG_CODE( x ) {}
+#endif
+
+
+/*
+=======================================================================================================================================
+MemZero                                                                                                                               =
+=======================================================================================================================================
+*/
+template <typename type_t> inline void MemZero( type_t* t )
+{
+	memset( t, 0, sizeof(type_t) );
+}
+
+
+#endif

+ 63 - 0
src/old_src/2009-5-11/engine_class.h

@@ -0,0 +1,63 @@
+#ifndef _ENGINE_CLASS_H_
+#define _ENGINE_CLASS_H_
+
+#include "common.h"
+
+
+// class with name
+class nc_t
+{
+	protected:
+		char* name;
+
+	public:
+		 nc_t(): name(NULL) {}
+		~nc_t() { if(name) free(name); }
+
+		void SetName( const char* name_ )
+		{
+			DEBUG_ERR( name != NULL );
+			name = (char*)malloc( (strlen(name_) + 1) * sizeof(char) );
+			strcpy( name, name_ );
+
+			if( strlen(name) > 20 )
+				WARNING( "Big name for: \"" << name << '\"' );
+		}
+
+		const char* GetName() const { return name; }
+};
+
+
+// engine class
+class engine_class_t: public nc_t
+{
+	protected:
+		uint id;
+
+	public:
+		 engine_class_t() {}
+		~engine_class_t() {}
+
+		uint GetID() const { return id; }
+		void SetID( uint id_ ) { id = id_; }
+};
+
+
+// data_class_t
+class data_class_t: public engine_class_t
+{
+	public:
+		uint users_num;
+
+		 data_class_t(): users_num(0) {}
+		~data_class_t() {}
+};
+
+
+// runtime_class_t
+class runtime_class_t: public engine_class_t
+{};
+
+
+
+#endif

+ 463 - 0
src/old_src/2009-5-11/geometry.cpp

@@ -0,0 +1,463 @@
+#include "geometry.h"
+#include "renderer.h"
+
+/*
+=================================================================================================================================================================
+Load                                                                                                                                                            =
+=================================================================================================================================================================
+*/
+bool mesh_data_t::Load( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str[400];
+	uint i, num;
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return 0;
+	}
+
+	// material. ToDo: add proper code
+	file >> str >> str;
+
+	// verts
+	file >> str >> num;
+	verts.resize( num );
+
+	for( i=0; i< verts.size(); i++ )
+	{
+		file >> str >> str >> str >> verts[i].coords.x >> verts[i].coords.y >> verts[i].coords.z;
+	}
+
+	// tris
+	file >> str >> num;
+	tris.resize( num );
+
+	for( i=0; i<tris.size(); i++ )
+	{
+		file >> str >> str >> str >> tris[i].vert_ids[0] >> tris[i].vert_ids[1] >> tris[i].vert_ids[2];
+	}
+
+	// uvs
+	file >> str >> num;
+	uvs.resize( num );
+
+	for( i=0; i<uvs.size(); i++ )
+	{
+		file >> str >> str >> str >> uvs[i].x >> uvs[i].y;
+	}
+
+	CalcAllNormals();
+
+	face_tangents.resize( tris.size() );
+	vert_tangents.resize( verts.size() );
+	face_bitangents.resize( tris.size() );
+	vert_bitangents.resize( verts.size() );
+	CalcAllTangents();
+
+	// populate vert list
+	vert_list.resize( tris.size() * 3 );
+	for( i=0; i<tris.size(); i++ )
+	{
+		vert_list[i*3+0] = tris[i].vert_ids[0];
+		vert_list[i*3+1] = tris[i].vert_ids[1];
+		vert_list[i*3+2] = tris[i].vert_ids[2];
+	}
+
+	file.close();
+
+	return 1;
+}
+
+
+/*
+=================================================================================================================================================================================
+CalcFaceNormals                                                                                                                                                 =
+=================================================================================================================================================================
+*/
+void mesh_data_t::CalcFaceNormals()
+{
+	for( uint i=0; i<tris.size(); i++ )
+	{
+		triangle_t& tri = tris[i];
+		const vec3_t& v0 = verts[ tri.vert_ids[0] ].coords;
+		const vec3_t& v1 = verts[ tri.vert_ids[1] ].coords;
+		const vec3_t& v2 = verts[ tri.vert_ids[2] ].coords;
+
+		tri.normal = ( v1 - v0 ).Cross( v2 - v0 );
+
+		tri.normal.Normalize();
+	}
+}
+
+
+/*
+=================================================================================================================================================================
+CalcVertNormals                                                                                                                                                 =
+=================================================================================================================================================================
+*/
+void mesh_data_t::CalcVertNormals()
+{
+	for( uint i=0; i<verts.size(); i++ )
+		verts[i].normal.SetZero();
+
+	for( uint i=0; i<tris.size(); i++ )
+	{
+		triangle_t& tri = tris[i];
+		verts[ tri.vert_ids[0] ].normal += tri.normal;
+		verts[ tri.vert_ids[1] ].normal += tri.normal;
+		verts[ tri.vert_ids[2] ].normal += tri.normal;
+	}
+
+	for( uint i=0; i<verts.size(); i++ )
+		verts[i].normal.Normalize();
+}
+
+
+
+/*
+=================================================================================================================================================================================
+CalcFaceTangents                                                                                                                                                =
+=================================================================================================================================================================
+*/
+void mesh_data_t::CalcFaceTangents()
+{
+//	for( int i=0; i<tris.size(); i++ )
+//	{
+//		const triangle_t& tri = tris[i];
+//		const int vi0 = tri.vert_ids[0];
+//		const int vi1 = tri.vert_ids[1];
+//		const int vi2 = tri.vert_ids[2];
+//		const vec3_t& v0 = verts[ vi0 ].coords;
+//		const vec3_t& v1 = verts[ vi1 ].coords;
+//		const vec3_t& v2 = verts[ vi2 ].coords;
+//		vec3_t edge01 = v1 - v0;
+//		vec3_t edge02 = v2 - v0;
+//		vec2_t uvedge01 = uvs[vi1] - uvs[vi0];
+//		vec2_t uvedge02 = uvs[vi2] - uvs[vi0];
+//
+//		float det = (uvedge01.y * uvedge02.x) - (uvedge01.x * uvedge02.y);
+//		DEBUG_ERR( IsZero(det) );
+//		det = 1.0f / det;
+//
+//		vec3_t t = ( edge01 * -uvedge02.y + edge02 * uvedge01.y ) * det;
+//		vec3_t b = ( edge01 * -uvedge02.x + edge02 * uvedge01.x ) * det;
+//		t.Normalize();
+//		b.Normalize();
+//
+//		vec3_t bitangent( tri.normal * t );
+//    float handedness = ( bitangent.Dot( b ) < 0.0f) ? -1.0f : 1.0f;
+//
+//		face_tangents[i] = vec4_t( t.x, t.y, t.z, handedness );
+//
+//	}
+
+
+	for( uint i=0; i<tris.size(); i++ )
+	{
+		const triangle_t& tri = tris[i];
+		const int vi0 = tri.vert_ids[0];
+		const int vi1 = tri.vert_ids[1];
+		const int vi2 = tri.vert_ids[2];
+		const vec3_t& v0 = verts[ vi0 ].coords;
+		const vec3_t& v1 = verts[ vi1 ].coords;
+		const vec3_t& v2 = verts[ vi2 ].coords;
+		vec3_t edge01 = v1 - v0;
+		vec3_t edge02 = v2 - v0;
+		vec2_t uvedge01 = uvs[vi1] - uvs[vi0];
+		vec2_t uvedge02 = uvs[vi2] - uvs[vi0];
+
+
+		float det = (uvedge01.y * uvedge02.x) - (uvedge01.x * uvedge02.y);
+		DEBUG_ERR( IsZero(det) );
+		det = 1.0f / det;
+
+		vec3_t t = ( edge02 * uvedge01.y - edge01 * uvedge02.y ) * det;
+		vec3_t b = ( edge02 * uvedge01.x - edge01 * uvedge02.x ) * det;
+
+		t.Normalize();
+		b.Normalize();
+
+		face_tangents[i] = t;
+		face_bitangents[i] = b;
+
+	}
+
+}
+
+
+/*
+=================================================================================================================================================================================
+CalcVertTangents                                                                                                                                                =
+=================================================================================================================================================================
+*/
+void mesh_data_t::CalcVertTangents()
+{
+	for( uint i=0; i<vert_tangents.size(); i++ )
+		vert_tangents[i].SetZero();
+
+	for( uint i=0; i<tris.size(); i++ )
+	{
+		const vec3_t& ft = face_tangents[i];
+		const vec3_t& fb = face_bitangents[i];
+		const triangle_t& tri = tris[i];
+
+		vert_tangents[ tri.vert_ids[0] ] += ft;
+		vert_tangents[ tri.vert_ids[1] ] += ft;
+		vert_tangents[ tri.vert_ids[2] ] += ft;
+
+		vert_bitangents[ tri.vert_ids[0] ] += fb;
+		vert_bitangents[ tri.vert_ids[1] ] += fb;
+		vert_bitangents[ tri.vert_ids[2] ] += fb;
+	}
+
+	for( uint i=0; i<vert_tangents.size(); i++ )
+	{
+		vert_tangents[i].Normalize();
+		vert_bitangents[i].Normalize();
+	}
+
+//    vec3_t* tan1 = new vec3_t[verts.size() * 2];
+//    vec3_t* tan2 = tan1 + verts.size();
+//    memset( tan1, 0, verts.size() * 2 * sizeof(vec3_t) );
+//
+//    for (long a = 0; a < tris.size(); a++)
+//    {
+//			triangle_t* triangle = &tris[a];
+//			long i1 = triangle->vert_ids[0];
+//			long i2 = triangle->vert_ids[1];
+//			long i3 = triangle->vert_ids[2];
+//
+//			const vec3_t& v1 = verts[i1].coords;
+//			const vec3_t& v2 = verts[i2].coords;
+//			const vec3_t& v3 = verts[i3].coords;
+//
+//			const vec2_t& w1 = uvs[i1];
+//			const vec2_t& w2 = uvs[i2];
+//			const vec2_t& w3 = uvs[i3];
+//
+//			float x1 = v2.x - v1.x;
+//			float x2 = v3.x - v1.x;
+//			float y1 = v2.y - v1.y;
+//			float y2 = v3.y - v1.y;
+//			float z1 = v2.z - v1.z;
+//			float z2 = v3.z - v1.z;
+//
+//			float s1 = w2.x - w1.x;
+//			float s2 = w3.x - w1.x;
+//			float t1 = w2.y - w1.y;
+//			float t2 = w3.y - w1.y;
+//
+//			float r = 1.0F / (s1 * t2 - s2 * t1);
+//			vec3_t sdir( (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
+//							(t2 * z1 - t1 * z2) * r);
+//			vec3_t tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
+//							(s1 * z2 - s2 * z1) * r);
+//
+//			tan1[i1] += sdir;
+//			tan1[i2] += sdir;
+//			tan1[i3] += sdir;
+//
+//			tan2[i1] += tdir;
+//			tan2[i2] += tdir;
+//			tan2[i3] += tdir;
+//
+//    }
+//
+//    for (long a = 0; a < verts.size(); a++)
+//    {
+//        const vec3_t& n = verts[a].normal;
+//        const vec3_t& t = tan1[a];
+//
+//        // Gram-Schmidt orthogonalize
+//        vert_tangents[a] = vec4_t(
+//					( (t - n) * n.Dot(t)).Normalized(),
+//					( (n*t).Dot( tan2[a] ) < 0.0F) ? -1.0F : 1.0F // handedness
+//				);
+//    }
+//
+//    delete[] tan1;
+}
+
+
+/*
+=================================================================================================================================================================
+Render                                                                                                                                                          =
+=================================================================================================================================================================
+*/
+void mesh_t::Render()
+{
+	glPushMatrix();
+	r::MultMatrix( world_transformation );
+
+	glPolygonMode( GL_FRONT, GL_FILL );
+	glEnable( GL_DEPTH_TEST );
+	glDisable( GL_BLEND );
+	glDisable( GL_TEXTURE_2D );
+
+
+	// render with vert arrays
+	//extern shader_prog_t shaderp;
+	//GLuint loc = shaderp.GetAttrLocation( "tangent" );
+
+	glEnableClientState( GL_VERTEX_ARRAY );
+	glEnableClientState( GL_NORMAL_ARRAY );
+	glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+	//glEnableVertexAttribArray( loc );
+
+	glVertexPointer( 3, GL_FLOAT, sizeof(vertex_t), &mesh_data->verts[0].coords[0] );
+	glNormalPointer( GL_FLOAT, sizeof(vertex_t), &mesh_data->verts[0].normal[0] );
+	glTexCoordPointer( 2, GL_FLOAT, 0, &mesh_data->uvs[0] );
+	//glVertexAttribPointer( loc, 4, GL_FLOAT, 0, 0, &mesh_data->vert_tangents[0] );
+
+	glDrawElements( GL_TRIANGLES, mesh_data->vert_list.size(), GL_UNSIGNED_INT, &mesh_data->vert_list[0] );
+
+	glDisableClientState( GL_VERTEX_ARRAY );
+	glDisableClientState( GL_NORMAL_ARRAY );
+	glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+	//glDisableVertexAttribArray( loc );
+
+
+	// render
+	/*extern shader_prog_t shaderp;
+	GLuint loc = shaderp.GetAttrLocation( "tangent" );
+	GLuint loc1 = shaderp.GetAttrLocation( "bitangent" ); LALA*/
+
+//	glBegin( GL_TRIANGLES );
+//		for( i=0; i<mesh_data->tris.size(); i++ )
+//		{
+//			triangle_t& tri = mesh_data->tris[i];
+//
+//			//glNormal3fv( &tri.normal[0] );
+//			/*glVertexAttrib3fv( loc, &mesh_data->face_tangents[ i ][0] );
+//			glVertexAttrib3fv( loc1, &mesh_data->face_bitangents[ i ][0] ); LALA*/
+//
+//			for( j=0; j<3; j++ )
+//			{
+//				const int vert_id = tri.vert_ids[j];
+//				vertex_t& vert = mesh_data->verts[ vert_id ];
+//
+//				//glVertexAttrib3fv( loc, &mesh_data->vert_tangents[ vert_id ][0] );
+//				//glVertexAttrib3fv( loc1, &mesh_data->vert_bitangents[ vert_id ][0] );
+//				glNormal3fv( &vert.normal[0] );
+//				glTexCoord2fv( &mesh_data->uvs[vert_id][0] );
+//				glVertex3fv( &vert.coords[0] );
+//			}
+//		}
+//	glEnd();
+
+
+
+
+
+
+
+
+//
+//	r::SetGLState_Wireframe();
+//	glColor3fv( &vec3_t(1.0, 1.0, 0.0)[0] );
+//	glBegin( GL_TRIANGLES );
+//		for( i=0; i<mesh_data->tris.size(); i++ )
+//		{
+//			triangle_t& tri = mesh_data->tris[i];
+//
+//			for( j=0; j<3; j++ )
+//			{
+//				const int vert_id = tri.vert_ids[j];
+//				vertex_t& vert = mesh_data->verts[ vert_id ];
+//				glVertex3fv( &vert.coords[0] );
+//			}
+//		}
+//	glEnd();
+
+
+
+	// tri normals
+	if( 0 )
+	{
+		r::SetGLState_Solid();
+
+		glBegin( GL_LINES );
+			for( int i=0; i<mesh_data->tris.size(); i++ )
+			{
+				const triangle_t& tri = mesh_data->tris[i];
+
+				vec3_t middle = mesh_data->verts[ tri.vert_ids[0] ].coords;
+				middle = ( middle + mesh_data->verts[ tri.vert_ids[1] ].coords ) / 2.0f;
+				middle = ( middle + mesh_data->verts[ tri.vert_ids[2] ].coords ) / 2.0f;
+
+				vec3_t vec2 = (tri.normal * 0.1) + middle;
+
+				glColor3fv( &vec3_t( 0.0, 0.0, 1.0 )[0] );
+				glVertex3fv( &middle[0] );
+				glVertex3fv( &vec2[0] );
+
+				vec2 = vec3_t(mesh_data->face_tangents[i] * 0.1) + middle;
+				glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+				glVertex3fv( &middle[0] );
+				glVertex3fv( &vec2[0] );
+
+				vec2 = vec3_t(mesh_data->face_bitangents[i] * 0.1) + middle;
+				glColor3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+				glVertex3fv( &middle[0] );
+				glVertex3fv( &vec2[0] );
+			}
+		glEnd();
+	}
+
+
+	// vert normals
+	if( 0 )
+	{
+		r::NoShaders();
+		glColor3f( 0.0, 0.0, 1.0 );
+		glDisable( GL_LIGHTING );
+		glDisable( GL_TEXTURE_2D );
+
+		glBegin( GL_LINES );
+			for( int i=0; i<mesh_data->tris.size(); i++ )
+			{
+				triangle_t* tri = &mesh_data->tris[i];
+				for( int j=0; j<3; j++ )
+				{
+					vertex_t* vert = &mesh_data->verts[tri->vert_ids[j]];
+
+					vec3_t vec0;
+					vec0 = (vert->normal * 0.1f) + vert->coords;
+
+					glVertex3fv( &vert->coords[0] );
+					glVertex3fv( &vec0[0] );
+				}
+			}
+		glEnd();
+	}
+
+	// render axis
+	if( 0 ) RenderAxis();
+
+	glPopMatrix();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 54 - 0
src/old_src/2009-5-11/geometry.h

@@ -0,0 +1,54 @@
+#ifndef _GEOMETRY_H_
+#define _GEOMETRY_H_
+
+#include <iostream>
+#include <fstream>
+#include "common.h"
+#include "shaders.h"
+#include "math.h"
+#include "primitives.h"
+#include "engine_class.h"
+
+class mesh_data_t: public data_class_t
+{
+	public:
+		vector<vertex_t>   verts;
+		vector<triangle_t> tris;
+		vector<vec2_t>     uvs; // one for every vert so we can use vert arrays
+
+		vector<vec3_t>     face_tangents;
+		vector<vec3_t>     vert_tangents;
+		vector<vec3_t>     face_bitangents;
+		vector<vec3_t>     vert_bitangents;
+
+		vector<uint>       vert_list; // for vertex arrays
+
+		mesh_data_t() {}
+		~mesh_data_t() {}
+
+		bool Load( const char* filename );
+		void Unload() { verts.clear(); tris.clear(); uvs.clear(); face_tangents.clear(); vert_tangents.clear(); vert_list.clear(); }
+		void CalcFaceNormals();
+		void CalcVertNormals();
+		void CalcAllNormals() { CalcFaceNormals(); CalcVertNormals(); }
+		void CalcFaceTangents();
+		void CalcVertTangents();
+		void CalcAllTangents() { CalcFaceTangents(); CalcVertTangents(); }
+};
+
+
+// mesh
+class mesh_runtime_class_t: public runtime_class_t {}; // for ambiguity reasons
+
+class mesh_t: public object_t, public mesh_runtime_class_t
+{
+	protected:
+		mesh_data_t* mesh_data;
+
+	public:
+		void Init( mesh_data_t* meshd ) { mesh_data = meshd; }
+		void Render();
+};
+
+
+#endif

+ 71 - 0
src/old_src/2009-5-11/handlers.cpp

@@ -0,0 +1,71 @@
+#include "handlers.h"
+
+namespace hndl { // begin of namespace
+
+
+SDL_Surface* main_surf;
+SDL_Surface* icon_image;
+
+uint timer_tick = 25; // in ms
+
+
+// InitWindow
+void InitWindow( int w, int h, const char* window_caption )
+{
+	SDL_Init( SDL_INIT_VIDEO );
+	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+	// the icon
+	icon_image = SDL_LoadBMP("gfx/icon.bmp");
+	Uint32 colorkey = SDL_MapRGB( icon_image->format, 255, 0, 255 );
+	SDL_SetColorKey( icon_image, SDL_SRCCOLORKEY, colorkey );
+	SDL_WM_SetIcon( icon_image, NULL );
+
+	main_surf = SDL_SetVideoMode( w, h, 24, SDL_HWSURFACE | SDL_OPENGL );
+
+	// move the window
+#ifdef WIN32
+	SDL_SysWMinfo i;
+	SDL_VERSION( &i.version );
+	if( SDL_GetWMInfo(&i) )
+	{
+		HWND hwnd = i.window;
+		SetWindowPos( hwnd, HWND_TOP, 10, 25, w, h, NULL );
+	}
+#endif
+
+	SDL_WM_SetCaption( window_caption, NULL );
+}
+
+
+// TogleFullScreen
+void TogleFullScreen()
+{
+	SDL_WM_ToggleFullScreen( main_surf );
+}
+
+
+// QuitApp
+void QuitApp( int code )
+{
+	SDL_FreeSurface( main_surf );
+	SDL_Quit();
+	//mem_PrintInfo( MEM_PRINT_ALL );
+	exit(code);
+}
+
+
+// WaitForNextTick
+void WaitForNextFrame()
+{
+	static uint nextTime = SDL_GetTicks();
+
+	uint now = SDL_GetTicks();
+	if( nextTime > now )
+		SDL_Delay(nextTime - now);
+
+	nextTime += timer_tick;
+}
+
+
+} // end of namespace

+ 27 - 0
src/old_src/2009-5-11/handlers.h

@@ -0,0 +1,27 @@
+#ifndef _HANDLERS_H_
+#define _HANDLERS_H_
+
+#include <SDL.h>
+#include <SDL_syswm.h>
+#include "common.h"
+#include "input.h"
+#include "renderer.h"
+
+namespace hndl {
+
+
+extern uint timer_tick;
+
+extern void InitWindow( int w, int h, const char* window_caption  );
+extern void QuitApp( int code );
+extern void WaitForNextFrame();
+extern void TogleFullScreen();
+
+inline uint GetTicks()
+{
+	return SDL_GetTicks();
+}
+
+
+} // end namespace
+#endif

+ 235 - 0
src/old_src/2009-5-11/hud.cpp

@@ -0,0 +1,235 @@
+#include "hud.h"
+#include "renderer.h"
+#include "texture.h"
+
+namespace hud {
+
+
+/*
+=======================================================================================================================================
+data members                                                                                                                          =
+=======================================================================================================================================
+*/
+static texture_t* font_map;
+
+static shader_prog_t* shader;
+
+static float  initial_x;
+static float  font_w;
+static float  font_h;
+static float  color[4];
+static bool   italic;
+static float  crnt_x;
+static float  crnt_y;
+
+
+
+/*
+=======================================================================================================================================
+static funcs                                                                                                                          =
+=======================================================================================================================================
+*/
+
+
+// SetGL
+static void SetGL()
+{
+	shader->Bind();
+	font_map->BindToTxtrUnit(0); // bind the font_map to the first texture unit and...
+	glUniform1i( shader->uniform_locations[0], 0 ); // ...inform the shader that the the font_map uniform is 0 aka to first texture unit
+
+	glEnable( GL_BLEND );
+	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+	glDisable( GL_LIGHTING );
+	glDisable( GL_DEPTH_TEST );
+	glColor4fv( color );
+	glPolygonMode( GL_FRONT, GL_FILL );
+
+	// matrix stuff
+	glMatrixMode( GL_TEXTURE );
+	glPushMatrix();
+	glLoadIdentity();
+
+	glMatrixMode( GL_PROJECTION );
+	glPushMatrix();
+	glLoadIdentity();
+	glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
+
+	glMatrixMode( GL_MODELVIEW );
+	glPushMatrix();
+	glLoadIdentity();
+
+}
+
+
+// RestoreGL
+static void RestoreGL()
+{
+	glPopMatrix();
+	glMatrixMode( GL_PROJECTION );
+	glPopMatrix();
+	glMatrixMode( GL_TEXTURE );
+	glPopMatrix();
+}
+
+
+// DrawChar
+static void DrawChar( char c )
+{
+	// first check for special chars
+	if( c=='\n' ) // new line
+	{
+		//glTranslatef( initial_x, -font_h, 0.0f );
+		crnt_x = initial_x;
+		crnt_y -= font_h;
+		return;
+	}
+	if( c=='\t' ) // tab
+	{
+		DrawChar( ' ' );
+		DrawChar( ' ' );
+		return;
+	}
+	if( c<' ' || c>'~' ) // out of range
+	{
+		c = '~'+1;
+	}
+
+	const int chars_per_line = 16; // the chars that font_map.tga has per line
+	const int lines_num       = 8; // the lines of chars in font_map.tga
+
+	// the uvs
+	float char_width = 1.0f/float(chars_per_line);
+	float char_height = 1.0f/float(lines_num);
+	float uv_top = float(lines_num - (c-' ')/chars_per_line) / float(lines_num);
+	float uv_left = float( (c-' ')%chars_per_line ) / float(chars_per_line);
+	float uv_right = uv_left + char_width;
+	float uv_bottom = uv_top - char_height;
+	float uvs[4][2] = { {uv_left, uv_top}, {uv_left, uv_bottom}, {uv_right, uv_bottom}, {uv_right, uv_top} };
+
+	// the coords
+	float fwh = font_w/2.0f;
+	float fhh = font_h/2.0f;
+	float coords[4][2] = { {-fwh, fhh}, {-fwh, -fhh}, {fwh, -fhh}, {fwh, fhh} }; // fron top left counterclockwise
+
+
+	if( italic )
+	{
+		coords[0][0] += font_w/5.0f;
+		coords[3][0] += font_w/5.0f;
+	}
+
+	glBegin(GL_QUADS);
+		glTexCoord2fv( uvs[0] );  // top left
+		glVertex2fv( coords[0] );
+		glTexCoord2fv( uvs[1] );  // bottom left
+		glVertex2fv( coords[1] );
+		glTexCoord2fv( uvs[2] );  // botton right
+		glVertex2fv( coords[2] );
+		glTexCoord2fv( uvs[3] );  // top right
+		glVertex2fv( coords[3] );
+	glEnd();
+
+	// draw outline
+	/*if( 1 )
+	glDisable( GL_TEXTURE_2D );
+	glColor3f( 0.0, 0.0, 1.0 );
+	glBegin(GL_LINES);
+		glVertex2fv( coords[0] );
+		glVertex2fv( coords[1] );
+		glVertex2fv( coords[2] );
+		glVertex2fv( coords[3] );
+	glEnd();
+	glEnable( GL_TEXTURE_2D );*/
+	// end draw outline
+
+	crnt_x += font_w*0.8f;
+	//glTranslatef( font_w*0.8f, 0.0, 0.0 ); // font_w*(float) to remove the space
+}
+
+
+/*
+=======================================================================================================================================
+non static funcs                                                                                                                      =
+=======================================================================================================================================
+*/
+
+
+// Init
+// exec after init SDL
+void Init()
+{
+	font_map = ass::LoadTxtr( "gfx/fontmapa.tga" );
+	font_map->TexParameter( GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+	font_map->TexParameter( GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+	shader = ass::LoadShdr( "shaders/txt.shdr" );
+	SetPos( 0.0f, 0.0f );
+	SetFontWidth( 0.05f );
+	SetColor( vec4_t(1.0f, 1.0f, 1.0f, 1.0f) );
+	italic = false;
+}
+
+
+// SetFontWidth
+// sets font width from the given param and the height fron the aspect ratio
+void SetFontWidth( float w_ )
+{
+	// width
+	font_w = w_;
+	// height
+	font_h = font_w * r::aspect_ratio;
+}
+
+
+// SetColor
+void SetColor( const vec4_t& color_ )
+{
+	for( int i=0; i<4; i++ )
+		color[i] = color_[i];
+}
+
+// SetPos
+void SetPos( float x_, float y_ )
+{
+	initial_x = crnt_x = x_;
+	crnt_y = y_;
+}
+
+
+// Printf
+void Printf( const char* format, ... )
+{
+	va_list ap;
+	char text[512];
+
+	va_start(ap, format);		// Parses The String For Variables
+		vsprintf(text, format, ap);  // And Converts Symbols To Actual Numbers
+	va_end(ap);
+
+	SetGL();
+	for( int i=0; i<(int)strlen(text); i++ )
+	{
+		glLoadIdentity();
+		glTranslatef( crnt_x, crnt_y, 0.0f );
+		DrawChar( text[i] );
+	}
+	RestoreGL();
+}
+
+
+//Print
+void Print( const char* text )
+{
+	SetGL();
+	glTranslatef( crnt_x, crnt_y, 0.0f );
+	for( uint i=0; i<strlen(text); i++ )
+	{
+		glLoadIdentity();
+		glTranslatef( crnt_x, crnt_y, 0.0f );
+		DrawChar( text[i] );
+	}
+	RestoreGL();
+}
+
+
+} // end namespace

+ 20 - 0
src/old_src/2009-5-11/hud.h

@@ -0,0 +1,20 @@
+#ifndef _HUD_H_
+#define _HUD_H_
+
+#include "common.h"
+#include "math.h"
+
+
+namespace hud { // begin namespace
+
+
+extern void Init(); // exec after init SDL
+extern void SetColor( const vec4_t& color );
+extern void SetPos( float x_, float y_ );
+extern void SetFontWidth( float w_ );
+extern void Printf( const char* format, ... );
+extern void Print( const char* str );
+
+
+} // end namespace
+#endif

+ 104 - 0
src/old_src/2009-5-11/input.cpp

@@ -0,0 +1,104 @@
+#include "input.h"
+
+
+namespace i {
+
+
+
+/*
+=================================================================================================================================================================
+data vars                                                                                                                                                       =
+=================================================================================================================================================================
+*/
+short keys [SDLK_LAST];  // shows the current key state. 0: unpressed, 1: pressed once, n is >1: kept pressed 'n' times continucely
+short mouse_btns [8];    // mouse btns. Supporting 3 btns & wheel. Works the same as above
+vec2_t mouse_pos_ndc;    // the coords are in the ndc space
+vec2_t mouse_pos;        // the coords are in the window space
+vec2_t mouse_velocity;
+
+
+/*
+=================================================================================================================================================================
+Reset                                                                                                                                                           =
+=================================================================================================================================================================
+*/
+void Reset( void )
+{
+	memset( keys, 0, sizeof(keys) );
+	memset(mouse_btns, 0, sizeof(mouse_btns) );
+	mouse_pos_ndc.SetZero();
+	mouse_velocity.SetZero();
+}
+
+
+/*
+=================================================================================================================================================================
+HandleEvents                                                                                                                                                    =
+=================================================================================================================================================================
+*/
+void HandleEvents()
+{
+	SDL_Event event_;
+
+	// add the times a key is bying pressed
+	for( int x=0; x<SDLK_LAST; x++ )
+	{
+		if( keys[x] ) ++keys[x];
+	}
+	for( int x=0; x<8; x++ )
+	{
+		if( mouse_btns[x] ) ++mouse_btns[x];
+	}
+
+	mouse_velocity.SetZero();
+	vec2_t prev_mouse_pos_ndc( mouse_pos_ndc );
+
+	while (SDL_PollEvent(&event_))
+	{
+		switch( event_.type )
+		{
+			case SDL_KEYDOWN:
+				keys[event_.key.keysym.sym] = 1;
+				break;
+
+			case SDL_KEYUP:
+				keys[event_.key.keysym.sym] = 0;
+				break;
+
+			case SDL_MOUSEBUTTONDOWN:
+				mouse_btns[event_.button.button] = 1;
+				break;
+
+			case SDL_MOUSEBUTTONUP:
+				mouse_btns[event_.button.button] = 0;
+				break;
+
+			case SDL_MOUSEMOTION:
+				mouse_pos.x = event_.button.x;
+				mouse_pos.y = event_.button.y;
+
+				mouse_pos_ndc.x = (2.0f * mouse_pos.x) / (float)r::w - 1.0f;
+				mouse_pos_ndc.y = 1.0f - (2.0f * mouse_pos.y) / (float)r::h;
+
+				mouse_velocity = mouse_pos_ndc - prev_mouse_pos_ndc;
+
+				break;
+
+			case SDL_QUIT:
+				hndl::QuitApp(1);
+				break;
+		}
+	}
+
+	//SDL_WarpMouse( renderer.w/2, renderer.h/2);
+
+	//cout << fixed << " velocity: " << mouse_velocity.x() << ' ' << mouse_velocity.y() << endl;
+	//cout << fixed << mouse_pos_ndc.x() << ' ' << mouse_pos_ndc.y() << endl;
+	//cout << crnt_keys[SDLK_m] << ' ' << prev_keys[SDLK_m] << "      " << keys[SDLK_m] << endl;
+	//cout << mouse_btns[SDL_BUTTON_LEFT] << endl;
+
+}
+
+
+
+} // end namespace

+ 27 - 0
src/old_src/2009-5-11/input.h

@@ -0,0 +1,27 @@
+#ifndef _INPUT_H_
+#define _INPUT_H_
+
+#include <SDL.h>
+#include "common.h"
+#include "handlers.h"
+#include "math.h"
+
+namespace i {
+
+
+extern void Reset();
+extern void HandleEvents();
+
+// keys and btns
+extern short keys [SDLK_LAST];  // shows the current key state. 0: unpressed, 1: pressed once, n is >1: kept pressed 'n' times continucely
+extern short mouse_btns [8];    // mouse btns. Supporting 3 btns & wheel. Works the same as above
+
+// mouse movement
+extern vec2_t mouse_pos_ndc; // the coords are in the NDC space
+extern vec2_t mouse_pos;     // the coords are in the window space. (0,0) is in the uper left corner
+extern vec2_t mouse_velocity;
+
+
+
+} // end namespace
+#endif

+ 60 - 0
src/old_src/2009-5-11/lights.cpp

@@ -0,0 +1,60 @@
+#include "lights.h"
+
+
+uint light_t::lights_num = 0;
+
+
+/*
+=======================================================================================================================================
+Update                                                                                                                                =
+=======================================================================================================================================
+*/
+void light_t::Update()
+{
+	glEnable( GL_LIGHT0 + gl_id );
+	glLightfv( GL_LIGHT0+gl_id, GL_POSITION, &world_translation[0] );
+	glLightfv( GL_LIGHT0+gl_id, GL_SPOT_DIRECTION, &GetDir()[0] );
+}
+
+
+/*
+=======================================================================================================================================
+Render light                                                                                                                          =
+=======================================================================================================================================
+*/
+void light_t::Render()
+{
+	glPushMatrix();
+	r::MultMatrix( world_transformation );
+
+	if( r::show_lights )
+	{
+		glEnable( GL_LIGHT0 + gl_id );
+		// set GL
+		r::SetGLState_Solid();
+		glColor3fv( &(GetAmbient()*GetDiffuse())[0] );
+
+		r::RenderSphere( 1.0f/8.0f, 8 );
+
+		// render the light direction
+
+		if( type != SPOT )
+		{
+			r::SetGLState_WireframeDotted();
+			glLineWidth( 4.0 );
+			glBegin( GL_LINES );
+				glVertex3fv( &vec3_t( 0.0, 0.0, 0.0 )[0] );
+				glVertex3fv( &(vec3_t( 1.0, 0.0, 0.0 )*2.0)[0] );
+			glEnd();
+		}
+
+	}
+
+	if( r::show_axis )
+	{
+		r::SetGLState_Solid();
+		RenderAxis();
+	}
+
+	glPopMatrix();
+}

+ 98 - 0
src/old_src/2009-5-11/lights.h

@@ -0,0 +1,98 @@
+#ifndef _LIGHTS_H_
+#define _LIGHTS_H_
+
+#include "common.h"
+#include "renderer.h"
+#include "primitives.h"
+#include "texture.h"
+
+/*
+LIGHTING MODEL
+
+Final intensity:                If = Ia + Id + Is
+Ambient intensity:              Ia = Al * Am
+Ambient intensity of light:     Al
+Ambient intensity of material:  Am
+Defuse intensity:               Id = Dl * Dm * LambertTerm
+Defuse intensity of light:      Dl
+Defuse intensity of material:   Dm
+LambertTerm:                    max( Normal dot Light, 0.0 )
+Specular intensity:             Is = Sm x Sl x pow( max(R dot E, 0.0), f )
+Specular intensity of light:    Sl
+Specular intensity of material: Sm
+*/
+
+class light_runtime_class_t: public runtime_class_t {}; // for ambiguity reasons
+
+class light_t: public object_t, public light_runtime_class_t
+{
+	public:
+		// the light types
+		enum types_e
+		{
+			POINT,
+			DIRECTIONAL,
+			SPOT
+		};
+
+		ushort type;
+
+		uint gl_id;
+		static uint lights_num;
+
+		// funcs
+		light_t(): type(POINT) { gl_id = lights_num++; };
+		~light_t() {};
+		void Update(); // Update the ogl with the changes in pos and dir. Call it before rendering and after camera transf
+
+		// set params
+		void SetAmbient ( const vec4_t& col ) { glLightfv( GL_LIGHT0+gl_id, GL_AMBIENT,  &((vec4_t&)col)[0] ); }
+		void SetDiffuse ( const vec4_t& col ) { glLightfv( GL_LIGHT0+gl_id, GL_DIFFUSE,  &((vec4_t&)col)[0] ); }
+		void SetSpecular( const vec4_t& col ) { glLightfv( GL_LIGHT0+gl_id, GL_SPECULAR, &((vec4_t&)col)[0] ); }
+		void SetCutOff  ( float c )           { DEBUG_ERR( (c>90.0||c<0.0)  && c!=180.0) glLightf( GL_LIGHT0+gl_id, GL_SPOT_CUTOFF, c ); }
+		void SetExp     ( float exp )         { DEBUG_ERR( exp<0.0 || exp>128.0 ) glLightf( GL_LIGHT0+gl_id, GL_SPOT_EXPONENT, exp ); }
+
+		// get
+		vec4_t GetAmbient() const  { vec4_t col; glGetLightfv(GL_LIGHT0+gl_id, GL_AMBIENT,  &col[0]); return col; }
+		vec4_t GetDiffuse() const  { vec4_t col; glGetLightfv(GL_LIGHT0+gl_id, GL_DIFFUSE,  &col[0]); return col; }
+		vec4_t GetSpecular() const { vec4_t col; glGetLightfv(GL_LIGHT0+gl_id, GL_SPECULAR, &col[0]); return col; }
+		float  GetCutOff() const   { float cutoff; glGetLightfv( GL_LIGHT0+gl_id, GL_SPOT_CUTOFF, &cutoff ); return cutoff; }
+		float  GetExp() const      { float exp; glGetLightfv( GL_LIGHT0+gl_id, GL_SPOT_EXPONENT, &exp ); return exp; }
+		vec3_t GetDir() const      { return world_rotation.GetColumn(0); } // the light direction is always the x axis
+
+		void Render();
+};
+
+///                                                                                             /
+class light2_t: public object_t, public light_runtime_class_t
+{
+	public:
+		enum types_e
+		{
+			POINT,
+			PROJ_TXTR
+		};
+
+		vec3_t diffuse_color;
+		vec3_t specular_color;
+		types_e type;
+};
+
+class point_light_t: public light2_t
+{
+	public:
+		float radius;
+};
+
+class proj_light_t: public light2_t
+{
+	public:
+		camera_t camera;
+		texture_t txtr;
+		bool casts_shadow;
+
+		proj_light_t(): casts_shadow(false) { MakeParent(&camera); }
+};
+
+
+#endif

+ 232 - 0
src/old_src/2009-5-11/main_animation.cpp

@@ -0,0 +1,232 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "level.h"
+
+const float fovy = ToRad(60.0);
+camera_t main_cam( r::aspect_ratio*fovy, fovy, 0.5, 100.0 );
+camera_t other_cam( ToRad(60.0), ToRad(60.0), 1.0, 10.0 );
+
+
+light_t lights[1];
+
+model_data_t mdata;
+model_t model;
+skeleton_anim_t anim;
+texture_t txtr, txtr1;
+
+float frame_asd = 0.0;
+
+texture_t render_target;
+
+class cube_t: public object_t
+{
+	public:
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( /*model.world_transformation */ world_transformation );
+
+			r::SetGLState_Solid();
+			glEnable( GL_TEXTURE_2D );
+
+			glActiveTexture( GL_TEXTURE0 );
+			glBindTexture( GL_TEXTURE_2D, render_target.gl_id );
+
+			//glEnable( GL_BLEND );
+
+			r::Color4( vec4_t(1.0, 1.0, 1.0, 1) );
+			r::RenderCube();
+
+			glPopMatrix();
+		}
+}cube;
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	//mem::Enable( mem::THREADS );
+	MathSanityChecks();
+	hndl::InitWindow( r::w, r::h, "mAlice Engine" );
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+
+	other_cam.MoveLocalY( 2.5 );
+	other_cam.MoveLocalZ( 5.0f );
+	other_cam.RotateLocalY( ToRad(-30.0) );
+	other_cam.MoveLocalX( -3.0f );
+
+	ass::LoadMat( "materials/imp/imp.mat" );
+
+	// initialize the TESTS
+	lights[0].SetAmbient( vec4_t( 0.4, 0.4, 0.4, 1.0 ) );
+	lights[0].SetDiffuse( vec4_t( 1.5, 1.5, 1.0, 1.0 ) );
+	lights[0].local_translation = vec3_t( -1.0, 1.0, 0.0 );
+	lights[0].type = light_t::DIRECTIONAL;
+	//lights[0].SetCutOff( 0.0 );
+	//lights[0].SetExp( 120.0 );
+
+
+	txtr.Load( "models/imp/imp_d.tga" );
+	txtr1.Load( "models/imp/imp_local.tga" );
+	mdata.Load( "models/test/imp.mdl" );
+	model.Init( &mdata );
+//	model.local_translation = vec3_t( 1.0, 0.0, 0.0 );
+	model.local_rotation.Set( euler_t( -PI/2, 0.0, 0.0) );
+	//model.SetChilds( 1, &cube );
+	//model.GetBone("arm.L.001")->AddChilds( 1, &cube );
+	anim.Load( "models/test/walk.imp.anim" );
+	model.Play( &anim, 0, 0.7, model_t::START_IMMEDIATELY );
+
+
+	render_target.Load( "gfx/no_tex.tga" );
+
+
+	//cube.local_translation = vec3_t( 2.2, 0.05, 1.75 );
+	cube.local_translation = vec3_t( 3.2, 0.05, 1.75 );
+	cube.local_scale = 2.0;
+	//cube.local_rotation.Set( euler_t( ToRad(-10.0), 0.0, ToRad(-25.0)) );
+	//cube.local_scale = 0.5;
+	//cube.parent = model.GetBone("arm.L.001");
+
+
+	lvl::Register( (model_t*)&model );
+	lvl::Register( (object_t*)&cube );
+	lvl::Register( &main_cam );
+	lvl::Register( &other_cam );
+	lvl::Register( (light_t*)&lights[0] );
+
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_2 ] ) mover = &model;
+		if( i::keys[ SDLK_3 ] ) mover = &lights[0];
+		if( i::keys[ SDLK_4 ] ) mover = &other_cam;
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		mover->local_rotation.Reorthogonalize();
+
+		lvl::InterpolateAllModels();
+		lvl::UpdateAllWorldTrfs();
+		lvl::UpdateAllLights();
+		lvl::UpdateAllFrustumPlanes();
+
+
+
+		// render to txtr
+			glClearColor( 0.0, 0.0, 0.1, 1.0 );
+			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+			const int width = 128;
+			float a = 1;
+			r::SetViewport( 0, 0, width, width/a );
+			r::SetProjectionMatrix( other_cam );
+			r::SetViewMatrix( other_cam );
+
+			lvl::RenderAll();
+
+			glActiveTexture( GL_TEXTURE0 );
+			glBindTexture( GL_TEXTURE_2D, render_target.gl_id );
+			glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, width, width/a, 0 );
+		// end render to txtr
+
+
+		glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+		r::SetViewport( 0, 0, r::w, r::h );
+		r::SetProjectionMatrix( main_cam );
+		r::SetViewMatrix( main_cam );
+
+		r::RenderGrid();
+
+		// render rest
+		model.Deform();
+		lvl::RenderAll();
+
+
+		r::SetGLState_Solid();
+		material_t* mat = ass::LoadMat( "materials/grass0/grass0.mat" );
+		mat->Use();
+		float size = 0.5f;
+		glBegin(GL_QUADS);
+			glNormal3f( 0.0f, 0.0f, 1.0f);
+			glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size,  size);
+			glTexCoord2f(1.0, 0.0); glVertex3f( size, -size,  size);
+			glTexCoord2f(1.0, 1.0); glVertex3f( size,  size,  size);
+			glTexCoord2f(0.0, 1.0); glVertex3f(-size,  size,  size);
+		glEnd();
+
+
+
+		// print some debug stuff
+		hud::SetColor( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	cout << "Appl quits after " << hndl::GetTicks() << " ticks" << endl;
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 231 - 0
src/old_src/2009-5-11/main_deffered.cpp

@@ -0,0 +1,231 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "scene.h"
+#include "scanner.h"
+#include "skybox.h"
+
+
+light_t lights[1];
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 100.0 );
+
+class cube_t: public object_t
+{
+	public:
+		cube_t()
+		{
+			local_translation = vec3_t( 3.2, 0.05, 1.75 );
+			local_scale = 2.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1.0, 0.0, 1) );
+
+			r::RenderCube( true );
+
+			glPopMatrix();
+		}
+}cube;
+
+
+class shpere_t: public object_t
+{
+	public:
+		shpere_t()
+		{
+			local_translation = vec3_t( -1.2, 1.05, -1.75 );
+			local_scale = 1.5;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 0.5, 0.25, 1) );
+
+			r::RenderSphere( 1.0, 32 );
+
+			glPopMatrix();
+		}
+}sphere;
+
+
+class flore_t: public object_t
+{
+	public:
+		flore_t()
+		{
+			local_scale = 10.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(.6, .6, 1., 1) );
+
+			glNormal3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+			glBegin( GL_QUADS );
+				glVertex3f( 1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, 1.0 );
+				glVertex3f( 1.0, 0.0, 1.0 );
+			glEnd();
+
+			glPopMatrix();
+		}
+}flore;
+
+mesh_t imp;
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	MathSanityChecks();
+
+	hndl::InitWindow( r::w, r::h, "GODlike's Engine" );
+	scn::Init();
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+
+	lights[0].SetAmbient( vec4_t( 0.4, 0.9, 0.4, 1.0 ) );
+	lights[0].SetDiffuse( vec4_t( 1.0, 1.0, 1.0, 1.0 ) );
+	lights[0].local_translation = vec3_t( -1.0, 0.3, 1.0 );
+
+	imp.Init( ass::LoadMeshD( "models/test/imp.mesh" ) );
+	imp.local_rotation.RotateXAxis( -PI/2 );
+
+	scene::Register( (object_t*)&cube );
+	scene::Register( (object_t*)&sphere );
+	scene::Register( (object_t*)&flore );
+	scene::Register( (object_t*)&imp );
+	scene::Register( &main_cam );
+	scene::Register( &lights[0] );
+
+	glMaterialfv( GL_FRONT, GL_AMBIENT, &vec4_t( 0.1, 0.1, 0.1, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_DIFFUSE, &vec4_t( 0.5, 0.0, 0.0, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_SPECULAR, &vec4_t( 1., 1., 1., 0.1 )[0] );
+	glMaterialf( GL_FRONT, GL_SHININESS, 100.0 );
+
+	const char* skybox_fnames [] = { "env/hellsky4_forward.tga", "env/hellsky4_back.tga", "env/hellsky4_left.tga", "env/hellsky4_right.tga",
+																	 "env/hellsky4_up.tga", "env/hellsky4_down.tga" };
+	scene::skybox.Load( skybox_fnames );
+
+
+	/************************************************************************************************************************************
+	*																													MAIN LOOP                                                                 *
+	*************************************************************************************************************************************/
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_3 ] ) mover = &lights[0];
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		if( i::keys[SDLK_k] ) main_cam.LookAtPoint( lights[0].world_translation );
+
+
+		mover->local_rotation.Reorthogonalize();
+
+		scene::InterpolateAllModels();
+		//scene::UpdateAllLights();
+		scene::UpdateAllWorldTrfs();
+		scene::UpdateAllCameras();
+
+		///   RENDER TO FBO
+		r::dfr::MaterialPass( main_cam );
+
+
+		///  POST PROCESSING
+		glMatrixMode( GL_PROJECTION );
+		glLoadIdentity();
+		glOrtho( 0.0, r::w, 0.0, r::h, -1.0, 1.0 );
+
+		glMatrixMode( GL_MODELVIEW );
+		glLoadIdentity();
+
+		glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+		//glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); no need for that
+
+		r::dfr::AmbientPass( main_cam, vec3_t(0.3, 0.3, 0.3) );
+		//r::d::AmbientPass( vec3_t( 1.0, 1.0, 1.0 ) );
+		r::dfr::LightingPass( main_cam );
+
+
+		// print some debug stuff
+		hud::SetColor( vec4_t(1.0, 1.0, 1.0, 1.0) );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	INFO( "Appl quits after " << hndl::GetTicks() << " ticks" );
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 364 - 0
src/old_src/2009-5-11/main_particles.cpp

@@ -0,0 +1,364 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+using namespace std;
+
+
+light_t light0;
+light_t light1;
+
+shader_prog_t shaderp;
+
+bsphere_t bsph;
+bsphere_t bsph1;
+
+aabb_t aabb;
+aabb_t aabb1;
+
+plane_t plane;
+
+ray_t ray;
+
+lineseg_t seg;
+
+obb_t obb;
+obb_t obb1;
+
+texture_t tex_normal[3];
+texture_t tex_color[3];
+
+mesh_data_t mesh_d[3];
+mesh_t mesh[3];
+
+
+class test_obj_t: public object_t
+{
+	public:
+		void Render()
+		{
+			UpdateWorldTransform();
+			glPushMatrix();
+
+			mat4_t transform( mat4_t::TRS(world_translate, world_rotate, world_scale) );
+			transform.Transpose();
+			glMultMatrixf( &transform(0,0) );
+
+			r::SetGLState_Solid();
+			glColor3fv( &vec3_t( 0.0, 1.0, 0.0 ).Normalized()[0] );
+
+			r::RenderCube();
+
+			r::SetGLState_Solid();
+			glPopMatrix();
+		}
+} test;
+
+
+class _t
+{
+	public:
+		int x;
+		_t(): x(10) {}
+		_t( int x_ ): x(x_) {}
+		~_t() {}
+};
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	array_t<_t> asdfasdf;
+	asdfasdf.Malloc( 2 );
+	INFO( asdfasdf[0].x );
+
+	mem::PrintInfo( mem::PRINT_HEADER );
+	mem::Enable( mem::PRINT_ERRORS | mem::THREADS );
+	MathCompilerTest();
+	hndl::InitWindow( r::w, r::h, "Malice Engine" );
+	mem::PrintInfo( mem::PRINT_HEADER );
+	r::Init();
+	hud::Init();
+
+	cam.CalcCullingPlanes();
+	cam.MoveY( 2.5 );
+	cam.MoveZ( 5.0f );
+
+	particle_emitter_t pem;
+	pem.Init();
+
+	/*
+	=======================================================================================================================================
+	initialize the TESTS                                                                                                                  =
+	=======================================================================================================================================
+	*/
+	tex_normal[0].Load( "meshes/sarge/body_local.tga" );
+	tex_color[0].Load( "meshes/sarge/body.tga" );
+	mesh_d[0].Load( "meshes/sarge/mesh.txt" );
+	mesh[0].mesh_data = &mesh_d[0];
+	mesh[0].local_translate = vec3_t( -5.0, -1, 10 );
+
+	tex_normal[1].Load( "meshes/test/normal.tga" );
+	tex_color[1].Load( "meshes/test/color.tga" );
+	mesh_d[1].Load( "meshes/test/mesh.txt" );
+	mesh[1].mesh_data = &mesh_d[1];
+	mesh[1].local_translate = vec3_t( -2.0, 0, 0 );
+
+
+	tex_normal[2].Load( "meshes/test2/normal.tga" );
+	tex_color[2].Load( "meshes/test2/color.tga" );
+	mesh_d[2].Load( "meshes/test2/mesh.txt" );
+	mesh[2].mesh_data = &mesh_d[2];
+	mesh[2].local_translate = vec3_t( 3.0, 0, 0 );
+
+
+	bsph.Set( &mesh[0].mesh_data->verts[0], sizeof(vertex_t), mesh[0].mesh_data->verts.size );
+
+	aabb.Set( &mesh[0].mesh_data->verts[0], sizeof(vertex_t), mesh[0].mesh_data->verts.size );
+
+
+	bsph1.radius = 1.0f;
+	bsph1.center = vec3_t( -5.0, 0.0, 10.0 );
+
+	plane.normal = vec3_t(0.0, 0.0, 1.0).Normalized();
+	plane.offset = -10.0f;
+
+	aabb1.min = vec3_t( -10, 1, 10 );
+	aabb1.max = vec3_t( -9, 3, 12 );
+
+	ray = ray_t( vec3_t(0, 1, 0), vec3_t(0, 0, -1).Normalized() );
+
+	seg = lineseg_t( vec3_t(0, 4, -1.0), vec3_t(0, 0, -3) );
+
+	obb.Set( &mesh[0].mesh_data->verts[0], sizeof(vertex_t), mesh[0].mesh_data->verts.size );
+	obb1.center = vec3_t(0, 0, 10.0f);  obb1.extends = vec3_t(0.5, 2, 1); obb1.rotation.LoadEuler( euler_t(PI/8, 0, 0) );
+
+	// shaders
+	//shaderp.LoadCompileLink( "shaders/test.vert", "shaders/test.frag" ); LALA
+	//shaderp.LoadCompileLink( "shaders/spec3l.vert", "shaders/spec3l.frag" );
+	//                                                                        /
+
+
+	// lights                                                                 /
+	light0.SetAmbient( vec4_t( 0.1, 0.1, 0.1, 1.0 ) );
+	light0.SetDiffuse( vec4_t( 0.5, 0.5, 0.5, 1 ) );
+	light0.SetSpecular( vec4_t( 1.5, 1.5, 1.5, 1.0 ) );
+	light0.local_translate = vec3_t( 0, 1.2, 4.0 );
+
+	light1.SetAmbient( vec4_t( 0.3, 0.1, 0.1, 1.0 ) );
+	light1.SetDiffuse( vec4_t( 0.0, 0.0, 0.0, 1.0 ) );
+	light1.SetSpecular( vec4_t( 1.0, 1.1, .1, 1.0 ) );
+	light1.local_translate = vec3_t( 3., 1.2, 5. );
+
+	//                                                                        /
+
+	//light0.parent = &cam;
+
+	do
+	{
+		StartBench();
+
+		i::HandleEvents();
+		r::Run();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &cam;
+		else if( i::keys[ SDLK_2 ] ){ mover = &mesh[0];}
+		else if( i::keys[ SDLK_3 ] ) mover = &light0;
+		else if( i::keys[ SDLK_4 ] ) mover = &test;
+
+		if( mover == &mesh[0] ) dist=0.04;
+
+		if( i::keys[SDLK_a] ) mover->MoveX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		mover->local_rotate.Reorthogonalize();
+
+		cam.Render();
+
+
+		light0.Render();
+		light1.Render();
+
+		r::RenderGrid();
+
+		//pem.Render();
+
+		///////////////////////////////////////////////////////////////////////
+
+
+		//test.Render();
+
+
+
+
+		// multitexture
+
+		//shaderp.Use(); LALA
+
+
+		glMaterialfv( GL_FRONT, GL_SPECULAR, &vec4_t( .8, 0.5, 0.5, 1.0)[0] );
+		glMaterialfv( GL_FRONT, GL_DIFFUSE, &vec4_t(1, 1, 1, 1.0)[0] );
+		glMaterialfv( GL_FRONT, GL_AMBIENT, &vec4_t(1, 1, 1, 1.0)[0] );
+		glMaterialf( GL_FRONT, GL_SHININESS, 7.0 );
+
+		glActiveTextureARB(GL_TEXTURE1_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_normal[0].id);
+		glActiveTextureARB(GL_TEXTURE0_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_color[0].id);
+
+
+		//glUniform1i( shaderp.GetUniLocation("color_map"), 0 ); LALA
+		//glUniform1i( shaderp.GetUniLocation("normal_map"), 1 ); LALA
+
+
+//		int light_ids[3] = {0, -1, -1};
+//		glUniform1iv( shaderp.GetUniLocation("light_ids"), 3, light_ids );
+
+
+		// material and shader
+
+
+		mesh[0].Render();
+
+
+		glActiveTextureARB(GL_TEXTURE1_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_normal[1].id);
+		glActiveTextureARB(GL_TEXTURE0_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_color[1].id);
+
+		//shaderp.Use(); LALA
+		mesh[1].Render();
+
+
+
+		// render mesh 2
+		glActiveTextureARB(GL_TEXTURE1_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_normal[2].id);
+		glActiveTextureARB(GL_TEXTURE0_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_color[2].id);
+
+		//shaderp.Use(); LALA
+		mesh[2].Render();
+
+		r::NoShaders();
+
+
+		//////////////////////////////////////////////////////////////////////
+
+		//plane.Render();
+
+		bsphere_t bshp_trf( bsph.Transformed( mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale ) );
+		bshp_trf.Render();
+		bsph1.Render();
+
+		aabb_t aabb_transf( aabb.Transformed( mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale ) );
+		//aabb_transf.Render();
+		aabb1.Render();
+
+		ray_t ray_transf( ray.Transformed( mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale ) );
+		ray_transf.Render();
+
+		lineseg_t seg_transf( seg.Transformed( mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale ) );
+		seg_transf.Render();
+		//bvolume_t* bv = &seg_transf;
+		//bv->Render();
+
+
+		//obb.Render();
+		obb_t obb_transf( obb.Transformed(mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale) );
+		//obb_transf.Render();
+		obb1.Render();
+
+
+
+		hud::SetPos( -0.98, 0.6 );
+		hud::SetFontWidth( 0.03 );
+		hud::SetColor( &vec4_t(1,1,1,1)[0] );
+		if( bsph1.Intersects(bshp_trf) )  hud::Printf( "collision sphere-sphere\n" );
+		if( aabb1.Intersects(ray_transf) )  hud::Printf( "collision ray-aabb\n" );
+		if( bsph1.Intersects( ray_transf ) )  hud::Printf( "collision ray-sphere\n" );
+		if( obb1.Intersects(obb_transf) )  hud::Printf( "collision obb-obb\n" );
+		if( bsph1.Intersects(seg_transf) )  hud::Printf( "collision seg-sphere\n" );
+		if( aabb1.Intersects(seg_transf) )  hud::Printf( "collision seg-aabb\n" );
+		if( aabb1.Intersects(bshp_trf) )  hud::Printf( "collision aabb-sphere\n" );
+		if( obb1.Intersects( bshp_trf ) )  hud::Printf( "collision obb-sphere\n" );
+
+		hud::SetColor( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+		if( obb1.Intersects( ray_transf ) )  hud::Printf( "collision obb-ray\n" );
+		if( obb1.Intersects( seg_transf ) )  hud::Printf( "collision obb-segment\n" );
+		hud::SetColor( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+
+		vec3_t normal, impact_p;
+		float depth;
+		//aabb1.SeparationTest( aabb_transf, normal, impact_p, depth );
+		//bsph1.SeparationTest( bshp_trf, normal, impact_p, depth );
+		//aabb1.SeparationTest( bshp_trf, normal, impact_p, depth );
+		bshp_trf.SeperationTest( obb1, normal, impact_p, depth );
+		//bshp_trf.SeperationTest( aabb1, normal, impact_p, depth );
+
+		hud::SetColor( &vec4_t(0.0, 1.0, 0.0, 0.5)[0] );
+		hud::SetFontWidth( 0.035 );
+
+
+//		hud::Printf( "plane-aabb dist: %f\n", aabb_transf.PlaneTest(plane) );
+//		hud::Printf( "plane-shpere dist: %f\n", bshp_trf.PlaneTest(plane) );
+//		hud::Printf( "plane-obb dist: %f\n", obb_transf.PlaneTest(plane) );
+
+		//test.Render();
+
+
+		/////////////////////////////////////////////////////////////////////
+
+		// print some debug stuff
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+		HudPrintMemInfo();
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		hndl::WaitForNextTick();
+	}while( true );
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 270 - 0
src/old_src/2009-5-11/main_project_txtr.cpp

@@ -0,0 +1,270 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "level.h"
+#include "scanner.h"
+
+light_t lights[1];
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 100.0 );
+camera_t light_cam( ToRad(90.0), ToRad(90.0), 0.10, 10.0 );
+
+class cube_t: public object_t
+{
+	public:
+		cube_t()
+		{
+			local_translation = vec3_t( 3.2, 0.05, 1.75 );
+			local_scale = 2.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1.0, 0.0, 1) );
+			r::RenderCube( true );
+
+			glPopMatrix();
+		}
+}cube;
+
+
+class shpere_t: public object_t
+{
+	public:
+		shpere_t()
+		{
+			local_translation = vec3_t( -1.2, 1.05, -1.75 );
+			local_scale = 1.5;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 0.5, 0.25, 1) );
+			r::RenderSphere( 1.0, 32 );
+
+			glPopMatrix();
+		}
+}sphere;
+
+
+class flore_t: public object_t
+{
+	public:
+		flore_t()
+		{
+			local_scale = 10.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1., 1., 1) );
+
+			glNormal3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+			glBegin( GL_QUADS );
+				glVertex3f( 1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, 1.0 );
+				glVertex3f( 1.0, 0.0, 1.0 );
+			glEnd();
+
+			glPopMatrix();
+		}
+}flore;
+
+
+texture_t* proj;
+
+shader_prog_t* shdr, *shdr1;
+
+#define SHADOW_QUALITY 512
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	//mem::Enable( mem::THREADS );
+	MathSanityChecks();
+
+	hndl::InitWindow( r::w, r::h, "mAlice Engine" );
+	scn::Init();
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+
+	/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// initialize the TESTS
+	lights[0].SetAmbient( vec4_t( 0.4, 0.9, 0.4, 1.0 ) );
+	lights[0].SetDiffuse( vec4_t( 1.0, 1.0, 1.0, 1.0 ) );
+	lights[0].local_translation = vec3_t( -1.0, 1.0, 1.0 );
+	lights[0].type = light_t::DIRECTIONAL;
+	//lights[0].SetCutOff( 0.0 );
+	//lights[0].SetExp( 120.0 );
+
+	proj = ass::LoadTxtr( "gfx/flashlight.tga" );
+
+	lights[0].MakeParent( &light_cam );
+	//light_cam.RotateLocalY( -PI/2 );
+
+	shdr = ass::LoadShdr( "shaders/test.shdr" );
+	//shdr1 = ass::LoadShdr( "shaders/glass.shader" );
+
+	glMaterialfv( GL_FRONT, GL_AMBIENT, &vec4_t( 0.1, 0.1, 0.1, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_DIFFUSE, &vec4_t( 0.5, 0.0, 0.0, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_SPECULAR, &vec4_t( 1., 1., 1., 0.1 )[0] );
+	glMaterialf( GL_FRONT, GL_SHININESS, 120.0 );
+
+	/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+	lvl::Register( (object_t*)&cube );
+	lvl::Register( (object_t*)&sphere );
+	lvl::Register( (object_t*)&flore );
+	lvl::Register( &lights[0] );
+	lvl::Register( &main_cam );
+	lvl::Register( &light_cam );
+
+	light_cam.MakeParent( &main_cam );
+
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_3 ] ) mover = &lights[0];
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		mover->local_rotation.Reorthogonalize();
+
+		lvl::InterpolateAllModels();
+		//lvl::UpdateAllLights();
+		lvl::UpdateAllWorldTrfs();
+		lvl::UpdateAllCameras();
+
+		// RENDER
+		glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		r::SetProjectionViewMatrices( main_cam );
+		r::SetViewport( 0, 0, r::w, r::h );
+		lvl::UpdateAllLights();
+
+		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+		glDisable(GL_POLYGON_OFFSET_FILL);
+
+		//r::RenderGrid();
+		r::SetGLState_Solid();
+		glEnable( GL_LIGHTING );
+
+		shdr->Bind();
+
+		//glUniform1i( shdr->GetUniLocation("t0"), 0 );
+
+		glActiveTexture( GL_TEXTURE0 + 0 );
+		proj->Bind();
+
+		const float mBias[] = {0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0};
+		glMatrixMode( GL_TEXTURE );
+		glLoadMatrixf( mBias );
+		r::MultMatrix( light_cam.projection_mat );
+		r::MultMatrix( light_cam.view_mat );
+		r::MultMatrix( main_cam.world_transformation );
+		glMatrixMode(GL_MODELVIEW);
+
+		lvl::RenderAll();
+
+		shdr1->UnBind();
+		glMatrixMode( GL_TEXTURE );
+		glLoadIdentity();
+		glMatrixMode(GL_MODELVIEW);
+
+		// Debug stuff
+//		r::SetGLState_Solid();
+//		glEnable( GL_TEXTURE_2D );
+//		glDisable( GL_LIGHTING );
+//		depth_map.Bind();
+//		float size = 2.0f;
+//		r::Color3( vec3_t( 1.0, 1.0, 1.0 ) );
+//		glBegin(GL_QUADS);
+//			glNormal3f( 0.0f, 0.0f, 1.0f);
+//			glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size,  -5);
+//			glTexCoord2f(1.0, 0.0); glVertex3f( size, -size,  -5);
+//			glTexCoord2f(1.0, 1.0); glVertex3f( size,  size,  -5);
+//			glTexCoord2f(0.0, 1.0); glVertex3f(-size,  size,  -5);
+//		glEnd();
+		// END RENDER
+
+
+		// print some debug stuff
+		hud::SetColor( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	cout << "Appl quits after " << hndl::GetTicks() << " ticks" << endl;
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 274 - 0
src/old_src/2009-5-11/main_projection_test.cpp

@@ -0,0 +1,274 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "level.h"
+#include "scanner.h"
+#include "fbos.h"
+#include "skybox.h"
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 200.0 );
+
+class cube_t: public object_t
+{
+	public:
+		cube_t()
+		{
+			local_translation = vec3_t( 3.2, 0.05, 1.75 );
+			local_scale = 2.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1.0, 0.0, 1) );
+
+			r::RenderCube( true );
+
+			glPopMatrix();
+		}
+}cube;
+
+
+class shpere_t: public object_t
+{
+	public:
+		shpere_t()
+		{
+			local_translation = vec3_t( -1.2, 1.05, -1.75 );
+			local_scale = 1.5;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 0.5, 0.25, 1) );
+
+			r::RenderSphere( 1.0, 32 );
+
+			glPopMatrix();
+		}
+}sphere;
+
+
+class flore_t: public object_t
+{
+	public:
+		flore_t()
+		{
+			local_scale = 10.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1., 1., 1) );
+
+			glNormal3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+			glBegin( GL_QUADS );
+				glVertex3f( 1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, 1.0 );
+				glVertex3f( 1.0, 0.0, 1.0 );
+			glEnd();
+
+			glPopMatrix();
+		}
+}flore;
+
+
+vec3_t point( 1.0, 2.0, 0.5 );
+
+
+skybox_t skybox;
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	//mem::Enable( mem::THREADS );
+	MathSanityChecks();
+
+	hndl::InitWindow( r::w, r::h, "GODlike's Engine" );
+	scn::Init();
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+
+	lvl::Register( (object_t*)&cube );
+	lvl::Register( (object_t*)&sphere );
+	lvl::Register( (object_t*)&flore );
+	lvl::Register( &main_cam );
+
+	const char* skybox_fnames [] = { "env/hellsky4_forward.tga", "env/hellsky4_back.tga", "env/hellsky4_left.tga", "env/hellsky4_right.tga",
+																	 "env/hellsky4_up.tga", "env/hellsky4_down.tga" };
+	skybox.Load( skybox_fnames );
+
+
+	/************************************************************************************************************************************
+	*																													MAIN LOOP                                                                 *
+	*************************************************************************************************************************************/
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		if( i::keys[SDLK_k] ) main_cam.LookAtPoint( point );
+
+		mover->local_rotation.Reorthogonalize();
+
+		lvl::InterpolateAllModels();
+		lvl::UpdateAllWorldTrfs();
+		lvl::UpdateAllCameras();
+
+		r::SetProjectionViewMatrices( main_cam );
+		r::SetViewport( 0, 0, r::w, r::h );
+		glClearColor( 0.1f, 0.1f, 0.2f, 0.0f );
+		glClear( GL_DEPTH_BUFFER_BIT );
+
+		skybox.Render( main_cam.view_mat.GetRotationPart() );
+
+		r::NoShaders();
+
+		glDisable( GL_BLEND );
+		glEnable( GL_DEPTH_TEST );
+		glDisable( GL_TEXTURE_2D );
+
+		lvl::RenderAll();
+
+		r::RenderGrid();
+
+		glPointSize( 10.0 );
+		glBegin( GL_POINTS );
+			r::Color3( vec3_t(1.0, 0.0, 1.0) );
+			glVertex3fv( &point[0] );
+		glEnd();
+
+
+		///                                                                                            /
+		vec4_t pos_viewspace = main_cam.view_mat * vec4_t(point, 1.0);
+		vec4_t pos_clipspace = main_cam.projection_mat * pos_viewspace;
+		vec4_t point_scrspace = pos_clipspace / pos_clipspace.w;
+
+
+		float depth;
+		glReadPixels( i::mouse_pos.x, r::h-i::mouse_pos.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
+
+
+		int viewpoint[] = {0, 0, r::w, r::h};
+		vec3_t point_rc; // point recreated
+		r::UnProject( i::mouse_pos.x, (float)viewpoint[3]-i::mouse_pos.y, depth, main_cam.view_mat, main_cam.projection_mat, viewpoint, point_rc.x, point_rc.y, point_rc.z );
+
+
+		/// test for deffered
+		// do some crap for pos_eyespace
+		vec3_t v[4];
+		{
+			//int pixels[4][2]={ { 0,0 },{0,r::h},{r::w,r::h},{r::w,0} };
+			int pixels[4][2]={ {r::w,r::h}, {0,r::h}, { 0,0 }, {r::w,0} };
+			int viewport[4]={ 0,0,r::w,r::h };
+
+			mat3_t view_rotation = main_cam.view_mat.GetRotationPart();
+
+			float d[3];
+			for( int i=0; i<4; i++ )
+			{
+				r::UnProject( pixels[i][0],pixels[i][1],10, main_cam.view_mat, main_cam.projection_mat, viewport, d[0],d[1],d[2] );
+				v[i] = vec3_t ( d[0], d[1], d[2] );
+				v[i] -= main_cam.world_translation;
+				v[i].Normalize();
+				v[i] = v[i]*view_rotation;
+			}
+		}
+
+		// operations that happen in the shader:
+		vec2_t planes;
+		planes.x = -main_cam.zfar / (main_cam.zfar - main_cam.znear);
+		planes.y = -main_cam.zfar * main_cam.znear / (main_cam.zfar - main_cam.znear);
+		point_rc.z = - planes.y / (planes.x + depth);
+
+		//vec3_t view(  )
+
+		//pos.xy = view.xy / view.z*pos.z;
+
+
+		/// print some debug stuff
+		hud::SetColor( vec4_t(1.0, 1.0, 1.0, 1.0) );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		hud::Printf( "mouse: %f %f\n", i::mouse_pos.x, i::mouse_pos.y );
+		hud::Printf( "depth: %f\n", depth );
+		hud::Printf( "wspac: %f %f %f %f\n", point.x, point.y, point.z, 1.0 );
+		hud::Printf( "vspac: %f %f %f %f\n", pos_viewspace.x, pos_viewspace.y, pos_viewspace.z, pos_viewspace.w );
+		hud::Printf( "vsp_r: %f %f %f\n", point_rc.x, point_rc.y, point_rc.z );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	INFO( "Appl quits after " << hndl::GetTicks() << " ticks" );
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 287 - 0
src/old_src/2009-5-11/main_shadows.cpp

@@ -0,0 +1,287 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "level.h"
+
+light_t lights[1];
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 100.0 );
+camera_t light_cam( ToRad(60.0), ToRad(60.0), 0.10, 10.0 );
+
+class cube_t: public object_t
+{
+	public:
+		cube_t()
+		{
+			local_translation = vec3_t( 3.2, 0.05, 1.75 );
+			local_scale = 2.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1.0, 0.0, 1) );
+			r::RenderCube( true );
+
+			glPopMatrix();
+		}
+}cube;
+
+
+class shpere_t: public object_t
+{
+	public:
+		shpere_t()
+		{
+			local_translation = vec3_t( -1.2, 1.05, -1.75 );
+			local_scale = 1.5;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 0.5, 0.25, 1) );
+			r::RenderSphere( 1.0, 32 );
+
+			glPopMatrix();
+		}
+}sphere;
+
+
+class flore_t: public object_t
+{
+	public:
+		flore_t()
+		{
+			local_scale = 100.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1., 1., 1) );
+
+			glBegin( GL_QUADS );
+				glVertex3f( 1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, 1.0 );
+				glVertex3f( 1.0, 0.0, 1.0 );
+			glEnd();
+
+			glPopMatrix();
+		}
+}flore;
+
+
+texture_t depth_map;
+
+shader_prog_t* shdr;
+
+#define SHADOW_QUALITY 512
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	//mem::Enable( mem::THREADS );
+	MathSanityChecks();
+	hndl::InitWindow( r::w, r::h, "mAlice Engine" );
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+
+	/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// initialize the TESTS
+	lights[0].SetAmbient( vec4_t( 0.4, 0.4, 0.4, 1.0 ) );
+	lights[0].SetDiffuse( vec4_t( 1.5, 1.5, 1.0, 1.0 ) );
+	lights[0].local_translation = vec3_t( -1.0, 1.0, 1.0 );
+	lights[0].type = light_t::DIRECTIONAL;
+	//lights[0].SetCutOff( 0.0 );
+	//lights[0].SetExp( 120.0 );
+
+	depth_map.CreateEmpty( SHADOW_QUALITY, SHADOW_QUALITY, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT );
+	depth_map.TexParameter( GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
+	depth_map.TexParameter( GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );
+	depth_map.TexParameter( GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+	depth_map.TexParameter( GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+	lights[0].MakeParent( &light_cam );
+	//light_cam.RotateLocalY( -PI/2 );
+
+	shdr = ass::LoadShdr( "shaders/test.shader" );
+
+	/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+	lvl::Register( (object_t*)&cube );
+	lvl::Register( (object_t*)&sphere );
+	lvl::Register( (object_t*)&flore );
+	lvl::Register( &lights[0] );
+	lvl::Register( &main_cam );
+	lvl::Register( &light_cam );
+
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_3 ] ) mover = &lights[0];
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		mover->local_rotation.Reorthogonalize();
+
+		lvl::InterpolateAllModels();
+		lvl::UpdateAllLights();
+		lvl::UpdateAllWorldTrfs();
+		lvl::UpdateAllCameras();
+
+
+
+		/// RENDER 2 TXTR
+		glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+		r::SetProjectionViewMatrices( light_cam );
+		r::SetViewport( 0, 0, SHADOW_QUALITY, SHADOW_QUALITY );
+
+		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+		glPolygonOffset(4.0f, 8.0f);
+		glEnable(GL_POLYGON_OFFSET_FILL);
+
+		r::SetGLState_Solid();
+		glDisable( GL_TEXTURE_2D );
+		glDisable( GL_LIGHTING );
+		lvl::RenderAll();
+
+		glActiveTexture( GL_TEXTURE0 );
+		depth_map.Bind();
+		glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, SHADOW_QUALITY, SHADOW_QUALITY);
+
+		/// END RENDER 2 TXTR
+
+
+		// RENDER
+		glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		r::SetProjectionViewMatrices( main_cam );
+		r::SetViewport( 0, 0, r::w, r::h );
+		lvl::UpdateAllLights();
+
+		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+		glDisable(GL_POLYGON_OFFSET_FILL);
+
+		//r::RenderGrid();
+		r::SetGLState_Solid();
+
+		shdr->TurnOn();
+
+		glActiveTexture( GL_TEXTURE0 + 0 );
+		depth_map.Bind();
+
+		const float mBias[] = {0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0};
+
+		glMatrixMode(GL_TEXTURE);
+		glLoadMatrixf( mBias );
+		r::MultMatrix( light_cam.projection_mat );
+		r::MultMatrix( light_cam.view_mat );
+		r::MultMatrix( main_cam.world_transformation );
+
+		glMatrixMode(GL_MODELVIEW);
+
+		glUniform1i( shdr->GetUniLocation( "s0" ), 0 );
+
+		lvl::RenderAll();
+
+		shdr->TurnOff();
+		glMatrixMode( GL_TEXTURE );
+		glLoadIdentity();
+		glMatrixMode(GL_MODELVIEW);
+
+		// Debug stuff
+//		r::SetGLState_Solid();
+//		glEnable( GL_TEXTURE_2D );
+//		glDisable( GL_LIGHTING );
+//		depth_map.Bind();
+//		float size = 2.0f;
+//		r::Color3( vec3_t( 1.0, 1.0, 1.0 ) );
+//		glBegin(GL_QUADS);
+//			glNormal3f( 0.0f, 0.0f, 1.0f);
+//			glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size,  -5);
+//			glTexCoord2f(1.0, 0.0); glVertex3f( size, -size,  -5);
+//			glTexCoord2f(1.0, 1.0); glVertex3f( size,  size,  -5);
+//			glTexCoord2f(0.0, 1.0); glVertex3f(-size,  size,  -5);
+//		glEnd();
+		// END RENDER
+
+
+		// print some debug stuff
+		hud::SetColor( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	cout << "Appl quits after " << hndl::GetTicks() << " ticks" << endl;
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 93 - 0
src/old_src/2009-5-11/material.cpp

@@ -0,0 +1,93 @@
+#include "material.h"
+#include "assets.h"
+
+
+material_t* material_t::used_previously = NULL;
+
+/*
+=======================================================================================================================================
+Load                                                                                                                                  =
+=======================================================================================================================================
+*/
+bool material_t::Load( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str [256];
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return false;
+	}
+
+	// the textures
+	file >> str >> textures_num;
+	for( uint i=0; i<textures_num; i++ )
+	{
+		file >> str >> str;
+		textures[i] = ass::LoadTxtr( str );
+	}
+
+	// shader
+	file >> str >> str;
+	shader = ass::LoadShdr( str );
+
+	// colors
+	for( uint i=0; i<COLS_NUM; i++ )
+	{
+		file >> str;
+		for( uint j=0; j<4; j++ )
+			file >> colors[i][j];
+	}
+
+	// shininess
+	file >> str >> shininess;
+
+	file.close();
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Use                                                                                                                                   =
+=======================================================================================================================================
+*/
+void material_t::Use()
+{
+	shader->Bind();
+
+//	if( used_previously == this ) return;
+//	used_previously = this;
+
+	glMaterialfv( GL_FRONT, GL_AMBIENT, &colors[AMBIENT_COL][0] );
+	glMaterialfv( GL_FRONT, GL_DIFFUSE, &colors[DIFFUSE_COL][0] );
+	glMaterialfv( GL_FRONT, GL_SPECULAR, &colors[SPECULAR_COL][0] );
+	glMaterialf( GL_FRONT, GL_SHININESS, shininess );
+
+
+	switch( textures_num )
+	{
+		case 4:
+			glUniform1i( shader->GetUniLocation( "t3" ), 3 );
+			glActiveTexture( GL_TEXTURE0 + 3 );
+			glBindTexture( GL_TEXTURE_2D, textures[3]->gl_id );
+		case 3:
+			glUniform1i( shader->GetUniLocation( "t2" ), 2 );
+			glActiveTexture( GL_TEXTURE0 + 2 );
+			glBindTexture( GL_TEXTURE_2D, textures[2]->gl_id );
+		case 2:
+			glUniform1i( shader->GetUniLocation( "t1" ), 1 );
+			glActiveTexture( GL_TEXTURE0 + 1 );
+			glBindTexture( GL_TEXTURE_2D, textures[1]->gl_id );
+		case 1:
+			glUniform1i( shader->GetUniLocation( "t0" ), 0 );
+			glActiveTexture( GL_TEXTURE0 + 0 );
+			glBindTexture( GL_TEXTURE_2D, textures[0]->gl_id );
+	}
+
+}
+
+
+
+

+ 48 - 0
src/old_src/2009-5-11/material.h

@@ -0,0 +1,48 @@
+#ifndef _MATERIAL_H_
+#define _MATERIAL_H_
+
+#include "common.h"
+#include "shaders.h"
+#include "math.h"
+#include "texture.h"
+#include "engine_class.h"
+
+
+class material_t: public data_class_t
+{
+	public:
+		static const uint TEXTURE_UNITS_NUM = 4;
+		texture_t* textures[TEXTURE_UNITS_NUM];
+		uint textures_num;
+
+		shader_prog_t* shader;
+
+		enum
+		{
+			AMBIENT_COL,
+			DIFFUSE_COL,
+			SPECULAR_COL,
+			COLS_NUM
+		};
+
+		vec4_t colors[COLS_NUM];
+		float shininess;
+
+		static material_t* used_previously;
+
+		 material_t(): shader(NULL), shininess(0.0)
+		{
+			for( uint i=0; i<TEXTURE_UNITS_NUM; i++ )
+				textures[i] = NULL;
+		}
+
+		~material_t() {}
+
+		bool Load( const char* filename );
+		void Unload();
+
+		void Use();
+};
+
+
+#endif

+ 2273 - 0
src/old_src/2009-5-11/math.cpp

@@ -0,0 +1,2273 @@
+#include "math.h"
+
+#define ME (*this)
+
+
+/**
+=======================================================================================================================================
+misc                                                                                                                                  =
+=======================================================================================================================================
+*/
+
+// MathSanityChecks
+// test if the compiler keeps the correct sizes for the classes
+void MathSanityChecks()
+{
+	const int fs = sizeof(float); // float size
+	if( sizeof(vec2_t)!=fs*2 || sizeof(vec3_t)!=fs*3 || sizeof(vec4_t)!=fs*4 || sizeof(quat_t)!=fs*4 || sizeof(euler_t)!=fs*3 ||
+	    sizeof(mat3_t)!=fs*9 || sizeof(mat4_t)!=fs*16 )
+		FATAL("Your compiler does class alignment. Quiting");
+}
+
+
+// 1/sqrt(f)
+float InvSqrt( float f )
+{
+#ifdef WIN32
+	float fhalf = 0.5f*f;
+	int i = *(int*)&f;
+	i = 0x5F3759DF - (i>>1);
+	f = *(float*)&i;
+	f *= 1.5f - fhalf*f*f;
+	return f;
+#elif defined( _DEBUG )
+	return 1/sqrtf(f);
+#else
+	float fhalf = 0.5f*f;
+	asm
+	(
+		"mov %1, %%eax;"
+		"sar %%eax;"
+		"mov $0x5F3759DF, %%ebx;"
+		"sub %%eax, %%ebx;"
+		"mov %%ebx, %0"
+		:"=g"(f)
+		:"g"(f)
+		:"%eax", "%ebx"
+	);
+	f *= 1.5f - fhalf*f*f;
+	return f;
+#endif
+}
+
+
+// PolynomialSinQuadrant
+// used in SinCos
+static float PolynomialSinQuadrant(float a)
+{
+	return a * ( 1.0f + a * a * (-0.16666f + a * a * (0.0083143f - a * a * 0.00018542f)));
+}
+
+
+// Sine and Cosine
+void SinCos( float a, float& sina, float& cosa )
+{
+#ifdef _DEBUG
+	sina = sin(a);
+	cosa = cos(a);
+#else
+	bool negative = false;
+	if (a < 0.0f)
+	{
+		a = -a;
+		negative = true;
+	}
+	const float k_two_over_pi = 1.0f / (PI/2.0f);
+	float float_a = k_two_over_pi * a;
+	int int_a = (int)float_a;
+
+	const float k_rational_half_pi = 201 / 128.0f;
+	const float k_remainder_half_pi = 4.8382679e-4f;
+
+	float_a = (a - k_rational_half_pi * int_a) - k_remainder_half_pi * int_a;
+
+	float float_a_minus_half_pi = (float_a - k_rational_half_pi) - k_remainder_half_pi;
+
+	switch( int_a & 3 )
+	{
+	case 0: // 0 - Pi/2
+		sina = PolynomialSinQuadrant(float_a);
+		cosa = PolynomialSinQuadrant(-float_a_minus_half_pi);
+		break;
+	case 1: // Pi/2 - Pi
+		sina = PolynomialSinQuadrant(-float_a_minus_half_pi);
+		cosa = PolynomialSinQuadrant(-float_a);
+		break;
+	case 2: // Pi - 3Pi/2
+		sina = PolynomialSinQuadrant(-float_a);
+		cosa = PolynomialSinQuadrant(float_a_minus_half_pi);
+		break;
+	case 3: // 3Pi/2 - 2Pi
+		sina = PolynomialSinQuadrant(float_a_minus_half_pi);
+		cosa = PolynomialSinQuadrant(float_a);
+		break;
+	};
+
+	if( negative )
+		sina = -sina;
+#endif
+}
+
+
+/**
+=======================================================================================================================================
+vec2_t                                                                                                                                =
+=======================================================================================================================================
+*/
+vec2_t vec2_t::zero = vec2_t(0.0, 0.0);
+
+// copy
+vec2_t& vec2_t::operator =( const vec2_t & b )
+{
+	x = b.x;
+	y = b.y;
+	return ME;
+}
+
+// vec3
+inline vec2_t::vec2_t( const vec3_t& v3 )
+{
+	x = v3.x;
+	y = v3.y;
+}
+
+// vec4
+inline vec2_t::vec2_t( const vec4_t& v4 )
+{
+	x = v4.x;
+	y = v4.y;
+}
+
+// +
+vec2_t vec2_t::operator +( const vec2_t& b ) const
+{
+	return vec2_t( x+b.x, y+b.y );
+}
+
+// +=
+vec2_t& vec2_t::operator +=( const vec2_t& b )
+{
+	x += b.x;
+	y += b.y;
+	return *this;
+}
+
+// -
+vec2_t vec2_t::operator -( const vec2_t& b ) const
+{
+	return vec2_t( x-b.x, y-b.y );
+}
+
+// -=
+vec2_t& vec2_t::operator -=( const vec2_t& b )
+{
+	x -= b.x;
+	y -= b.y;
+	return *this;
+}
+
+// negative
+vec2_t vec2_t::operator -() const
+{
+	return vec2_t( -x, -y );
+}
+
+// *
+vec2_t vec2_t::operator *( const vec2_t& b ) const
+{
+	return vec2_t( x*b.x, y*b.y );
+}
+
+// *=
+vec2_t& vec2_t::operator *=( const vec2_t& b )
+{
+	x *= b.x;
+	y *= b.y;
+	return *this;
+}
+
+// scale
+vec2_t vec2_t::operator *( float f ) const
+{
+	return vec2_t( x*f, y*f );
+}
+
+// scale
+vec2_t& vec2_t::operator *=( float f )
+{
+	x *= f;
+	y *= f;
+	return *this;
+}
+
+// scale
+vec2_t vec2_t::operator /( float f ) const
+{
+	DEBUG_ERR( IsZero(f) ); // division by zero
+	return vec2_t( x/f,  y/f );
+}
+
+// scale
+vec2_t& vec2_t::operator /=( float f )
+{
+	DEBUG_ERR( IsZero(f) ); // division by zero
+	x /= f;
+	y /= f;
+	return *this;
+}
+
+// ==
+bool vec2_t::operator ==( const vec2_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) ) ? true : false;
+}
+
+// !=
+bool vec2_t::operator !=( const vec2_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) ) ? false : true;
+}
+
+// Length
+float vec2_t::Length() const
+{
+	return Sqrt( x*x + y*y );
+}
+
+// set to zero
+void vec2_t::SetZero()
+{
+	x = y = 0.0f;
+}
+
+// Normalize
+void vec2_t::Normalize()
+{
+	ME *= InvSqrt( x*x + y*y );
+}
+
+// Normalized (return the normalized)
+vec2_t vec2_t::Normalized() const
+{
+	return ME * InvSqrt( x*x + y*y );
+}
+
+// Dot
+float vec2_t::Dot( const vec2_t& b ) const
+{
+	return x*b.x + y*b.y;
+}
+
+/**
+=======================================================================================================================================
+vec3_t                                                                                                                                =
+=======================================================================================================================================
+*/
+vec3_t vec3_t( 0.0, 0.0, 0.0 )(0.0f, 0.0f, 0.0f);
+vec3_t vec3_t( 1.0, 1.0, 1.0 )(1.0f, 1.0f, 1.0f);
+vec3_t vec3_t( 1.0, 0.0, 0.0 )(1.0f, 0.0f, 0.0f);
+vec3_t vec3_t( 0.0, 1.0, 0.0 )(0.0f, 1.0f, 0.0f);
+vec3_t vec3_t( 0.0, 0.0, 1.0 )(0.0f, 0.0f, 1.0f);
+
+// constructor
+// vec4
+vec3_t::vec3_t( const vec4_t& v4 )
+{
+	x = v4.x;
+	y = v4.y;
+	z = v4.z;
+}
+
+// constructor
+// quat
+vec3_t::vec3_t( const quat_t& q )
+{
+	x = q.x;
+	y = q.y;
+	z = q.z;
+}
+
+// copy
+vec3_t& vec3_t::operator =( const vec3_t& b )
+{
+	x = b.x;
+	y = b.y;
+	z = b.z;
+	return ME;
+}
+
+// +
+vec3_t vec3_t::operator +( const vec3_t& b ) const
+{
+	return vec3_t( x+b.x, y+b.y, z+b.z );
+}
+
+// +=
+vec3_t& vec3_t::operator +=( const vec3_t& b )
+{
+	x += b.x;
+	y += b.y;
+	z += b.z;
+	return ME;
+}
+
+// -
+vec3_t vec3_t::operator -( const vec3_t& b ) const
+{
+	return vec3_t( x-b.x, y-b.y, z-b.z );
+}
+
+// -=
+vec3_t& vec3_t::operator -=( const vec3_t& b )
+{
+	x -= b.x;
+	y -= b.y;
+	z -= b.z;
+	return ME;
+}
+
+// *
+vec3_t vec3_t::operator *( const vec3_t& b ) const
+{
+	return vec3_t( x*b.x, y*b.y, z*b.z );
+}
+
+// *=
+vec3_t& vec3_t::operator *=( const vec3_t& b )
+{
+	x *= b.x;
+	y *= b.y;
+	z *= b.z;
+	return *this;
+}
+
+// negative
+vec3_t vec3_t::operator -() const
+{
+	return vec3_t( -x, -y, -z );
+}
+
+// scale
+vec3_t vec3_t::operator *( float f ) const
+{
+	return vec3_t( x*f, y*f, z*f );
+}
+
+// scale
+vec3_t& vec3_t::operator *=( float f )
+{
+	x*=f;  y*=f;  z*=f;
+	return ME;
+}
+
+// down-scale
+vec3_t vec3_t::operator /( float f ) const
+{
+	DEBUG_ERR( IsZero(f) ); // division by zero
+	return vec3_t( x/f, y/f, z/f );
+}
+
+// down-scale
+vec3_t& vec3_t::operator /=( float f )
+{
+	DEBUG_ERR( IsZero(f) ); // division by zero
+	x /= f;
+	y /= f;
+	z /= f;
+	return ME;
+}
+
+// vec3 * mat3
+vec3_t vec3_t::operator *( const mat3_t& m3 ) const
+{
+	return vec3_t(
+		x*m3(0,0) + y*m3(1,0) + z*m3(2,0),
+		x*m3(0,1) + y*m3(1,1) + z*m3(2,1),
+		x*m3(0,2) + y*m3(1,2) + z*m3(2,2)
+	);
+}
+
+// ==
+bool vec3_t::operator ==( const vec3_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? true : false;
+}
+
+// !=
+bool vec3_t::operator !=( const vec3_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? false : true;
+}
+
+// Dot
+float vec3_t::Dot( const vec3_t& b ) const
+{
+	return x*b.x + y*b.y + z*b.z;
+}
+
+// cross prod
+vec3_t vec3_t::Cross( const vec3_t& b ) const
+{
+	return vec3_t( y*b.z-z*b.y, z*b.x-x*b.z, x*b.y-y*b.x );
+}
+
+// Length
+float vec3_t::Length() const
+{
+	return Sqrt( x*x + y*y + z*z );
+}
+
+// LengthSquared
+float vec3_t::LengthSquared() const
+{
+	return x*x + y*y + z*z;
+}
+
+// Normalize
+void vec3_t::Normalize()
+{
+	ME *= InvSqrt( x*x + y*y + z*z );
+}
+
+// Normalized (return the normalized)
+vec3_t vec3_t::Normalized() const
+{
+	return ME * InvSqrt( x*x + y*y + z*z );
+}
+
+// Project
+vec3_t vec3_t::Project( const vec3_t& to_this ) const
+{
+	return to_this * ( ME.Dot(to_this)/(to_this.Dot(to_this)) );
+}
+
+// Rotated
+vec3_t vec3_t::Rotated( const quat_t& q ) const
+{
+	DEBUG_ERR( !IsZero(1.0f-q.Length()) ); // Not normalized quat
+
+	float vmult = 2.0f*(q.x*x + q.y*y + q.z*z);
+	float crossmult = 2.0*q.w;
+	float pmult = crossmult*q.w - 1.0;
+
+	return vec3_t( pmult*x + vmult*q.x + crossmult*(q.y*z - q.z*y),
+							   pmult*y + vmult*q.y + crossmult*(q.z*x - q.x*z),
+	               pmult*z + vmult*q.z + crossmult*(q.x*y - q.y*x) );
+}
+
+// Rotate
+void vec3_t::Rotate( const quat_t& q )
+{
+	ME = Rotated(q);
+}
+
+// Print
+void vec3_t::Print() const
+{
+	for( int i=0; i<3; i++ )
+		cout << fixed << ME[i] << " ";
+	cout << "\n" << endl;
+}
+
+// Lerp
+vec3_t vec3_t::Lerp( const vec3_t& v1, float t ) const
+{
+	return (ME*(1.0f-t))+(v1*t);
+}
+
+// Transformed [mat3]
+vec3_t vec3_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	return ( !IsZero(scale-1.0f) ) ? (rotate * (ME * scale)) + translate : (rotate * ME) + translate;
+}
+
+// Transformed [mat3] no scale
+vec3_t vec3_t::Transformed( const vec3_t& translate, const mat3_t& rotate ) const
+{
+	return (rotate * ME) + translate;
+}
+
+// Transformed [quat]
+vec3_t vec3_t::Transformed( const vec3_t& translate, const quat_t& rotate, float scale ) const
+{
+	return ( !IsZero(scale-1.0f) ) ? (ME * scale).Rotated(rotate) + translate : ME.Rotated(rotate) + translate;
+}
+
+
+/**
+=======================================================================================================================================
+vec4_t                                                                                                                                =
+=======================================================================================================================================
+*/
+vec4_t vec4_t::zero = vec4_t(0.0, 0.0, 0.0, 0.0);
+vec4_t vec4_t::one = vec4_t(1.0, 1.0, 1.0, 1.0);
+vec4_t vec4_t::i = vec4_t(1.0, 0.0, 0.0, 0.0);
+vec4_t vec4_t::j = vec4_t(0.0, 1.0, 0.0, 0.0);
+vec4_t vec4_t::k = vec4_t(0.0, 0.0, 1.0, 0.0);
+vec4_t vec4_t::l = vec4_t(0.0, 0.0, 0.0, 1.0);
+
+// copy
+vec4_t& vec4_t::operator =( const vec4_t& b )
+{
+	x = b.x;
+	y = b.y;
+	z = b.z;
+	w = b.w;
+	return ME;
+}
+
+// +
+vec4_t vec4_t::operator +( const vec4_t& b ) const
+{
+	return vec4_t( x+b.x, y+b.y, z+b.z, w+b.w );
+}
+
+// +=
+vec4_t& vec4_t::operator +=( const vec4_t& b )
+{
+	x += b.x;
+	y += b.y;
+	z += b.z;
+	w += b.w;
+	return ME;
+}
+
+// -
+vec4_t vec4_t::operator -( const vec4_t& b ) const
+{
+	return vec4_t( x-b.x, y-b.y, z-b.z, w-b.w );
+}
+
+// -=
+vec4_t& vec4_t::operator -=( const vec4_t& b )
+{
+	x -= b.x;
+	y -= b.y;
+	z -= b.z;
+	w -= b.w;
+	return ME;
+}
+
+// negative
+vec4_t vec4_t::operator -() const
+{
+	return vec4_t( -x, -y, -z, -w );
+}
+
+// *
+vec4_t vec4_t::operator *( const vec4_t& b ) const
+{
+	return vec4_t( x*b.x, y*b.y, z*b.z, w*b.w );
+}
+
+// *=
+vec4_t& vec4_t::operator *=( const vec4_t& b )
+{
+	x *= b.x;
+	y *= b.y;
+	z *= b.z;
+	w *= b.w;
+	return *this;
+}
+
+// scale
+vec4_t vec4_t::operator *( float f ) const
+{
+	return vec4_t( x*f, y*f, z*f, w*f );
+}
+
+// scale
+vec4_t& vec4_t::operator *=( float f )
+{
+	x *= f;
+	y *= f;
+	z *= f;
+	w *= f;
+	return ME;
+}
+
+// down-scale
+vec4_t vec4_t::operator /( float f ) const
+{
+	DEBUG_ERR( IsZero(f) ); // Division by zero
+	return vec4_t( x/f, y/f, z/f, w/f );
+}
+
+// down-scale
+vec4_t& vec4_t::operator /=( float f )
+{
+	DEBUG_ERR( IsZero(f) ); // Division by zero
+	x /= f;
+	y /= f;
+	z /= f;
+	w /= f;
+	return ME;
+}
+
+// vec4 * mat4
+vec4_t vec4_t::operator *( const mat4_t& m4 ) const
+{
+	return vec4_t(
+		x*m4(0,0) + y*m4(1,0) + z*m4(2,0) + w*m4(3,0),
+		x*m4(0,1) + y*m4(1,1) + z*m4(2,1) + w*m4(3,1),
+		x*m4(0,2) + y*m4(1,2) + z*m4(2,2) + w*m4(3,2),
+		x*m4(0,3) + y*m4(1,3) + z*m4(2,3) + w*m4(3,3)
+	);
+}
+
+// ==
+bool vec4_t::operator ==( const vec4_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) && IsZero(w-b.w) ) ? true : false;
+}
+
+// !=
+bool vec4_t::operator !=( const vec4_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) && IsZero(w-b.w) ) ? false : true;
+}
+
+// Dot
+float vec4_t::Dot( const vec4_t& b ) const
+{
+	return x*b.x + y*b.y + z*b.z + w*b.w;
+}
+
+// Length
+float vec4_t::Length() const
+{
+	return Sqrt( x*x + y*y + z*z + w*w );
+}
+
+// Normalize
+void vec4_t::Normalize()
+{
+	ME *= InvSqrt( x*x +y*y + z*z + w*w );
+}
+
+// SetZero
+void vec4_t::SetZero()
+{
+	w = z = y = x = 0.0;
+}
+
+// Print
+void vec4_t::Print() const
+{
+	for( int i=0; i<4; i++ )
+		cout << fixed << ME[i] << " ";
+	cout << "\n" << endl;
+}
+
+
+/**
+=======================================================================================================================================
+quat_t                                                                                                                                =
+=======================================================================================================================================
+*/
+quat_t quat_t::zero = quat_t( 0.0, 0.0, 0.0, 0.0 );
+quat_t quat_t::ident = quat_t( 1.0, 0.0, 0.0, 0.0 );
+
+
+// copy
+quat_t& quat_t::operator =( const quat_t& b )
+{
+	w = b.w;
+	x = b.x;
+	y = b.y;
+	z = b.z;
+	return ME;
+}
+
+// +
+quat_t quat_t::operator +( const quat_t& b ) const
+{
+	return quat_t( w+b.w, x+b.x, y+b.y, z+b.z );
+}
+
+// +=
+quat_t& quat_t::operator +=( const quat_t& b )
+{
+	w += b.w;
+	x += b.x;
+	y += b.y;
+	z += b.z;
+	return ME;
+}
+
+// -
+quat_t quat_t::operator -( const quat_t& b ) const
+{
+	return quat_t( w-b.w, x-b.x, y-b.y, z-b.z );
+}
+
+// -=
+quat_t& quat_t::operator -=( const quat_t& b )
+{
+	w -= b.w;
+	x -= b.x;
+	y -= b.y;
+	z -= b.z;
+	return ME;
+}
+
+// *
+quat_t quat_t::operator *( const quat_t& b ) const
+{
+	return quat_t(
+		-x * b.x - y * b.y - z * b.z + w * b.w,
+		 x * b.w + y * b.z - z * b.y + w * b.x,
+		-x * b.z + y * b.w + z * b.x + w * b.y,
+		 x * b.y - y * b.x + z * b.w + w * b.z
+	);
+}
+
+// *=
+quat_t& quat_t::operator *=( const quat_t& b )
+{
+	ME = ME*b;
+	return ME;
+}
+
+// quat * float
+quat_t quat_t::operator *( float f ) const
+{
+	return quat_t( w*f, x*f,y*f, z*f );
+}
+
+// quat * float (self)
+quat_t& quat_t::operator *=( float f )
+{
+	w *= f;
+	x *= f;
+	y *= f;
+	z *= f;
+	return *this;
+}
+
+// quat / float
+quat_t quat_t::operator /( float f ) const
+{
+	DEBUG_ERR( IsZero(f) ); // Division by zero
+	return quat_t( w/f, x/f, y/f, z/f );
+}
+
+// quat / float (self)
+quat_t& quat_t::operator /=( float f )
+{
+	DEBUG_ERR( IsZero(f) ); // Division by zero
+	w /= f;
+	x /= f;
+	y /= f;
+	z /= f;
+	return ME;
+}
+
+// ==
+bool quat_t::operator ==( const quat_t& b ) const
+{
+	return ( IsZero(w-b.w) && IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? true : false;
+}
+
+// !=
+bool quat_t::operator !=( const quat_t& b ) const
+{
+	return ( IsZero(w-b.w) && IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? false : true;
+}
+
+// Conjugate
+void quat_t::Conjugate()
+{
+	x = -x;
+	y = -y;
+	z = -z;
+}
+
+// Conjugated
+quat_t quat_t::Conjugated() const
+{
+	return quat_t( w, -x, -y, -z );
+}
+
+// Normalize
+void quat_t::Normalize()
+{
+	ME *= InvSqrt( x*x + y*y + z*z + w*w );
+}
+
+// SetIdent
+void quat_t::SetIdent()
+{
+	ME = ident;
+}
+
+// SetZero
+void quat_t::SetZero()
+{
+	z = y = x = w = 0.0;
+}
+
+// Length
+float quat_t::Length() const
+{
+	return Sqrt( w*w + x*x + y*y + z*z );
+}
+
+// Invert
+void quat_t::Invert()
+{
+	float norm = w*w + x*x + y*y + z*z;
+
+	DEBUG_ERR( IsZero(norm) ); // Norm is zero
+
+	float normi = 1.0f / norm;
+	ME = quat_t( normi*w, -normi*x, -normi*y, -normi*z );
+}
+
+// Print
+void quat_t::Print() const
+{
+	cout << fixed << "(w,x,y,z) = " << w << ' ' << x << ' ' << y << ' ' << z  << '\n' << endl;
+}
+
+// 3x3 to quat
+void quat_t::Set( const mat3_t& a )
+{
+	float trace = a(0, 0) + a(1, 1) + a(2, 2) + 1.0f;
+	if( trace > EPSILON )
+	{
+		float s = 0.5f * InvSqrt(trace);
+		w = 0.25f / s;
+		x = ( a(2, 1) - a(1, 2) ) * s;
+		y = ( a(0, 2) - a(2, 0) ) * s;
+		z = ( a(1, 0) - a(0, 1) ) * s;
+	}
+	else
+	{
+		if( a(0, 0) > a(1, 1) && a(0, 0) > a(2, 2) )
+		{
+			float s = 2.0f * ( Sqrt( 1.0f + a(0, 0) - a(1, 1) - a(2, 2)) );
+			w = (a(1, 2) - a(2, 1) ) / s;
+			x = 0.25f * s;
+			y = (a(0, 1) + a(1, 0) ) / s;
+			z = (a(0, 2) + a(2, 0) ) / s;
+		}
+		else if( a(1, 1) > a(2, 2) )
+		{
+			float s = 2.0f * ( Sqrt( 1.0f + a(1, 1) - a(0, 0) - a(2, 2)) );
+			w = (a(0, 2) - a(2, 0) ) / s;
+			x = (a(0, 1) + a(1, 0) ) / s;
+			y = 0.25f * s;
+			z = (a(1, 2) + a(2, 1) ) / s;
+		}
+		else
+		{
+			float s = 2.0f * ( Sqrt( 1.0f + a(2, 2) - a(0, 0) - a(1, 1) ) );
+			w = (a(0, 1) - a(1, 0) ) / s;
+			x = (a(0, 2) + a(2, 0) ) / s;
+			y = (a(1, 2) + a(2, 1) ) / s;
+			z = 0.25f * s;
+		}
+	}
+}
+
+// euler to quat
+void quat_t::Set( const euler_t &e )
+{
+	float cx, sx;
+	SinCos( e.heading()*0.5, sx, cx );
+
+	float cy, sy;
+	SinCos( e.attitude()*0.5, sy, cy );
+
+	float cz, sz;
+	SinCos( e.bank()*0.5, sz, cz );
+
+	float cxcy = cx*cy;
+	float sxsy = sx*sy;
+	w = cxcy*cz - sxsy*sz;
+	x = cxcy*sz + sxsy*cz;
+	y = sx*cy*cz + cx*sy*sz;
+	z = cx*sy*cz - sx*cy*sz;
+}
+
+// Set
+// axis_ang
+void quat_t::Set( const axisang_t& axisang )
+{
+	float lengthsq = axisang.axis.LengthSquared();
+	if ( IsZero( lengthsq ) )
+	{
+		SetIdent();
+		return;
+	}
+
+	float rad = axisang.ang * 0.5f;
+
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	float scalefactor = sintheta/ Sqrt(lengthsq);
+
+	w = costheta;
+	x = scalefactor * axisang.axis.x;
+	y = scalefactor * axisang.axis.y;
+	z = scalefactor * axisang.axis.z;
+}
+
+// CalcFromVecVec
+void quat_t::CalcFromVecVec( const vec3_t& from, const vec3_t& to )
+{
+	vec3_t axis( from.Cross(to) );
+	ME = quat_t(  from.Dot(to), axis.x, axis.y, axis.z);
+	Normalize();
+	w += 1.0f;
+
+	if( w <= EPSILON )
+	{
+		if( from.z*from.z > from.x*from.x )
+			ME = quat_t( 0.0f, 0.0f, from.z, -from.y );
+		else
+			ME = quat_t( 0.0f, from.y, -from.x, 0.0f );
+	}
+	Normalize();
+}
+
+// Set
+// vec3
+void quat_t::Set( const vec3_t& v )
+{
+	w = 0.0;
+	x = v.x;
+	y = v.y;
+	z = v.y;
+}
+
+// Set
+// vec4
+void quat_t::Set( const vec4_t& v )
+{
+	w = v.w;
+	x = v.x;
+	y = v.y;
+	z = v.y;
+}
+
+// Dot
+float quat_t::Dot( const quat_t& b ) const
+{
+	return w*b.w + x*b.x + y*b.y + z*b.z;
+}
+
+// SLERP
+quat_t quat_t::Slerp( const quat_t& q1_, float t ) const
+{
+	const quat_t& q0 = ME;
+	quat_t q1( q1_ );
+	float cos_half_theta = q0.w*q1.w + q0.x*q1.x + q0.y*q1.y + q0.z*q1.z;
+	if( cos_half_theta < 0.0 )
+	{
+		q1 *= -1.0f; // quat changes
+		cos_half_theta = -cos_half_theta;
+	}
+	if( fabs(cos_half_theta) >= 1.0f )
+	{
+		return quat_t( q0 );
+	}
+
+	float half_theta = acos( cos_half_theta );
+	float sin_half_theta = Sqrt(1.0f - cos_half_theta*cos_half_theta);
+
+	if( fabs(sin_half_theta) < 0.001f )
+	{
+		return quat_t( q0*0.5f + q1*0.5f );
+	}
+	float ratio_a = sin((1.0f - t) * half_theta) / sin_half_theta;
+	float ratio_b = sin(t * half_theta) / sin_half_theta;
+	quat_t tmp, tmp1, sum;
+	tmp = q0*ratio_a;
+	tmp1 = q1*ratio_b;
+	sum = tmp + tmp1;
+	sum.Normalize();
+	return quat_t( sum );
+}
+
+
+/**
+=======================================================================================================================================
+euler_t                                                                                                                               =
+=======================================================================================================================================
+*/
+
+// cpy
+euler_t& euler_t::operator =( const euler_t& b )
+{
+	memcpy( this, &b, sizeof(euler_t) );
+	return ME;
+}
+
+// LoadZero
+void euler_t::SetZero()
+{
+	z = y = x = 0.0;
+}
+
+// Set
+// quat
+void euler_t::Set( const quat_t& q )
+{
+	float test = q.x*q.y + q.z*q.w;
+	if (test > 0.499f)
+	{
+		heading() = 2.0f * atan2( q.x, q.w );
+		attitude() = PI/2.0f;
+		bank() = 0.0;
+		return;
+	}
+	if (test < -0.499f)
+	{
+		heading() = -2.0f * atan2( q.x, q.w );
+		attitude() = -PI/2.0f;
+		bank() = 0.0;
+		return;
+	}
+
+	float sqx = q.x*q.x;
+	float sqy = q.y*q.y;
+	float sqz = q.z*q.z;
+	heading() = atan2( 2.0f*q.y*q.w-2.0f*q.x*q.z, 1.0f-2.0f*sqy-2.0f*sqz );
+	attitude() = asin( 2.0f*test );
+	bank() = atan2( 2.0f*q.x*q.w-2.0f*q.y*q.z, 1.0f-2.0f*sqx-2.0f*sqz );
+}
+
+// Set
+// mat3
+void euler_t::Set( const mat3_t& m3 )
+{
+	float cx, sx;
+	float cy, sy;
+	float cz, sz;
+
+	sy = m3(0,2);
+	cy = Sqrt( 1.0f - sy*sy );
+	// normal case
+	if ( !IsZero( cy ) )
+	{
+		float factor = 1.0f/cy;
+		sx = -m3(1,2) * factor;
+		cx = m3(2,2) * factor;
+		sz = -m3(0,1) * factor;
+		cz = m3(0,0) * factor;
+	}
+	// x and z axes aligned
+	else
+	{
+		sz = 0.0f;
+		cz = 1.0f;
+		sx = m3(2,1);
+		cx = m3(1,1);
+	}
+
+	z = atan2f( sz, cz );
+	y = atan2f( sy, cy );
+	x = atan2f( sx, cx );
+}
+
+// Print
+void euler_t::Print() const
+{
+	for( int i=0; i<3; i++ )
+		cout << fixed << ME[i] << "(" << ME[i]/PI << " PI) Rad" << " / " << ToDegrees(ME[i]) << " Deg" << "\n";
+	cout << endl;
+}
+
+
+/**
+=======================================================================================================================================
+axisang_t                                                                                                                             =
+=======================================================================================================================================
+*/
+
+// Set
+// quat
+void axisang_t::Set( const quat_t& q )
+{
+	ang = 2.0f*acos( q.w );
+	float length = Sqrt( 1.0f - q.w*q.w );
+	if( IsZero(length) )
+		axis.SetZero();
+	else
+	{
+		length = 1.0f/length;
+		axis = vec3_t( q.x*length, q.y*length, q.z*length );
+	}
+}
+
+// Set
+// mat3
+void axisang_t::Set( const mat3_t& m3 )
+{
+	if( (fabs(m3(0,1)-m3(1,0))< EPSILON)  && (fabs(m3(0,2)-m3(2,0))< EPSILON)  && (fabs(m3(1,2)-m3(2,1))< EPSILON) )
+	{
+
+		if( (fabs(m3(0,1)+m3(1,0)) < 0.1 ) && (fabs(m3(0,2)+m3(2,0)) < 0.1) && (fabs(m3(1,2)+m3(2,1)) < 0.1) && (fabs(m3(0,0)+m3(1,1)+m3(2,2))-3) < 0.1 )
+		{
+			axis = vec3_t( 1.0f, 0.0f, 0.0f );
+			ang = 0.0f;
+			return;
+		}
+
+		ang = PI;
+		axis.x = (m3(0,0)+1)/2;
+		if( axis.x > 0.0f )
+			axis.x = Sqrt(axis.x);
+		else
+			axis.x = 0;
+		axis.y = (m3(1,1)+1)/2;
+		if( axis.y > 0 )
+			axis.y = Sqrt(axis.y);
+		else
+			axis.y = 0;
+		axis.z = (m3(2,2)+1)/2;
+		if( axis.z > 0 )
+			axis.z = Sqrt(axis.z);
+		else
+			axis.z = 0.0f;
+
+		bool xZero = ( fabs(axis.x)<EPSILON );
+		bool yZero = ( fabs(axis.y)<EPSILON );
+		bool zZero = ( fabs(axis.z)<EPSILON );
+		bool xyPositive = ( m3(0,1) > 0 );
+		bool xzPositive = ( m3(0,2) > 0 );
+		bool yzPositive = ( m3(1,2) > 0 );
+		if( xZero && !yZero && !zZero ){
+			if( !yzPositive ) axis.y = -axis.y;
+		}else if( yZero && !zZero ){
+			if( !xzPositive ) axis.z = -axis.z;
+		}else if (zZero){
+			if( !xyPositive ) axis.x = -axis.x;
+		}
+
+		return;
+	}
+
+	float s = Sqrt((m3(2,1) - m3(1,2))*(m3(2,1) - m3(1,2))+(m3(0,2) - m3(2,0))*(m3(0,2) - m3(2,0))+(m3(1,0) - m3(0,1))*(m3(1,0) - m3(0,1)));
+
+	if( fabs(s) < 0.001 ) s = 1;
+
+	ang = acos( ( m3(0,0) + m3(1,1) + m3(2,2) - 1)/2 );
+	axis.x= (m3(2,1) - m3(1,2))/s;
+	axis.y= (m3(0,2) - m3(2,0))/s;
+	axis.z= (m3(1,0) - m3(0,1))/s;
+}
+
+
+
+/**
+=======================================================================================================================================
+matrix 3x3                                                                                                                            =
+=======================================================================================================================================
+*/
+static float mat3_ident[3*3] = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 };
+mat3_t mat3_t::ident( (const mat3_t&)mat3_ident );
+static float mat3_zero[3*3] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+mat3_t mat3_t::zero( (const mat3_t&)mat3_zero );
+
+
+// copy
+mat3_t& mat3_t::operator =( const mat3_t& b )
+{
+	ME[0] = b[0];
+	ME[1] = b[1];
+	ME[2] = b[2];
+	ME[3] = b[3];
+	ME[4] = b[4];
+	ME[5] = b[5];
+	ME[6] = b[6];
+	ME[7] = b[7];
+	ME[8] = b[8];
+	return ME;
+}
+
+// 3x3 + 3x3
+mat3_t mat3_t::operator +( const mat3_t& b ) const
+{
+	mat3_t c;
+	for( int i=0; i<9; i++ )
+		c[i] = ME[i] + b[i];
+	return c;
+}
+
+// 3x3 + 3x3 (self)
+mat3_t& mat3_t::operator +=( const mat3_t& b )
+{
+	for( int i=0; i<9; i++ )
+		ME[i] += b[i];
+	return ME;
+}
+
+// 3x3 - 3x3
+mat3_t mat3_t::operator -( const mat3_t& b ) const
+{
+	mat3_t c;
+	for( int i=0; i<9; i++ )
+		c[i] = ME[i] - b[i];
+	return c;
+}
+
+// 3x3 - 3x3 (self)
+mat3_t& mat3_t::operator -=( const mat3_t& b )
+{
+	for( int i=0; i<9; i++ )
+		ME[i] -= b[i];
+	return *this;
+}
+
+// 3x3 * 3x3
+mat3_t mat3_t::operator *( const mat3_t& b ) const
+{
+	mat3_t c;
+	c(0, 0) = ME(0, 0)*b(0, 0) + ME(0, 1)*b(1, 0) + ME(0, 2)*b(2, 0);
+	c(0, 1) = ME(0, 0)*b(0, 1) + ME(0, 1)*b(1, 1) + ME(0, 2)*b(2, 1);
+	c(0, 2) = ME(0, 0)*b(0, 2) + ME(0, 1)*b(1, 2) + ME(0, 2)*b(2, 2);
+	c(1, 0) = ME(1, 0)*b(0, 0) + ME(1, 1)*b(1, 0) + ME(1, 2)*b(2, 0);
+	c(1, 1) = ME(1, 0)*b(0, 1) + ME(1, 1)*b(1, 1) + ME(1, 2)*b(2, 1);
+	c(1, 2) = ME(1, 0)*b(0, 2) + ME(1, 1)*b(1, 2) + ME(1, 2)*b(2, 2);
+	c(2, 0) = ME(2, 0)*b(0, 0) + ME(2, 1)*b(1, 0) + ME(2, 2)*b(2, 0);
+	c(2, 1) = ME(2, 0)*b(0, 1) + ME(2, 1)*b(1, 1) + ME(2, 2)*b(2, 1);
+	c(2, 2) = ME(2, 0)*b(0, 2) + ME(2, 1)*b(1, 2) + ME(2, 2)*b(2, 2);
+	return c;
+}
+
+// 3x3 * 3x3 (self)
+mat3_t& mat3_t::operator *=( const mat3_t& b )
+{
+	ME = ME * b;
+	return ME;
+}
+
+// 3x3 * float
+mat3_t mat3_t::operator *( float f ) const
+{
+	mat3_t c;
+	for( uint i=0; i<9; i++ )
+		c[i] = ME[i] * f;
+	return c;
+}
+
+// 3x3 * float (self)
+mat3_t& mat3_t::operator *=( float f )
+{
+	for( uint i=0; i<9; i++ )
+		ME[i] *= f;
+	return *this;
+}
+
+// 3x3 * vec3
+vec3_t mat3_t::operator *( const vec3_t& b ) const
+{
+	return vec3_t(
+		ME(0, 0)*b.x + ME(0, 1)*b.y + ME(0, 2)*b.z,
+		ME(1, 0)*b.x + ME(1, 1)*b.y + ME(1, 2)*b.z,
+		ME(2, 0)*b.x + ME(2, 1)*b.y + ME(2, 2)*b.z
+	);
+}
+
+// ==
+bool mat3_t::operator ==( const mat3_t& b ) const
+{
+	for( int i=0; i<9; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return false;
+	return true;
+}
+
+// !=
+bool mat3_t::operator !=( const mat3_t& b ) const
+{
+	for( int i=0; i<9; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return true;
+	return false;
+}
+
+// SetRows
+void mat3_t::SetRows( const vec3_t& a, const vec3_t& b, const vec3_t& c )
+{
+	ME(0,0) = a.x;
+	ME(0,1) = a.y;
+	ME(0,2) = a.z;
+	ME(1,0) = b.x;
+	ME(1,1) = b.y;
+	ME(1,2) = b.z;
+	ME(2,0) = c.x;
+	ME(2,1) = c.y;
+	ME(2,2) = c.z;
+}
+
+// SetColumns
+void mat3_t::SetColumns( const vec3_t& a, const vec3_t& b, const vec3_t& c )
+{
+	ME(0,0) = a.x;
+	ME(1,0) = a.y;
+	ME(2,0) = a.z;
+	ME(0,1) = b.x;
+	ME(1,1) = b.y;
+	ME(2,1) = b.z;
+	ME(0,2) = c.x;
+	ME(1,2) = c.y;
+	ME(2,2) = c.z;
+}
+
+// GetRows
+void mat3_t::GetRows( vec3_t& a, vec3_t& b, vec3_t& c ) const
+{
+	a.x = ME(0,0);
+	a.y = ME(0,1);
+	a.z = ME(0,2);
+	b.x = ME(1,0);
+	b.y = ME(1,1);
+	b.z = ME(1,2);
+	c.x = ME(2,0);
+	c.y = ME(2,1);
+	c.z = ME(2,2);
+}
+
+// GetColumns
+void mat3_t::GetColumns( vec3_t& a, vec3_t& b, vec3_t& c ) const
+{
+	a.x = ME(0,0);
+	a.y = ME(1,0);
+	a.z = ME(2,0);
+	b.x = ME(0,1);
+	b.y = ME(1,1);
+	b.z = ME(2,1);
+	c.x = ME(0,2);
+	c.y = ME(1,2);
+	c.z = ME(2,2);
+}
+
+// Set
+// quat
+void mat3_t::Set( const quat_t& q )
+{
+	DEBUG_ERR( !IsZero( 1.0f - q.Length()) ); // Not normalized quat
+
+	float xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
+
+	xs = q.x+q.x;
+	ys = q.y+q.y;
+	zs = q.z+q.z;
+	wx = q.w*xs;
+	wy = q.w*ys;
+	wz = q.w*zs;
+	xx = q.x*xs;
+	xy = q.x*ys;
+	xz = q.x*zs;
+	yy = q.y*ys;
+	yz = q.y*zs;
+	zz = q.z*zs;
+
+	ME(0,0) = 1.0f - (yy + zz);
+	ME(0,1) = xy - wz;
+	ME(0,2) = xz + wy;
+
+	ME(1,0) = xy + wz;
+	ME(1,1) = 1.0f - (xx + zz);
+	ME(1,2) = yz - wx;
+
+	ME(2,0) = xz - wy;
+	ME(2,1) = yz + wx;
+	ME(2,2) = 1.0f - (xx + yy);
+}
+
+// Set
+// euler
+void  mat3_t::Set( const euler_t& e )
+{
+	float ch, sh, ca, sa, cb, sb;
+  SinCos( e.heading(), sh, ch );
+  SinCos( e.attitude(), sa, ca );
+  SinCos( e.bank(), sb, cb );
+
+  ME(0, 0) = ch * ca;
+  ME(0, 1) = sh*sb - ch*sa*cb;
+  ME(0, 2) = ch*sa*sb + sh*cb;
+  ME(1, 0) = sa;
+  ME(1, 1) = ca*cb;
+  ME(1, 2) = -ca*sb;
+  ME(2, 0) = -sh*ca;
+  ME(2, 1) = sh*sa*cb + ch*sb;
+  ME(2, 2) = -sh*sa*sb + ch*cb;
+}
+
+// Set
+// axis angles
+void mat3_t::Set( const axisang_t& axisang )
+{
+	DEBUG_ERR( !IsZero( 1.0f-axisang.axis.Length() ) ); // Not normalized axis
+
+	float c, s;
+	SinCos( axisang.ang, s, c );
+	float t = 1.0f - c;
+
+	const vec3_t& axis = axisang.axis;
+	ME(0,0) = c + axis.x*axis.x*t;
+	ME(1,1) = c + axis.y*axis.y*t;
+	ME(2,2) = c + axis.z*axis.z*t;
+
+	float tmp1 = axis.x*axis.y*t;
+	float tmp2 = axis.z*s;
+	ME(1,0) = tmp1 + tmp2;
+	ME(0,1) = tmp1 - tmp2;
+	tmp1 = axis.x*axis.z*t;
+	tmp2 = axis.y*s;
+	ME(2,0) = tmp1 - tmp2;
+	ME(0,2) = tmp1 + tmp2;    tmp1 = axis.y*axis.z*t;
+	tmp2 = axis.x*s;
+	ME(2,1) = tmp1 + tmp2;
+	ME(1,2) = tmp1 - tmp2;
+
+}
+
+// SetRotationX
+void mat3_t::SetRotationX( float rad )
+{
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	ME(0,0) = 1.0f;
+	ME(0,1) = 0.0f;
+	ME(0,2) = 0.0f;
+	ME(1,0) = 0.0f;
+	ME(1,1) = costheta;
+	ME(1,2) = -sintheta;
+	ME(2,0) = 0.0f;
+	ME(2,1) = sintheta;
+	ME(2,2) = costheta;
+}
+
+// SetRotationY
+void mat3_t::SetRotationY( float rad )
+{
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	ME(0,0) = costheta;
+	ME(0,1) = 0.0f;
+	ME(0,2) = sintheta;
+	ME(1,0) = 0.0f;
+	ME(1,1) = 1.0f;
+	ME(1,2) = 0.0f;
+	ME(2,0) = -sintheta;
+	ME(2,1) = 0.0f;
+	ME(2,2) = costheta;
+}
+
+// LoadRotationZ
+void mat3_t::SetRotationZ( float rad )
+{
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	ME(0,0) = costheta;
+	ME(0,1) = -sintheta;
+	ME(0,2) = 0.0f;
+	ME(1,0) = sintheta;
+	ME(1,1) = costheta;
+	ME(1,2) = 0.0f;
+	ME(2,0) = 0.0f;
+	ME(2,1) = 0.0f;
+	ME(2,2) = 1.0f;
+}
+
+// RotateXAxis
+/* the slow code is in comments and above the comments the optimized one
+If we analize the mat3 we can extract the 3 unit vectors rotated by the mat3. The 3 rotated vectors are in mat's colomns.
+This means that: mat3.colomn[0] == i*mat3. RotateXAxis() rotates rad angle not from i vector (aka x axis) but
+from the vector from colomn 0*/
+void mat3_t::RotateXAxis( float rad )
+{
+	float sina, cosa;
+	SinCos( rad, sina, cosa );
+
+	/*vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );*/
+
+	// z_axis = z_axis*cosa - y_axis*sina;
+	ME(0,2) = ME(0,2)*cosa - ME(0,1)*sina;
+	ME(1,2) = ME(1,2)*cosa - ME(1,1)*sina;
+	ME(2,2) = ME(2,2)*cosa - ME(2,1)*sina;
+
+	// z_axis.Normalize();
+	float len = InvSqrt( ME(0,2)*ME(0,2) + ME(1,2)*ME(1,2) + ME(2,2)*ME(2,2) );
+	ME(0,2) *= len;
+	ME(1,2) *= len;
+	ME(2,2) *= len;
+
+	// y_axis = z_axis * x_axis;
+	ME(0,1) = ME(1,2)*ME(2,0) - ME(2,2)*ME(1,0);
+	ME(1,1) = ME(2,2)*ME(0,0) - ME(0,2)*ME(2,0);
+	ME(2,1) = ME(0,2)*ME(1,0) - ME(1,2)*ME(0,0);
+
+	// y_axis.Normalize();
+	/*len = InvSqrt( ME(0,1)*ME(0,1) + ME(1,1)*ME(1,1) + ME(2,1)*ME(2,1) );
+	ME(0,1) *= len;
+	ME(1,1) *= len;
+	ME(2,1) *= len;*/
+
+	// SetColumns( x_axis, y_axis, z_axis );
+
+}
+
+// RotateYAxis
+void mat3_t::RotateYAxis( float rad )
+{
+	float sina, cosa;
+	SinCos( rad, sina, cosa );
+
+	/*vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );*/
+
+	// z_axis = z_axis*cosa + x_axis*sina;
+	ME(0,2) = ME(0,2)*cosa + ME(0,0)*sina;
+	ME(1,2) = ME(1,2)*cosa + ME(1,0)*sina;
+	ME(2,2) = ME(2,2)*cosa + ME(2,0)*sina;
+
+	// z_axis.Normalize();
+	float len = InvSqrt( ME(0,2)*ME(0,2) + ME(1,2)*ME(1,2) + ME(2,2)*ME(2,2) );
+	ME(0,2) *= len;
+	ME(1,2) *= len;
+	ME(2,2) *= len;
+
+	// x_axis = (z_axis*y_axis) * -1.0f;
+	ME(0,0) = ME(2,2)*ME(1,1) - ME(1,2)*ME(2,1);
+	ME(1,0) = ME(0,2)*ME(2,1) - ME(2,2)*ME(0,1);
+	ME(2,0) = ME(1,2)*ME(0,1) - ME(0,2)*ME(1,1);
+
+	// x_axis.Normalize();
+	/*len = InvSqrt( ME(0,0)*ME(0,0) + ME(1,0)*ME(1,0) + ME(2,0)*ME(2,0) );
+	ME(0,0) *= len;
+	ME(1,0) *= len;
+	ME(2,0) *= len;*/
+
+	// SetColumns( x_axis, y_axis, z_axis );
+}
+
+
+// RotateZAxis
+void mat3_t::RotateZAxis( float rad )
+{
+	float sina, cosa;
+	SinCos( rad, sina, cosa );
+
+	/*vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );*/
+
+	// x_axis = x_axis*cosa + y_axis*sina;
+	ME(0,0) = ME(0,0)*cosa + ME(0,1)*sina;
+	ME(1,0) = ME(1,0)*cosa + ME(1,1)*sina;
+	ME(2,0) = ME(2,0)*cosa + ME(2,1)*sina;
+
+	// x_axis.Normalize();
+	float len = InvSqrt( ME(0,0)*ME(0,0) + ME(1,0)*ME(1,0) + ME(2,0)*ME(2,0) );
+	ME(0,0) *= len;
+	ME(1,0) *= len;
+	ME(2,0) *= len;
+
+	// y_axis = z_axis*x_axis;
+	ME(0,1) = ME(1,2)*ME(2,0) - ME(2,2)*ME(1,0);
+	ME(1,1) = ME(2,2)*ME(0,0) - ME(0,2)*ME(2,0);
+	ME(2,1) = ME(0,2)*ME(1,0) - ME(1,2)*ME(0,0);
+
+	// y_axis.Normalize();
+	/*len = InvSqrt( ME(0,1)*ME(0,1) + ME(1,1)*ME(1,1) + ME(2,1)*ME(2,1) );
+	ME(0,1) *= len;
+	ME(1,1) *= len;
+	ME(2,1) *= len;*/
+
+	//SetColumns( x_axis, y_axis, z_axis );
+}
+
+// Transpose
+void mat3_t::Transpose()
+{
+	float temp = ME(0,1);
+	ME(0,1) = ME(1,0);
+	ME(1,0) = temp;
+	temp = ME(0,2);
+	ME(0,2) = ME(2,0);
+	ME(2,0) = temp;
+	temp = ME(1,2);
+	ME(1,2) = ME(2,1);
+	ME(2,1) = temp;
+}
+
+// Transposed
+mat3_t mat3_t::Transposed() const
+{
+	mat3_t m3;
+	m3[0] = ME[0];
+	m3[1] = ME[3];
+	m3[2] = ME[6];
+	m3[3] = ME[1];
+	m3[4] = ME[4];
+	m3[5] = ME[7];
+	m3[6] = ME[2];
+	m3[7] = ME[5];
+	m3[8] = ME[8];
+	return m3;
+}
+
+// Reorthogonalize
+void mat3_t::Reorthogonalize()
+{
+	// method 1: standard orthogonalization method
+	/*mat3_t correction_m3 =
+	(
+		(mat3_t::ident * 3.0f) -
+		(ME * ME.Transposed())
+	) * 0.5f;
+
+	ME = correction_m3 * ME;*/
+
+	// method 2: Gram-Schmidt method with a twist for z_axis
+	vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );
+
+	x_axis.Normalize();
+
+	y_axis = y_axis - ( x_axis * x_axis.Dot(y_axis) );
+	y_axis.Normalize();
+
+	z_axis = x_axis.Cross(y_axis);
+
+	SetColumns( x_axis, y_axis, z_axis );
+}
+
+// SetIdent
+void mat3_t::SetIdent()
+{
+	ME = ident;
+}
+
+// SetZero
+void mat3_t::SetZero()
+{
+	ME[0] = ME[1] = ME[2] = ME[3] = ME[4] = ME[5] = ME[6] = ME[7] = ME[8] = 0.0f;
+}
+
+// Print
+void mat3_t::Print() const
+{
+	for( int i=0; i<3; i++ )
+	{
+		for( int j=0; j<3; j++ )
+			cout << fixed << ME(i, j) << " ";
+		cout << endl;
+	}
+	cout << endl;
+}
+
+// Determinant
+float mat3_t::Det() const
+{
+	/* accurate method:
+	return ME(0, 0)*ME(1, 1)*ME(2, 2) + ME(0, 1)*ME(1, 2)*ME(2, 0) + ME(0, 2)*ME(1, 0)*ME(2, 1)
+	- ME(0, 0)*ME(1, 2)*ME(2, 1) - ME(0, 1)*ME(1, 0)*ME(2, 2) - ME(0, 2)*ME(1, 1)*ME(2, 0);*/
+	return ME(0, 0)*( ME(1, 1)*ME(2, 2) - ME(1, 2)*ME(2, 1) ) -
+	ME(0, 1)*( ME(1, 0)*ME(2, 2) - ME(1, 2)*ME(2, 0) ) +
+	ME(0, 2)*( ME(0, 1)*ME(2, 1) - ME(1, 1)*ME(2, 0) );
+}
+
+
+// Invert
+// using Gramer's method ( Inv(A) = ( 1/Det(A) ) * Adj(A)  )
+mat3_t mat3_t::Inverted() const
+{
+	mat3_t result;
+
+	// compute determinant
+	float cofactor0 = ME(1,1)*ME(2,2) - ME(1,2)*ME(2,1);
+	float cofactor3 = ME(0,2)*ME(2,1) - ME(0,1)*ME(2,2);
+	float cofactor6 = ME(0,1)*ME(1,2) - ME(0,2)*ME(1,1);
+	float det = ME(0,0)*cofactor0 + ME(1,0)*cofactor3 + ME(2,0)*cofactor6;
+
+	DEBUG_ERR( IsZero( det ) ); // Cannot invert det == 0
+
+	// create adjoint matrix and multiply by 1/det to get inverse
+	float invDet = 1.0f/det;
+	result(0,0) = invDet*cofactor0;
+	result(0,1) = invDet*cofactor3;
+	result(0,2) = invDet*cofactor6;
+
+	result(1,0) = invDet*(ME(1,2)*ME(2,0) - ME(1,0)*ME(2,2));
+	result(1,1) = invDet*(ME(0,0)*ME(2,2) - ME(0,2)*ME(2,0));
+	result(1,2) = invDet*(ME(0,2)*ME(1,0) - ME(0,0)*ME(1,2));
+
+	result(2,0) = invDet*(ME(1,0)*ME(2,1) - ME(1,1)*ME(2,0));
+	result(2,1) = invDet*(ME(0,1)*ME(2,0) - ME(0,0)*ME(2,1));
+	result(2,2) = invDet*(ME(0,0)*ME(1,1) - ME(0,1)*ME(1,0));
+
+	return result;
+}
+
+// Invert
+// see above
+void mat3_t::Invert()
+{
+	ME = Inverted();
+}
+
+
+/**
+=======================================================================================================================================
+mat4_t                                                                                                                                =
+=======================================================================================================================================
+*/
+static float mat4_ident[4*4] = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 };
+mat4_t mat4_t::ident( (const mat4_t&)mat4_ident );
+static float mat4_zero[4*4] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+mat4_t mat4_t::zero( (const mat4_t&)mat4_zero );
+
+// copy
+mat4_t& mat4_t::operator =( const mat4_t& b )
+{
+	ME[0] = b[0];
+	ME[1] = b[1];
+	ME[2] = b[2];
+	ME[3] = b[3];
+	ME[4] = b[4];
+	ME[5] = b[5];
+	ME[6] = b[6];
+	ME[7] = b[7];
+	ME[8] = b[8];
+	ME[9] = b[9];
+	ME[10] = b[10];
+	ME[11] = b[11];
+	ME[12] = b[12];
+	ME[13] = b[13];
+	ME[14] = b[14];
+	ME[15] = b[15];
+	return ME;
+}
+
+// 4x4 + 4x4
+mat4_t mat4_t::operator +( const mat4_t& b ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] + b[i];
+	return c;
+}
+
+// 4x4 + 4x4 (self)
+mat4_t& mat4_t::operator +=( const mat4_t& b )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] += b[i];
+	return ME;
+}
+
+// 4x4 - 4x4
+mat4_t mat4_t::operator -( const mat4_t& b ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] - b[i];
+	return c;
+}
+
+// 4x4 - 4x4 (self)
+mat4_t& mat4_t::operator -=( const mat4_t& b )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] -= b[i];
+	return ME;
+}
+
+// 4x4 * 4x4
+mat4_t mat4_t::operator *( const mat4_t& b ) const
+{
+	mat4_t c;
+	c(0,0) = ME(0,0)*b(0,0) + ME(0,1)*b(1,0) + ME(0,2)*b(2,0) + ME(0,3)*b(3,0);
+	c(0,1) = ME(0,0)*b(0,1) + ME(0,1)*b(1,1) + ME(0,2)*b(2,1) + ME(0,3)*b(3,1);
+	c(0,2) = ME(0,0)*b(0,2) + ME(0,1)*b(1,2) + ME(0,2)*b(2,2) + ME(0,3)*b(3,2);
+	c(0,3) = ME(0,0)*b(0,3) + ME(0,1)*b(1,3) + ME(0,2)*b(2,3) + ME(0,3)*b(3,3);
+	c(1,0) = ME(1,0)*b(0,0) + ME(1,1)*b(1,0) + ME(1,2)*b(2,0) + ME(1,3)*b(3,0);
+	c(1,1) = ME(1,0)*b(0,1) + ME(1,1)*b(1,1) + ME(1,2)*b(2,1) + ME(1,3)*b(3,1);
+	c(1,2) = ME(1,0)*b(0,2) + ME(1,1)*b(1,2) + ME(1,2)*b(2,2) + ME(1,3)*b(3,2);
+	c(1,3) = ME(1,0)*b(0,3) + ME(1,1)*b(1,3) + ME(1,2)*b(2,3) + ME(1,3)*b(3,3);
+	c(2,0) = ME(2,0)*b(0,0) + ME(2,1)*b(1,0) + ME(2,2)*b(2,0) + ME(2,3)*b(3,0);
+	c(2,1) = ME(2,0)*b(0,1) + ME(2,1)*b(1,1) + ME(2,2)*b(2,1) + ME(2,3)*b(3,1);
+	c(2,2) = ME(2,0)*b(0,2) + ME(2,1)*b(1,2) + ME(2,2)*b(2,2) + ME(2,3)*b(3,2);
+	c(2,3) = ME(2,0)*b(0,3) + ME(2,1)*b(1,3) + ME(2,2)*b(2,3) + ME(2,3)*b(3,3);
+	c(3,0) = ME(3,0)*b(0,0) + ME(3,1)*b(1,0) + ME(3,2)*b(2,0) + ME(3,3)*b(3,0);
+	c(3,1) = ME(3,0)*b(0,1) + ME(3,1)*b(1,1) + ME(3,2)*b(2,1) + ME(3,3)*b(3,1);
+	c(3,2) = ME(3,0)*b(0,2) + ME(3,1)*b(1,2) + ME(3,2)*b(2,2) + ME(3,3)*b(3,2);
+	c(3,3) = ME(3,0)*b(0,3) + ME(3,1)*b(1,3) + ME(3,2)*b(2,3) + ME(3,3)*b(3,3);
+	return c;
+}
+
+// 4x4 * 4x4 (self)
+mat4_t& mat4_t::operator *=( const mat4_t& b )
+{
+	ME = ME * b;
+	return ME;
+}
+
+// 4x4 * vec3
+vec3_t mat4_t::operator *( const vec3_t& b ) const
+{
+	return vec3_t(
+		ME(0,0)*b.x + ME(0,1)*b.y + ME(0,2)*b.z + ME(0,3),
+		ME(1,0)*b.x + ME(1,1)*b.y + ME(1,2)*b.z + ME(1,3),
+		ME(2,0)*b.x + ME(2,1)*b.y + ME(2,2)*b.z + ME(2,3)
+	);
+}
+
+// 4x4 * vec4
+vec4_t mat4_t::operator *( const vec4_t& b ) const
+{
+	return vec4_t(
+		ME(0,0)*b.x + ME(0,1)*b.y + ME(0,2)*b.z + ME(0,3)*b.w,
+		ME(1,0)*b.x + ME(1,1)*b.y + ME(1,2)*b.z + ME(1,3)*b.w,
+		ME(2,0)*b.x + ME(2,1)*b.y + ME(2,2)*b.z + ME(2,3)*b.w,
+		ME(3,0)*b.x + ME(3,1)*b.y + ME(3,2)*b.z + ME(3,3)*b.w
+	);
+}
+
+// 4x4 * scalar
+mat4_t mat4_t::operator *( float f ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] * f;
+	return c;
+}
+
+// 4x4 * scalar (self)
+mat4_t& mat4_t::operator *=( float f )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] *= f;
+	return ME;
+}
+
+// ==
+bool mat4_t::operator ==( const mat4_t& b ) const
+{
+	for( int i=0; i<16; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return false;
+	return true;
+}
+
+// !=
+bool mat4_t::operator !=( const mat4_t& b ) const
+{
+	for( int i=0; i<16; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return true;
+	return false;
+}
+
+// SetRows
+void mat4_t::SetRows( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d )
+{
+	ME(0,0) = a.x;
+	ME(0,1) = a.y;
+	ME(0,2) = a.z;
+	ME(0,3) = a.w;
+	ME(1,0) = b.x;
+	ME(1,1) = b.y;
+	ME(1,2) = b.z;
+	ME(1,3) = b.w;
+	ME(2,0) = c.x;
+	ME(2,1) = c.y;
+	ME(2,2) = c.z;
+	ME(2,3) = c.w;
+	ME(3,0) = d.x;
+	ME(3,1) = d.y;
+	ME(3,2) = d.z;
+	ME(3,3) = d.w;
+}
+
+// SetRow
+void mat4_t::SetRow( uint i, const vec4_t& v )
+{
+	DEBUG_ERR( i > 3 );
+	ME(i,0) = v.x;
+	ME(i,1) = v.y;
+	ME(i,2) = v.z;
+	ME(i,3) = v.w;
+}
+
+// SetColumns
+void mat4_t::SetColumns( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d )
+{
+	ME(0,0) = a.x;
+	ME(1,0) = a.y;
+	ME(2,0) = a.z;
+	ME(3,0) = a.w;
+	ME(0,1) = b.x;
+	ME(1,1) = b.y;
+	ME(2,1) = b.z;
+	ME(3,1) = b.w;
+	ME(0,2) = c.x;
+	ME(1,2) = c.y;
+	ME(2,2) = c.z;
+	ME(3,2) = c.w;
+	ME(0,3) = d.x;
+	ME(1,3) = d.y;
+	ME(2,3) = d.z;
+	ME(3,3) = d.w;
+}
+
+// SetColumn
+void mat4_t::SetColumn( uint i, const vec4_t& v )
+{
+	DEBUG_ERR( i > 3 );
+	ME(0,i) = v.x;
+	ME(1,i) = v.y;
+	ME(2,i) = v.z;
+	ME(3,i) = v.w;
+}
+
+// Transpose
+void mat4_t::Transpose()
+{
+	float tmp = ME(0,1);
+	ME(0,1) = ME(1,0);
+	ME(1,0) = tmp;
+	tmp = ME(0,2);
+	ME(0,2) = ME(2,0);
+	ME(2,0) = tmp;
+	tmp = ME(0,3);
+	ME(0,3) = ME(3,0);
+	ME(3,0) = tmp;
+	tmp = ME(1,2);
+	ME(1,2) = ME(2,1);
+	ME(2,1) = tmp;
+	tmp = ME(1,3);
+	ME(1,3) = ME(3,1);
+	ME(3,1) = tmp;
+	tmp = ME(2,3);
+	ME(2,3) = ME(3,2);
+	ME(3,2) = tmp;
+}
+
+// Transposed
+// return the transposed
+mat4_t mat4_t::Transposed() const
+{
+	mat4_t m4;
+	m4[0] = ME[0];
+	m4[1] = ME[4];
+	m4[2] = ME[8];
+	m4[3] = ME[12];
+	m4[4] = ME[1];
+	m4[5] = ME[5];
+	m4[6] = ME[9];
+	m4[7] = ME[13];
+	m4[8] = ME[2];
+	m4[9] = ME[6];
+	m4[10] = ME[10];
+	m4[11] = ME[14];
+	m4[12] = ME[3];
+	m4[13] = ME[7];
+	m4[14] = ME[11];
+	m4[15] = ME[15];
+	return m4;
+}
+
+// SetIdent
+void mat4_t::SetIdent()
+{
+	ME = ident;
+}
+
+// SetZero
+void mat4_t::SetZero()
+{
+	ME[15] = ME[14] = ME[13] = ME[12] = ME[11] = ME[10] = ME[9] = ME[8] = ME[7] = ME[6] = ME[5] =
+	ME[4] = ME[3] = ME[2] = ME[1] = ME[0] = 0.0f;
+}
+
+// Set
+// vec3
+void mat4_t::Set( const vec3_t& v )
+{
+	SetIdent();
+	ME(0, 3) = v.x;
+	ME(1, 3) = v.y;
+	ME(2, 3) = v.z;
+}
+
+// Set
+// vec4
+void mat4_t::Set( const vec4_t& v )
+{
+	ME(0, 0) = 1.0;
+	ME(0, 1) = 0.0;
+	ME(0, 2) = 0.0;
+	ME(0, 3) = v.x;
+	ME(1, 0) = 0.0;
+	ME(1, 1) = 1.0;
+	ME(1, 2) = 0.0;
+	ME(1, 3) = v.y;
+	ME(2, 0) = 0.0;
+	ME(2, 1) = 0.0;
+	ME(2, 2) = 1.0;
+	ME(2, 3) = v.z;
+	ME(3, 0) = 0.0;
+	ME(3, 1) = 0.0;
+	ME(3, 2) = 0.0;
+	ME(3, 3) = v.w;
+}
+
+// 3x3 to 4x4
+void mat4_t::Set( const mat3_t& m3 )
+{
+	ME(0,0) = m3(0,0);
+	ME(0,1) = m3(0,1);
+	ME(0,2) = m3(0,2);
+	ME(1,0) = m3(1,0);
+	ME(1,1) = m3(1,1);
+	ME(1,2) = m3(1,2);
+	ME(2,0) = m3(2,0);
+	ME(2,1) = m3(2,1);
+	ME(2,2) = m3(2,2);
+	ME(3, 0) = ME(3, 1) = ME(3, 2) = ME(0, 3) = ME(1, 3) = ME(2, 3) = 0.0f;
+	ME(3, 3) = 1.0f;
+}
+
+// Set
+// from transformation and rotation
+void mat4_t::Set( const vec3_t& transl, const mat3_t& rot )
+{
+	SetRotationPart(rot);
+	SetTranslationPart(transl);
+	ME(3,0) = ME(3,1) = ME(3,2) = 0.0;
+	ME(3,3) = 1.0f;
+}
+
+// Set
+// from transformation, rotation and scale
+void mat4_t::Set( const vec3_t& translate, const mat3_t& rotate, float scale )
+{
+	if( !IsZero( scale-1.0 ) )
+		SetRotationPart( rotate*scale );
+	else
+		SetRotationPart( rotate );
+
+	SetTranslationPart( translate );
+
+	ME(3,0) = ME(3,1) = ME(3,2) = 0.0;
+	ME(3,3) = 1.0f;
+}
+
+// SetRotationPart
+void mat4_t::SetRotationPart( const mat3_t& m3 )
+{
+	ME(0,0) = m3(0,0);
+	ME(0,1) = m3(0,1);
+	ME(0,2) = m3(0,2);
+	ME(1,0) = m3(1,0);
+	ME(1,1) = m3(1,1);
+	ME(1,2) = m3(1,2);
+	ME(2,0) = m3(2,0);
+	ME(2,1) = m3(2,1);
+	ME(2,2) = m3(2,2);
+}
+
+// GetRotationPart
+mat3_t mat4_t::GetRotationPart() const
+{
+	mat3_t m3;
+	m3(0,0) = ME(0,0);
+	m3(0,1) = ME(0,1);
+	m3(0,2) = ME(0,2);
+	m3(1,0) = ME(1,0);
+	m3(1,1) = ME(1,1);
+	m3(1,2) = ME(1,2);
+	m3(2,0) = ME(2,0);
+	m3(2,1) = ME(2,1);
+	m3(2,2) = ME(2,2);
+	return m3;
+}
+
+// SetTranslationPart
+void mat4_t::SetTranslationPart( const vec4_t& v )
+{
+	ME(0, 3) = v.x;
+	ME(1, 3) = v.y;
+	ME(2, 3) = v.z;
+	ME(3, 3) = v.w;
+}
+
+// SetTranslationPart
+void mat4_t::SetTranslationPart( const vec3_t& v )
+{
+	ME(0, 3) = v.x;
+	ME(1, 3) = v.y;
+	ME(2, 3) = v.z;
+}
+
+// GetTranslationPart
+vec3_t mat4_t::GetTranslationPart() const
+{
+	return vec3_t( ME(0, 3), ME(1, 3), ME(2, 3) );
+}
+
+// Print
+void mat4_t::Print() const
+{
+	cout << fixed;
+	for( int i=0; i<4; i++ )
+	{
+		for( int j=0; j<4; j++ )
+		{
+			if( ME(i, j) < 0.0 )
+				cout << ME(i, j) << " ";
+			else
+				cout << " " << ME(i, j) << " ";
+		}
+		cout << endl;
+	}
+	cout << endl;
+}
+
+// Determinant
+float mat4_t::Det() const
+{
+	return
+	ME(0, 3)*ME(1, 2)*ME(2, 1)*ME(3, 0) - ME(0, 2)*ME(1, 3)*ME(2, 1)*ME(3, 0) -
+	ME(0, 3)*ME(1, 1)*ME(2, 2)*ME(3, 0) + ME(0, 1)*ME(1, 3)*ME(2, 2)*ME(3, 0) +
+	ME(0, 2)*ME(1, 1)*ME(2, 3)*ME(3, 0) - ME(0, 1)*ME(1, 2)*ME(2, 3)*ME(3, 0) -
+	ME(0, 3)*ME(1, 2)*ME(2, 0)*ME(3, 1) + ME(0, 2)*ME(1, 3)*ME(2, 0)*ME(3, 1) +
+	ME(0, 3)*ME(1, 0)*ME(2, 2)*ME(3, 1) - ME(0, 0)*ME(1, 3)*ME(2, 2)*ME(3, 1) -
+	ME(0, 2)*ME(1, 0)*ME(2, 3)*ME(3, 1) + ME(0, 0)*ME(1, 2)*ME(2, 3)*ME(3, 1) +
+	ME(0, 3)*ME(1, 1)*ME(2, 0)*ME(3, 2) - ME(0, 1)*ME(1, 3)*ME(2, 0)*ME(3, 2) -
+	ME(0, 3)*ME(1, 0)*ME(2, 1)*ME(3, 2) + ME(0, 0)*ME(1, 3)*ME(2, 1)*ME(3, 2) +
+	ME(0, 1)*ME(1, 0)*ME(2, 3)*ME(3, 2) - ME(0, 0)*ME(1, 1)*ME(2, 3)*ME(3, 2) -
+	ME(0, 2)*ME(1, 1)*ME(2, 0)*ME(3, 3) + ME(0, 1)*ME(1, 2)*ME(2, 0)*ME(3, 3) +
+	ME(0, 2)*ME(1, 0)*ME(2, 1)*ME(3, 3) - ME(0, 0)*ME(1, 2)*ME(2, 1)*ME(3, 3) -
+	ME(0, 1)*ME(1, 0)*ME(2, 2)*ME(3, 3) + ME(0, 0)*ME(1, 1)*ME(2, 2)*ME(3, 3);
+}
+
+// Invert
+void mat4_t::Invert()
+{
+	ME = Inverted();
+}
+
+// Inverted
+mat4_t mat4_t::Inverted() const
+{
+	float tmp[12];
+	float det;
+
+	mat4_t m4;
+
+	tmp[0] = ME(2,2) * ME(3,3);
+	tmp[1] = ME(3,2) * ME(2,3);
+	tmp[2] = ME(1,2) * ME(3,3);
+	tmp[3] = ME(3,2) * ME(1,3);
+	tmp[4] = ME(1,2) * ME(2,3);
+	tmp[5] = ME(2,2) * ME(1,3);
+	tmp[6] = ME(0,2) * ME(3,3);
+	tmp[7] = ME(3,2) * ME(0,3);
+	tmp[8] = ME(0,2) * ME(2,3);
+	tmp[9] = ME(2,2) * ME(0,3);
+	tmp[10] = ME(0,2) * ME(1,3);
+	tmp[11] = ME(1,2) * ME(0,3);
+
+	m4(0,0) =  tmp[0]*ME(1,1) + tmp[3]*ME(2,1) + tmp[4]*ME(3,1);
+	m4(0,0) -= tmp[1]*ME(1,1) + tmp[2]*ME(2,1) + tmp[5]*ME(3,1);
+	m4(0,1) =  tmp[1]*ME(0,1) + tmp[6]*ME(2,1) + tmp[9]*ME(3,1);
+	m4(0,1) -= tmp[0]*ME(0,1) + tmp[7]*ME(2,1) + tmp[8]*ME(3,1);
+	m4(0,2) =  tmp[2]*ME(0,1) + tmp[7]*ME(1,1) + tmp[10]*ME(3,1);
+	m4(0,2) -= tmp[3]*ME(0,1) + tmp[6]*ME(1,1) + tmp[11]*ME(3,1);
+	m4(0,3) =  tmp[5]*ME(0,1) + tmp[8]*ME(1,1) + tmp[11]*ME(2,1);
+	m4(0,3) -= tmp[4]*ME(0,1) + tmp[9]*ME(1,1) + tmp[10]*ME(2,1);
+	m4(1,0) =  tmp[1]*ME(1,0) + tmp[2]*ME(2,0) + tmp[5]*ME(3,0);
+	m4(1,0) -= tmp[0]*ME(1,0) + tmp[3]*ME(2,0) + tmp[4]*ME(3,0);
+	m4(1,1) =  tmp[0]*ME(0,0) + tmp[7]*ME(2,0) + tmp[8]*ME(3,0);
+	m4(1,1) -= tmp[1]*ME(0,0) + tmp[6]*ME(2,0) + tmp[9]*ME(3,0);
+	m4(1,2) =  tmp[3]*ME(0,0) + tmp[6]*ME(1,0) + tmp[11]*ME(3,0);
+	m4(1,2) -= tmp[2]*ME(0,0) + tmp[7]*ME(1,0) + tmp[10]*ME(3,0);
+	m4(1,3) =  tmp[4]*ME(0,0) + tmp[9]*ME(1,0) + tmp[10]*ME(2,0);
+	m4(1,3) -= tmp[5]*ME(0,0) + tmp[8]*ME(1,0) + tmp[11]*ME(2,0);
+
+	tmp[0] = ME(2,0)*ME(3,1);
+	tmp[1] = ME(3,0)*ME(2,1);
+	tmp[2] = ME(1,0)*ME(3,1);
+	tmp[3] = ME(3,0)*ME(1,1);
+	tmp[4] = ME(1,0)*ME(2,1);
+	tmp[5] = ME(2,0)*ME(1,1);
+	tmp[6] = ME(0,0)*ME(3,1);
+	tmp[7] = ME(3,0)*ME(0,1);
+	tmp[8] = ME(0,0)*ME(2,1);
+	tmp[9] = ME(2,0)*ME(0,1);
+	tmp[10] = ME(0,0)*ME(1,1);
+	tmp[11] = ME(1,0)*ME(0,1);
+
+	m4(2,0) = tmp[0]*ME(1,3) + tmp[3]*ME(2,3) + tmp[4]*ME(3,3);
+	m4(2,0)-= tmp[1]*ME(1,3) + tmp[2]*ME(2,3) + tmp[5]*ME(3,3);
+	m4(2,1) = tmp[1]*ME(0,3) + tmp[6]*ME(2,3) + tmp[9]*ME(3,3);
+	m4(2,1)-= tmp[0]*ME(0,3) + tmp[7]*ME(2,3) + tmp[8]*ME(3,3);
+	m4(2,2) = tmp[2]*ME(0,3) + tmp[7]*ME(1,3) + tmp[10]*ME(3,3);
+	m4(2,2)-= tmp[3]*ME(0,3) + tmp[6]*ME(1,3) + tmp[11]*ME(3,3);
+	m4(2,3) = tmp[5]*ME(0,3) + tmp[8]*ME(1,3) + tmp[11]*ME(2,3);
+	m4(2,3)-= tmp[4]*ME(0,3) + tmp[9]*ME(1,3) + tmp[10]*ME(2,3);
+	m4(3,0) = tmp[2]*ME(2,2) + tmp[5]*ME(3,2) + tmp[1]*ME(1,2);
+	m4(3,0)-= tmp[4]*ME(3,2) + tmp[0]*ME(1,2) + tmp[3]*ME(2,2);
+	m4(3,1) = tmp[8]*ME(3,2) + tmp[0]*ME(0,2) + tmp[7]*ME(2,2);
+	m4(3,1)-= tmp[6]*ME(2,2) + tmp[9]*ME(3,2) + tmp[1]*ME(0,2);
+	m4(3,2) = tmp[6]*ME(1,2) + tmp[11]*ME(3,2) + tmp[3]*ME(0,2);
+	m4(3,2)-= tmp[10]*ME(3,2) + tmp[2]*ME(0,2) + tmp[7]*ME(1,2);
+	m4(3,3) = tmp[10]*ME(2,2) + tmp[4]*ME(0,2) + tmp[9]*ME(1,2);
+	m4(3,3)-= tmp[8]*ME(1,2) + tmp[11]*ME(2,2) + tmp[5]*ME(0,2);
+
+	det = ME(0,0)*m4(0,0)+ME(1,0)*m4(0,1)+ME(2,0)*m4(0,2)+ME(3,0)*m4(0,3);
+	DEBUG_ERR( IsZero( det ) ); // Cannot invert, det == 0
+	det = 1/det;
+	m4 *= det;
+	return m4;
+}
+
+// Lerp
+mat4_t mat4_t::Lerp( const mat4_t& b, float t ) const
+{
+	return (ME*(1.0f-t))+(b*t);
+}
+
+// CombineTransformations
+mat4_t mat4_t::CombineTransformations( const mat4_t& m0, const mat4_t& m1 )
+{
+	/* the clean code is:
+	mat3_t rot = m0.GetRotationPart() * m1.GetRotationPart();  // combine the rotations
+	vec3_t tra = (m1.GetTranslationPart()).Transformed( m0.GetTranslationPart(), m0.GetRotationPart(), 1.0 );
+	return mat4_t( tra, rot );
+	and the optimized: */
+	DEBUG_ERR( !IsZero( m0(3,0)+m0(3,1)+m0(3,2)+m0(3,3)-1.0 ) ||
+	           !IsZero( m1(3,0)+m1(3,1)+m1(3,2)+m1(3,3)-1.0 ) ); // one of the 2 mat4 doesnt represent transformation
+
+	mat4_t m4;
+
+	m4(0, 0) = m0(0, 0)*m1(0, 0) + m0(0, 1)*m1(1, 0) + m0(0, 2)*m1(2, 0);
+	m4(0, 1) = m0(0, 0)*m1(0, 1) + m0(0, 1)*m1(1, 1) + m0(0, 2)*m1(2, 1);
+	m4(0, 2) = m0(0, 0)*m1(0, 2) + m0(0, 1)*m1(1, 2) + m0(0, 2)*m1(2, 2);
+	m4(1, 0) = m0(1, 0)*m1(0, 0) + m0(1, 1)*m1(1, 0) + m0(1, 2)*m1(2, 0);
+	m4(1, 1) = m0(1, 0)*m1(0, 1) + m0(1, 1)*m1(1, 1) + m0(1, 2)*m1(2, 1);
+	m4(1, 2) = m0(1, 0)*m1(0, 2) + m0(1, 1)*m1(1, 2) + m0(1, 2)*m1(2, 2);
+	m4(2, 0) = m0(2, 0)*m1(0, 0) + m0(2, 1)*m1(1, 0) + m0(2, 2)*m1(2, 0);
+	m4(2, 1) = m0(2, 0)*m1(0, 1) + m0(2, 1)*m1(1, 1) + m0(2, 2)*m1(2, 1);
+	m4(2, 2) = m0(2, 0)*m1(0, 2) + m0(2, 1)*m1(1, 2) + m0(2, 2)*m1(2, 2);
+
+	m4(0, 3) = m0(0, 0)*m1(0, 3) + m0(0, 1)*m1(1, 3) + m0(0, 2)*m1(2, 3) + m0(0, 3);
+	m4(1, 3) = m0(1, 0)*m1(0, 3) + m0(1, 1)*m1(1, 3) + m0(1, 2)*m1(2, 3) + m0(1, 3);
+	m4(2, 3) = m0(2, 0)*m1(0, 3) + m0(2, 1)*m1(1, 3) + m0(2, 2)*m1(2, 3) + m0(2, 3);
+
+	m4(3,0) = m4(3,1) = m4(3,2) = 0.0;
+	m4(3,3) = 1.0f;
+
+	return m4;
+}

+ 476 - 0
src/old_src/2009-5-11/math.h

@@ -0,0 +1,476 @@
+#ifndef _MATH_H_
+#define _MATH_H_
+
+#include <math.h>
+#include "common.h"
+
+#define PI 3.14159265358979323846f
+#define EPSILON 1.0e-6f
+
+
+class vec2_t;
+class vec4_t;
+class vec3_t;
+class quat_t;
+class euler_t;
+class axisang_t;
+class mat3_t;
+class mat4_t;
+
+
+
+/*
+=======================================================================================================================================
+vector 2                                                                                                                              =
+=======================================================================================================================================
+*/
+class vec2_t
+{
+	public:
+		// data members
+		float x, y;
+		static vec2_t zero;
+		// access to the data
+		inline float& operator []( uint i )  { return (&x)[i]; }
+		inline float  operator []( uint i ) const { return (&x)[i]; }
+		// constructors & distructors
+		inline vec2_t() {}
+		inline vec2_t( float x_, float y_ ): x(x_), y(y_) {}
+		inline vec2_t( float f ): x(f), y(f) {}
+		inline vec2_t( const vec2_t& b ) { (*this) = b; }
+		inline vec2_t( const vec3_t& v3 );
+		inline vec2_t( const vec4_t& v4 );
+		// ops with same type
+		vec2_t& operator = ( const vec2_t& b );
+		vec2_t  operator + ( const vec2_t& b ) const;
+		vec2_t& operator +=( const vec2_t& b );
+		vec2_t  operator - ( const vec2_t& b ) const;
+		vec2_t& operator -=( const vec2_t& b );
+		vec2_t  operator - () const; // return the negative
+		vec2_t  operator * ( const vec2_t& b ) const;
+		vec2_t& operator *=( const vec2_t& b );
+		// other types
+		vec2_t  operator * ( float f ) const;
+		vec2_t& operator *=( float f );
+		vec2_t  operator / ( float f ) const;
+		vec2_t& operator /=( float f );
+		// comparision
+		bool operator ==( const vec2_t& b ) const;
+		bool operator !=( const vec2_t& b ) const;
+		// other
+		float  Length() const;
+		void   SetZero();
+		void   Normalize();
+		vec2_t Normalized() const;
+		float  Dot( const vec2_t& b ) const;
+};
+
+
+/*
+=======================================================================================================================================
+vector 3                                                                                                                              =
+used as column matrix in mat*vec                                                                                                      =
+=======================================================================================================================================
+*/
+class vec3_t
+{
+	public:
+		// data members
+		float x, y, z;
+		static vec3_t zero;
+		static vec3_t one;
+		static vec3_t i, j, k; // unit vectors
+		// access to the data
+		inline float& operator []( uint i )  { return (&x)[i]; }
+		inline float  operator []( uint i ) const { return (&x)[i]; }
+		// constructors & distructors
+		inline vec3_t() {}
+		inline vec3_t( float x_, float y_, float z_ ): x(x_), y(y_), z(z_) {}
+		inline vec3_t( float f ): x(f), y(f), z(f) {}
+		inline vec3_t( const vec3_t& b ) { (*this)=b; }
+		inline vec3_t( const vec2_t& v2, float z_ ): x(v2.x), y(v2.y), z(z_) {}
+		       vec3_t( const vec4_t& v4 );
+		       vec3_t( const quat_t& q );
+		// ops with same type
+		vec3_t& operator = ( const vec3_t& b );
+		vec3_t  operator + ( const vec3_t& b ) const;
+		vec3_t& operator +=( const vec3_t& b );
+		vec3_t  operator - ( const vec3_t& b ) const;
+		vec3_t& operator -=( const vec3_t& b );
+		vec3_t  operator * ( const vec3_t& b ) const;
+		vec3_t& operator *=( const vec3_t& b );
+		vec3_t  operator - () const; // return the negative
+		// other types
+		vec3_t  operator * ( float f ) const;
+		vec3_t& operator *=( float f );
+		vec3_t  operator / ( float f ) const;
+		vec3_t& operator /=( float f );
+		vec3_t  operator * ( const mat3_t& m3 ) const;
+		// comparision
+		bool operator ==( const vec3_t& b ) const;
+		bool operator !=( const vec3_t& b ) const;
+		// other
+		float  Dot( const vec3_t& b ) const;
+		vec3_t Cross( const vec3_t& b ) const;
+		float  Length() const;
+		float  LengthSquared() const;
+		float  DistanceSquared( const vec3_t& b ) const { return ((*this)-b).LengthSquared(); }
+		void   Normalize();
+		vec3_t Normalized() const;
+		void   SetZero() { z=y=x=0.0; };
+		vec3_t Project( const vec3_t& to_this ) const;
+		vec3_t Rotated( const quat_t& q ) const; // returns q * this * q.Conjucated() aka rotates this. 21 muls, 12 adds
+		void   Rotate( const quat_t& q );
+		vec3_t Lerp( const vec3_t& v1, float t ) const; // return Lerp( this, v1, t )
+		void   Print() const;
+		// transformations. The faster way is by far the mat4 * vec3 or the Transformed( vec3_t, mat3_t )
+		vec3_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void   Transform( const vec3_t& translate, const mat3_t& rotate, float scale ) { (*this)=Transformed( translate, rotate, scale ); }
+		vec3_t Transformed( const vec3_t& translate, const mat3_t& rotate ) const;
+		void   Transform( const vec3_t& translate, const mat3_t& rotate ) { (*this)=Transformed( translate, rotate ); }
+		vec3_t Transformed( const vec3_t& translate, const quat_t& rotate, float scale ) const;
+		void   Transform( const vec3_t& translate, const quat_t& rotate, float scale ) { (*this)=Transformed( translate, rotate, scale ); }
+};
+
+
+/*
+=======================================================================================================================================
+vector 4                                                                                                                              =
+=======================================================================================================================================
+*/
+class vec4_t
+{
+	public:
+		// data members
+		float x, y, z, w;
+		static vec4_t zero, one, i, j, k, l;
+		// access to the data
+		inline float& operator []( uint i )  { return (&x)[i]; }
+		inline float operator []( uint i ) const { return (&x)[i]; }
+		// constructors & distructors
+		inline vec4_t() {}
+		inline vec4_t( float x_, float y_, float z_, float w_ ): x(x_), y(y_), z(z_), w(w_) {}
+		inline vec4_t( float f ): x(f), y(f), z(f), w(f) {}
+		inline vec4_t( const vec4_t& b ) { (*this)=b; }
+		inline vec4_t( const vec3_t& v3, float w_ ): x(v3.x), y(v3.y), z(v3.z), w(w_) {}
+		// ops with same
+		vec4_t& operator = ( const vec4_t& b );
+		vec4_t  operator + ( const vec4_t& b ) const;
+		vec4_t& operator +=( const vec4_t& b );
+		vec4_t  operator - ( const vec4_t& b ) const;
+		vec4_t& operator -=( const vec4_t& b );
+		vec4_t  operator - () const; // return the negative
+		vec4_t  operator * ( const vec4_t& b ) const; // for color operations
+		vec4_t& operator *=( const vec4_t& b );       //       >>
+		// ops with other
+		vec4_t  operator * ( float f ) const;
+		vec4_t& operator *=( float f );
+		vec4_t  operator / ( float f ) const;
+		vec4_t& operator /=( float f );
+		vec4_t  operator * ( const mat4_t& m4 ) const;
+		// comparision
+		bool operator ==( const vec4_t& b ) const;
+		bool operator !=( const vec4_t& b ) const;
+		// other
+		void  SetZero();
+		float Length() const;
+		void  Normalize();
+		void  Print() const;
+		float Dot( const vec4_t& b ) const;
+};
+
+
+/*
+=======================================================================================================================================
+quaternion                                                                                                                            =
+=======================================================================================================================================
+*/
+class quat_t
+{
+	public:
+		// data members
+		float w, x, y, z;
+		static quat_t zero;
+		static quat_t ident;
+		// access to the data
+		inline float& operator []( uint i )  { return (&w)[i]; }
+		inline float operator []( uint i) const { return (&w)[i]; }
+		// constructors & distructors
+		inline quat_t() {}
+		inline quat_t( float w_, float x_, float y_, float z_ ): w(w_), x(x_), y(y_), z(z_) {}
+		inline quat_t( const quat_t& q ) { (*this)=q; }
+		inline quat_t( const mat3_t& m3 ) { Set(m3); }
+		inline quat_t( const euler_t& eu ) { Set(eu); }
+		inline quat_t( const axisang_t& axisang ) { Set( axisang ); }
+		inline quat_t( const vec3_t& v0, const vec3_t& v1 ) { CalcFromVecVec( v0, v1 ); }
+		inline quat_t( const vec3_t& v ) { Set(v); }
+		inline quat_t( const vec4_t& v ) { Set(v); }
+		// ops with same
+		quat_t& operator = ( const quat_t& b );
+		quat_t  operator + ( const quat_t& b ) const;
+		quat_t& operator +=( const quat_t& b );
+		quat_t  operator - ( const quat_t& b ) const;
+		quat_t& operator -=( const quat_t& b );
+		quat_t  operator * ( const quat_t& b ) const;
+		quat_t& operator *=( const quat_t& b );
+		// ops with other
+		quat_t  operator * ( float f ) const; // used to combine rotations. 16 muls and 12 adds
+		quat_t& operator *=( float f );
+		quat_t  operator / ( float f ) const;
+		quat_t& operator /=( float f );
+		// comparision
+		bool operator ==( const quat_t& b ) const;
+		bool operator !=( const quat_t& b ) const;
+		// other
+		void   Set( const mat3_t& m );
+		void   Set( const euler_t& e );
+		void   Set( const axisang_t& axisang );
+		void   CalcFromVecVec( const vec3_t& v0, const vec3_t& v1 ); // calculates the quat from v0 to v1
+		void   Set( const vec3_t& v ); // quat is: v.x*i + v.y*j + v.z*k + 0.0
+		void   Set( const vec4_t& v ); // quat is: v.x*i + v.y*j + v.z*k + v.w
+		void   SetIdent();
+		void   SetZero();
+		float  Length() const;
+		void   Invert();
+		void   Conjugate();
+		quat_t Conjugated() const;
+		void   Normalize();
+		void   Print() const;
+		float  Dot( const quat_t& b ) const;
+		quat_t Slerp( const quat_t& q1, float t ) const; // returns Slerp( this, q1, t )
+};
+
+
+/*
+=======================================================================================================================================
+euler angles in RAD                                                                                                                   =
+=======================================================================================================================================
+*/
+class euler_t
+{
+	public:
+		// data members
+		float x, y, z;
+		// access to the data
+		inline float& operator []( uint i )      { return (&x)[i]; }
+		inline float  operator []( uint i) const { return (&x)[i]; }
+		float& bank()           { return x; }
+		float  bank() const     { return x; }
+		float& heading()        { return y; }
+		float  heading() const  { return y; }
+		float& attitude()       { return z; }
+		float  attitude() const { return z; }
+		// constructors & distructors
+		inline euler_t() {}
+		inline euler_t( float x_, float y_, float z_  ) { x=x_; y=y_; z=z_; }
+		inline euler_t( const euler_t& b ) { (*this)=b; }
+		inline euler_t( const quat_t& q ) { Set(q); }
+		inline euler_t( const mat3_t& m3 ) { Set(m3); }
+		// ops with same
+		euler_t& operator = ( const euler_t& b );
+		// other
+		void SetZero();
+		void Set( const quat_t& q );
+		void Set( const mat3_t& m3 );
+		void Print() const;
+};
+
+
+/*
+=======================================================================================================================================
+axis orientation                                                                                                                      =
+=======================================================================================================================================
+*/
+class axisang_t
+{
+	public:
+		// data members
+		float ang;
+		vec3_t axis;
+		// constructors & distructors
+		inline axisang_t() {}
+		inline axisang_t( float rad, const vec3_t& axis_ ) { ang=rad; axis=axis_; }
+		inline axisang_t( const quat_t& q ) { Set(q); }
+		inline axisang_t( const mat3_t& m3 ) { Set(m3); }
+		// misc
+		void Set( const quat_t& q );
+		void Set( const mat3_t& m3 );
+};
+
+
+/*
+=======================================================================================================================================
+matrix 3x3                                                                                                                            =
+=======================================================================================================================================
+*/
+class mat3_t
+{
+	public:
+		// data members
+		float data_m3[9];
+		static mat3_t ident;
+		static mat3_t zero;
+		// accessors
+		inline float& operator ()( uint i, uint j ) { return data_m3[3*i+j]; }
+		inline float  operator ()( uint i, uint j ) const { return data_m3[3*i+j]; }
+		inline float& operator []( uint i) { return data_m3[i]; }    // used to access the array serial. It must be data_m3[i] cause its optimized
+		inline float  operator []( uint i) const { return data_m3[i]; }
+		// constructors & distructors
+		inline mat3_t() {}
+		inline mat3_t( const mat3_t& b ) { (*this)=b; }
+		inline mat3_t( const quat_t& q ) { Set(q); }
+		inline mat3_t( const euler_t& eu ) { Set(eu); }
+		inline mat3_t( const axisang_t& axisang ) { Set(axisang); }
+		// ops with mat3
+		mat3_t& operator = ( const mat3_t& b );
+		mat3_t  operator + ( const mat3_t& b ) const;
+		mat3_t& operator +=( const mat3_t& b );
+		mat3_t  operator - ( const mat3_t& b ) const;
+		mat3_t& operator -=( const mat3_t& b );
+		mat3_t  operator * ( const mat3_t& b ) const; // 27 muls, 18 adds
+		mat3_t& operator *=( const mat3_t& b );
+		// ops with others
+		vec3_t  operator * ( const vec3_t& b ) const;  // 9 muls, 6 adds
+		mat3_t  operator * ( float f ) const;
+		mat3_t& operator *=( float f );
+		// comparision
+		bool operator ==( const mat3_t& b ) const;
+		bool operator !=( const mat3_t& b ) const;
+		// other
+		void   SetRows( const vec3_t& a, const vec3_t& b, const vec3_t& c );
+		void   SetRow( const uint i, const vec3_t& v ) { (*this)(i,0)=v.x; (*this)(i,1)=v.y; (*this)(i,2)=v.z; }
+		void   GetRows( vec3_t& a, vec3_t& b, vec3_t& c ) const;
+		vec3_t GetRow( const uint i ) const { return vec3_t( (*this)(i,0), (*this)(i,1), (*this)(i,2) ); }
+		void   SetColumns( const vec3_t& a, const vec3_t& b, const vec3_t& c );
+		void   SetColumn( const uint i, const vec3_t& v ) { (*this)(0,i)=v.x; (*this)(1,i)=v.y; (*this)(2,i)=v.z; }
+		void   GetColumns( vec3_t& a, vec3_t& b, vec3_t& c ) const;
+		vec3_t GetColumn( const uint i ) const { return vec3_t( (*this)(0,i), (*this)(1,i), (*this)(2,i) ); }
+		void   Set( const quat_t& q ); // 12 muls, 12 adds
+		void   Set( const euler_t& e );
+		void   Set( const axisang_t& axisang );
+		void   SetRotationX( float rad );
+		void   SetRotationY( float rad );
+		void   SetRotationZ( float rad );
+		void   RotateXAxis( float rad ); // it rotates "this" in the axis defined by the rotation AND not the world axis
+		void   RotateYAxis( float rad );
+		void   RotateZAxis( float rad );
+		void   Transpose();
+		mat3_t Transposed() const;
+		void   Reorthogonalize();
+		void   SetIdent();
+		void   SetZero();
+		void   Print() const;
+		float  Det() const;
+		void   Invert();
+		mat3_t Inverted() const;
+};
+
+
+/*
+=======================================================================================================================================
+matrix 4x4                                                                                                                            =
+=======================================================================================================================================
+*/
+class mat4_t
+{
+	public:
+		// data members
+		float data_m4[16];
+		static mat4_t ident;
+		static mat4_t zero;
+		// access to the data
+		inline float& operator ()( uint i, uint j )  { return data_m4[4*i+j]; }
+		inline float  operator ()( uint i, uint j ) const { return data_m4[4*i+j]; }
+		inline float& operator []( uint i) { return data_m4[i]; }
+		inline float  operator []( uint i) const { return data_m4[i]; }
+		// constructors & distructors
+		inline mat4_t()  {};
+		inline mat4_t( const mat4_t& m4 )  { (*this)=m4; };
+		inline mat4_t( const mat3_t& m3 )  { Set(m3); }
+		inline mat4_t( const vec3_t& v ) { Set(v); }
+		inline mat4_t( const vec4_t& v ) { Set(v); }
+		inline mat4_t( const vec3_t& transl, const mat3_t& rot ) { Set(transl, rot); }
+		inline mat4_t( const vec3_t& transl, const mat3_t& rot, float scale ) { Set(transl, rot, scale); }
+		// with same
+		mat4_t& operator = ( const mat4_t& b );
+		mat4_t  operator + ( const mat4_t& b ) const;
+		mat4_t& operator +=( const mat4_t& b );
+		mat4_t  operator - ( const mat4_t& b ) const;
+		mat4_t& operator -=( const mat4_t& b );
+		mat4_t  operator * ( const mat4_t& b ) const;  // 64 muls, 48 adds. Use CombineTransformations instead
+		mat4_t& operator *=( const mat4_t& b );        //      >>
+		// with other types
+		vec3_t  operator * ( const vec3_t& v3 ) const; // 9 muls, 9 adds
+		vec4_t  operator * ( const vec4_t& v4 ) const; // 16 muls, 12 adds
+		mat4_t  operator * ( float f ) const;
+		mat4_t& operator *=( float f );
+		// comparision
+		bool operator ==( const mat4_t& b ) const;
+		bool operator !=( const mat4_t& b ) const;
+		// other
+		void   Set( const mat3_t& m3 ); // sets the rotation part equal to mat3 and the rest like the ident
+		void   Set( const vec3_t& v ); // sets the translation part equal to vec3 and the rest like the ident
+		void   Set( const vec4_t& v ); // sets the translation part equal to vec4 and the rest like the ident
+		void   Set( const vec3_t& transl, const mat3_t& rot ); // this = mat4_t(transl) * mat4_t(rot)
+		void   Set( const vec3_t& transl, const mat3_t& rot, float scale ); // this = mat4_t(transl) * mat4_t(rot) * mat4_t(scale). 9 muls
+		void   SetIdent();
+		void   SetZero();
+		void   SetRows( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d );
+		void   SetRow( uint i, const vec4_t& v );
+		void   SetColumns( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d );
+		void   SetColumn( uint i, const vec4_t& v );
+		void   SetRotationPart( const mat3_t& m3 );
+		void   SetTranslationPart( const vec4_t& v4 );
+		mat3_t GetRotationPart() const;
+		void   SetTranslationPart( const vec3_t& v3 );
+		vec3_t GetTranslationPart() const;
+		void   Transpose();
+		mat4_t Transposed() const;
+		void   Print() const;
+		float  Det() const;
+		void   Invert();
+		mat4_t Inverted() const;
+		mat4_t Lerp( const mat4_t& b, float t ) const;
+		static mat4_t CombineTransformations( const mat4_t& m0, const mat4_t& m1 );  // 12 muls, 27 adds. Something like m4 = m0 * m1 ...
+		                                                                             // ...but without touching the 4rth row and allot faster
+};
+
+
+
+/*
+=======================================================================================================================================
+misc                                                                                                                                  =
+=======================================================================================================================================
+*/
+extern void  MathSanityChecks();
+extern void  SinCos( float rad, float& sin_, float& cos_ );
+extern float InvSqrt( float f );
+inline float Sqrt( float f ) { return 1/InvSqrt(f); }
+inline float ToRad( float degrees ) { return degrees*(PI/180.0); }
+inline float ToDegrees( float rad ) { return rad*(180.0/PI); }
+inline float Sin( float rad ) { return sin(rad); }
+inline float Cos( float rad ) { return cos(rad); }
+inline bool  IsZero( float f ) { return ( fabs(f) < EPSILON ); }
+inline float Max( float a, float b ) { return (a>b) ? a : b; }
+inline float Min( float a, float b ) { return (a<b) ? a : b; }
+
+//  CombineTransformations
+//  mat4(t0,r0,s0)*mat4(t1,r1,s1) == mat4(tf,rf,sf)
+inline void CombineTransformations( const vec3_t& t0, const mat3_t& r0, float s0,
+                                    const vec3_t& t1, const mat3_t& r1, float s1,
+                                    vec3_t& tf, mat3_t& rf, float& sf )
+{
+	tf = t1.Transformed( t0, r0, s0 );
+	rf = r0 * r1;
+	sf = s0 * s1;
+}
+
+//  CombineTransformations as the above but without scale
+inline void CombineTransformations( const vec3_t& t0, const mat3_t& r0, const vec3_t& t1, const mat3_t& r1, vec3_t& tf, mat3_t& rf)
+{
+	tf = t1.Transformed( t0, r0 );
+	rf = r0 * r1;
+}
+
+
+#endif

+ 1012 - 0
src/old_src/2009-5-11/memory.cpp

@@ -0,0 +1,1012 @@
+#include "memory.h"
+
+#ifdef _USE_MEM_MANAGER_
+
+namespace mem {
+
+#ifdef malloc
+#undef malloc
+#endif
+
+#ifdef realloc
+#undef realloc
+#endif
+
+#ifdef calloc
+#undef calloc
+#endif
+
+#ifdef free
+#undef free
+#endif
+
+#ifdef new
+#undef new
+#endif
+
+#ifdef delete
+#undef delete
+#endif
+
+
+#ifdef _DEBUG
+	#define SANITY_CHECKS SanityChecks();
+	#define PRINT_CALL_INFO(x) { if(mem::print_call_info) INFO(x) }
+#else
+	#define SANITY_CHECKS
+	#define PRINT_CALL_INFO(x)
+#endif
+
+#define MERROR(x) {++errors_num; if(print_errors) ERROR(x)}
+
+/*
+=======================================================================================================================================
+variables and types                                                                                                                   =
+=======================================================================================================================================
+*/
+
+// owner info for the block
+struct mblock_owner_t
+{
+	const char* file;
+	int         line;
+	const char* func;
+};
+
+// used as a list node
+struct mem_block_t
+{
+	void*          addr;
+	size_t         size;     // aka offset
+	bool           free_space;
+	bool           active;   // if true then the block/node is an active node of the list
+	uint   id;      // the id in the mem_blocks array
+	mem_block_t*   prev;
+	mem_block_t*   next;
+	mblock_owner_t owner;  // for leak tracking
+};
+
+// the buffer
+const size_t buffer_size = 30*MEGABYTE;
+char prealloced_buff [buffer_size];
+void* buffer = prealloced_buff;
+size_t free_size = buffer_size;
+
+// block stuff
+const int MAX_MEM_BLOCKS = 20*KILOBYTE;
+mem_block_t mem_blocks[ MAX_MEM_BLOCKS ]; // this is actualy a list
+uint active_mem_blocks_num = 3;
+mem_block_t& head_node = mem_blocks[0];
+mem_block_t& tail_node = mem_blocks[1];
+
+// dummy
+static void DummyFunc() {}
+
+// Used so we can save a check in NewBlock
+static void Init();
+void (*p_Init)(void) = Init;
+
+// threads
+void (*p_Lock)(void) = DummyFunc;
+void (*p_Unlock)(void) = DummyFunc;
+SDL_sem* semaphore = NULL;
+
+// unknown owner
+mblock_owner_t unknown_owner = {"??", 0, "??"};
+
+// times we called each
+uint malloc_called_num = 0;
+uint calloc_called_num = 0;
+uint realloc_called_num = 0;
+uint free_called_num = 0;
+uint new_called_num = 0;
+uint delete_called_num = 0;
+
+// errors & other
+bool print_errors = false;
+uint errors_num = 0;
+bool print_call_info = false; // works only in debug
+
+/*
+=======================================================================================================================================
+FreeBlocksNum                                                                                                                         =
+=======================================================================================================================================
+*/
+static int FreeBlocksNum()
+{
+	mem_block_t* mb = head_node.next;
+	int num = 0;
+	do
+	{
+		if( mb->free_space )
+			++num;
+		mb = mb->next;
+	} while( mb != &tail_node );
+	return num;
+}
+
+/*
+=======================================================================================================================================
+SetOwner                                                                                                                              =
+set the file,func,line to the given block                                                                                             =
+=======================================================================================================================================
+*/
+static inline void SetOwner( mem_block_t* mb, mblock_owner_t* owner )
+{
+	DEBUG_ERR( mb == &head_node || mb == &tail_node ); // shouldn't change the head_node or tail node
+	mb->owner.file = owner->file;
+	mb->owner.line = owner->line;
+	mb->owner.func = owner->func;
+}
+
+
+/*
+=======================================================================================================================================
+SanityChecks                                                                                                                          =
+=======================================================================================================================================
+*/
+static bool SanityChecks()
+{
+	// the head_node
+	if( !(head_node.addr == NULL || head_node.size == 0 || head_node.prev == NULL || head_node.id == 0 ||
+	    head_node.active == true || head_node.free_space == false) )
+		MERROR( "In head_node" );
+
+	// check the list
+	uint num = 0;
+	for( int i=0; i<MAX_MEM_BLOCKS; i++ )
+		if( mem_blocks[i].active ) ++num;
+
+	if( active_mem_blocks_num != num ) MERROR( "In mem_blocks list" );
+
+	// check the size
+	size_t size = 0;
+	mem_block_t* mb = head_node.next;
+	do
+	{
+		if( !mb->free_space )
+			size += mb->size;
+
+		// the prev's next has to be ME and the next's prev has to show me also
+		if( mb->prev->next!=mb || mb->next->prev!=mb )
+			MERROR( "Chain is broken" );
+
+		if( mb->next!=&tail_node && ((char*)mb->addr)+mb->size!=mb->next->addr )
+			MERROR( "In crnt and next sizes cohisency" );
+
+		if( mb->next == NULL || mb->prev==NULL )
+			MERROR( "Prev or next are NULL" );
+
+		mb = mb->next;
+	} while( mb!=&tail_node );
+
+	if( size != buffer_size-free_size ) MERROR( "In size" );
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+BytesStr                                                                                                                              =
+=======================================================================================================================================
+*/
+static char* BytesStr( size_t size )
+{
+	static char str[10];
+
+	if( size > MEGABYTE )
+		sprintf( str, "%dMB", (uint)(size/MEGABYTE) );
+	else if( size > KILOBYTE )
+		sprintf( str, "%dKB", (uint)(size/KILOBYTE) );
+	else
+		sprintf( str, "%dB ", (uint)(size) );
+	return str;
+}
+
+
+/*
+=======================================================================================================================================
+PrintBlockInfo                                                                                                                        =
+=======================================================================================================================================
+*/
+static void PrintBlockInfo( const mem_block_t* mb )
+{
+	const char cond = (mb->free_space) ? 'F' : 'U';
+	cout << setw(4) << setfill(' ') << mb->id << setw(0) << ' ' << cond << ' ' << setw(6) <<  BytesStr( mb->size ) << setw(0) << hex <<
+	     " 0x" << mb->addr << dec;
+
+	if( cond=='U' ) cout << " " << mb->owner.file << ' ' << mb->owner.line << ' ' << mb->owner.func;
+
+	cout << endl;
+}
+
+
+/*
+=======================================================================================================================================
+PrintInfo                                                                                                                             =
+=======================================================================================================================================
+*/
+void PrintInfo( uint flags )
+{
+	cout << "\n=========================== MEM REPORT =========================" << endl;
+
+	// header
+	if( (flags & PRINT_ALL)==PRINT_ALL || (flags & PRINT_HEADER)==PRINT_HEADER )
+	{
+		cout << "Used space: " << BytesStr(buffer_size-free_size) << "(" << buffer_size-free_size << ")";
+		cout << ", free: " << BytesStr(free_size) << " (" << free_size << ")";
+		cout << ", total: " << BytesStr(buffer_size) << " (" << buffer_size << ")" << endl;
+
+		int num = FreeBlocksNum();
+		cout << "Active blocks: " << active_mem_blocks_num << "(free space: " << num << ", used space: " << active_mem_blocks_num-num <<
+						"), total: " << MAX_MEM_BLOCKS << endl;
+
+		// get the block with the max free space
+		mem_block_t* tmp = head_node.next;
+		mem_block_t* mb = &head_node;
+		do
+		{
+			if( tmp->free_space && tmp->size > mb->size )
+				mb = tmp;
+			tmp = tmp->next;
+		} while( tmp!=&tail_node );
+
+		cout << "Block with max free space: " << mb->id << ", size: " << BytesStr( mb->size ) << " (" << mb->size << ")" << endl;
+
+		// print how many times malloc,realloc etc have been called
+		cout << "Func calls: malloc:" << malloc_called_num << ", calloc:" << calloc_called_num << ", realloc:" << realloc_called_num <<
+		     ", free:" << free_called_num << ", new:" << new_called_num << ", delete:" << delete_called_num << endl;
+
+		cout << "Errors count:" << errors_num << endl;
+	}
+
+	// blocks
+	if( (flags & PRINT_ALL)==PRINT_ALL || (flags & PRINT_BLOCKS)==PRINT_BLOCKS )
+	{
+		cout << "Block table (id, type, size [, file, line, func]):" << endl;
+
+		mem_block_t* mb = head_node.next;
+		do
+		{
+			PrintBlockInfo( mb );
+			mb = mb->next;
+		} while( mb!=&tail_node );
+	}
+
+	cout << "================================================================\n" << endl;
+}
+
+
+/*
+=======================================================================================================================================
+Init                                                                                                                                  =
+=======================================================================================================================================
+*/
+static void Init()
+{
+#ifdef _DEBUG
+	memset( buffer, (char)0xCC, buffer_size );
+#endif
+
+	// mem block stuff
+
+	// set the head block. Its the head of the list
+	head_node.addr = NULL;
+	head_node.size = 0;
+	head_node.prev = NULL;
+	head_node.next = &mem_blocks[2];
+	head_node.id = 0;
+	head_node.active = true;
+	head_node.free_space = false;
+
+	// set the head block. Its the head of the list
+	tail_node.addr = NULL;
+	tail_node.size = 0;
+	tail_node.prev = &mem_blocks[2];
+	tail_node.next = NULL;
+	tail_node.id = 1;
+	tail_node.active = true;
+	tail_node.free_space = false;
+
+	// set the first block
+	mem_blocks[2].addr = buffer;
+	mem_blocks[2].size = buffer_size;
+	mem_blocks[2].prev = &head_node;
+	mem_blocks[2].next = &tail_node;
+	mem_blocks[2].id = 2;
+	mem_blocks[2].active = true;
+	mem_blocks[2].free_space = true;
+
+	// set the rest
+	memset( &mem_blocks[3], 0, sizeof(mem_block_t)*(MAX_MEM_BLOCKS-3) );
+	for( int i=3; i<MAX_MEM_BLOCKS; i++ )
+	{
+		mem_blocks[i].id = i;
+	}
+
+	p_Init = DummyFunc;
+
+	semaphore = SDL_CreateSemaphore(1);
+}
+
+
+/*
+=======================================================================================================================================
+thread stuff                                                                                                                          =
+=======================================================================================================================================
+*/
+static void Lock()
+{
+	if( SDL_SemWait(semaphore)==-1 )
+		MERROR( "Cant lock semaphore" );
+}
+
+static void Unlock()
+{
+	if( SDL_SemPost(semaphore)==-1 )
+		MERROR( "Cant unlock semaphore" );
+}
+
+
+/*
+=======================================================================================================================================
+Enable                                                                                                                                =
+=======================================================================================================================================
+*/
+void Enable( uint flags )
+{
+	if( (flags & THREADS)==THREADS )
+	{
+		p_Lock = Lock;
+		p_Unlock = Unlock;
+	}
+
+	if( (flags & PRINT_ERRORS)==PRINT_ERRORS )
+		print_errors = true;
+
+
+	if( (flags & PRINT_CALL_INFO)==PRINT_CALL_INFO )
+		print_call_info = true;
+}
+
+
+/*
+=======================================================================================================================================
+Disable                                                                                                                               =
+=======================================================================================================================================
+*/
+void Disable( uint flags )
+{
+	if( (flags & THREADS)==THREADS )
+	{
+		p_Lock = DummyFunc;
+		p_Unlock = DummyFunc;
+	}
+
+	if( (flags & PRINT_ERRORS)==PRINT_ERRORS )
+		print_errors = false;
+
+	if( (flags & PRINT_CALL_INFO)==PRINT_CALL_INFO )
+		print_call_info = false;
+}
+
+
+/*
+=======================================================================================================================================
+GetBlock                                                                                                                              =
+find the active block who has for addr the given ptr param. Func used by free and realloc                                             =
+=======================================================================================================================================
+*/
+static mem_block_t* GetBlock( void* ptr )
+{
+	//if( ptr<buffer || ptr>((char*)buffer+buffer_size) ) return &head_node;
+
+	mem_block_t* mb = tail_node.prev;
+	do
+	{
+		if( mb->addr==ptr )
+			return mb;
+		mb = mb->prev;
+	} while( mb!=&head_node );
+
+	return NULL;
+
+//
+//	int a = 1;
+//	int b = active_mem_blocks_num-2;
+//	mem_block_t* mb = head_node.next;
+//	int pos = 1;
+//
+//	for(;;)
+//	{
+//		int tmp = (a+b)/2;
+//
+//		// move the mb to crnt_pos
+//		if( pos < tmp )
+//			for( int i=0; i<tmp-pos; i++ )
+//				mb = mb->next;
+//		else
+//			for( int i=0; i<pos-tmp; i++ )
+//				mb = mb->prev;
+//		pos = tmp;
+//
+//		if( ptr < mb->addr )
+//			b = pos;
+//		else if( ptr > mb->addr )
+//			a = pos;
+//		else
+//			return mb;
+//		if( b-a < 2 ) break;
+//	}
+//
+//	return NULL;
+}
+
+
+/*
+=======================================================================================================================================
+GetInactiveBlock                                                                                                                      =
+get an inactive node/block                                                                                                            =
+=======================================================================================================================================
+*/
+static mem_block_t* GetInactiveBlock()
+{
+	for( int i=2; i<MAX_MEM_BLOCKS; i++ )
+	{
+		if( !mem_blocks[i].active )
+			return &mem_blocks[i];
+	}
+
+	FATAL( "Cannot find an inactive node. Inc the mem_blocks arr" );
+	return NULL;
+}
+
+
+/*
+=======================================================================================================================================
+WorstFit                                                                                                                              =
+"worst fit" algorithm. It returns the block with the biger free space                                                                 =
+=======================================================================================================================================
+*/
+static mem_block_t* WorstFit( size_t size )
+{
+	mem_block_t* tmp = tail_node.prev;
+	mem_block_t* candidate = &head_node;
+	do
+	{
+		if( tmp->size > candidate->size && tmp->free_space )
+			candidate = tmp;
+		tmp = tmp->prev;
+	} while( tmp!=&head_node );
+
+	return candidate;
+}
+
+
+/*
+=======================================================================================================================================
+BestFit                                                                                                                               =
+=======================================================================================================================================
+*/
+static mem_block_t* BestFit( size_t size )
+{
+	mem_block_t* tmp = tail_node.prev;
+	mem_block_t* candidate = &head_node;
+
+	// find a free block firstly
+	do
+	{
+		if( tmp->free_space )
+		{
+			candidate = tmp;
+			break;
+		}
+		tmp = tmp->prev;
+	} while( tmp!=&head_node );
+
+	if( candidate == &head_node ) return candidate; // we failed to find free node
+
+	// now run the real deal
+	do
+	{
+		if( tmp->free_space )
+		{
+			if( (tmp->size < candidate->size) && (tmp->size > size) )
+				candidate = tmp;
+			else if( tmp->size == size )
+				return tmp;
+		}
+		tmp = tmp->prev;
+	} while( tmp!=&head_node );
+
+	return candidate;
+}
+
+
+/*
+=======================================================================================================================================
+BadFit                                                                                                                                =
+=======================================================================================================================================
+*/
+static mem_block_t* BadFit( size_t size )
+{
+	mem_block_t* tmp = tail_node.prev;
+	do
+	{
+		if( tmp->size >= size && tmp->free_space )
+			return tmp;
+		tmp = tmp->prev;
+	} while( tmp!=&head_node );
+
+	return &head_node;
+}
+
+
+/*
+=======================================================================================================================================
+NewBlock                                                                                                                              =
+just free the given block                                                                                                             =
+=======================================================================================================================================
+*/
+static mem_block_t* NewBlock( size_t size )
+{
+	p_Init();
+
+	// a simple check
+	if( size < 1 )
+	{
+		MERROR( "Size is < 1" );
+		return &head_node;
+	}
+
+	// get an inactive block
+	mem_block_t* newmb = GetInactiveBlock();
+
+	// use an algorithm to find the best candidate
+	mem_block_t* candidate = BestFit(size);
+	if( candidate==&head_node )
+	{
+		FATAL( "There are no free blocks" );
+		return &head_node;
+	}
+
+	// case 0: we have found a big enought free block
+	if( candidate->size > size )
+	{
+		// reorganize the prev and the next of the 3 involved blocks
+		DEBUG_ERR( candidate->prev==NULL );
+		candidate->prev->next = newmb;
+		newmb->prev = candidate->prev;
+		newmb->next = candidate;
+		candidate->prev = newmb;
+
+		// do the rest of the changes
+		newmb->addr = candidate->addr;
+		newmb->size = size;
+
+		candidate->addr = ((char*)candidate->addr) + size;
+		candidate->size -= size;
+
+		newmb->active = true;
+		newmb->free_space = false;
+		++active_mem_blocks_num;
+	}
+	// case 1: we have found a block with the exchact space
+	else if( candidate->size == size )
+	{
+		newmb = candidate;
+		newmb->free_space = false;
+	}
+	// case 2: we cannot find a block!!!
+	else // if( max_free_bytes < bytes )
+	{
+		FATAL( "Cant find block with " << size << " free space. Inc buffer" );
+		return &head_node;
+	}
+
+	free_size -= size;
+	return newmb;
+}
+
+
+/*
+=======================================================================================================================================
+FreeBlock                                                                                                                             =
+=======================================================================================================================================
+*/
+static void FreeBlock( mem_block_t* crnt )
+{
+	DEBUG_ERR( crnt->free_space || !crnt->active || crnt==&head_node || crnt==&tail_node ); // self explanatory
+
+	free_size += crnt->size;
+
+#ifdef _DEBUG
+	memset( crnt->addr, (char)0xCC, crnt->size );
+#endif
+
+	// rearange the blocks
+	mem_block_t* prev = crnt->prev;
+	mem_block_t* next = crnt->next;
+	// if we have a prev block with free space we resize the prev and then we remove the current one
+	if( prev != &head_node && prev->free_space )
+	{
+		prev->size += crnt->size;
+		prev->next = next;
+		next->prev = prev;
+
+		// remove the crnt block from the list
+		crnt->active = false;
+		--active_mem_blocks_num;
+
+		// rearange the blocks for the next check
+		crnt = prev;
+		prev = crnt->prev;
+	}
+
+	// if we have a next block with free space we resize the next and then we remove the crnt one
+	if( next != &tail_node && next->free_space )
+	{
+		next->addr = crnt->addr;
+		next->size += crnt->size;
+		next->prev = prev;
+		prev->next = next;
+
+		// remove the next block from the list
+		crnt->active = false;
+		--active_mem_blocks_num;
+	}
+
+	crnt->free_space = true;
+}
+
+
+/*
+=======================================================================================================================================
+ReallocBlock                                                                                                                          =
+it gets the block we want to realloc and returns the reallocated (either the same or a new)                                           =
+=======================================================================================================================================
+*/
+static mem_block_t* ReallocBlock( mem_block_t* crnt, size_t size )
+{
+	DEBUG_ERR( crnt->free_space || !crnt->active || crnt==&head_node || crnt==&tail_node ); // self explanatory
+
+
+	// case 0: If size is 0 and p points to an existing block of memory, the memory block pointed by ptr is deallocated and a NULL...
+	// ...pointer is returned.(ISO behaviour)
+	if( size==0 )
+	{
+		FreeBlock( crnt );
+		crnt = &head_node;
+	}
+	// case 1: we want more space
+	else if( size > crnt->size )
+	{
+		mem_block_t* next = crnt->next;
+		// case 1.0: the next block has enough space. Then we eat from the next
+		if( next!=&tail_node && next->free_space && next->size >= size )
+		{
+			free_size -= size - crnt->size;
+			next->addr = ((char*)next->addr) + (size - crnt->size); // shift right the addr
+			next->size -= size - crnt->size;
+			crnt->size = size;
+		}
+		// case 1.1: We cannot eat from the next. Create new block and move the crnt's data there
+		else
+		{
+			mem_block_t* mb = NewBlock( size );
+			memcpy( mb->addr, crnt->addr, crnt->size );
+			FreeBlock( crnt );
+			crnt = mb;
+		}
+	}
+	// case 2: we want less space
+	else if( size < crnt->size )
+	{
+		mem_block_t* next = crnt->next;
+		// case 2.0: we have next
+		if( next!=&tail_node )
+		{
+			// case 2.0.0: the next block is free space...
+			// ...resize next and crnt
+			if( next->free_space )
+			{
+				free_size -= size - crnt->size;
+				next->addr = ((char*)next->addr) - (crnt->size - size); // shl
+				next->size += crnt->size - size;
+				crnt->size = size;
+			}
+			// case 2.0.1: the next block is used space. Create new free block
+			else
+			{
+				free_size -= size - crnt->size;
+				mem_block_t* newmb = GetInactiveBlock();
+				newmb->active = true;
+				newmb->free_space = true;
+				newmb->prev = crnt;
+				newmb->next = next;
+				newmb->addr = ((char*)crnt->addr) + size;
+				newmb->size = crnt->size - size;
+
+				next->prev = newmb;
+
+				crnt->size = size;
+				crnt->next = newmb;
+			}
+		}
+		// case 2.1: We DONT have next. Create a new node
+		else
+		{
+			free_size -= size - crnt->size;
+			mem_block_t* newmb = GetInactiveBlock();
+			newmb->active = true;
+			newmb->free_space = true;
+			newmb->prev = crnt;
+			newmb->next = next;
+			newmb->addr = ((char*)crnt->addr) + size;
+			newmb->size = crnt->size - size;
+
+			crnt->size = size;
+			crnt->next = newmb;
+		}
+	}
+
+	return crnt;
+}
+
+
+/*
+=======================================================================================================================================
+Malloc                                                                                                                                =
+=======================================================================================================================================
+*/
+static void* Malloc( size_t size, mblock_owner_t* owner=&unknown_owner )
+{
+	p_Lock();
+
+	PRINT_CALL_INFO( "caller: \"" << owner->file << ':' << owner->line << "\", size: " << size );
+
+	mem_block_t* mb = NewBlock( size );
+	SetOwner( mb, owner );
+	SANITY_CHECKS
+
+	p_Unlock();
+	return mb->addr;
+}
+
+
+/*
+=======================================================================================================================================
+Calloc                                                                                                                                =
+=======================================================================================================================================
+*/
+static void* Calloc( size_t num, size_t size, mblock_owner_t* owner=&unknown_owner )
+{
+	p_Lock();
+
+
+	PRINT_CALL_INFO( "caller: \"" << owner->file << ':' << owner->line << "size: " << size );
+
+	mem_block_t* mb = NewBlock( num*size );
+	SetOwner( mb, owner);
+	memset( mb->addr, 0x00000000, num*size );
+	SANITY_CHECKS
+
+	p_Unlock();
+	return mb->addr;
+}
+
+
+/*
+=======================================================================================================================================
+Realloc                                                                                                                               =
+=======================================================================================================================================
+*/
+static void* Realloc( void* ptr, size_t size, mblock_owner_t* owner=&unknown_owner )
+{
+	p_Lock();
+
+	// ISO beheviur
+	if( ptr==NULL )
+	{
+		p_Unlock();
+		return Malloc( size, owner );
+	}
+
+	// find the block we want to realloc
+	mem_block_t* mb = GetBlock( ptr );
+
+	PRINT_CALL_INFO( "caller: \"" << owner->file << ':' << owner->line << "\", user: \"" << mb->owner.file << ':' << mb->owner.line <<
+		"\", new size: " << size );
+
+	if( mb==NULL )
+	{
+		MERROR( "Addr 0x" << hex << ptr << dec << " not found" );
+		p_Unlock();
+		return NULL;
+	}
+	if( mb->free_space  )
+	{
+		MERROR( "Addr 0x" << hex << ptr << dec << " is free space" );
+		p_Unlock();
+		return NULL;
+	}
+
+	mem_block_t* crnt = ReallocBlock( mb, size );
+	SetOwner( crnt, owner );
+	SANITY_CHECKS
+
+	p_Unlock();
+	return crnt->addr;
+}
+
+
+/*
+=======================================================================================================================================
+Free                                                                                                                                  =
+=======================================================================================================================================
+*/
+static void Free( void* ptr, mblock_owner_t* owner=&unknown_owner )
+{
+	p_Lock();
+
+	// find the block we want to delete
+	mem_block_t* mb = GetBlock( ptr );
+	if( mb==NULL )
+	{
+		MERROR( "Addr 0x" << hex << ptr << dec << " not found" );
+		p_Unlock();
+		return;
+	}
+	if( mb->free_space  )
+	{
+		MERROR( "Addr 0x" << hex << ptr << dec << " is free space" );
+		p_Unlock();
+		return;
+	}
+
+	PRINT_CALL_INFO( "caller: \"" << owner->file << ':' << owner->line << "\", user: \"" << mb->owner.file << ':' << mb->owner.line
+		<< "\", mb size: " << mb->size );
+
+	FreeBlock( mb );
+	SANITY_CHECKS
+
+	p_Unlock();
+}
+
+} // end namespace
+
+/**
+=======================================================================================================================================
+overloaded stuff                                                                                                                      =
+=======================================================================================================================================
+*/
+
+// malloc
+void* malloc( size_t size ) throw()
+{
+	++mem::malloc_called_num;
+	return mem::Malloc( size );
+}
+
+// realloc
+void* realloc( void* p, size_t size ) throw()
+{
+	++mem::realloc_called_num;
+	return mem::Realloc( p, size );
+}
+
+// calloc
+void* calloc( size_t num, size_t size ) throw()
+{
+	++mem::calloc_called_num;
+	return mem::Calloc( num, size );
+}
+
+// free
+void free( void* p ) throw()
+{
+	++mem::free_called_num;
+	mem::Free( p );
+}
+
+// new
+void* operator new( size_t size ) throw(std::bad_alloc)
+{
+	++mem::new_called_num;
+	return mem::Malloc( size );
+}
+
+// new[]
+void* operator new[]( size_t size ) throw(std::bad_alloc)
+{
+	++mem::new_called_num;
+	return mem::Malloc( size );
+}
+
+// delete
+void operator delete( void* p ) throw()
+{
+	++mem::delete_called_num;
+	mem::Free(p);
+}
+
+// delete []
+void operator delete[]( void* p ) throw()
+{
+	++mem::delete_called_num;
+	mem::Free(p);
+}
+
+
+/**
+=======================================================================================================================================
+overloaded stuff with owner                                                                                                           =
+=======================================================================================================================================
+*/
+
+// malloc
+void* malloc( size_t size, const char* file, int line, const char* func )
+{
+	++mem::malloc_called_num;
+	mem::mblock_owner_t owner = {file, line, func};
+	return mem::Malloc( size, &owner );
+}
+
+// realloc
+void* realloc( void* p, size_t size, const char* file, int line, const char* func )
+{
+	++mem::realloc_called_num;
+	mem::mblock_owner_t owner = {file, line, func};
+	return mem::Realloc( p, size, &owner );
+}
+
+// calloc
+void* calloc( size_t num, size_t size, const char* file, int line, const char* func )
+{
+	++mem::calloc_called_num;
+	mem::mblock_owner_t owner = {file, line, func};
+	return mem::Calloc( num, size, &owner );
+}
+
+// free
+void free( void* p, const char* file, int line, const char* func )
+{
+	++mem::free_called_num;
+	mem::mblock_owner_t owner = {file, line, func};
+	mem::Free( p, &owner );
+}
+
+// new
+void* operator new( size_t size, const char* file, int line, const char* func )
+{
+	++mem::new_called_num;
+	mem::mblock_owner_t owner = {file, line, func};
+	return mem::Malloc( size, &owner );
+}
+
+// new[]
+void* operator new[]( size_t size, const char* file, int line, const char* func )
+{
+	++mem::new_called_num;
+	mem::mblock_owner_t owner = {file, line, func};
+	return mem::Malloc( size, &owner );
+}
+
+// delete
+void operator delete( void* p, const char* file, int line, const char* func )
+{
+	++mem::delete_called_num;
+	mem::mblock_owner_t owner = {file, line, func};
+	mem::Free( p, &owner );
+}
+
+// delete []
+void operator delete[]( void* p, const char* file, int line, const char* func )
+{
+	++mem::delete_called_num;
+	mem::mblock_owner_t owner = {file, line, func};
+	mem::Free( p, &owner );
+}
+
+#endif // _USE_MEM_MANAGER_

+ 59 - 0
src/old_src/2009-5-11/memory.h

@@ -0,0 +1,59 @@
+#ifndef _MEMORY_H_
+#define _MEMORY_H_
+
+#include <SDL.h>
+#include "common.h"
+
+#define MEGABYTE 1048576
+#define KILOBYTE 1024
+
+namespace mem {
+
+// for PrintInfo
+const uint PRINT_ALL    = 0x0001;
+const uint PRINT_HEADER = 0x0002;
+const uint PRINT_BLOCKS = 0x0004;
+
+// for Enable
+const uint THREADS         = 0x0001;
+const uint PRINT_ERRORS    = 0x0002;
+const uint PRINT_CALL_INFO = 0x0004;
+
+
+extern uint malloc_called_num, calloc_called_num, realloc_called_num, free_called_num, new_called_num, delete_called_num;
+extern size_t free_size;
+extern const size_t buffer_size;
+extern uint errors_num;
+
+extern void PrintInfo( uint flags=PRINT_ALL );
+extern void Enable( uint flags );
+extern void Disable( uint flags );
+
+} // end namespace
+
+
+//#define _USE_MEM_MANAGER_ // comment this line if you dont want to use mem manager
+
+// MACROS
+#ifdef _USE_MEM_MANAGER_
+
+extern void* malloc( size_t size, const char* file, int line, const char* func );
+extern void* realloc( void* p, size_t size, const char* file, int line, const char* func );
+extern void* calloc( size_t num, size_t size, const char* file, int line, const char* func );
+extern void  free( void* p, const char* file, int line, const char* func );
+extern void* operator new( size_t size, const char* file, int line, const char* func );
+extern void* operator new[]( size_t size, const char* file, int line, const char* func );
+extern void  operator delete( void* p, const char* file, int line, const char* func );
+extern void  operator delete[]( void* p, const char* file, int line, const char* func );
+
+#define new new( __FILENAME__, __LINE__, __FUNCTION__ )
+#define malloc( x ) malloc( x, __FILENAME__, __LINE__, __FUNCTION__ )
+#define realloc( x, y ) realloc( x, y, __FILENAME__, __LINE__, __FUNCTION__ )
+#define calloc( x, y ) calloc( x, y, __FILENAME__, __LINE__, __FUNCTION__ )
+#define free(x) free( x, __FILENAME__, __LINE__, __FUNCTION__ )
+
+
+#endif
+
+
+#endif

+ 643 - 0
src/old_src/2009-5-11/model.cpp

@@ -0,0 +1,643 @@
+#include "model.h"
+#include "assets.h"
+#include "material.h"
+
+
+/**
+=======================================================================================================================================
+model's data                                                                                                                          =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+skeleton_data_t::Load                                                                                                                 =
+=======================================================================================================================================
+*/
+bool skeleton_data_t::Load( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str[200];
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return false;
+	}
+
+	// bones num
+	int bones_num;
+	file >> str >> bones_num;
+	bones.resize( bones_num );
+
+	for( uint i=0; i<bones.size(); i++ )
+	{
+		bone_data_t& bone = bones[i];
+		bone.id = i;
+		// name
+		file >> str >> str >> str >> str;
+		bone.SetName( str );
+
+		// head
+		file >> str;
+		for( int j=0; j<3; j++ )
+			file >> bone.head[j];
+
+		// tail
+		file >> str;
+		for( int j=0; j<3; j++ )
+			file >> bone.tail[j];
+
+		// matrix
+		mat4_t m4;
+		file >> str;
+		for( int j=0; j<4; j++ )
+			for( int k=0; k<4; k++ )
+				file >> m4(j,k);
+
+		// matrix for real
+		bone.rot_skel_space = m4.GetRotationPart();
+		bone.tsl_skel_space = m4.GetTranslationPart();
+		mat4_t MAi( m4.Inverted() );
+		bone.rot_skel_space_inv = MAi.GetRotationPart();
+		bone.tsl_skel_space_inv = MAi.GetTranslationPart();
+
+		// parent
+		int parent_id;
+		file >> str >> parent_id;
+		if( parent_id != -1 )
+			bone.parent = &bones[parent_id];
+		else
+			bone.parent = NULL;
+
+		// childs
+		uint childs_num;
+		file >> str >> childs_num >> str;
+		DEBUG_ERR( childs_num>MAX_CHILDS_PER_BONE );
+		bone.childs_num = childs_num;
+		for( int j=0; j<bone.childs_num; j++ )
+		{
+			int child_id;
+			file >> child_id;
+			bone.childs[j] = &bones[child_id];
+		}
+
+	}
+
+	file.close();
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+model_data_t::LoadVWeights                                                                                                            =
+=======================================================================================================================================
+*/
+bool model_data_t::LoadVWeights( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str[200];
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return false;
+	}
+
+	uint verts_num;
+	file >> str >> verts_num;
+
+	// check if all verts have weights. This pressent time we treat
+	// as error if one or more verts dont have weigths.
+	if( verts_num != mesh_data->verts.size() )
+	{
+		ERROR( "verts_num != mesh_data->verts.size()" );
+		return false;
+	}
+
+	vert_weights.resize( verts_num );
+	for( size_t i=0; i<vert_weights.size(); i++ )
+	{
+		uint bones_num;
+		file >> str >> str >> str >> bones_num;
+
+		// we treat as error if one vert doesnt have a bone
+		if( bones_num < 1 )
+		{
+			ERROR( "Vert \"" << i << "\" doesnt have at least one bone" );
+			file.close();
+			return false;
+		}
+
+		// and here is another possible error
+		if( bones_num > MAX_BONES_PER_VERT )
+		{
+			ERROR( "Cannot have more than " << MAX_BONES_PER_VERT << " bones per vertex" );
+			file.close();
+			return false;
+		}
+
+		vert_weights[i].bones_num = bones_num;
+		for( uint j=0; j<bones_num; j++ )
+		{
+			int bone_id;
+			float weight;
+			file >> str >> bone_id >> str >> weight;
+			vert_weights[i].bones[j] = &skeleton_data->bones[ bone_id ];
+			vert_weights[i].weights[j] = weight;
+		}
+	}
+
+	file.close();
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+model_data_t::Load                                                                                                                    =
+=======================================================================================================================================
+*/
+bool model_data_t::Load( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str[256];
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return false;
+	}
+
+	// mesh
+	file >> str >> str;
+	mesh_data = ass::LoadMeshD( str );
+	if( !mesh_data ) return false;
+
+	// skeleton
+	file >> str >> str;
+	skeleton_data = new skeleton_data_t;
+	if( !skeleton_data->Load( str ) ) return false;
+
+	// vert weights
+	file >> str >> str;
+	if( !LoadVWeights( str ) ) return false;
+
+	file.close();
+	return true;
+}
+
+
+
+/**
+=======================================================================================================================================
+skeleton animation                                                                                                                    =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+Load                                                                                                                                  =
+=======================================================================================================================================
+*/
+bool skeleton_anim_t::Load( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str[200];
+	int tmpi;
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return false;
+	}
+
+	// read the keyframes
+	file >> str >> tmpi >> str; // the keyframes num
+	keyframes.resize( tmpi );
+
+	for( uint i=0; i<keyframes.size(); i++ )
+	{
+		file >> tmpi;
+		keyframes[i] = tmpi;
+	}
+
+	// frames_num
+	frames_num = keyframes[ keyframes.size()-1 ] + 1;
+
+	// bones
+	file >> str >> tmpi;
+	bones.resize( tmpi );
+
+	for( uint i=0; i<bones.size(); i++ )
+	{
+		file >> str >> str >> str >> str >> str >> tmpi;
+		if( tmpi ) // if has animation
+		{
+			bones[i].keyframes.resize( keyframes.size() );
+
+			for( uint j=0; j<keyframes.size(); j++ )
+			{
+				file >> str >> str >> str;
+				for( int k=0; k<4; k++ )
+					file >> bones[i].keyframes[j].rotation[k];
+
+				file >> str;
+				for( int k=0; k<3; k++ )
+					file >> bones[i].keyframes[j].translation[k];
+			}
+		}
+	}
+
+	file.close();
+	return true;
+}
+
+
+/**
+=======================================================================================================================================
+model                                                                                                                                 =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+model_t::Init                                                                                                                         =
+=======================================================================================================================================
+*/
+void model_t::Init( model_data_t* model_data_ )
+{
+	model_data = model_data_;
+
+	// init the bones
+	bones.resize( model_data->skeleton_data->bones.size() );
+
+	// init the verts
+	verts.resize( model_data->mesh_data->verts.size() );
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Interpolate                                                                                                                  =
+=======================================================================================================================================
+*/
+void model_t::Interpolate( skeleton_anim_t* anim, float frame )
+{
+	DEBUG_ERR( frame >= anim->frames_num );
+
+	// calculate the t (used in slerp and lerp) and
+	// calc the l_pose and r_pose witch indicate the pose ids in witch the frame lies between
+	const vector<uint>& keyframes = anim->keyframes;
+	float t = 0.0;
+	uint l_pose = 0, r_pose = 0;
+	for( uint j=0; j<keyframes.size(); j++ )
+	{
+		if( (float)keyframes[j] == frame )
+		{
+			l_pose = r_pose = j;
+			t = 0.0;
+			break;
+		}
+		else if( (float)keyframes[j] > frame )
+		{
+			l_pose = j-1;
+			r_pose = j;
+			t = ( frame - (float)keyframes[l_pose] ) / float( keyframes[r_pose] - keyframes[l_pose] );
+			break;
+		}
+	}
+
+
+	// now for all bones update bone's poses
+	for( uint bone_id=0; bone_id<bones.size(); bone_id++ )
+	{
+		const bone_anim_t& banim = anim->bones[bone_id];
+
+		mat3_t& local_rot = bones[bone_id].rotation;
+		vec3_t& local_transl = bones[bone_id].translation;
+
+		// if the bone has animations then slerp and lerp to find the rotation and translation
+		if( banim.keyframes.size() != 0 )
+		{
+			const bone_pose_t& l_bpose = banim.keyframes[l_pose];
+			const bone_pose_t& r_bpose = banim.keyframes[r_pose];
+
+			// rotation
+			const quat_t& q0 = l_bpose.rotation;
+			const quat_t& q1 = r_bpose.rotation;
+			local_rot.Set( q0.Slerp(q1, t) );
+
+			// translation
+			const vec3_t& v0 = l_bpose.translation;
+			const vec3_t& v1 = r_bpose.translation;
+			local_transl = v0.Lerp( v1, t );
+		}
+		// else put the idents
+		else
+		{
+			local_rot.SetIdent();
+			local_transl.SetZero();
+		}
+	}
+
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Interpolate                                                                                                                  =
+=======================================================================================================================================
+*/
+void model_t::Interpolate()
+{
+	DEBUG_ERR( !model_data );
+
+	for( ushort i=0; i<MAX_SIMULTANEOUS_ANIMS; i++ )
+	{
+		action_t* crnt = &crnt_actions[i];
+		action_t* next = &next_actions[i];
+
+		if( crnt->anim == NULL ) continue; // if the slot doesnt have anim dont bother
+
+		if( crnt->frame + crnt->step > crnt->anim->frames_num ) // if the crnt is finished then play the next or loop the crnt
+		{
+			if( next->anim == NULL ) // if there is no next anim then loop the crnt
+				crnt->frame = 0.0;
+			else // else play the next
+			{
+				crnt->anim = next->anim;
+				crnt->step = next->step;
+				crnt->frame = 0.0;
+				next->anim = NULL;
+			}
+		}
+
+		Interpolate( crnt->anim, crnt->frame );
+
+		crnt->frame += crnt->step; // inc the frame
+	}
+
+	UpdateBoneTransforms();
+}
+
+
+/*
+=======================================================================================================================================
+model_t::UpdateBoneTransforms                                                                                                         =
+=======================================================================================================================================
+*/
+void model_t::UpdateBoneTransforms()
+{
+	uint queue[ 128 ];
+	uint head = 0, tail = 0;
+
+
+	// put the roots
+	for( uint i=0; i<bones.size(); i++ )
+		if( model_data->skeleton_data->bones[i].parent == NULL )
+			queue[tail++] = i; // queue push
+
+	// loop
+	while( head != tail ) // while queue not empty
+	{
+		uint bone_id = queue[head++]; // queue pop
+		const bone_data_t& boned = model_data->skeleton_data->bones[bone_id];
+		bone_t& bone = bones[bone_id];
+
+		// bone.final_transform = MA * ANIM * MAi
+		// where MA is bone matrix at armature space and ANIM the interpolated transformation.
+		CombineTransformations( bone.translation, bone.rotation,
+		                        boned.tsl_skel_space_inv, boned.rot_skel_space_inv,
+		                        bone.translation, bone.rotation );
+
+		CombineTransformations( boned.tsl_skel_space, boned.rot_skel_space,
+		                        bone.translation, bone.rotation,
+		                        bone.translation, bone.rotation );
+
+		// and finaly add the parent's transform
+		if( boned.parent )
+		{
+			const bone_t& parent = bones[ boned.parent->id ];
+			// bone.final_final_transform = parent.transf * bone.final_transform
+			CombineTransformations( parent.translation, parent.rotation,
+		                          bone.translation, bone.rotation,
+		                          bone.translation, bone.rotation );
+		}
+
+		// now add the bone's childes
+		for( uint i=0; i<boned.childs_num; i++ )
+			queue[tail++] = boned.childs[i]->id;
+	}
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Play                                                                                                                         =
+=======================================================================================================================================
+*/
+void model_t::Play( skeleton_anim_t* anim, ushort slot, float step, ushort play_type, float smooth_transition_frames )
+{
+	DEBUG_ERR( !model_data );
+	DEBUG_ERR( anim->bones.size() != model_data->skeleton_data->bones.size() ); // the anim is not for this skeleton
+	DEBUG_ERR( slot >= MAX_SIMULTANEOUS_ANIMS ); // wrong slot
+
+	switch( play_type )
+	{
+		case START_IMMEDIATELY:
+			crnt_actions[slot].anim = anim;
+			crnt_actions[slot].step = step;
+			crnt_actions[slot].frame = 0.0;
+			break;
+
+		case WAIT_CRNT_TO_FINISH:
+			next_actions[slot].anim = anim;
+			next_actions[slot].step = step;
+			next_actions[slot].frame = 0.0;
+			break;
+
+		case SMOOTH_TRANSITION:
+			DEBUG_ERR( true ); // unimplemented
+			break;
+
+		default:
+			DEBUG_ERR( true );
+	}
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Deform                                                                                                                       =
+=======================================================================================================================================
+*/
+void model_t::Deform()
+{
+	DEBUG_ERR( !model_data );
+	DEBUG_ERR( verts.size() == 0 );
+
+
+	// deform the verts
+	for( uint i=0; i<model_data->mesh_data->verts.size(); i++ ) // for all verts
+	{
+		const vertex_weight_t& vw = model_data->vert_weights[i];
+
+		// a small optimazation detour in case the vert has only one bone
+		if( vw.bones_num == 1 )
+		{
+			uint bid = vw.bones[0]->id;
+			const mat3_t& rot = bones[ bid ].rotation;
+			const vec3_t& transl = bones[ bid ].translation;
+
+			verts[i].coords = model_data->mesh_data->verts[i].coords.Transformed( transl, rot );
+			verts[i].normal = rot * model_data->mesh_data->verts[i].normal;
+			continue;
+		}
+
+		// calc the matrix according the weights
+		mat3_t m3;
+		m3.SetZero();
+		vec3_t v3;
+		v3.SetZero();
+		// for all bones of this vert
+		for( int j=0; j< vw.bones_num; j++ )
+		{
+			uint bid = vw.bones[j]->id;
+
+			m3 += bones[ bid ].rotation * vw.weights[j];
+			v3 += bones[ bid ].translation * vw.weights[j];
+		}
+
+		// apply the matrix to the verts
+		verts[i].coords = model_data->mesh_data->verts[i].coords.Transformed( v3, m3 );
+		verts[i].normal = m3 * model_data->mesh_data->verts[i].normal;
+	}
+
+	// deform the heads and tails
+	if( r::show_skeletons )
+	{
+		for( uint i=0; i<model_data->skeleton_data->bones.size(); i++ )
+		{
+			const mat3_t& rot = bones[ i ].rotation;
+			const vec3_t& transl = bones[ i ].translation;
+
+			bones[i].head = model_data->skeleton_data->bones[i].head.Transformed( transl, rot );
+			bones[i].tail = model_data->skeleton_data->bones[i].tail.Transformed( transl, rot );
+		}
+	}
+
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Render                                                                                                                       =
+=======================================================================================================================================
+*/
+void model_t::Render()
+{
+	DEBUG_ERR( !model_data );
+
+	// transform
+	glPushMatrix();
+	r::MultMatrix( world_transformation );
+
+	// material
+	glEnable( GL_TEXTURE_2D );
+	glEnable( GL_LIGHTING );
+	glPolygonMode( GL_FRONT, GL_FILL );
+	glEnable( GL_DEPTH_TEST );
+	glDisable( GL_BLEND );
+
+	material_t* mat = ass::SearchMat( "imp.mat" );
+	if( mat == NULL )
+	{
+		ERROR( "skata" );
+	}
+	else
+		mat->Use();
+
+	/*glEnable( GL_BLEND );
+	glColor4fv( &vec4_t(1., 1., 1.0, 1.0)[0] );
+	glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_ONE );*/
+	//glBlendFunc( GL_ZERO, GL_ONE_MINUS_SRC_ALPHA );
+	//glBlendFunc( GL_ONE, GL_ONE_MINUS_DST_ALPHA );
+
+	// draw
+	glEnableClientState( GL_VERTEX_ARRAY );
+	glEnableClientState( GL_NORMAL_ARRAY );
+	glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+
+	glVertexPointer( 3, GL_FLOAT, sizeof(vertex_t), &verts[0].coords[0] );
+	glNormalPointer( GL_FLOAT, sizeof(vertex_t), &verts[0].normal[0] );
+	glTexCoordPointer( 2, GL_FLOAT, 0, &model_data->mesh_data->uvs[0] );
+
+	glDrawElements( GL_TRIANGLES, model_data->mesh_data->vert_list.size(), GL_UNSIGNED_INT, &model_data->mesh_data->vert_list[0] );
+
+	glDisableClientState( GL_VERTEX_ARRAY );
+	glDisableClientState( GL_NORMAL_ARRAY );
+	glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+
+	if( r::show_axis )
+	{
+		RenderAxis();
+	}
+
+
+	// reposition and draw the skeleton
+	if( r::show_skeletons )
+	{
+
+		glDisable( GL_DEPTH_TEST );
+		for( uint i=0; i<model_data->skeleton_data->bones.size(); i++ )
+		{
+
+			glPointSize( 4.0f );
+			glColor3fv( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+			glBegin( GL_POINTS );
+				glVertex3fv( &bones[i].head[0] );
+			glEnd();
+
+			glBegin( GL_LINES );
+				glVertex3fv( &bones[i].head[0] );
+				glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+				glVertex3fv( &bones[i].tail[0] );
+			glEnd();
+		}
+	}
+
+	// end
+	glPopMatrix();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 206 - 0
src/old_src/2009-5-11/model.h

@@ -0,0 +1,206 @@
+/*
+How tha animation works:
+
+First we interpolate using animation data. This produces a few poses that they are the transformations of a bone in bone space.
+Secondly we update the bones transformations by using the poses from the above step and add their father's transformations also. This
+produces transformations (rots and translations in manner of 1 mat3 and 1 vec3) of a bone in armature space. Thirdly we use the
+transformations to deform the mesh and the skeleton (if nessesary). This produces a set of vertices and a set of heads and tails. The
+last step is to use the verts, heads and tails to render the model. END
+
+Interpolate -> poses[] -> UpdateTransformations -> rots[] & transls[] -> Deform -> verts[] -> Render
+*/
+
+/*
+About the class naming:
+
+The classes named *_data_t hold data that remain unchanged during frames. On the other hand the *_t hold runtime information (aka
+the data that change during frames)
+*/
+
+#ifndef _MODEL_H_
+#define _MODEL_H_
+
+#include <fstream>
+#include "common.h"
+#include "primitives.h"
+#include "geometry.h"
+#include "math.h"
+
+
+/**
+=======================================================================================================================================
+model's data                                                                                                                          =
+=======================================================================================================================================
+*/
+
+const uint MAX_BONES_PER_VERT = 4;
+const uint MAX_CHILDS_PER_BONE = 4;
+
+// bone_data_t
+class bone_data_t: public nc_t
+{
+	public:
+		ushort id; // pos inside the skeleton_t::bones array
+		bone_data_t* parent;
+		bone_data_t* childs[MAX_CHILDS_PER_BONE];
+		ushort childs_num;
+
+		vec3_t head, tail;
+
+		/* the rotation and translation that transform the bone from bone space to armature space. Meaning that if
+		MA = TRS(rot_skel_space, tsl_skel_space) then head = MA * vec3_t(0.0, length, 0.0) and tail = MA * vec3_t( 0.0, 0.0, 0.0 )
+		We also keep the inverted ones for fast calculations. rot_skel_space_inv = MA.Inverted().GetRotationPart() and NOT
+		rot_skel_space_inv = rot_skel_space.Inverted()*/
+		mat3_t rot_skel_space;
+		vec3_t tsl_skel_space;
+		mat3_t rot_skel_space_inv;
+		vec3_t tsl_skel_space_inv;
+
+		 bone_data_t() {}
+		~bone_data_t() {}
+};
+
+
+// skeleton_data_t
+class skeleton_data_t
+{
+	public:
+		vector<bone_data_t> bones;
+
+		 skeleton_data_t() {}
+		~skeleton_data_t() { bones.clear(); }
+		bool Load( const char* filename );
+};
+
+
+// vertex_weight_t
+class vertex_weight_t
+{
+	public:
+		bone_data_t* bones[MAX_BONES_PER_VERT];
+		float weights[MAX_BONES_PER_VERT];
+		ushort bones_num;
+};
+
+
+// model_data_t
+class model_data_t: public data_class_t
+{
+	protected:
+		bool LoadVWeights( const char* filename );
+
+	public:
+		mesh_data_t* mesh_data;
+		skeleton_data_t* skeleton_data;
+		vector<vertex_weight_t> vert_weights;
+
+		model_data_t() {}
+		~model_data_t() {}
+		bool Load( const char* path );
+		void Unload();
+};
+
+
+/**
+=======================================================================================================================================
+model animation                                                                                                                       =
+=======================================================================================================================================
+*/
+
+// bone_pose_t
+class bone_pose_t
+{
+	public:
+		quat_t rotation;
+		vec3_t translation;
+};
+
+
+// bone_anim_t
+class bone_anim_t
+{
+	public:
+		vector<bone_pose_t> keyframes; // its empty if the bone doesnt have any animation
+
+		bone_anim_t() {}
+		~bone_anim_t() { if(keyframes.size()) keyframes.clear();}
+};
+
+
+// skeleton_anim_t
+class skeleton_anim_t: public data_class_t
+{
+	public:
+		vector<uint> keyframes;
+		uint frames_num;
+
+		vector<bone_anim_t> bones;
+
+		skeleton_anim_t() {};
+		~skeleton_anim_t() { Unload(); }
+		bool Load( const char* filename );
+		void Unload() { keyframes.clear(); bones.clear(); }
+};
+
+
+/**
+=======================================================================================================================================
+model                                                                                                                                 =
+=======================================================================================================================================
+*/
+
+// model_t
+class model_runtime_class_t: public runtime_class_t {}; // for ambiguity reasons
+
+class model_t: public object_t, public model_runtime_class_t
+{
+	protected:
+		void Interpolate( skeleton_anim_t* animation, float frame );
+		void UpdateBoneTransforms();
+
+	public:
+		class bone_t
+		{
+			public:
+				mat3_t rotation;
+				vec3_t translation;
+				vec3_t head, tail;
+		};
+
+		model_data_t* model_data;
+		vector<bone_t> bones;
+		vector<vertex_t> verts;
+
+		// for actions
+		class action_t
+		{
+			public:
+				skeleton_anim_t* anim;
+				float step;
+				float frame;
+		};
+		static const ushort MAX_SIMULTANEOUS_ANIMS = 2;
+		action_t crnt_actions[MAX_SIMULTANEOUS_ANIMS];
+		action_t next_actions[MAX_SIMULTANEOUS_ANIMS];
+
+		enum play_type_e
+		{
+			START_IMMEDIATELY,
+			WAIT_CRNT_TO_FINISH,
+			SMOOTH_TRANSITION
+		};
+
+		// funcs
+		 model_t(): model_data(NULL) {}
+		~model_t() { bones.clear(); verts.clear(); }
+
+		void Init( model_data_t* model_data_ );
+		bone_t* GetBone( const string& name );
+
+		void Play( skeleton_anim_t* animation, ushort slot, float step, ushort play_type, float smooth_transition_frames=0.0 );
+		void Interpolate();
+		void Deform();
+		void Render();
+};
+
+#endif

+ 139 - 0
src/old_src/2009-5-11/particles.cbp

@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6" />
+	<Project>
+		<Option title="3d_engine" />
+		<Option pch_mode="2" />
+		<Option compiler="gcc" />
+		<Option show_notes="0">
+			<notes>
+				<![CDATA[I export:
+
+quat_f = ToQuat( MAS * ToM4(quat) * invert(MAS) )
+
+MAS: bone.matrix["ARMATURE_SPACE"]
+quat_f: final rotation]]>
+			</notes>
+		</Option>
+		<Build>
+			<Target title="Debug">
+				<Option output="bin/Debug/particles" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj/Debug/" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Compiler>
+					<Add option="-pedantic-errors" />
+					<Add option="-pedantic" />
+					<Add option="-ansi" />
+					<Add option="-pg" />
+					<Add option="-g" />
+					<Add option="-D_DEBUG" />
+				</Compiler>
+				<Linker>
+					<Add option="-pg" />
+				</Linker>
+			</Target>
+			<Target title="Release Centrin">
+				<Option output="bin/Release/particles" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj/Release/" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Compiler>
+					<Add option="-march=pentium-m" />
+					<Add option="-fexpensive-optimizations" />
+					<Add option="-O3" />
+				</Compiler>
+				<Linker>
+					<Add option="-s" />
+				</Linker>
+			</Target>
+			<Target title="Release C2D">
+				<Option output="bin/Release/particles" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj/Release/" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Compiler>
+					<Add option="-fexpensive-optimizations" />
+					<Add option="-O3" />
+					<Add option="-mtune=core2" />
+				</Compiler>
+				<Linker>
+					<Add option="-s" />
+				</Linker>
+			</Target>
+		</Build>
+		<Compiler>
+			<Add option="-pedantic" />
+			<Add option="-Wall" />
+			<Add option="-D_USE_SHADERS_" />
+			<Add directory="/usr/include/SDL" />
+		</Compiler>
+		<Linker>
+			<Add option="`sdl-config --static-libs`" />
+			<Add library="GLU" />
+			<Add library="GLEW" />
+			<Add library="glut" />
+		</Linker>
+		<Unit filename="assets.cpp" />
+		<Unit filename="assets.h" />
+		<Unit filename="camera.cpp" />
+		<Unit filename="camera.h" />
+		<Unit filename="collision.cpp" />
+		<Unit filename="collision.h" />
+		<Unit filename="common.cpp" />
+		<Unit filename="common.h" />
+		<Unit filename="engine_class.h" />
+		<Unit filename="geometry.cpp" />
+		<Unit filename="geometry.h" />
+		<Unit filename="handlers.cpp" />
+		<Unit filename="handlers.h" />
+		<Unit filename="hud.cpp" />
+		<Unit filename="hud.h" />
+		<Unit filename="input.cpp" />
+		<Unit filename="input.h" />
+		<Unit filename="level.cpp" />
+		<Unit filename="level.h" />
+		<Unit filename="lights.cpp" />
+		<Unit filename="lights.h" />
+		<Unit filename="main_deffered.cpp" />
+		<Unit filename="material.cpp" />
+		<Unit filename="material.h" />
+		<Unit filename="math.cpp" />
+		<Unit filename="math.h" />
+		<Unit filename="memory.cpp" />
+		<Unit filename="memory.h" />
+		<Unit filename="model.cpp" />
+		<Unit filename="model.h" />
+		<Unit filename="particles.cpp" />
+		<Unit filename="particles.h" />
+		<Unit filename="primitives.cpp" />
+		<Unit filename="primitives.h" />
+		<Unit filename="r_deferred.cpp" />
+		<Unit filename="renderer.cpp" />
+		<Unit filename="renderer.h" />
+		<Unit filename="scanner.cpp" />
+		<Unit filename="scanner.h" />
+		<Unit filename="shaders.cpp" />
+		<Unit filename="shaders.h" />
+		<Unit filename="shaders/ambient_pass.frag" />
+		<Unit filename="shaders/ambient_pass.shdr" />
+		<Unit filename="shaders/ambient_pass.vert" />
+		<Unit filename="shaders/light_pass.frag" />
+		<Unit filename="shaders/mat_pass.frag" />
+		<Unit filename="shaders/mat_pass.vert" />
+		<Unit filename="shaders/skybox.frag" />
+		<Unit filename="shaders/skybox.vert" />
+		<Unit filename="skybox.cpp" />
+		<Unit filename="skybox.h" />
+		<Unit filename="spatial.cpp" />
+		<Unit filename="spatial.h" />
+		<Unit filename="texture.cpp" />
+		<Unit filename="texture.h" />
+		<Extensions>
+			<code_completion />
+			<envvars />
+			<debugger />
+			<lib_finder disable_auto="1" />
+		</Extensions>
+	</Project>
+</CodeBlocks_project_file>

+ 212 - 0
src/old_src/2009-5-11/particles.cpp

@@ -0,0 +1,212 @@
+#include "particles.h"
+
+using namespace std;
+
+#define MIN 0
+#define MAX 1
+#define VEL0 0
+#define VEL1 1
+
+/*
+=============================================================================================================================================================
+Render @ particle_t                                                                                                                                         =
+=============================================================================================================================================================
+*/
+void particle_t::Render()
+{
+	if( !life ) return;
+	glPointSize( 4.0 );
+	--life;
+
+	// calc new pos
+	float dt = ( float(hndl::timer_tick)/1000 );
+	vec3_t s_vel; // sigma velocity
+	s_vel.SetZero();
+	for( int i=0; i<PARTICLE_VELS_NUM; i++ )
+	{
+		velocity[i] = (acceleration[i] * dt) + velocity[i];
+		s_vel += velocity[i];
+	}
+
+	local_translation = s_vel * dt + local_translation;
+
+	local_rotation = mat3_t( quat_t( vec3_t(1.0, 0.0, 0.0), s_vel ) );
+
+	UpdateWorldTransform();
+
+
+	// draw the point
+	glColor3f( 1.0, 0.0, 0.0 );
+	glBegin( GL_POINTS );
+		glVertex3fv( &world_translation[0] );
+	glEnd();
+
+	// draw axis
+	if( 1 )
+	{
+		glPushMatrix();
+		r::MultMatrix( world_transformation );
+
+		glBegin( GL_LINES );
+			// x-axis
+			glColor3f( 1.0, 0.0, 0.0 );
+			glVertex3f( 0.0, 0.0, 0.0 );
+			glVertex3f( 1.0, 0.0, 0.0 );
+			// y-axis
+			glColor3f( 0.0, 1.0, 0.0 );
+			glVertex3f( 0.0, 0.0, 0.0 );
+			glVertex3f( 0.0, 1.0, 0.0 );
+			// z-axis
+			glColor3f( 0.0, 0.0, 1.0 );
+			glVertex3f( 0.0, 0.0, 0.0 );
+			glVertex3f( 0.0, 0.0, 1.0 );
+		glEnd();
+
+		glPopMatrix();
+	}
+
+	// draw the velocities
+	if( 0 )
+	{
+		// draw the velocities
+		for( int i=0; i<PARTICLE_VELS_NUM; i++ )
+		{
+			glColor3f( 0.0, 0.0, 1.0 );
+			glBegin( GL_LINES );
+				glVertex3fv( &world_translation[0] );
+				glVertex3fv( &(velocity[i]+world_translation)[0] );
+			glEnd();
+		}
+
+		// draw the Sv
+		glColor3f( 1.0, 1.0, 1.0 );
+		glBegin( GL_LINES );
+			glVertex3fv( &world_translation[0] );
+			glVertex3fv( &(s_vel+world_translation)[0] );
+		glEnd();
+	}
+}
+
+
+/*
+=============================================================================================================================================================
+Init @ particle_emitter_t                                                                                                                                   =
+=============================================================================================================================================================
+*/
+void particle_emitter_t::Init()
+{
+	particles.resize(200);
+
+	particle_life[0] = 200;
+	particle_life[1] = 400;
+	particles_per_frame = 1;
+
+	velocities[VEL0].angs[MIN] = euler_t( 0.0, ToRad(-30.0), ToRad(10.0) );
+	velocities[VEL0].angs[MAX] = euler_t( 0.0, ToRad(30.0), ToRad(45.0) );
+	velocities[VEL0].magnitude = 5.0f;
+	velocities[VEL0].acceleration_magnitude = -0.1f;
+	velocities[VEL0].rotatable = true;
+
+	velocities[VEL1].angs[MIN] = euler_t( 0.0, 0.0, ToRad(270.0) );
+	velocities[VEL1].angs[MAX] = euler_t( 0.0, 0.0, ToRad(270.0) );
+	velocities[VEL1].magnitude = 0.0f;
+	velocities[VEL1].acceleration_magnitude = 1.0f;
+	velocities[VEL1].rotatable = false;
+
+	particles_local_translation[0] = vec3_t( 0.0, 0.0, 0.0 );
+	particles_local_translation[1] = vec3_t( 0.0, 0.0, 0.0 );
+}
+
+
+/*
+==============================================================================================================================================================
+ReInitParticle @ particle_emitter_t                                                                                                                          =
+==============================================================================================================================================================
+*/
+void particle_emitter_t::ReInitParticle( particle_t& particle )
+{
+	// life
+	particle.life = RandRange( particle_life[MIN], particle_life[MAX] );
+
+	// pos
+	particle.local_translation = vec3_t(
+		RandRange( particles_local_translation[MIN].x, particles_local_translation[MAX].x ),
+		RandRange( particles_local_translation[MIN].y, particles_local_translation[MAX].y ),
+		RandRange( particles_local_translation[MIN].z, particles_local_translation[MAX].z )
+	);
+	particle.local_rotation.SetIdent();
+	particle.local_scale = 1.0f;
+
+	particle.parent = this;
+	particle.UpdateWorldTransform();
+
+	particle.local_translation = particle.world_translation;
+	particle.local_rotation = particle.world_rotation;
+	particle.local_scale = particle.world_scale;
+	particle.parent = NULL;
+
+	// initial velocities
+	for( int i=0; i<PARTICLE_VELS_NUM; i++ )
+	{
+		euler_t tmp_angs = euler_t(
+			RandRange( velocities[i].angs[MIN].x, velocities[i].angs[MAX].x ),
+			RandRange( velocities[i].angs[MIN].y, velocities[i].angs[MAX].y ),
+			RandRange( velocities[i].angs[MIN].z, velocities[i].angs[MAX].z )
+		);
+		mat3_t m3;
+		m3.Set( tmp_angs );
+		if( velocities[i].rotatable ) m3 = world_rotation * m3;
+		particle.velocity[i] = particle.acceleration[i] = m3 * vec3_t( 1.0, 0.0, 0.0 );
+		particle.velocity[i] *= velocities[i].magnitude;
+		particle.acceleration[i] *= velocities[i].acceleration_magnitude;
+
+	}
+}
+
+
+/*
+=============================================================================================================================================================
+Render @ particle_emitter_t                                                                                                                                 =
+=============================================================================================================================================================
+*/
+void particle_emitter_t::Render()
+{
+	UpdateWorldTransform();
+
+	// emitt new particles
+	int remain = particles_per_frame;
+	for( uint i=0; i<particles.size(); i++ )
+	{
+		if( particles[i].life != 0 ) continue;
+
+		ReInitParticle( particles[i] );
+
+		--remain;
+		if( remain == 0 ) break;
+	}
+
+	// render all particles
+	for( uint i=0; i<particles.size(); i++ )
+		particles[i].Render();
+
+	// render the debug cube
+	if( 1 )
+	{
+		glEnable( GL_DEPTH_TEST );
+		glDisable( GL_TEXTURE_2D );
+		glDisable( GL_BLEND );
+		glLineWidth( 2.0 );
+		glPolygonMode( GL_FRONT, GL_LINE );
+
+		glPushMatrix();
+
+		UpdateWorldTransform();
+		r::MultMatrix( world_transformation );
+
+		glColor3f( 0.0, 1.0, 0.0 );
+
+		r::RenderCube();
+
+		glPopMatrix();
+	}
+}

+ 79 - 0
src/old_src/2009-5-11/particles.h

@@ -0,0 +1,79 @@
+#ifndef _PARTICLES_H_
+#define _PARTICLES_H_
+
+#include "common.h"
+#include "math.h"
+#include "primitives.h"
+#include "handlers.h"
+
+#define PARTICLE_VELS_NUM 2
+
+/*
+===============================================================================================================================================================
+particle_t                                                                                                                                                    =
+===============================================================================================================================================================
+*/
+class particle_t: public object_t
+{
+	public:
+		vec3_t velocity[PARTICLE_VELS_NUM];
+		vec3_t acceleration[PARTICLE_VELS_NUM];
+		int life; // frames to death
+
+		particle_t() {life = 0;}
+
+		void Render();
+};
+
+
+/*
+========
+particle_emitter_t
+========
+*/
+class particle_emitter_t: public object_t
+{
+	private:
+		struct velocity_t
+		{
+			euler_t angs[2]; // MIN MAX
+			float   magnitude;
+			float   acceleration_magnitude;
+			bool    rotatable;
+			vec3_t  vel[2];
+		};
+
+	public:
+		vector<particle_t> particles;
+
+		int start_frame;
+		int stop_frame;
+		int frame;
+		bool repeat_emittion;
+		int particle_life[2];  // []
+		int particles_per_frame;
+
+		vec3_t particles_local_translation[2]; // []
+
+		// velocities
+		velocity_t velocities[PARTICLE_VELS_NUM];
+
+		//float initial_fade; // []
+		//int fade_frame;
+		//float fade_rate;
+		//
+		//float initial_size; // []
+		//int size_frame;
+		//float size_rate;
+
+
+		particle_emitter_t(){}
+		~particle_emitter_t(){ particles.clear(); }
+
+		void Init();
+		void ReInitParticle( particle_t& particle );
+		void Render();
+
+};
+
+#endif

+ 131 - 0
src/old_src/2009-5-11/primitives.cpp

@@ -0,0 +1,131 @@
+#include "primitives.h"
+#include "renderer.h"
+
+
+/*
+=======================================================================================================================================
+Constructor                                                                                                                           =
+=======================================================================================================================================
+*/
+object_t::object_t()
+{
+	parent = NULL;
+	local_translation.SetZero();
+	local_scale = 1.0f;
+	local_rotation.SetIdent();
+	world_translation.SetZero();
+	world_scale = 1.0f;
+	world_rotation.SetIdent();
+}
+
+
+/*
+=======================================================================================================================================
+RenderAxis                                                                                                                            =
+In localspace                                                                                                                         =
+=======================================================================================================================================
+*/
+void object_t::RenderAxis()
+{
+	r::SetGLState_Wireframe();
+	glDisable( GL_DEPTH_TEST );
+
+	glBegin( GL_LINES );
+		glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+		glVertex3fv( &vec3_t( 0.0, 0.0, 0.0 )[0] );
+		glVertex3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+
+		glColor3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+		glVertex3fv( &vec3_t( 0.0, 0.0, 0.0 )[0] );
+		glVertex3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+
+		glColor3fv( &vec3_t( 0.0, 0.0, 1.0 )[0] );
+		glVertex3fv( &vec3_t( 0.0, 0.0, 0.0 )[0] );
+		glVertex3fv( &vec3_t( 0.0, 0.0, 1.0 )[0] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+UpdateWorldTransform                                                                                                                  =
+=======================================================================================================================================
+*/
+void object_t::UpdateWorldTransform()
+{
+	if( parent )
+	{
+		/* the original code:
+		world_scale = parent->world_scale * local_scale;
+		world_rotation = parent->world_rotation * local_rotation;
+		world_translation = local_translation.Transformed( parent->world_translation, parent->world_rotation, parent->world_scale ); */
+		CombineTransformations( parent->world_translation, parent->world_rotation, parent->world_scale, local_translation, local_rotation,
+														local_scale, world_translation, world_rotation, world_scale );
+	}
+	else
+	{
+		world_scale = local_scale;
+		world_rotation = local_rotation;
+		world_translation = local_translation;
+	}
+
+	world_transformation = mat4_t( world_translation, world_rotation, world_scale );
+}
+
+
+/*
+=======================================================================================================================================
+Move(s)                                                                                                                               =
+Move the object according to it's local axis                                                                                          =
+=======================================================================================================================================
+*/
+void object_t::MoveLocalX( float distance )
+{
+	vec3_t x_axis = local_rotation.GetColumn(0);
+	local_translation += x_axis * distance;
+}
+
+void object_t::MoveLocalY( float distance )
+{
+	vec3_t y_axis = local_rotation.GetColumn(1);
+	local_translation += y_axis * distance;
+}
+
+void object_t::MoveLocalZ( float distance )
+{
+	vec3_t z_axis = local_rotation.GetColumn(2);
+	local_translation += z_axis * distance;
+}
+
+
+/*
+=======================================================================================================================================
+AddChilds                                                                                                                             =
+=======================================================================================================================================
+*/
+void object_t::AddChilds( uint amount, ... )
+{
+	va_list vl;
+  va_start(vl, amount);
+
+	for( uint i=0; i<amount; i++ )
+	{
+		childs.push_back( va_arg( vl, object_t* ) );
+	}
+
+	va_end(vl);
+}
+
+
+/*
+=======================================================================================================================================
+MakeParent                                                                                                                            =
+make "this" the parent of the obj given as param                                                                                      =
+=======================================================================================================================================
+*/
+void object_t::MakeParent( object_t* obj )
+{
+	DEBUG_ERR( obj->parent ); // cant have allready a parent
+	childs.push_back( obj );
+	obj->parent = this;
+}

+ 88 - 0
src/old_src/2009-5-11/primitives.h

@@ -0,0 +1,88 @@
+#ifndef _PRIMITIVES_H_
+#define _PRIMITIVES_H_
+
+#include <math.h>
+#include "common.h"
+#include "math.h"
+#include "engine_class.h"
+
+// vertex_t
+class vertex_t
+{
+	public:
+		vec3_t coords;
+		vec3_t normal;
+};
+
+// triangle_t
+class triangle_t
+{
+	public:
+		uint   vert_ids[3]; // an array with the vertex indexes in the mesh class
+		vec3_t normal;
+};
+
+
+
+/*
+=======================================================================================================================================
+object_t                                                                                                                              =
+=======================================================================================================================================
+*/
+class object_t: public runtime_class_t
+{
+	public:
+		vec3_t local_translation;
+		float  local_scale;
+		mat3_t local_rotation;
+
+		vec3_t world_translation;
+		float  world_scale;
+		mat3_t world_rotation;
+
+		mat4_t world_transformation;
+
+		object_t* parent;
+		vector<object_t*> childs;
+
+		// funcs
+		 object_t();
+		~object_t() {};
+		virtual void Render() = 0;
+		void RenderAxis();
+		void UpdateWorldTransform();
+		void RotateLocalX( float ang_degrees ) { local_rotation.RotateXAxis( ang_degrees ); }
+		void RotateLocalY( float ang_degrees ) { local_rotation.RotateYAxis( ang_degrees ); }
+		void RotateLocalZ( float ang_degrees ) { local_rotation.RotateZAxis( ang_degrees ); }
+		void MoveLocalX( float distance );
+		void MoveLocalY( float distance );
+		void MoveLocalZ( float distance );
+		void AddChilds( uint amount, ... );
+		void MakeParent( object_t* obj );
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif

+ 322 - 0
src/old_src/2009-5-11/r_deferred.cpp

@@ -0,0 +1,322 @@
+#include "renderer.h"
+#include "texture.h"
+#include "renderer.h"
+#include "lights.h"
+#include "scene.h"
+
+extern light_t lights[1];
+
+namespace r {
+namespace dfr {
+
+/*
+=======================================================================================================================================
+VARS                                                                                                                                  =
+=======================================================================================================================================
+*/
+
+enum mat_pass_fbo_attached_img_e
+{
+	MPFAI_NORMAL,
+	MPFAI_DIFFUSE,
+	MPFAI_SPECULAR,
+	MPFAI_DEPTH,
+	MAT_PASS_FBO_ATTACHED_IMGS_NUM
+};
+
+enum illum_pass_fbo_attached_img_e
+{
+	IPFAI_DIFFUSE,
+	ILLUM_PASS_FBO_ATTACHED_IMGS_NUM
+};
+
+static GLenum mat_pass_color_attachments[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT };
+const int mat_pass_color_attachments_num = 3;
+
+static GLenum illum_pass_color_attachments[] = { GL_COLOR_ATTACHMENT0_EXT };
+const int illum_pass_color_attachments_num = 1;
+
+static uint mat_pass_fbo_id = 0, illum_pass_fbo_id = 0;
+
+// framebuffer attachable images
+static texture_t
+	mat_pass_fbo_attached_imgs[MAT_PASS_FBO_ATTACHED_IMGS_NUM],
+	illum_pass_fbo_attached_imgs[ILLUM_PASS_FBO_ATTACHED_IMGS_NUM];
+
+static shader_prog_t shdr_point_light_pass, shdr_ambient_pass;
+
+
+// the bellow are used to speedup the calculation of the frag pos (view space) inside the shader. This is done by precompute the
+// view vectors each for one corner of the screen and tha planes used to compute the frag_pos_view_space.z from the depth value.
+static vec3_t view_vectors[4];
+static vec2_t planes;
+
+
+/*
+=======================================================================================================================================
+InitMatPassFBO                                                                                                                        =
+=======================================================================================================================================
+*/
+static void InitMatPassFBO()
+{
+	// create FBO
+	glGenFramebuffersEXT( 1, &mat_pass_fbo_id );
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mat_pass_fbo_id );
+
+	// create buffers
+	const int internal_format = GL_RGBA_FLOAT32_ATI;
+	mat_pass_fbo_attached_imgs[MPFAI_NORMAL].CreateEmpty( r::w, r::h, internal_format, GL_RGBA, GL_UNSIGNED_BYTE );
+	mat_pass_fbo_attached_imgs[MPFAI_DIFFUSE].CreateEmpty( r::w, r::h, internal_format, GL_RGBA, GL_UNSIGNED_BYTE );
+	mat_pass_fbo_attached_imgs[MPFAI_SPECULAR].CreateEmpty( r::w, r::h, internal_format, GL_RGBA, GL_UNSIGNED_BYTE );
+
+	mat_pass_fbo_attached_imgs[MPFAI_DEPTH].CreateEmpty( r::w, r::h, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT );
+
+	// attach the buffers to the FBO
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mat_pass_fbo_attached_imgs[MPFAI_NORMAL].gl_id, 0 );
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mat_pass_fbo_attached_imgs[MPFAI_DIFFUSE].gl_id, 0 );
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, mat_pass_fbo_attached_imgs[MPFAI_SPECULAR].gl_id, 0 );
+
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,  GL_TEXTURE_2D, mat_pass_fbo_attached_imgs[MPFAI_DEPTH].gl_id, 0 );
+
+	// test if success
+	if( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT )
+		FATAL( "Cannot create deferred shading material pass FBO" );
+
+	// unbind
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
+
+
+/*
+=======================================================================================================================================
+Init                                                                                                                                  =
+=======================================================================================================================================
+*/
+static void InitIllumPassFBO()
+{
+	// create FBO
+	glGenFramebuffersEXT( 1, &illum_pass_fbo_id );
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, illum_pass_fbo_id );
+
+	// create the txtrs
+	illum_pass_fbo_attached_imgs[IPFAI_DIFFUSE].CreateEmpty( r::w, r::h, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE );
+
+	// attach
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, illum_pass_fbo_attached_imgs[IPFAI_DIFFUSE].gl_id, 0 );
+
+	// test if success
+	if( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT )
+		FATAL( "Cannot create deferred shading illumination pass FBO" );
+
+	// unbind
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
+
+/*
+=======================================================================================================================================
+Init                                                                                                                                  =
+=======================================================================================================================================
+*/
+void Init()
+{
+	// the shaders
+	shdr_point_light_pass.Load( "shaders/light_pass_point.shdr" );
+	shdr_ambient_pass.Load( "shaders/ambient_pass.shdr" );
+
+	// material pass
+	InitMatPassFBO();
+
+	// illumination pass
+	InitIllumPassFBO();
+}
+
+
+/*
+=======================================================================================================================================
+MaterialPass                                                                                                                          =
+=======================================================================================================================================
+*/
+void MaterialPass( const camera_t& cam )
+{
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mat_pass_fbo_id );
+	glDrawBuffers( mat_pass_color_attachments_num, mat_pass_color_attachments );
+
+	glClear( GL_DEPTH_BUFFER_BIT );
+	r::SetProjectionViewMatrices( cam );
+	r::SetViewport( 0, 0, r::w, r::h );
+	scene::UpdateAllLights();
+
+	scene::skybox.Render( cam.GetViewMatrix().GetRotationPart() );
+
+	shader_prog_t* shdr = ass::SearchShdr( "no_normmap_no_diffmap.shdr" );
+	if( shdr == NULL ) shdr = ass::LoadShdr( "shaders/no_normmap_no_diffmap.shdr" );
+	shdr->Bind();
+
+	glDisable( GL_BLEND );
+	glEnable( GL_DEPTH_TEST );
+	glDisable( GL_TEXTURE_2D );
+
+	scene::RenderAllObjs();
+
+	r::NoShaders();
+
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
+
+
+/*
+=======================================================================================================================================
+CalcViewVector                                                                                                                        =
+=======================================================================================================================================
+*/
+static void CalcViewVector( const camera_t& cam )
+{
+	int pixels[4][2]={ {r::w,r::h}, {0,r::h}, { 0,0 }, {r::w,0} }; // from righ up and CC wise to right down, Just like we render the quad
+	int viewport[4]={ 0, 0, r::w, r::h };
+
+	mat3_t view_rotation = cam.GetViewMatrix().GetRotationPart();
+
+	for( int i=0; i<4; i++ )
+	{
+		/* Original Code:
+		r::UnProject( pixels[i][0], pixels[i][1], 10, cam.GetViewMatrix(), cam.GetProjectionMatrix(), viewport,
+		              view_vectors[i].x, view_vectors[i].y, view_vectors[i].z );
+		view_vectors[i] = cam.GetViewMatrix() * view_vectors[i];
+		The original code is the above 3 lines. The optimized follows:*/
+
+		mat4_t inv_pm = cam.GetProjectionMatrix().Inverted();
+
+		vec4_t vec;
+		vec.x = (2.0*(pixels[i][0]-viewport[0]))/viewport[2] - 1.0;
+		vec.y = (2.0*(pixels[i][1]-viewport[1]))/viewport[3] - 1.0;
+		vec.z = 2.0*10.0 - 1.0;
+		vec.w = 1.0;
+
+		view_vectors[i] = vec3_t(inv_pm * vec);
+		// end of optimized code
+	}
+}
+
+
+/*
+=======================================================================================================================================
+CalcPlanes                                                                                                                            =
+=======================================================================================================================================
+*/
+static void CalcPlanes( const camera_t& cam )
+{
+	planes.x = -cam.GetZFar() / (cam.GetZFar() - cam.GetZNear());
+	planes.y = -cam.GetZFar() * cam.GetZNear() / (cam.GetZFar() - cam.GetZNear());
+}
+
+
+/*
+=======================================================================================================================================
+AmbientPass                                                                                                                           =
+=======================================================================================================================================
+*/
+void AmbientPass( const camera_t& cam, const vec3_t& color )
+{
+	glDisable( GL_DEPTH_TEST );
+	glDisable( GL_BLEND );
+	glPolygonMode( GL_FRONT, GL_FILL );
+
+	// set the shader
+	shdr_ambient_pass.Bind();
+
+	glUniform3fv( shdr_ambient_pass.GetUniLocation("ambient_color"), 1, &((vec3_t)color)[0] );
+
+	mat_pass_fbo_attached_imgs[MPFAI_DIFFUSE].BindToTxtrUnit(0);  glUniform1i( shdr_ambient_pass.GetUniLocation("ambient_map"), 0 );
+	mat_pass_fbo_attached_imgs[MPFAI_DEPTH].BindToTxtrUnit(1);  glUniform1i( shdr_ambient_pass.GetUniLocation("depth_map"), 1 );
+
+	glUniform2fv( shdr_ambient_pass.GetUniLocation("camerarange"), 1, &(vec2_t(cam.GetZNear(), cam.GetZFar()))[0] );
+
+	glUniform2fv( shdr_ambient_pass.GetUniLocation("screensize"), 1, &(vec2_t(r::w, r::w))[0] );
+
+
+	float points [][2] = { {r::w,r::h}, {0,r::h}, {0,0}, {r::w,0} };
+	float uvs [][2] = { {1.0,1.0}, {0.0,1.0}, {0.0,0.0}, {1.0,0.0} };
+
+	mat_pass_fbo_attached_imgs[MPFAI_DIFFUSE].BindToTxtrUnit(0);
+
+	glBegin( GL_QUADS );
+		glTexCoord2fv( uvs[0] );
+		glVertex2fv( points[0] );
+		glTexCoord2fv( uvs[1] );
+		glVertex2fv( points[1] );
+		glTexCoord2fv( uvs[2] );
+		glVertex2fv( points[2] );
+		glTexCoord2fv( uvs[3] );
+		glVertex2fv( points[3] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+LightingPass                                                                                                                          =
+=======================================================================================================================================
+*/
+void LightingPass( const camera_t& cam )
+{
+	CalcViewVector( cam );
+	CalcPlanes( cam );
+
+	shdr_point_light_pass.Bind();
+
+	// bind textures
+	for( int i=0; i<MAT_PASS_FBO_ATTACHED_IMGS_NUM; i++ )
+	{
+		mat_pass_fbo_attached_imgs[i].BindToTxtrUnit(i);
+		glUniform1i( shdr_point_light_pass.uniform_locations[i], i );
+	}
+
+	// other uniforms
+	glUniform2fv( shdr_point_light_pass.GetUniLocation("planes"), 1, &planes[0] );
+
+	vec3_t light_pos_eye_space = cam.GetViewMatrix() * lights[0].world_translation;
+	glUniform3fv( shdr_point_light_pass.GetUniLocation("light_pos_eyespace"), 1, &light_pos_eye_space[0] );
+
+	glUniform1f( shdr_point_light_pass.GetUniLocation("inv_light_radius"), 1/4.0 );
+
+	// render
+	glDisable( GL_DEPTH_TEST );
+	glEnable( GL_BLEND );
+	glBlendFunc( GL_ONE, GL_ONE );
+
+	int loc = shdr_point_light_pass.GetAttrLocation( "view_vector" );
+
+	float points [][2] = { {r::w,r::h}, {0,r::h}, {0,0}, {r::w,0} };
+	float uvs [][2] = { {1.0,1.0}, {0.0,1.0}, {0.0,0.0}, {1.0,0.0} };
+
+	glBegin( GL_QUADS );
+		glVertexAttrib3fv( loc, &(view_vectors[0])[0] );
+		glTexCoord2fv( uvs[0] );
+		glVertex2fv( points[0] );
+		glVertexAttrib3fv( loc, &(view_vectors[1])[0] );
+		glTexCoord2fv( uvs[1] );
+		glVertex2fv( points[1] );
+		glVertexAttrib3fv( loc, &(view_vectors[2])[0] );
+		glTexCoord2fv( uvs[2] );
+		glVertex2fv( points[2] );
+		glVertexAttrib3fv( loc, &(view_vectors[3])[0] );
+		glTexCoord2fv( uvs[3] );
+		glVertex2fv( points[3] );
+	glEnd();
+
+}
+
+
+/*
+=======================================================================================================================================
+IlluminationPass                                                                                                                      =
+=======================================================================================================================================
+*/
+void IlluminationPass( const camera_t& cam, const vec3_t& color )
+{
+
+}
+
+
+
+}} // end namespaces

+ 403 - 0
src/old_src/2009-5-11/renderer.cpp

@@ -0,0 +1,403 @@
+#include "renderer.h"
+
+namespace r {
+
+
+namespace dfr {
+
+extern void Init(); // none else needs to know about r::dfr::Init()
+
+}
+
+
+/*
+=======================================================================================================================================
+data vars                                                                                                                             =
+=======================================================================================================================================
+*/
+
+uint w = 1024, h = 768, frames_num = 0;
+float aspect_ratio = (float)w/(float)h;
+
+int  max_color_atachments = 0;
+
+// standard shader preprocessor defines. Used to pass some global params to the shaders
+char* std_shader_preproc_defines = " ";
+
+// if to show debug crap
+bool show_axis = true;
+bool show_fnormals = false;
+bool show_vnormals = false;
+bool show_lights = true;
+bool show_skeletons = true;
+bool show_cameras = true;
+bool show_bvolumes = true;
+
+
+/*
+=======================================================================================================================================
+Init                                                                                                                                  =
+=======================================================================================================================================
+*/
+void Init()
+{
+	glewInit();
+	if( !glewIsSupported("GL_VERSION_2_1") )
+	{
+		FATAL( "OpenGL ver 2.1 not supported" );
+	}
+
+	if( !glewIsSupported("GL_EXT_framebuffer_object") )
+	{
+		FATAL( "Frame buffer objects not supported" );
+	}
+
+	glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+	glClearDepth( 1.0f );
+	glClearStencil( 0 );
+	glDepthFunc( GL_LEQUAL );
+
+
+	// query for max_color_atachments
+	glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS_EXT, &max_color_atachments );
+
+
+	// CullFace is always on
+	glCullFace( GL_BACK );
+	glEnable( GL_CULL_FACE );
+
+	// init deffered stuf
+	dfr::Init();
+}
+
+
+/*
+=======================================================================================================================================
+SetProjectionMatrix                                                                                                                   =
+=======================================================================================================================================
+*/
+void SetProjectionMatrix( const camera_t& cam )
+{
+	glMatrixMode( GL_PROJECTION );
+	LoadMatrix( cam.GetProjectionMatrix() );
+}
+
+
+/*
+=======================================================================================================================================
+SetViewMatrix                                                                                                                         =
+=======================================================================================================================================
+*/
+void SetViewMatrix( const camera_t& cam )
+{
+	glMatrixMode( GL_MODELVIEW );
+	LoadMatrix( cam.GetViewMatrix() );
+}
+
+
+/*
+=======================================================================================================================================
+UnProject                                                                                                                             =
+my version of gluUproject                                                                                                             =
+=======================================================================================================================================
+*/
+bool UnProject( float winX, float winY, float winZ, // window screen coords
+                const mat4_t& modelview_mat, const mat4_t& projection_mat, const int* view,
+                float& objX, float& objY, float& objZ )
+{
+	mat4_t inv_pm = projection_mat * modelview_mat;
+	inv_pm.Invert();
+
+	// the vec is in ndc space meaning: -1<=vec.x<=1 -1<=vec.y<=1 -1<=vec.z<=1
+	vec4_t vec;
+	vec.x = (2.0*(winX-view[0]))/view[2] - 1.0;
+	vec.y = (2.0*(winY-view[1]))/view[3] - 1.0;
+	vec.z = 2.0*winZ - 1.0;
+	vec.w = 1.0;
+
+	vec4_t final = inv_pm * vec;
+	final /= final.w;
+	objX = final.x;
+	objY = final.y;
+	objZ = final.z;
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+PrepareNextFrame                                                                                                                      =
+=======================================================================================================================================
+*/
+void PrepareNextFrame()
+{
+	frames_num++;
+}
+
+
+/*
+=======================================================================================================================================
+PrintLastError                                                                                                                        =
+=======================================================================================================================================
+*/
+void PrintLastError()
+{
+	GLenum errid = glGetError();
+	if( errid != GL_NO_ERROR )
+		ERROR( "GL_ERR: " << gluErrorString( errid ) );
+}
+
+
+/*
+=======================================================================================================================================
+RenderGrid                                                                                                                            =
+=======================================================================================================================================
+*/
+void RenderGrid()
+{
+	float col0[] = { 0.5f, 0.5f, 0.5f };
+	float col1[] = { 0.0f, 0.0f, 1.0f };
+	float col2[] = { 1.0f, 0.0f, 0.0f };
+
+	glDisable( GL_TEXTURE_2D );
+	glDisable( GL_LIGHTING );
+	glEnable( GL_DEPTH_TEST );
+	glDisable( GL_LINE_STIPPLE );
+	glLineWidth(1.0);
+	glColor3fv( col0 );
+
+	float space = 1.0; // space between lines
+	int num = 57;  // lines number. must be odd
+
+	float opt = ((num-1)*space/2);
+	glBegin( GL_LINES );
+		for( int x=0; x<num; x++ )
+		{
+			if( x==num/2 ) // if the middle line then change color
+				glColor3fv( col1 );
+			else if( x==(num/2)+1 ) // if the next line after the middle one change back to default col
+				glColor3fv( col0 );
+
+			float opt1 = (x*space);
+			// line in z
+			glVertex3f( opt1-opt, 0.0, -opt );
+			glVertex3f( opt1-opt, 0.0, opt );
+
+			if( x==num/2 ) // if middle line change col so you can highlight the x-axis
+				glColor3fv( col2 );
+
+			// line in the x
+			glVertex3f( -opt, 0.0, opt1-opt );
+			glVertex3f( opt, 0.0, opt1-opt );
+		}
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+RenderQuad                                                                                                                            =
+=======================================================================================================================================
+*/
+void RenderQuad( float w, float h )
+{
+	float wdiv2 = w/2, hdiv2 = h/2;
+	float points [][2] = { {wdiv2,hdiv2}, {-wdiv2,hdiv2}, {-wdiv2,-hdiv2}, {wdiv2,-hdiv2} };
+	float uvs [][2] = { {1.0,1.0}, {0.0,1.0}, {0.0,0.0}, {1.0,0.0} };
+
+	glBegin( GL_QUADS );
+		glNormal3fv( &(-vec3_t( 0.0, 0.0, 1.0 ))[0] );
+		glTexCoord2fv( uvs[0] );
+		glVertex2fv( points[0] );
+		glTexCoord2fv( uvs[1] );
+		glVertex2fv( points[1] );
+		glTexCoord2fv( uvs[2] );
+		glVertex2fv( points[2] );
+		glTexCoord2fv( uvs[3] );
+		glVertex2fv( points[3] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+RenderSphere                                                                                                                          =
+=======================================================================================================================================
+*/
+void RenderSphere( float r, int p )
+{
+	const float twopi  = PI*2;
+	const float pidiv2 = PI/2;
+
+	float theta1 = 0.0;
+	float theta2 = 0.0;
+	float theta3 = 0.0;
+
+	float ex = 0.0f;
+	float ey = 0.0f;
+	float ez = 0.0f;
+
+	float px = 0.0f;
+	float py = 0.0f;
+	float pz = 0.0f;
+
+
+	for( int i = 0; i < p/2; ++i )
+	{
+		theta1 = i * twopi / p - pidiv2;
+		theta2 = (i + 1) * twopi / p - pidiv2;
+
+		glBegin( GL_QUAD_STRIP );
+		{
+			for( int j = p; j >= 0; --j )
+			{
+				theta3 = j * twopi / p;
+
+				float sintheta1, costheta1;
+				SinCos( theta1, sintheta1, costheta1 );
+				float sintheta2, costheta2;
+				SinCos( theta2, sintheta2, costheta2 );
+				float sintheta3, costheta3;
+				SinCos( theta3, sintheta3, costheta3 );
+
+
+				ex = costheta2 * costheta3;
+				ey = sintheta2;
+				ez = costheta2 * sintheta3;
+				px = r * ex;
+				py = r * ey;
+				pz = r * ez;
+
+				glNormal3f( ex, ey, ez );
+				glTexCoord2f( -(j/(float)p) , 2*(i+1)/(float)p );
+				glVertex3f( px, py, pz );
+
+				ex = costheta1 * costheta3;
+				ey = sintheta1;
+				ez = costheta1 * sintheta3;
+				px = r * ex;
+				py = r * ey;
+				pz = r * ez;
+
+				glNormal3f( ex, ey, ez );
+				glTexCoord2f( -(j/(float)p), 2*i/(float)p );
+				glVertex3f( px, py, pz );
+			}
+		}
+		glEnd();
+	}
+}
+
+
+/*
+=======================================================================================================================================
+RenderCube                                                                                                                            =
+=======================================================================================================================================
+*/
+void RenderCube( bool cols, float size )
+{
+	size *= 0.5f;
+	glBegin(GL_QUADS);
+		// Front Face
+		if(cols) glColor3f( 0.0, 0.0, 1.0 );
+		glNormal3f( 0.0f, 0.0f, 1.0f);
+		glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size,  size);
+		glTexCoord2f(1.0, 0.0); glVertex3f( size, -size,  size);
+		glTexCoord2f(1.0, 1.0); glVertex3f( size,  size,  size);
+		glTexCoord2f(0.0, 1.0); glVertex3f(-size,  size,  size);
+		// Back Face
+		if(cols) glColor3f( 0.0, 0.0, size );
+		glNormal3f( 0.0f, 0.0f,-1.0f);
+		glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size, -size);
+		glTexCoord2f(1.0, 1.0); glVertex3f(-size,  size, -size);
+		glTexCoord2f(0.0, 1.0); glVertex3f( size,  size, -size);
+		glTexCoord2f(0.0, 0.0); glVertex3f( size, -size, -size);
+		// Top Face
+		if(cols) glColor3f( 0.0, 1.0, 0.0 );
+		glNormal3f( 0.0f, 1.0f, 0.0f);
+		glTexCoord2f(0.0, 1.0); glVertex3f(-size,  size, -size);
+		glTexCoord2f(0.0, 0.0); glVertex3f(-size,  size,  size);
+		glTexCoord2f(1.0, 0.0); glVertex3f( size,  size,  size);
+		glTexCoord2f(1.0, 1.0); glVertex3f( size,  size, -size);
+		// Bottom Face
+		if(cols) glColor3f( 0.0, size, 0.0 );
+		glNormal3f( 0.0f,-1.0f, 0.0f);
+		glTexCoord2f(1.0, 1.0); glVertex3f(-size, -size, -size);
+		glTexCoord2f(0.0, 1.0); glVertex3f( size, -size, -size);
+		glTexCoord2f(0.0, 0.0); glVertex3f( size, -size,  size);
+		glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size,  size);
+		// Right face
+		if(cols) glColor3f( 1.0, 0.0, 0.0 );
+		glNormal3f( 1.0f, 0.0f, 0.0f);
+		glTexCoord2f(1.0, 0.0); glVertex3f( size, -size, -size);
+		glTexCoord2f(1.0, 1.0); glVertex3f( size,  size, -size);
+		glTexCoord2f(0.0, 1.0); glVertex3f( size,  size,  size);
+		glTexCoord2f(0.0, 0.0); glVertex3f( size, -size,  size);
+		// Left Face
+		if(cols) glColor3f( size, 0.0, 0.0 );
+		glNormal3f(-1.0f, 0.0f, 0.0f);
+		glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size, -size);
+		glTexCoord2f(1.0, 0.0); glVertex3f(-size, -size,  size);
+		glTexCoord2f(1.0, 1.0); glVertex3f(-size,  size,  size);
+		glTexCoord2f(0.0, 1.0); glVertex3f(-size,  size, -size);
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+SetGLState                                                                                                                            =
+=======================================================================================================================================
+*/
+
+void SetGLState_Wireframe()
+{
+	NoShaders();
+	glPolygonMode( GL_FRONT, GL_LINE );
+	glDisable( GL_TEXTURE_2D );
+	glDisable( GL_LIGHTING );
+	glEnable( GL_DEPTH_TEST );
+	glDisable( GL_LINE_STIPPLE );
+	glDisable( GL_BLEND );
+	glLineWidth( 1.0 );
+}
+
+void SetGLState_WireframeDotted()
+{
+	NoShaders();
+	glPolygonMode( GL_FRONT, GL_LINE );
+	glDisable( GL_TEXTURE_2D );
+	glDisable( GL_LIGHTING );
+	glDisable( GL_BLEND );
+	glEnable( GL_DEPTH_TEST );
+	glEnable( GL_LINE_STIPPLE );
+	glLineStipple( 4, 0xAAAA );
+	glLineWidth( 1.0 );
+}
+
+void SetGLState_Solid()
+{
+	NoShaders();
+	glPolygonMode( GL_FRONT, GL_FILL );
+	glDisable( GL_TEXTURE_2D );
+	glDisable( GL_LIGHTING );
+	glEnable( GL_DEPTH_TEST );
+	glDisable( GL_LINE_STIPPLE );
+	glDisable( GL_BLEND );
+}
+
+void SetGLState_AlphaSolid()
+{
+	NoShaders();
+	glPolygonMode( GL_FRONT, GL_FILL );
+	glDisable( GL_TEXTURE_2D );
+	glDisable( GL_LIGHTING );
+	glEnable( GL_DEPTH_TEST );
+	glDisable( GL_LINE_STIPPLE );
+	glEnable( GL_BLEND );
+	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+}
+
+
+} // end namespace
+

+ 61 - 0
src/old_src/2009-5-11/renderer.h

@@ -0,0 +1,61 @@
+#ifndef _RENDERER_H_
+#define _RENDERER_H_
+
+#include "common.h"
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include "math.h"
+#include "shaders.h"
+#include "camera.h"
+
+namespace r { // begin namespace
+
+
+extern uint w, h, frames_num;
+extern float aspect_ratio;
+
+extern int  max_color_atachments;
+
+extern bool show_axis, show_fnormals, show_vnormals, show_lights, show_skeletons, show_cameras, show_bvolumes;
+
+extern void Init();
+extern void PrepareNextFrame();
+extern void PrintLastError();
+extern void RenderGrid();
+extern void RenderSphere( float radius, int precision );
+extern void RenderCube( bool cols = false, float size = 1.0f );
+extern void RenderQuad( float w, float h );
+inline const char* GetStdShaderPreprocDefines() { extern char* std_shader_preproc_defines; return std_shader_preproc_defines; }
+
+extern void SetGLState_Wireframe();
+extern void SetGLState_WireframeDotted();
+extern void SetGLState_Solid();
+extern void SetGLState_AlphaSolid();
+
+// ogl and glu wrappers
+inline void MultMatrix( const mat4_t& m4 ) { glMultMatrixf( &(m4.Transposed())(0,0) ); }
+inline void LoadMatrix( const mat4_t& m4 ) { glLoadMatrixf( &(m4.Transposed())(0,0) ); }
+inline void Color3( const vec3_t& v ) { glColor3fv( &((vec3_t&)v)[0] ); }
+inline void Color4( const vec4_t& v ) { glColor4fv( &((vec4_t&)v)[0] ); }
+inline void NoShaders() { shader_prog_t::UnBind(); }
+extern bool UnProject( float winX, float winY, float winZ, const mat4_t& modelview_mat, const mat4_t& projection_mat, const int* view, float& objX, float& objY, float& objZ );
+
+// Matrix stuff
+extern void SetProjectionMatrix( const camera_t& cam );
+extern void SetViewMatrix( const camera_t& cam );
+inline void SetProjectionViewMatrices( const camera_t& cam ) { SetProjectionMatrix(cam); SetViewMatrix(cam); }
+inline void SetViewport( uint x, uint y, uint w, uint h ) { glViewport(x,y,w,h); }
+
+// deferred shading
+namespace dfr {
+
+extern void MaterialPass( const camera_t& cam );
+extern void AmbientPass( const camera_t& cam, const vec3_t& color );
+extern void LightingPass( const camera_t& cam );
+
+} // end namespace dfr
+
+
+} // end namespace
+#endif

+ 1000 - 0
src/old_src/2009-5-11/scanner.cpp

@@ -0,0 +1,1000 @@
+#include "scanner.h"
+#include <fstream>
+
+namespace scn {
+
+#define SERROR(x) ERROR( "SCAN_ERR (" << filename << ':' << line_nmbr << "): " << x )
+
+/*
+=======================================================================================================================================
+data vars                                                                                                                             =
+=======================================================================================================================================
+*/
+static char eof_char = 0x7F;
+
+       token_t crnt_token;
+static char    line_txt [MAX_SCRIPT_LINE_LEN] = {eof_char};
+static char*   pchar;
+static fstream file;
+static char    token_info_str [128];
+       char    filename[64];
+       int     line_nmbr = 0;
+
+
+/*
+=======================================================================================================================================
+reserved words listed in length                                                                                                       =
+=======================================================================================================================================
+*/
+struct res_word_t
+{
+	const char*  string;
+	token_code_e code;
+};
+
+static res_word_t rw2 [] =
+{
+	{"ke", TC_KE}, {NULL, TC_ERROR}
+};
+
+static res_word_t rw3 [] =
+{
+	{"key", TC_KEY}, {NULL, TC_ERROR}
+};
+
+static res_word_t rw4 [] =
+{
+	{"keyw", TC_KEYW}, {NULL, TC_ERROR}
+};
+
+static res_word_t rw5 [] =
+{
+	{"keywo", TC_KEYWO}, {NULL, TC_ERROR}
+};
+
+static res_word_t rw6 [] =
+{
+	{"keywor", TC_KEYWOR}, {NULL, TC_ERROR}
+};
+
+static res_word_t rw7 [] =
+{
+	{"keyword", TC_KEYWORD}, {NULL, TC_ERROR}
+};
+
+static res_word_t* rw_table [] =  //reserved word table
+{
+	NULL, NULL, rw2, rw3, rw4, rw5, rw6, rw7,
+};
+
+
+/*
+=======================================================================================================================================
+ascii map                                                                                                                             =
+=======================================================================================================================================
+*/
+enum ascii_code_e
+{
+	AC_ERROR,
+	AC_EOF,
+	AC_LETTER,
+	AC_DIGIT,
+	AC_SPECIAL,
+	AC_WHITESPACE,
+	AC_QUOTE,
+	AC_DOUBLEQUOTE
+};
+
+static ascii_code_e ascii_lookup_table [128];
+
+static void InitAsciiMap()
+{
+	uint x;
+	memset( &ascii_lookup_table[0], AC_ERROR, sizeof(char)*128 );
+	for (x='a'; x<='z'; x++) ascii_lookup_table[x] = AC_LETTER;
+	for (x='A'; x<='Z'; x++) ascii_lookup_table[x] = AC_LETTER;
+	for (x='0'; x<='9'; x++) ascii_lookup_table[x] = AC_DIGIT;
+
+	ascii_lookup_table[':'] = ascii_lookup_table['['] = ascii_lookup_table[']'] = ascii_lookup_table['('] = AC_SPECIAL;
+	ascii_lookup_table[')'] = ascii_lookup_table['.'] = ascii_lookup_table['{'] = ascii_lookup_table['}'] = AC_SPECIAL;
+	ascii_lookup_table[','] = ascii_lookup_table[';'] = ascii_lookup_table['?'] = ascii_lookup_table['='] = AC_SPECIAL;
+	ascii_lookup_table['!'] = ascii_lookup_table['<'] = ascii_lookup_table['>'] = ascii_lookup_table['|'] = AC_SPECIAL;
+	ascii_lookup_table['&'] = ascii_lookup_table['+'] = ascii_lookup_table['-'] = ascii_lookup_table['*'] = AC_SPECIAL;
+	ascii_lookup_table['/'] = ascii_lookup_table['~'] = ascii_lookup_table['%']                  = AC_SPECIAL;
+
+	ascii_lookup_table['\n']= ascii_lookup_table['\t']= ascii_lookup_table['\0']= ascii_lookup_table[' '] = AC_WHITESPACE;
+
+	ascii_lookup_table['\"']          = AC_DOUBLEQUOTE;
+	ascii_lookup_table['\'']          = AC_QUOTE;
+	ascii_lookup_table[(int)eof_char] = AC_EOF;
+	ascii_lookup_table['_']           = AC_LETTER;
+}
+
+inline ascii_code_e AsciiLookup( char ch_ )
+{
+	return ascii_lookup_table[ (int)ch_ ];
+}
+
+
+/*
+=======================================================================================================================================
+GetLine                                                                                                                               =
+it simply gets a new line from the file and it points to the first char of that line                                                  =
+=======================================================================================================================================
+*/
+static void GetLine()
+{
+	if( file.eof() )
+		pchar = &eof_char;
+	else
+	{
+		file.getline( line_txt, MAX_SCRIPT_LINE_LEN - 1 );
+		pchar = &line_txt[0];
+	}
+	++line_nmbr;
+}
+
+
+/*
+=======================================================================================================================================
+GetNextChar                                                                                                                           =
+get the next char from the line_txt. If line_txt empty then get new line. It returns '\0' if we are in the end of the line            =
+=======================================================================================================================================
+*/
+static char GetNextChar()
+{
+	if( *pchar=='\0' )
+		GetLine();
+	else
+		++pchar;
+
+	return *pchar;
+}
+
+
+/*
+=======================================================================================================================================
+PutBackChar                                                                                                                           =
+=======================================================================================================================================
+*/
+static char PutBackChar()
+{
+	if( pchar != line_txt && *pchar != eof_char )
+		--pchar;
+
+	return *pchar;
+}
+
+
+/**
+=======================================================================================================================================
+CHECKERS                                                                                                                              =
+=======================================================================================================================================
+*/
+
+/*
+=======================================================================================================================================
+CheckWord                                                                                                                             =
+=======================================================================================================================================
+*/
+bool CheckWord()
+{
+	char* tmp_str = crnt_token.as_string;
+	char ch = *pchar;
+
+	//build the string
+	do
+	{
+		*tmp_str++ = ch;
+		ch = GetNextChar();
+	}while ( AsciiLookup(ch)==AC_LETTER || AsciiLookup(ch)==AC_DIGIT );
+
+	*tmp_str = '\0';
+
+	//check if reserved
+	tmp_str = crnt_token.as_string;
+	int len = strlen(tmp_str);
+	crnt_token.code = TC_IDENTIFIER;
+	crnt_token.value.string = tmp_str;
+	crnt_token.type = DT_STR;
+
+	if( len<=7 && len>=2 )
+	{
+		int x = 0;
+		for (;;)
+		{
+			if( rw_table[len][x].string == NULL ) break;
+
+			if( strcmp(rw_table[len][x].string, tmp_str ) == 0 )
+			{
+				crnt_token.code = rw_table[len][x].code;
+				break;
+			}
+			++x;
+		}
+	}
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+CheckComment                                                                                                                          =
+=======================================================================================================================================
+*/
+bool CheckComment()
+{
+	// begining
+		if( GetNextChar()=='*' )
+			goto branchy_cmnt;
+		else if( *pchar=='/' )
+		{
+			// end
+			GetLine();
+			crnt_token.code = TC_COMMENT;
+			return true;
+		}
+		else
+			goto error;
+
+	// "branchy" comment
+	branchy_cmnt:
+		if( GetNextChar()=='*' )
+			goto finalize_branchy;
+		else if( *pchar==eof_char )
+			goto error;
+		else
+			goto branchy_cmnt;
+
+	// finalize "branchy"
+	finalize_branchy:
+		if( GetNextChar()=='/' )
+		{
+			crnt_token.code = TC_COMMENT;
+			GetNextChar();
+			return true;
+		}
+		else
+			goto branchy_cmnt;
+
+	//error
+	error:
+		crnt_token.code = TC_ERROR;
+		SERROR( "Incorrect commend ending" );
+		return false;
+}
+
+
+/*
+=======================================================================================================================================
+CheckNumber                                                                                                                           =
+=======================================================================================================================================
+*/
+static bool CheckNumber()
+{
+	int num = 0;     //value of the number & part of the float num before '.'
+	int fnum = 0;    //part of the float num after '.'
+	int dad = 0;     //digits after dot (for floats)
+	char* tmp_str = crnt_token.as_string;
+	crnt_token.type = DT_INT;
+	ascii_code_e asc;
+
+	// begin
+		if( *pchar == '0' )
+			goto _0;
+		else if( AsciiLookup(*pchar) == AC_DIGIT )
+		{
+			num = num*10 + *pchar-'0';
+			goto _0_9;
+		}
+		else if ( *pchar == '.' )
+			goto _float;
+		else
+			goto error;
+
+	// 0????
+	_0:
+		*tmp_str++ = *pchar; GetNextChar();
+		asc = AsciiLookup(*pchar);
+		if ( *pchar == 'x' || *pchar == 'X' )
+			goto _0x;
+		else if( asc == AC_DIGIT )
+		{
+			PutBackChar();
+			goto _0_9;
+		}
+		else if( *pchar == '.' )
+			goto _float;
+		else if( asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF )
+			goto finalize;
+		else
+			goto error;
+
+	// 0x????
+	_0x:
+		*tmp_str++ = *pchar; GetNextChar();
+		asc = AsciiLookup(*pchar);
+		if( (asc == AC_DIGIT)  ||
+				(*pchar >= 'a' && *pchar <= 'f' ) ||
+				(*pchar >= 'A' && *pchar <= 'F' ) )
+		{
+			num <<= 4;
+			if( *pchar>='a' && *pchar<='f' )
+				num += *pchar - 'a' + 0xA;
+			else if( *pchar>='A' && *pchar<='F' )
+				num += *pchar - 'A' + 0xA;
+			else
+				num += *pchar - '0';
+
+			goto _0x0_9orA_F;
+		}
+		else
+			goto error;
+
+	// 0x{0-9 || a-f}??
+	_0x0_9orA_F:
+		*tmp_str++ = *pchar; GetNextChar();
+		asc = AsciiLookup(*pchar);
+		if( (asc == AC_DIGIT)         ||
+				(*pchar >= 'a' && *pchar <= 'f' ) ||
+				(*pchar >= 'A' && *pchar <= 'F' ) )
+		{
+			num <<= 4;
+			if( *pchar>='a' && *pchar<='f' )
+				num += *pchar - 'a' + 0xA;
+			else if( *pchar>='A' && *pchar<='F' )
+				num += *pchar - 'A' + 0xA;
+			else
+				num += *pchar - '0';
+
+			goto _0x0_9orA_F;
+		}
+		else if( asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF )
+			goto finalize;
+		else
+			goto error; // err
+
+	// {0-9}
+	_0_9:
+		*tmp_str++ = *pchar; GetNextChar();
+		asc = AsciiLookup(*pchar);
+		if( asc == AC_DIGIT )
+		{
+			num = num * 10 + *pchar - '0';
+			goto _0_9;
+		}
+		else if( *pchar == '.' )
+			goto _float;
+		else if( asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF )
+			goto finalize;
+		else
+			goto error; // err
+
+	// {0-9}.??
+	_float:
+		*tmp_str++ = *pchar; GetNextChar();
+		asc = AsciiLookup(*pchar);
+		crnt_token.type = DT_FLOAT;
+		if( asc == AC_DIGIT )
+		{
+			fnum = fnum * 10 + *pchar - '0';
+			++dad;
+			goto _float;
+		}
+		else if( *pchar == '.' )
+		{
+			*tmp_str++ = *pchar; GetNextChar();
+			goto error;
+		}
+		else if( *pchar == 'f' )
+		{
+			*tmp_str++ = *pchar; GetNextChar();
+			goto finalize;
+		}
+		else if( asc == AC_SPECIAL || asc == AC_WHITESPACE || asc == AC_EOF )
+			goto finalize;
+		else
+			goto error;
+
+	// finalize
+	finalize:
+		crnt_token.code = TC_NUMBER;
+
+		if( crnt_token.type == DT_INT )
+		{
+			crnt_token.value.int_ = num;
+		}
+		else
+		{
+			double dbl = (double)num + (double)(pow(10, -dad)*fnum);
+			crnt_token.value.float_ = dbl;
+		}
+		*tmp_str = '\0';
+		return true;
+
+	//error
+	error:
+		crnt_token.code = TC_ERROR;
+
+		// run until white space or special
+		asc = AsciiLookup(*pchar);
+		while( asc!=AC_WHITESPACE && asc!=AC_SPECIAL && asc!=AC_EOF )
+		{
+			*tmp_str++ = *pchar;
+			asc = AsciiLookup(GetNextChar());
+		}
+
+		*tmp_str = '\0';
+		SERROR( "Bad number suffix \"" << crnt_token.as_string << '\"' );
+
+	return false;
+}
+
+
+/*
+=======================================================================================================================================
+CheckString                                                                                                                           =
+=======================================================================================================================================
+*/
+static bool CheckString()
+{
+	char* tmp_str = crnt_token.as_string;
+	char ch = GetNextChar();
+
+	for(;;)
+	{
+		//Error
+		if( ch=='\0' || ch==eof_char ) // if end of line or eof
+		{
+			crnt_token.code = TC_ERROR;
+			*tmp_str = '\0';
+			SERROR( "Incorect string ending \"" << crnt_token.as_string );
+			return false;
+		}
+		//Escape Codes
+		else if( ch=='\\' )
+		{
+			ch = GetNextChar();
+			if( ch=='\0' || ch==eof_char )
+			{
+				crnt_token.code = TC_ERROR;
+				*tmp_str = '\0';
+				SERROR( "Incorect string ending \"" << crnt_token.as_string << '\"' );
+				return false;
+			}
+
+			switch( ch )
+			{
+				case 'n' : *tmp_str++ = '\n'; break;
+				case 't' : *tmp_str++ = '\t'; break;
+				case '0' : *tmp_str++ = '\0'; break;
+				case 'a' : *tmp_str++ = '\a'; break;
+				case '\"': *tmp_str++ = '\"'; break;
+				case 'f' : *tmp_str++ = '\f'; break;
+				case 'v' : *tmp_str++ = '\v'; break;
+				case '\'': *tmp_str++ = '\''; break;
+				case '\\': *tmp_str++ = '\\'; break;
+				case '\?': *tmp_str++ = '\?'; break;
+				default  :
+					SERROR( "Unrecognized escape charachter \'\\" << ch << '\'' );
+					*tmp_str++ = ch;
+			}
+		}
+		//End
+		else if( ch=='\"' )
+		{
+			*tmp_str = '\0';
+			crnt_token.code = TC_STRING;
+			crnt_token.value.string = crnt_token.as_string;
+			GetNextChar();
+			return true;
+		}
+		//Build str( main loop )
+		else
+		{
+			*tmp_str++ = ch;
+		}
+
+		ch = GetNextChar();
+	}
+
+	return false;
+}
+
+
+/*
+=======================================================================================================================================
+CheckChar                                                                                                                             =
+=======================================================================================================================================
+*/
+static bool CheckChar()
+{
+	char ch = GetNextChar();
+	char ch0 = ch;
+	char* tmp_str = crnt_token.as_string;
+
+	crnt_token.code = TC_ERROR;
+	*tmp_str++ = ch;
+
+	if( ch=='\0' || ch==eof_char ) // check char after '
+	{
+		SERROR( "Newline in constant" );
+		return false;
+	}
+
+	if (ch=='\'') // if '
+	{
+		SERROR( "Empty constant" );
+		GetNextChar();
+		return false;
+	}
+
+	if (ch=='\\')                // if \ then maybe escape char
+	{
+		ch = GetNextChar();
+		*tmp_str++ = ch;
+		if( ch=='\0' || ch==eof_char ) //check again after the \.
+		{
+			SERROR( "Newline in constant" );
+			return false;
+		}
+
+		switch (ch)
+		{
+			case 'n' : ch0 = '\n'; break;
+			case 't' : ch0 = '\t'; break;
+			case '0' : ch0 = '\0'; break;
+			case 'a' : ch0 = '\a'; break;
+			case '\"': ch0 = '\"'; break;
+			case 'f' : ch0 = '\f'; break;
+			case 'v' : ch0 = '\v'; break;
+			case '\'': ch0 = '\''; break;
+			case '\\': ch0 = '\\'; break;
+			case '\?': ch0 = '\?'; break;
+			default  : ch0 = ch  ; SERROR( "Unrecognized escape charachter \'\\" << ch << '\'' );
+		}
+		crnt_token.value.char_ = ch0;
+	}
+	else
+	{
+		crnt_token.value.char_ = ch;
+	}
+
+	ch = GetNextChar();
+	if( ch=='\'' )    //end
+	{
+		*tmp_str = '\0';
+		crnt_token.code = TC_CHAR;
+		GetNextChar();
+		return true;
+	}
+
+	SERROR( "Expected \'");
+	return false;
+}
+
+
+/*
+=======================================================================================================================================
+CheckSpecial                                                                                                                          =
+=======================================================================================================================================
+*/
+static bool CheckSpecial()
+{
+	char ch = *pchar;
+	token_code_e code = TC_ERROR;
+
+	switch( ch )
+	{
+		case ',': code = TC_COMMA; break;
+		case ';': code = TC_PERIOD; break;
+		case '(': code = TC_LPAREN; break;
+		case ')': code = TC_RPAREN; break;
+		case '[': code = TC_LSQBRACKET; break;
+		case ']': code = TC_RSQBRACKET; break;
+		case '{': code = TC_LBRACKET; break;
+		case '}': code = TC_RBRACKET; break;
+		case '?': code = TC_QUESTIONMARK; break;
+		case '~': code = TC_ONESCOMPLEMENT; break;
+
+		case '.':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '*':
+					code = TC_POINTERTOMEMBER;
+					break;
+				default:
+					PutBackChar();
+					code = TC_DOT;
+			}
+			break;
+
+		case ':':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case ':':
+					code = TC_SCOPERESOLUTION;
+					break;
+				default:
+					PutBackChar();
+					code = TC_UPDOWNDOT;
+			}
+			break;
+
+		case '-':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '>':
+					code = TC_POINTERTOMEMBER;
+					break;
+				case '-':
+					code = TC_DEC;
+					break;
+				case '=':
+					code = TC_ASSIGNSUB;
+					break;
+				default:
+					PutBackChar();
+					code = TC_MINUS;
+			}
+			break;
+
+		case '=':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '=':
+					code = TC_EQUAL;
+					break;
+				default:
+					PutBackChar();
+					code = TC_ASSIGN;
+			}
+			break;
+
+		case '!':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '=':
+					code = TC_NOTEQUAL;
+					break;
+				default:
+					PutBackChar();
+					code = TC_NOT;
+			}
+			break;
+
+		case '<':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '=':
+					code = TC_LESSEQUAL;
+					break;
+				case '<':
+					ch = GetNextChar();
+					switch( ch )
+					{
+						case '=':
+							code = TC_ASSIGNSHL;
+							break;
+						default:
+							PutBackChar();
+							code = TC_SHL;
+					}
+					break;
+				default:
+					PutBackChar();
+					code = TC_LESS;
+			}
+			break;
+
+		case '>':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '=':
+					code = TC_GREATEREQUAL;
+					break;
+				case '>':
+					ch = GetNextChar();
+					switch( ch )
+					{
+						case '=':
+							code = TC_ASSIGNSHR;
+							break;
+						default:
+							PutBackChar();
+							code = TC_SHR;
+					}
+					break;
+				default:
+					PutBackChar();
+					code = TC_GREATER;
+			}
+			break;
+
+		case '|':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '|':
+					code = TC_LOGICALOR;
+					break;
+				case '=':
+					code = TC_ASSIGNOR;
+					break;
+				default:
+					PutBackChar();
+					code = TC_BITWISEOR;
+			}
+			break;
+
+		case '&':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '&':
+					code = TC_LOGICALAND;
+					break;
+				case '=':
+					code = TC_ASSIGNAND;
+					break;
+				default:
+					PutBackChar();
+					code = TC_BITWISEAND;
+			}
+			break;
+
+		case '+':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '+':
+					code = TC_INC;
+					break;
+				case '=':
+					code = TC_ASSIGNADD;
+					break;
+				default:
+					PutBackChar();
+					code = TC_PLUS;
+			}
+			break;
+
+		case '*':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '=':
+					code = TC_ASSIGNMUL;
+					break;
+				default:
+					PutBackChar();
+					code = TC_STAR;
+			}
+			break;
+
+		case '/':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '=':
+					code = TC_ASSIGNDIV;
+					break;
+				default:
+					PutBackChar();
+					code = TC_BSLASH;
+			}
+			break;
+
+		case '%':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '=':
+					code = TC_ASSIGNMOD;
+					break;
+				default:
+					PutBackChar();
+					code = TC_MOD;
+			}
+			break;
+
+		case '^':
+			ch = GetNextChar();
+			switch( ch )
+			{
+				case '=':
+					code = TC_ASSIGNXOR;
+					break;
+				default:
+					PutBackChar();
+					code = TC_XOR;
+			}
+			break;
+	}
+
+	GetNextChar();
+	crnt_token.code = code;
+
+	return true;
+}
+
+
+/**
+=======================================================================================================================================
+THE EXTERNS                                                                                                                           =
+=======================================================================================================================================
+*/
+
+/*
+=======================================================================================================================================
+GetTokenInfo                                                                                                                          =
+=======================================================================================================================================
+*/
+const char* GetTokenInfo( const token_t& token )
+{
+	switch( token.code )
+	{
+		case TC_COMMENT:
+			strcpy( token_info_str, "comment" );
+			break;
+		case TC_EOF:
+			strcpy( token_info_str, "end of file" );
+			break;
+		case TC_STRING:
+			sprintf( token_info_str, "string \"%s\"", token.value.string );
+			break;
+		case TC_CHAR:
+			sprintf( token_info_str, "char '%c' (\"%s\")", crnt_token.value.char_, token.as_string );
+			break;
+		case TC_NUMBER:
+			if( token.type == DT_FLOAT )
+				sprintf( token_info_str, "float %f (\"%s\")", token.value.float_, token.as_string );
+			else
+				sprintf( token_info_str, "int %lu (\"%s\")", token.value.int_, token.as_string );
+			break;
+		case TC_IDENTIFIER:
+			sprintf( token_info_str, "identifier \"%s\"", token.value.string );
+			break;
+		case TC_ERROR:
+			strcpy( token_info_str, "scanner error" );
+			break;
+		default:
+			if( token.code>=TC_KE && token.code<=TC_KEYWORD )
+				sprintf( token_info_str, "reserved word \"%s\"", token.value.string );
+			else if( token.code>=TC_SCOPERESOLUTION && token.code<=TC_ASSIGNOR )
+				sprintf( token_info_str, "operator no %d", token.code - TC_SCOPERESOLUTION );
+	}
+
+	return token_info_str;
+}
+
+/*
+=======================================================================================================================================
+PrintTokenInfo                                                                                                                        =
+=======================================================================================================================================
+*/
+void PrintTokenInfo( const token_t& token )
+{
+	cout << "Token: " << GetTokenInfo(token) << endl;
+}
+
+
+/*
+=======================================================================================================================================
+LoadFile                                                                                                                              =
+=======================================================================================================================================
+*/
+bool LoadFile( const char* filename_ )
+{
+	file.open( filename_, ios::in );
+
+	if( !file.good() )
+	{
+		ERROR( "Cannot open file \"" << filename_ << '\"' );
+		return false;
+	}
+
+	strcpy( filename, filename_ );
+
+	// init globals
+	pchar = line_txt;
+	line_txt[0] = '\0';
+	crnt_token.code = TC_ERROR;
+	line_nmbr = 0;
+	// end init globals
+
+	GetLine();
+	return true;
+}
+
+/*
+=======================================================================================================================================
+UnloadFile                                                                                                                            =
+=======================================================================================================================================
+*/
+void UnloadFile()
+{
+	file.close();
+}
+
+
+/*
+=======================================================================================================================================
+Init                                                                                                                                  =
+=======================================================================================================================================
+*/
+void Init()
+{
+	InitAsciiMap();
+}
+
+
+/*
+=======================================================================================================================================
+GetNextToken                                                                                                                          =
+=======================================================================================================================================
+*/
+const token_t& GetNextToken()
+{
+	start:
+
+	if( *pchar == '/' )
+	{
+		char ch = GetNextChar();
+		if( ch == '/' || ch == '*' )
+		{
+			PutBackChar();
+			CheckComment();
+		}
+		else
+		{
+			PutBackChar();
+			goto crappy_label;
+		}
+	}
+	else if( *pchar == '.' )
+	{
+		ascii_code_e asc = AsciiLookup(GetNextChar());
+		PutBackChar();
+		if( asc == AC_DIGIT )
+			CheckNumber();
+		else
+			CheckSpecial();
+	}
+	else
+	{
+		crappy_label:
+		switch( AsciiLookup(*pchar) )
+		{
+			case AC_WHITESPACE : GetNextChar();  goto start;
+			case AC_LETTER     : CheckWord();    break;
+			case AC_DIGIT      : CheckNumber();  break;
+			case AC_SPECIAL    : CheckSpecial(); break;
+			case AC_QUOTE      : CheckChar();    break;
+			case AC_DOUBLEQUOTE: CheckString();  break;
+			case AC_EOF:
+				crnt_token.code = TC_EOF;
+				break;
+			case AC_ERROR:
+			default:
+				SERROR( "Unexpected character \'" << *pchar << '\'');
+
+				GetNextChar();
+				goto start;
+		}
+	}
+
+	if( crnt_token.code == TC_COMMENT ) goto start;
+	return crnt_token;
+}
+
+
+} // end namespace

+ 104 - 0
src/old_src/2009-5-11/scanner.h

@@ -0,0 +1,104 @@
+#ifndef _SCANNER_H_
+#define _SCANNER_H_
+
+#include "common.h"
+
+namespace scn {
+
+/*
+=======================================================================================================================================
+parser macros                                                                                                                         =
+=======================================================================================================================================
+*/
+#define PARSE_ERR(x) ERROR( "PARSE_ERR (" << scn::GetFilename() << ':' << scn::GetLineNmbr() << "): " << x )
+
+// common parser errors
+#define PARSE_ERR_EXPECTED(x) PARSE_ERR( "Expected " << x << " and not " << scn::GetTokenInfo(scn::GetCrntToken()) );
+#define PARSE_ERR_UNEXPECTED() PARSE_ERR( "Unexpected token " << scn::GetTokenInfo(scn::GetCrntToken()) );
+
+
+/*
+=======================================================================================================================================
+scanner types                                                                                                                         =
+=======================================================================================================================================
+*/
+const int MAX_SCRIPT_LINE_LEN = 256;
+
+// token_code_e
+enum token_code_e
+{
+	// general codes
+	TC_ERROR, TC_EOF, TC_COMMENT, TC_NUMBER, TC_CHAR, TC_STRING, TC_IDENTIFIER,
+
+	// keywords listed by strlen (dummy keywords at the moment)
+	TC_KE,
+	TC_KEY,
+	TC_KEYW,
+	TC_KEYWO,
+	TC_KEYWOR,
+	TC_KEYWORD,
+
+	// operators
+	TC_SCOPERESOLUTION, TC_LSQBRACKET, TC_RSQBRACKET, TC_LPAREN, TC_RPAREN, TC_DOT, TC_POINTERTOMEMBER, TC_LBRACKET, TC_RBRACKET, TC_COMMA,
+		TC_PERIOD, TC_UPDOWNDOT, TC_QUESTIONMARK,                                                                  //0 - 12
+	TC_EQUAL, TC_NOTEQUAL, TC_LESS, TC_GREATER, TC_LESSEQUAL, TC_GREATEREQUAL, TC_LOGICALOR, TC_LOGICALAND,            //13 - 20
+	TC_PLUS, TC_MINUS, TC_STAR, TC_BSLASH, TC_NOT, TC_BITWISEAND, TC_BITWISEOR, TC_ONESCOMPLEMENT, TC_MOD, TC_XOR,       //21 - 30
+	TC_INC, TC_DEC, TC_SHL, TC_SHR,                                                                                //31 - 34
+	TC_ASSIGN, TC_ASSIGNADD, TC_ASSIGNSUB, TC_ASSIGNMUL, TC_ASSIGNDIV, TC_ASSIGNMOD, TC_ASSIGNSHL, TC_ASSIGNSHR, TC_ASSIGNAND, TC_ASSIGNXOR,
+		TC_ASSIGNOR                                                                                              //35 - 45
+};
+
+// token_data_type_e
+enum token_data_type_e
+{
+	DT_FLOAT,
+	DT_INT,
+	DT_CHAR,
+	DT_STR
+};
+
+// token_data_val_u
+union token_data_val_u
+{
+	char   char_;
+	ulong  int_;
+	double float_;
+	char*  string; // points to token_t::as_string if the token is string
+};
+
+// token_t
+class token_t
+{
+	public:
+		token_code_e       code;
+		token_data_type_e  type;
+		token_data_val_u   value;
+
+		char as_string[ MAX_SCRIPT_LINE_LEN ];
+
+		token_t(): code( TC_ERROR ) {}
+};
+
+
+/*
+=======================================================================================================================================
+scanner externs                                                                                                                       =
+=======================================================================================================================================
+*/
+
+extern void Init();
+extern bool LoadFile( const char* filename );
+extern void UnloadFile();
+
+extern void        PrintTokenInfo( const token_t& token );
+extern const char* GetTokenInfo( const token_t& token );
+
+extern const token_t& GetNextToken();
+inline const token_t& GetCrntToken() { extern token_t crnt_token; return crnt_token; }
+
+inline const char* GetFilename() { extern char filename[]; return filename; }
+inline int         GetLineNmbr() { extern int line_nmbr; return line_nmbr; }
+
+} // end namespace
+
+#endif

+ 213 - 0
src/old_src/2009-5-11/scene.cpp

@@ -0,0 +1,213 @@
+#include "scene.h"
+
+namespace scene {
+
+/*
+=======================================================================================================================================
+DATA                                                                                                                                  =
+=======================================================================================================================================
+*/
+skybox_t skybox;
+
+vector<object_t*> objects;
+vector<spatial_t*> spatials;
+vector<light_t*> lights;
+vector<model_t*> models;
+vector<mesh_t*> meshes;
+vector<camera_t*> cameras;
+
+
+/*
+=======================================================================================================================================
+TEMPLATES                                                                                                                             =
+=======================================================================================================================================
+*/
+template <typename type_t> bool Search( vector<type_t*>& vec, type_t* x )
+{
+	typename vector<type_t*>::iterator it;
+	for( it=vec.begin(); it<vec.end(); it++ )
+	{
+		if( x == *it )
+			return true;
+	}
+	return false;
+}
+
+template <typename type_t, typename base_class_t> void Register( vector<type_t*>& vec, type_t* x )
+{
+	DEBUG_ERR( Search<type_t>( vec, x ) ); // the obj must not be allready loaded
+
+	x->base_class_t::SetID( vec.size() );
+	vec.push_back( x );
+}
+
+template <typename type_t, typename base_class_t> void UnRegister( vector<type_t*>& vec, type_t* x )
+{
+	DEBUG_ERR( Search<type_t>( vec, x ) );
+
+	// decr the ids
+	typename vector<type_t*>::iterator it;
+	for( it=vec.begin()+x->base_class_t::GetID()+1; it<vec.end(); it++ )
+	{
+		(*it)->base_class_t::SetID( (*it)->base_class_t::GetID()-1 );
+	}
+
+	vec.erase( vec.begin() + x->base_class_t::GetID() );
+}
+
+
+/*
+=======================================================================================================================================
+object_t                                                                                                                              =
+=======================================================================================================================================
+*/
+void Register( object_t* x )
+{
+	Register< object_t, runtime_class_t >( objects, x );
+}
+
+void UnRegister( object_t* x )
+{
+	Register< object_t, runtime_class_t >( objects, x );
+}
+
+
+/*
+=======================================================================================================================================
+model_t                                                                                                                               =
+=======================================================================================================================================
+*/
+void Register( model_t* x )
+{
+	Register<model_t, model_runtime_class_t>( models, x );
+	Register( (object_t*)x );
+}
+
+void UnRegister( model_t* x )
+{
+	UnRegister<model_t, model_runtime_class_t>( models, x );
+	UnRegister( (object_t*)x );
+}
+
+
+/*
+=======================================================================================================================================
+light_t                                                                                                                               =
+=======================================================================================================================================
+*/
+void Register( light_t* x )
+{
+	Register<light_t, light_runtime_class_t>( lights, x );
+	Register( (object_t*)x );
+}
+
+void UnRegister( light_t* x )
+{
+	UnRegister<light_t, light_runtime_class_t>( lights, x );
+	UnRegister( (object_t*)x );
+}
+
+
+/*
+=======================================================================================================================================
+camera_t                                                                                                                              =
+=======================================================================================================================================
+*/
+void Register( camera_t* x )
+{
+	Register<camera_t, camera_runtime_class_t>( cameras, x );
+	Register( (object_t*)x );
+}
+
+void UnRegister( camera_t* x )
+{
+	UnRegister<camera_t, camera_runtime_class_t>( cameras, x );
+	UnRegister( (object_t*)x );
+}
+
+
+/*
+=======================================================================================================================================
+UpdateAllWorldTrfs                                                                                                                    =
+=======================================================================================================================================
+*/
+void UpdateAllWorldTrfs()
+{
+	DEBUG_ERR( objects.size() > 1024 );
+	object_t* queue [1024];
+	uint head = 0, tail = 0;
+	uint num = 0;
+
+
+	// put the roots
+	for( uint i=0; i<objects.size(); i++ )
+		if( objects[i]->parent == NULL )
+			queue[tail++] = objects[i]; // queue push
+
+	// loop
+	while( head != tail ) // while queue not empty
+	{
+		object_t* obj = queue[head++]; // queue pop
+
+		obj->UpdateWorldTransform();
+		++num;
+
+		for( uint i=0; i<obj->childs.size(); i++ )
+			queue[tail++] = obj->childs[i];
+	}
+
+	DEBUG_ERR( num != objects.size() );
+}
+
+
+/*
+=======================================================================================================================================
+RenderAll                                                                                                                             =
+=======================================================================================================================================
+*/
+void RenderAllObjs()
+{
+	for( uint i=0; i<objects.size(); i++ )
+		objects[i]->Render();
+}
+
+
+/*
+=======================================================================================================================================
+InterpolateAllModels                                                                                                                  =
+=======================================================================================================================================
+*/
+void InterpolateAllModels()
+{
+	for( uint i=0; i<models.size(); i++ )
+		models[i]->Interpolate();
+}
+
+
+/*
+=======================================================================================================================================
+UpdateAllLights                                                                                                                       =
+=======================================================================================================================================
+*/
+void UpdateAllLights()
+{
+	for( uint i=0; i<lights.size(); i++ )
+		lights[i]->Update();
+}
+
+
+/*
+=======================================================================================================================================
+UpdateAllCameras                                                                                                                      =
+=======================================================================================================================================
+*/
+void UpdateAllCameras()
+{
+	vector<camera_t*>::iterator it;
+	for( it=cameras.begin(); it<cameras.end(); it++ )
+	{
+		(*it)->Update();
+	}
+}
+
+} // end namespace

+ 55 - 0
src/old_src/2009-5-11/scene.h

@@ -0,0 +1,55 @@
+#ifndef _SCENE_H_
+#define _SCENE_H_
+
+#include "common.h"
+#include "primitives.h"
+#include "spatial.h"
+#include "lights.h"
+#include "geometry.h"
+#include "model.h"
+#include "skybox.h"
+
+namespace scene {
+
+extern vector<object_t*> objects;
+extern vector<spatial_t*> spatials;
+extern vector<light_t*> lights;
+extern vector<model_t*> models;
+extern vector<mesh_t*> meshes;
+extern vector<camera_t*> cameras;
+
+// object_t
+extern void Register( object_t* obj );
+extern void UnRegister( object_t* obj );
+
+// spatial_t
+extern void Register( spatial_t* spa );
+extern void UnRegister( spatial_t* spa );
+
+// light_t
+extern void Register( light_t* light );
+extern void UnRegister( light_t* light );
+
+// mesh_t
+extern void Register( mesh_t* mesh );
+extern void UnRegister( mesh_t* mesh );
+
+// model_t
+extern void Register( model_t* mdl );
+extern void UnRegister( model_t* mdl );
+
+// camera_t
+extern void Register( camera_t* mdl );
+extern void UnRegister( camera_t* mdl );
+
+// MISC
+extern void UpdateAllWorldTrfs();
+extern void RenderAllObjs();
+extern void InterpolateAllModels();
+extern void UpdateAllLights();
+extern void UpdateAllCameras();
+
+extern skybox_t skybox;
+
+} // end namespace
+#endif

+ 307 - 0
src/old_src/2009-5-11/shaders.cpp

@@ -0,0 +1,307 @@
+#include "shaders.h"
+#include "scanner.h"
+#include "renderer.h"
+
+
+/*
+=======================================================================================================================================
+LoadAndCompile                                                                                                                        =
+=======================================================================================================================================
+*/
+bool shader_t::LoadAndCompile( const char* filename, int type_, const char* preprocessor_str )
+{
+#ifdef _USE_SHADERS_
+	type = type_;
+	const char* source_strs[2] = {NULL, NULL};
+
+	source_strs[0] = preprocessor_str;
+
+	// create the shader
+	gl_id = glCreateShader( type );
+
+	// attach the source
+	source_strs[1] = ReadFile( filename );
+	if( source_strs[1] == NULL )
+	{
+		ERROR( "Cannot read file \"" << filename << '\"' );
+		return false;
+	}
+
+	glShaderSource( gl_id, 2, source_strs, NULL );
+	delete [] source_strs[1];
+
+	// compile
+	glCompileShader( gl_id );
+
+	int success;
+	glGetShaderiv( gl_id, GL_COMPILE_STATUS, &success );
+
+	if( !success )
+	{
+		// print info log
+		int info_len = 0;
+		int chars_written = 0;
+		char* info_log = NULL;
+
+		glGetShaderiv( gl_id, GL_INFO_LOG_LENGTH, &info_len );
+		info_log = (char*)malloc( (info_len+1)*sizeof(char) );
+		glGetShaderInfoLog( gl_id, info_len, &chars_written, info_log );
+		ERROR( "Shader \"" << filename << "\" compile log follows:\n" << info_log );
+		free( info_log );
+		return false;
+	}
+#endif
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+AttachShader                                                                                                                          =
+=======================================================================================================================================
+*/
+void shader_prog_t::AttachShader( const shader_t& shader )
+{
+#ifdef _USE_SHADERS_
+	if( gl_id == 0 )
+		gl_id = glCreateProgram();
+
+	glAttachShader( gl_id, shader.gl_id );
+#endif
+}
+
+
+/*
+=======================================================================================================================================
+Link                                                                                                                                  =
+=======================================================================================================================================
+*/
+bool shader_prog_t::Link()
+{
+#ifdef _USE_SHADERS_
+	// link
+	glLinkProgram( gl_id );
+
+	// check if linked correctly
+	int success;
+	glGetProgramiv( gl_id, GL_LINK_STATUS, &success );
+
+	if( !success )
+	{
+		int info_len = 0;
+		int chars_written = 0;
+		char* info_log_txt = NULL;
+
+		glGetProgramiv( gl_id, GL_INFO_LOG_LENGTH, &info_len );
+
+		info_log_txt = (char*)malloc( (info_len+1)*sizeof(char) );
+		glGetProgramInfoLog( gl_id, info_len, &chars_written, info_log_txt );
+		ERROR( "Shader program " << GetName() << " link log follows:\n" << info_log_txt );
+		free( info_log_txt );
+		return false;
+	}
+#endif
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+LoadCompileLink                                                                                                                       =
+=======================================================================================================================================
+*/
+bool shader_prog_t::LoadCompileLink( const char* vert_fname, const char* frag_fname, const char* preprocessor_str )
+{
+#ifdef _USE_SHADERS_
+	shader_t shaders[2];
+
+	if( !shaders[0].LoadAndCompile( vert_fname, GL_VERTEX_SHADER, preprocessor_str ) ) return false;
+
+	if( !shaders[1].LoadAndCompile( frag_fname, GL_FRAGMENT_SHADER, preprocessor_str ) ) return false;
+
+	AttachShader( shaders[0] );
+	AttachShader( shaders[1] );
+
+	return Link();
+#endif
+
+	return true;
+}
+
+/*
+=======================================================================================================================================
+Load                                                                                                                                  =
+=======================================================================================================================================
+*/
+bool shader_prog_t::Load( const char* filename )
+{
+	if( !scn::LoadFile( filename ) ) return false;
+
+	string vert = "", frag = "", pproc = "";
+	vector<string> uniforms;
+	const scn::token_t* token;
+
+
+	do
+	{
+		token = &scn::GetNextToken();
+
+		//** vert shader **
+		if( token->code == scn::TC_IDENTIFIER && !strcmp( token->value.string, "VERTEX_SHADER" ) )
+		{
+			token = &scn::GetNextToken();
+			if( token->code != scn::TC_STRING )
+			{
+				PARSE_ERR_EXPECTED( "string" );
+				return false;
+			}
+			vert = token->value.string;
+		}
+		//** frag shader **
+		else if( token->code == scn::TC_IDENTIFIER && !strcmp( token->value.string, "FRAGMENT_SHADER" ) )
+		{
+			token = &scn::GetNextToken();
+			if( token->code != scn::TC_STRING )
+			{
+				PARSE_ERR_EXPECTED( "string" );
+				return false;
+			}
+			frag = token->value.string;
+		}
+		//** preprocessor defines **
+		else if( token->code == scn::TC_IDENTIFIER && !strcmp( token->value.string, "PREPROCESSOR_DEFINES" ) )
+		{
+			token = &scn::GetNextToken();
+			// {
+			if( token->code != scn::TC_LBRACKET )
+			{
+				PARSE_ERR_EXPECTED( "{" );
+				return false;
+			}
+
+			// the defines as strings
+			do
+			{
+				token = &scn::GetNextToken();
+
+				if( token->code == scn::TC_RBRACKET )
+					break;
+				else if( token->code == scn::TC_STRING )
+				{
+					pproc += token->value.string;
+					pproc += '\n';
+				}
+				else
+				{
+					PARSE_ERR_EXPECTED( "string" );
+					return false;
+				}
+
+			}while( true );
+		}
+		//** uniform vars **
+		else if( token->code == scn::TC_IDENTIFIER && !strcmp( token->value.string, "UNIFORM_VARS" ) )
+		{
+			token = &scn::GetNextToken();
+			// {
+			if( token->code != scn::TC_LBRACKET )
+			{
+				PARSE_ERR_EXPECTED( "{" );
+				return false;
+			}
+
+			// for all the uniform var's name as string
+			do
+			{
+				token = &scn::GetNextToken();
+
+				if( token->code == scn::TC_RBRACKET )
+					break;
+				else if( token->code == scn::TC_STRING )
+					uniforms.push_back( token->value.string );
+				else
+				{
+					PARSE_ERR_EXPECTED( "string" );
+					return false;
+				}
+
+			}while( true );
+		}
+		// end of file
+		else if( token->code == scn::TC_EOF )
+		{
+			break;
+		}
+		// other crap
+		else
+		{
+			PARSE_ERR_UNEXPECTED();
+			return false;
+		}
+
+	}while( true );
+
+	scn::UnloadFile();
+
+	// add the standard preprocessor defines from renderer. Note that these defines overpower the shader ones in case of a re-definition
+	pproc += r::GetStdShaderPreprocDefines();
+
+	// ready the shader for use
+	if( !LoadCompileLink( vert.c_str(), frag.c_str(), pproc.c_str() ) ) return false;
+
+#ifdef _USE_SHADERS_
+
+	// bind the uniform vars
+	Bind();
+	for( uint i=0; i<uniforms.size(); i++ )
+	{
+		int loc = GetUniLocation( uniforms[i].c_str() );
+		/*if( loc == -1 )
+		{
+			ERROR( "Cannot get uniform loc \"" << uniforms[i] << '\"' );
+			return false;
+		}*/
+		uniform_locations.push_back( loc );
+	}
+	UnBind();
+
+#endif
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+GetUniLocation                                                                                                                        =
+=======================================================================================================================================
+*/
+int shader_prog_t::GetUniLocation( const char* name )
+{
+#ifdef _USE_SHADERS_
+	GLint loc = glGetUniformLocation( gl_id, name );
+	if( loc == -1 ) ERROR( "Cannot get uniform loc \"" << name << '\"' );
+	return loc;
+#endif
+}
+
+
+/*
+=======================================================================================================================================
+GetUniLocation                                                                                                                        =
+=======================================================================================================================================
+*/
+int shader_prog_t::GetAttrLocation( const char* name )
+{
+#ifdef _USE_SHADERS_
+	GLint loc = glGetAttribLocation( gl_id, name );
+	if( loc == -1 ) ERROR( "Cannot get attrib location \"" << name << '\"' );
+	return loc;
+#endif
+}
+
+
+
+
+

+ 65 - 0
src/old_src/2009-5-11/shaders.h

@@ -0,0 +1,65 @@
+#ifndef _SHADERS_H_
+#define _SHADERS_H_
+
+#include <iostream>
+#include <GL/glew.h>
+#include "common.h"
+#include "engine_class.h"
+
+using namespace std;
+
+
+// shader
+// ether vertex or fragment
+class shader_t
+{
+	public:
+		uint type;
+		uint gl_id;
+
+		bool LoadAndCompile( const char* filename, int type_, const char* preprocessor_str = "" );
+};
+
+
+// shader program
+// combines a fragment and a vertex shader (1 and 1 is most of the times)
+class shader_prog_t: public data_class_t
+{
+	protected:
+		bool Link();
+		void AttachShader( const shader_t& shader );
+
+	public:
+		uint gl_id;
+		vector<int> uniform_locations;
+
+		 shader_prog_t(): gl_id(0) {}
+		~shader_prog_t() {}
+
+		inline void Bind()
+		{
+#ifdef _USE_SHADERS_
+			DEBUG_ERR( gl_id==0 );
+			glUseProgram(gl_id);
+#endif
+		}
+
+		static inline void UnBind()
+		{
+#ifdef _USE_SHADERS_
+			glUseProgram(NULL);
+#endif
+		}
+
+		// example: LoadCompileLink( "file.vert", "file.frag", "MAX_LIGHTS 3\n_DEBUG" );
+		bool LoadCompileLink( const char* vert_fname, const char* frag_fname, const char* preprocessor_str = "" );
+
+		bool Load( const char* filename );
+		void Unload();
+
+		int GetUniLocation( const char* name );
+		int GetAttrLocation( const char* name );
+};
+
+
+#endif

+ 97 - 0
src/old_src/2009-5-11/skybox.cpp

@@ -0,0 +1,97 @@
+#include "skybox.h"
+#include "assets.h"
+#include "renderer.h"
+#include "math.h"
+#include "camera.h"
+
+
+static float coords [][4][3] =
+{
+	// front
+	{ { 1,  1, -1}, {-1,  1, -1}, {-1, -1, -1}, { 1, -1, -1} },
+	// back
+	{ {-1,  1,  1}, { 1,  1,  1}, { 1, -1,  1}, {-1, -1,  1} },
+	// left
+	{ {-1,  1, -1}, {-1,  1,  1}, {-1, -1,  1}, {-1, -1, -1} },
+	// right
+	{ { 1,  1,  1}, { 1,  1, -1}, { 1, -1, -1}, { 1, -1,  1} },
+	// up
+	{ { 1,  1,  1}, {-1,  1,  1}, {-1,  1, -1}, { 1,  1, -1} },
+	//
+	{ { 1, -1, -1}, {-1, -1, -1}, {-1, -1,  1}, { 1, -1,  1} }
+};
+
+
+
+/*
+=======================================================================================================================================
+Load                                                                                                                                  =
+=======================================================================================================================================
+*/
+bool skybox_t::Load( const char* filenames[6] )
+{
+	for( int i=0; i<6; i++ )
+	{
+		textures[i] = ass::LoadTxtr( filenames[i] );
+	}
+
+	noise = ass::LoadTxtr( "gfx/noise2.tga" );
+	noise->TexParameter( GL_TEXTURE_WRAP_S, GL_REPEAT );
+	noise->TexParameter( GL_TEXTURE_WRAP_T, GL_REPEAT );
+
+	shader = ass::LoadShdr( "shaders/skybox.shdr" );
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void skybox_t::Render( const mat3_t& rotation )
+{
+	glDisable( GL_DEPTH_TEST );
+	glDisable( GL_BLEND );
+	glPolygonMode( GL_FRONT, GL_FILL );
+	glDisable( GL_LIGHTING );
+	glEnable( GL_TEXTURE_2D );
+
+	glPushMatrix();
+
+	shader->Bind();
+	glUniform1i( shader->uniform_locations[0], 0 );
+	glUniform1i( shader->uniform_locations[1], 1 );
+	glUniform1f( shader->uniform_locations[2], (rotation_ang/(2*PI))*100 );
+	noise->BindToTxtrUnit(1);
+
+	// set the rotation matrix
+	mat3_t tmp( rotation );
+	tmp.RotateYAxis(rotation_ang);
+	r::LoadMatrix( mat4_t( tmp ) );
+	rotation_ang += 0.0001;
+	if( rotation_ang >= 2*PI ) rotation_ang = 0.0;
+
+
+
+	const float ffac = 0.001; // fault factor. To eliminate the artefacts in the edge of the quads caused by texture filtering
+	float uvs [][2] = { {1.0-ffac,1.0-ffac}, {0.0+ffac,1.0-ffac}, {0.0+ffac,0.0+ffac}, {1.0-ffac,0.0+ffac} };
+
+	for( int i=0; i<6; i++ )
+	{
+		textures[i]->BindToTxtrUnit(0);
+		glBegin( GL_QUADS );
+			glTexCoord2fv( uvs[0] );
+			glVertex3fv( coords[i][0] );
+			glTexCoord2fv( uvs[1] );
+			glVertex3fv( coords[i][1] );
+			glTexCoord2fv( uvs[2] );
+			glVertex3fv( coords[i][2] );
+			glTexCoord2fv( uvs[3] );
+			glVertex3fv( coords[i][3] );
+		glEnd();
+	}
+
+	glPopMatrix();
+}

+ 35 - 0
src/old_src/2009-5-11/skybox.h

@@ -0,0 +1,35 @@
+#ifndef _SKYBOX_H_
+#define _SKYBOX_H_
+
+#include "common.h"
+#include "texture.h"
+#include "math.h"
+
+class skybox_t
+{
+	protected:
+		enum textures_e
+		{
+			FRONT,
+			BACK,
+			LEFT,
+			RIGHT,
+			UP,
+			DOWN
+		};
+
+		texture_t* textures[6];
+		texture_t* noise;
+		shader_prog_t* shader;
+
+		float rotation_ang;
+
+	public:
+		skybox_t() { rotation_ang=0.0; }
+
+		bool Load( const char* filenames[6] );
+		void Render( const mat3_t& rotation );
+};
+
+
+#endif

+ 30 - 0
src/old_src/2009-5-11/spatial.cpp

@@ -0,0 +1,30 @@
+#include "spatial.h"
+
+
+
+/*
+=======================================================================================================================================
+UpdateBVolums                                                                                                                         =
+=======================================================================================================================================
+*/
+void spatial_t::UpdateBVolums()
+{
+	if( local_bvolume == NULL ) return;
+
+	DEBUG_ERR( local_bvolume->type!=BSPHERE || local_bvolume->type!=AABB || local_bvolume->type!=OBB );
+
+	switch( local_bvolume->type )
+	{
+		case BSPHERE:
+			(*(bsphere_t*)world_bvolume) = (*(bsphere_t*)local_bvolume).Transformed( world_translation, world_rotation, world_scale );
+			break;
+
+		case AABB:
+			(*(aabb_t*)world_bvolume) = (*(aabb_t*)local_bvolume).Transformed( world_translation, world_rotation, world_scale );
+			break;
+
+		case OBB:
+			(*(obb_t*)world_bvolume) = (*(obb_t*)local_bvolume).Transformed( world_translation, world_rotation, world_scale );
+			break;
+	}
+}

+ 24 - 0
src/old_src/2009-5-11/spatial.h

@@ -0,0 +1,24 @@
+#ifndef _SPATIAL_H_
+#define _SPATIAL_H_
+
+#include "common.h"
+#include "primitives.h"
+#include "collision.h"
+#include "engine_class.h"
+
+class spatial_runtime_class_t: public runtime_class_t {}; // for ambiguity reasons
+
+class spatial_t: public object_t, public spatial_runtime_class_t
+{
+	public:
+
+		bvolume_t* local_bvolume;
+		bvolume_t* world_bvolume;
+
+		spatial_t() {};
+		~spatial_t() {};
+		void UpdateBVolums();
+};
+
+
+#endif

+ 319 - 0
src/old_src/2009-5-11/texture.cpp

@@ -0,0 +1,319 @@
+#include "texture.h"
+
+
+static unsigned char tga_header_uncompressed[12] = {0,0,2,0,0,0,0,0,0,0,0,0};
+static unsigned char tga_header_compressed[12]   = {0,0,10,0,0,0,0,0,0,0,0,0};
+
+
+/*
+=======================================================================================================================================
+LoadUncompressedTGA                                                                                                                   =
+=======================================================================================================================================
+*/
+bool image_t::LoadUncompressedTGA( const string& filename, fstream& fs )
+{
+	// read the info from header
+	unsigned char header6[6];
+	fs.read( (char*)&header6[0], sizeof(header6) );
+	if( fs.gcount() != sizeof(header6) )
+	{
+		ERROR( "File \"" << filename << "\": Cannot read info header" );
+		return false;
+	}
+
+	width  = header6[1] * 256 + header6[0];
+	height = header6[3] * 256 + header6[2];
+	bpp	= header6[4];
+
+	if( (width <= 0) || (height <= 0) || ((bpp != 24) && (bpp !=32)) )
+	{
+		ERROR( "File \"" << filename << "\": Invalid image information" );
+		return false;
+	}
+
+	if( bpp == 24 )
+		format = GL_RGB;
+	else
+		format = GL_RGBA;
+
+	// read the data
+	int bytes_per_pxl	= (bpp / 8);
+	int image_size = bytes_per_pxl * width * height;
+	data = new char [ image_size ];
+
+	fs.read( data, image_size );
+	if( fs.gcount() != image_size )
+	{
+		ERROR( "File \"" << filename << "\": Cannot read image data" );
+		return false;
+	}
+
+	for( int i=0; i<int(image_size); i+=bytes_per_pxl)
+	{
+		uint temp = data[i];
+		data[i] = data[i + 2];
+		data[i + 2] = temp;
+	}
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+LoadCompressedTGA                                                                                                                     =
+=======================================================================================================================================
+*/
+bool image_t::LoadCompressedTGA( const string& filename, fstream& fs )
+{
+	unsigned char header6[6];
+	fs.read( (char*)&header6[0], sizeof(header6) );
+	if( fs.gcount() != sizeof(header6) )
+	{
+		ERROR( "File \"" << filename << "\": Cannot read info header" );
+		return false;
+	}
+
+	width  = header6[1] * 256 + header6[0];
+	height = header6[3] * 256 + header6[2];
+	bpp	= header6[4];
+
+	if( (width <= 0) || (height <= 0) || ((bpp != 24) && (bpp !=32)) )
+	{
+		ERROR( "File \"" << filename << "\": Invalid texture information" );
+		return false;
+	}
+
+	if( bpp == 24 )
+		format = GL_RGB;
+	else
+		format = GL_RGBA;
+
+	int bytes_per_pxl = (bpp / 8);
+	int image_size = bytes_per_pxl * width * height;
+	data = new char [image_size];
+
+	uint pixelcount = height * width;
+	uint currentpixel = 0;
+	uint currentbyte	= 0;
+	unsigned char colorbuffer [4];
+
+	do
+	{
+		unsigned char chunkheader = 0;
+
+		fs.read( (char*)&chunkheader, sizeof(unsigned char) );
+		if( fs.gcount() != sizeof(unsigned char) )
+		{
+			ERROR( "File \"" << filename << "\": Cannot read RLE header" );
+			return false;
+		}
+
+		if( chunkheader < 128 )
+		{
+			chunkheader++;
+			for( int counter = 0; counter < chunkheader; counter++ )
+			{
+				fs.read( (char*)&colorbuffer[0], bytes_per_pxl );
+				if( fs.gcount() != bytes_per_pxl )
+				{
+					ERROR( "File \"" << filename << "\": Cannot read image data" );
+					return false;
+				}
+
+				data[currentbyte		] = colorbuffer[2];
+				data[currentbyte + 1] = colorbuffer[1];
+				data[currentbyte + 2] = colorbuffer[0];
+
+				if( bytes_per_pxl == 4 )
+				{
+					data[currentbyte + 3] = colorbuffer[3];
+				}
+
+				currentbyte += bytes_per_pxl;
+				currentpixel++;
+
+				if( currentpixel > pixelcount )
+				{
+					ERROR( "File \"" << filename << "\": Too many pixels read" );
+					return false;
+				}
+			}
+		}
+		else
+		{
+			chunkheader -= 127;
+			fs.read( (char*)&colorbuffer[0], bytes_per_pxl );
+			if( fs.gcount() != bytes_per_pxl )
+			{
+				ERROR( "File \"" << filename << "\": Cannot read from file" );
+				return false;
+			}
+
+			for( int counter = 0; counter < chunkheader; counter++ )
+			{
+				data[currentbyte] = colorbuffer[2];
+				data[currentbyte+1] = colorbuffer[1];
+				data[currentbyte+2] = colorbuffer[0];
+
+				if( bytes_per_pxl == 4 )
+				{
+					data[currentbyte + 3] = colorbuffer[3];
+				}
+
+				currentbyte += bytes_per_pxl;
+				currentpixel++;
+
+				if( currentpixel > pixelcount )
+				{
+					ERROR( "File \"" << filename << "\": Too many pixels read" );
+					return false;
+				}
+			}
+		}
+	} while(currentpixel < pixelcount);
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+LoadTGA                                                                                                                               =
+Load a tga using the help of the above                                                                                                =
+=======================================================================================================================================
+*/
+bool image_t::LoadTGA( const char* filename )
+{
+	fstream fs;
+	char my_tga_header[12];
+	fs.open( filename, ios::in|ios::binary );
+
+	if( !fs.good() )
+	{
+		ERROR( "File \"" << filename << "\": Cannot open file" );
+		return false;
+	}
+
+	fs.read( &my_tga_header[0], sizeof(my_tga_header) );
+	if( fs.gcount() != sizeof(my_tga_header) )
+	{
+		ERROR( "File \"" << filename << "\": Cannot read file header" );
+		fs.close();
+		return false;
+	}
+
+	bool funcs_return;
+	if( memcmp(tga_header_uncompressed, &my_tga_header[0], sizeof(my_tga_header)) == 0 )
+	{
+		funcs_return = LoadUncompressedTGA(filename, fs);
+	}
+	else if( memcmp(tga_header_compressed, &my_tga_header[0], sizeof(my_tga_header)) == 0 )
+	{
+		funcs_return = LoadCompressedTGA(filename, fs);
+	}
+	else
+	{
+		ERROR( "File \"" << filename << "\": Invalid image header" );
+		funcs_return = false;
+	}
+
+	fs.close();
+	return funcs_return;
+}
+
+
+/*
+=======================================================================================================================================
+Load                                                                                                                                  =
+Load a texture file (tga supported) and bind it                                                                                       =
+=======================================================================================================================================
+*/
+bool texture_t::Load( const char* filename )
+{
+	image_t* img = 0;
+
+	// find the extension's pos
+	int ext_pos = -1;
+	for( char* chp=(char*)filename+strlen(filename)-1; chp>filename; chp-- )
+	{
+		if( *chp == '.' )
+		{
+			ext_pos = chp - filename;
+			break;
+		}
+	}
+
+	if( ext_pos == -1 )
+	{
+		ERROR( "File \"" << filename << "\": Doesnt have extension" );
+		return false;
+	}
+
+	if( strcmp( (char*)filename + ext_pos, ".tga" ) == 0 )
+	{
+		img = new image_t;
+		// load it
+		if( !img->LoadTGA( filename ) )  { delete img; return false; }
+	}
+	else
+	{
+		ERROR( "File \"" << filename << "\": Unsupported extension" );
+		return false;
+	}
+
+	// bind the texture
+	glGenTextures( 1, &gl_id );
+	Bind();
+	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
+	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
+
+	glTexImage2D( GL_TEXTURE_2D, 0, img->bpp/8, img->width, img->height, 0, img->format, GL_UNSIGNED_BYTE, img->data );
+
+	delete img;
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+CreateEmpty                                                                                                                           =
+=======================================================================================================================================
+*/
+void texture_t::CreateEmpty( float width_, float height_, int internal_format, int format_, int type_ )
+{
+	if( gl_id != 0 )
+	{
+		ERROR( "Texture allready loaded" );
+		return;
+	}
+
+	// ogl stuff
+	glGenTextures( 1, &gl_id );
+	Bind();
+	TexParameter( GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+	TexParameter( GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+	TexParameter( GL_TEXTURE_WRAP_S, GL_CLAMP );
+	TexParameter( GL_TEXTURE_WRAP_T, GL_CLAMP );
+
+	// allocate to vram
+	glTexImage2D( GL_TEXTURE_2D, 0, internal_format, width_, height_, 0, format_, type_, NULL );
+
+	GLenum errid = glGetError();
+	if( errid != GL_NO_ERROR )
+		ERROR( "GL_ERR: glTexImage2D failed: " << gluErrorString( errid ) );
+}
+
+
+/*
+=======================================================================================================================================
+Unload                                                                                                                                =
+=======================================================================================================================================
+*/
+void texture_t::Unload()
+{
+	glDeleteTextures( 1, &gl_id );
+}

+ 57 - 0
src/old_src/2009-5-11/texture.h

@@ -0,0 +1,57 @@
+#ifndef _TEXTURE_H_
+#define _TEXTURE_H_
+
+class texture_t;
+
+#include <fstream>
+#include "common.h"
+#include "renderer.h"
+#include "engine_class.h"
+#include "assets.h"
+
+
+// image_t
+class image_t
+{
+	private:
+		bool LoadUncompressedTGA( const string& filename, fstream& fs );
+		bool LoadCompressedTGA( const string& filename, fstream& fs );
+	public:
+		int   width;
+		int   height;
+		int   bpp;
+		int   format;
+		char* data;
+
+		 image_t(): data(NULL) {}
+		~image_t() { if( data ) delete [] data; }
+		bool LoadTGA( const char* filename );
+};
+
+
+// texture_t
+class texture_t: public data_class_t
+{
+	public:
+		uint gl_id; // idendification for ogl
+
+		 texture_t(): gl_id(0) {}
+		~texture_t() {}
+
+		bool Load( const char* filename );
+		void Unload();
+		void CreateEmpty( float width, float height, int internal_format, int format, int type );
+
+		       inline void Bind()   { DEBUG_ERR(!gl_id); glBindTexture( GL_TEXTURE_2D, gl_id ); }
+		static inline void UnBind() { glBindTexture( GL_TEXTURE_2D, 0 ); }
+		       inline void BindToTxtrUnit    ( uint unit ) { glActiveTexture(GL_TEXTURE0+unit); Bind(); }
+		static inline void UnBindFromTxtrUnit( uint unit ) { glActiveTexture(GL_TEXTURE0+unit); UnBind(); }
+
+		inline void TexParameter( GLenum param_name, GLint value ) { Bind(); glTexParameteri( GL_TEXTURE_2D, param_name, value ); };
+		inline int GetWidth() { Bind(); int i; glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &i ); return i; }
+		inline int GetHeight() { Bind(); int i; glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &i ); return i; }
+};
+
+
+
+#endif

+ 2036 - 0
src/old_src/collision.cpp

@@ -0,0 +1,2036 @@
+#include "collision.h"
+#include "renderer.h"
+
+
+static int render_seperation_lock = 0;
+#define LOCK_RENDER_SEPERATION ++render_seperation_lock;
+#define UNLOCK_RENDER_SEPERATION --render_seperation_lock;
+#define RENDER_SEPERATION_TEST if(render_seperation_lock==0) RenderSeparationData( normal, impact_point, depth );
+
+
+/*
+=======================================================================================================================================
+misc                                                                                                                                  =
+=======================================================================================================================================
+*/
+static void RenderSeparationData( const vec3_t& normal, const vec3_t& impact_point, float depth )
+{
+	float con = 0.5f;
+	const vec3_t& i = impact_point;
+
+	glLineWidth( 2.0f );
+	glBegin( GL_LINES );
+		glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+		glVertex3f( i.x-con, i.y, i.z );
+		glVertex3f( i.x+con, i.y, i.z );
+		glColor3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+		glVertex3f( i.x, i.y-con, i.z );
+		glVertex3f( i.x, i.y+con, i.z );
+		glColor3fv( &vec3_t( 0.0, 0.0, 1.0 )[0] );
+		glVertex3f( i.x, i.y, i.z-con );
+		glVertex3f( i.x, i.y, i.z+con );
+	glEnd();
+
+	glLineWidth( 6.0f );
+	glBegin( GL_LINES );
+		glColor3fv( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+		glVertex3fv( &((vec3_t&)impact_point)[0] );
+		glVertex3fv( &(impact_point+ normal*depth )[0] );
+	glEnd();
+}
+
+
+#define ABSTRACT_INTERSECTION_CODE \
+	switch( type ) \
+	{ \
+		case LINE_SEG: \
+			return Intersects( (const lineseg_t&)bv ); \
+		case RAY: \
+			return Intersects( (const ray_t&)bv ); \
+		case PLANE: \
+			return PlaneTest( (const plane_t&)bv ) == 0.0; \
+		case BSPHERE: \
+			return Intersects( (const bsphere_t&)bv ); \
+		case AABB: \
+			return Intersects( (const aabb_t&)bv ); \
+		case OBB: \
+			return Intersects( (const obb_t&)bv ); \
+		default: \
+			return false;\
+	} \
+	return false;
+
+
+#define ABSTRACT_SEPERATION_CODE \
+	switch( type ) \
+	{ \
+		case BSPHERE: \
+			return SeperationTest( (const bsphere_t&)bv, normal, impact_point, depth ); \
+		case AABB: \
+			return SeperationTest( (const aabb_t&)bv, normal, impact_point, depth ); \
+		case OBB: \
+			return SeperationTest( (const obb_t&)bv, normal, impact_point, depth ); \
+		default: \
+			return false; \
+	} \
+	return false;
+
+
+/**
+=======================================================================================================================================
+lineseg_t                                                                                                                             =
+=======================================================================================================================================
+*/
+
+/*
+=======================================================================================================================================
+DistanceSquared                                                                                                                       =
+seg - seg                                                                                                                             =
+=======================================================================================================================================
+*/
+float lineseg_t::DistanceSquared( const lineseg_t& ls, float& s_c, float& t_c ) const
+{
+	// compute intermediate parameters
+	vec3_t w0 = origin - ls.origin;
+	float a = dir.Dot( dir );
+	float b = dir.Dot( ls.dir );
+	float c = ls.dir.Dot( ls.dir );
+	float d = dir.Dot( w0 );
+	float e = ls.dir.Dot( w0 );
+
+	float denom = a*c - b*b;
+	// parameters to compute s_c, t_c
+	float sn, sd, tn, td;
+
+	// if denom is zero, try finding closest point on sl to origin0
+	if( IsZero(denom) )
+	{
+		// clamp s_c to 0
+		sd = td = c;
+		sn = 0.0f;
+		tn = e;
+	}
+	else
+	{
+		// clamp s_c within [0,1]
+		sd = td = denom;
+		sn = b*e - c*d;
+		tn = a*e - b*d;
+
+		// clamp s_c to 0
+		if (sn < 0.0f)
+		{
+			sn = 0.0f;
+			tn = e;
+			td = c;
+		}
+		// clamp s_c to 1
+		else if (sn > sd)
+		{
+			sn = sd;
+			tn = e + b;
+			td = c;
+		}
+	}
+
+	// clamp t_c within [0,1]
+	// clamp t_c to 0
+	if( tn < 0.0f )
+	{
+		t_c = 0.0f;
+		// clamp s_c to 0
+		if ( -d < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if ( -d > a )
+			s_c = 1.0f;
+		else
+			s_c = -d/a;
+	}
+	// clamp t_c to 1
+	else if( tn > td )
+	{
+		t_c = 1.0f;
+		// clamp s_c to 0
+		if( (-d+b) < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if( (-d+b) > a )
+			s_c = 1.0f;
+		else
+			s_c = (-d+b)/a;
+	}
+	else
+	{
+			t_c = tn/td;
+			s_c = sn/sd;
+	}
+
+	// compute difference vector and distance squared
+	vec3_t wc = w0 + dir*s_c - ls.dir*t_c;
+	return wc.Dot(wc);
+}
+
+
+/*
+=======================================================================================================================================
+DistanceSquared                                                                                                                       =
+seg - ray                                                                                                                             =
+=======================================================================================================================================
+*/
+float lineseg_t::DistanceSquared( const ray_t& ray, float& s_c, float& t_c ) const
+{
+	// compute intermediate parameters
+	vec3_t w0 = origin - ray.origin;
+	float a = dir.Dot( dir );
+	float b = dir.Dot( ray.dir );
+	float c = ray.dir.Dot( ray.dir );
+	float d = dir.Dot( w0 );
+	float e = ray.dir.Dot( w0 );
+
+	float denom = a*c - b*b;
+	// parameters to compute s_c, t_c
+	float sn, sd, tn, td;
+
+	// if denom is zero, try finding closest point on ME1 to origin0
+	if( IsZero(denom) )
+	{
+		// clamp s_c to 0
+		sd = td = c;
+		sn = 0.0f;
+		tn = e;
+	}
+	else
+	{
+		// clamp s_c within [0,1]
+		sd = td = denom;
+		sn = b*e - c*d;
+		tn = a*e - b*d;
+
+		// clamp s_c to 0
+		if (sn < 0.0f)
+		{
+			sn = 0.0f;
+			tn = e;
+			td = c;
+		}
+		// clamp s_c to 1
+		else if (sn > sd)
+		{
+			sn = sd;
+			tn = e + b;
+			td = c;
+		}
+	}
+
+	// clamp t_c within [0,+inf]
+	// clamp t_c to 0
+	if (tn < 0.0f)
+	{
+		t_c = 0.0f;
+		// clamp s_c to 0
+		if ( -d < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if ( -d > a )
+			s_c = 1.0f;
+		else
+			s_c = -d/a;
+	}
+	else
+	{
+		t_c = tn/td;
+		s_c = sn/sd;
+	}
+
+	// compute difference vector and distance squared
+	vec3_t wc = w0 + dir*s_c - ray.dir*t_c;
+	return wc.Dot(wc);
+}
+
+
+/*
+=======================================================================================================================================
+DistanceSquared                                                                                                                       =
+seg - point                                                                                                                           =
+=======================================================================================================================================
+*/
+float lineseg_t::DistanceSquared( const vec3_t& point, float& t_c ) const
+{
+	vec3_t w = point - origin;
+	float proj = w.Dot(dir);
+	// endpoint 0 is closest point
+	if ( proj <= 0 )
+	{
+		t_c = 0.0f;
+		return w.Dot(w);
+	}
+	else
+	{
+		float vsq = dir.Dot(dir);
+		// endpoint 1 is closest point
+		if ( proj >= vsq )
+		{
+			t_c = 1.0f;
+			return w.Dot(w) - 2.0f*proj + vsq;
+		}
+		// otherwise somewhere else in segment
+		else
+		{
+			t_c = proj/vsq;
+			return w.Dot(w) - t_c*proj;
+		}
+	}
+}
+
+
+/*
+=======================================================================================================================================
+ClosestPoints                                                                                                                         =
+seg - seg                                                                                                                             =
+=======================================================================================================================================
+*/
+void lineseg_t::ClosestPoints( const lineseg_t& segment1, vec3_t& point0, vec3_t& point1 ) const
+{
+  // compute intermediate parameters
+  vec3_t w0 = origin - segment1.origin;
+  float a = dir.Dot( dir );
+  float b = dir.Dot( segment1.dir );
+  float c = segment1.dir.Dot( segment1.dir );
+  float d = dir.Dot( w0 );
+  float e = segment1.dir.Dot( w0 );
+
+  float denom = a*c - b*b;
+  // parameters to compute s_c, t_c
+  float s_c, t_c;
+  float sn, sd, tn, td;
+
+  // if denom is zero, try finding closest point on segment1 to origin0
+  if( ::IsZero(denom) )
+  {
+		// clamp s_c to 0
+		sd = td = c;
+		sn = 0.0f;
+		tn = e;
+  }
+  else
+  {
+		// clamp s_c within [0,1]
+		sd = td = denom;
+		sn = b*e - c*d;
+		tn = a*e - b*d;
+
+		// clamp s_c to 0
+		if(sn < 0.0f)
+		{
+			sn = 0.0f;
+			tn = e;
+			td = c;
+		}
+		// clamp s_c to 1
+		else if(sn > sd)
+		{
+			sn = sd;
+			tn = e + b;
+			td = c;
+		}
+  }
+
+  // clamp t_c within [0,1]
+  // clamp t_c to 0
+  if(tn < 0.0f)
+  {
+		t_c = 0.0f;
+		// clamp s_c to 0
+		if( -d < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if( -d > a )
+			s_c = 1.0f;
+		else
+			s_c = -d/a;
+  }
+  // clamp t_c to 1
+  else if(tn > td)
+  {
+		t_c = 1.0f;
+		// clamp s_c to 0
+		if( (-d+b) < 0.0f )
+			s_c = 0.0f;
+		// clamp s_c to 1
+		else if( (-d+b) > a )
+			s_c = 1.0f;
+		else
+			s_c = (-d+b)/a;
+  }
+  else
+  {
+     t_c = tn/td;
+     s_c = sn/sd;
+  }
+
+  // compute closest points
+  point0 = origin + dir*s_c;
+  point1 = segment1.origin + segment1.dir*t_c;
+
+}
+
+/*
+=======================================================================================================================================
+ClosestPoints                                                                                                                         =
+seg - ray                                                                                                                             =
+=======================================================================================================================================
+*/
+void lineseg_t::ClosestPoints( const ray_t& ray, vec3_t& point0, vec3_t& point1 ) const
+{
+	// compute intermediate parameters
+	vec3_t w0 = origin - ray.origin;
+	float a = dir.Dot( dir );
+	float b = dir.Dot( ray.dir );
+	float c = ray.dir.Dot( ray.dir );
+	float d = dir.Dot( w0 );
+	float e = ray.dir.Dot( w0 );
+
+	float denom = a*c - b*b;
+	// parameters to compute s_c, t_c
+	float s_c, t_c;
+	float sn, sd, tn, td;
+
+	// if denom is zero, try finding closest point on 1 to origin0
+	if( IsZero(denom) )
+	{
+		// clamp s_c to 0
+		sd = td = c;
+		sn = 0.0f;
+		tn = e;
+	}
+	else
+	{
+		// clamp s_c within [0,1]
+		sd = td = denom;
+		sn = b*e - c*d;
+		tn = a*e - b*d;
+
+		// clamp s_c to 0
+		if( sn < 0.0f )
+		{
+			sn = 0.0f;
+			tn = e;
+			td = c;
+		}
+		// clamp s_c to 1
+		else if( sn > sd )
+		{
+			sn = sd;
+			tn = e + b;
+			td = c;
+		}
+	}
+
+	// clamp t_c within [0,+inf]
+	// clamp t_c to 0
+	if( tn < 0.0f )
+	{
+		t_c = 0.0f;
+		// clamp s_c to 0
+		if( -d < 0.0f )
+		{
+			s_c = 0.0f;
+		}
+		// clamp s_c to 1
+		else if( -d > a )
+		{
+			s_c = 1.0f;
+		}
+		else
+		{
+			s_c = -d/a;
+		}
+	}
+	else
+	{
+		t_c = tn/td;
+		s_c = sn/sd;
+	}
+
+	// compute closest points
+	point0 = origin + dir*s_c;
+	point1 = ray.origin + ray.dir*t_c;
+
+}
+
+
+/*
+=======================================================================================================================================
+ClosestPoints                                                                                                                         =
+seg - point                                                                                                                           =
+=======================================================================================================================================
+*/
+vec3_t lineseg_t::ClosestPoints( const vec3_t& point ) const
+{
+    vec3_t w = point - origin;
+    float proj = w.Dot( dir );
+    // endpoint 0 is closest point
+    if( proj <= 0.0f )
+			return origin;
+    else
+    {
+			float vsq = dir.Dot(dir);
+			// endpoint 1 is closest point
+			if( proj >= vsq )
+				return origin + dir;
+			// else somewhere else in segment
+			else
+				return origin + dir*(proj/vsq);
+    }
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+lineseg_t lineseg_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale  ) const
+{
+	lineseg_t seg;
+
+	seg.origin = origin.Transformed( translate, rotate, scale );
+	seg.dir = rotate * (dir * scale);
+
+	return seg;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void lineseg_t::Render()
+{
+	vec3_t P1 = origin+dir;
+
+	glColor3fv( &vec3_t(1.0f, 1.0f, 1.0f )[0] );
+	glBegin( GL_LINES );
+		glVertex3fv( &origin[0] );
+		glVertex3fv( &P1[0] );
+	glEnd();
+
+
+	glPointSize( 4.0f );
+	glBegin( GL_POINTS );
+		glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+		glVertex3fv( &origin[0] );
+		glColor3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+		glVertex3fv( &P1[0] );
+	glEnd();
+
+	glDisable( GL_DEPTH_TEST );
+	glColor3fv( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+	glBegin( GL_LINES );
+		glVertex3fv( &origin[0] );
+		glVertex3fv( &(P1)[0] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+line - any                                                                                                                            =
+=======================================================================================================================================
+*/
+bool lineseg_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+line - sphere                                                                                                                         =
+=======================================================================================================================================
+*/
+bool lineseg_t::Intersects( const bsphere_t& sphere ) const
+{
+	return sphere.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+line - aabb                                                                                                                           =
+=======================================================================================================================================
+*/
+bool lineseg_t::Intersects( const aabb_t& box ) const
+{
+	return box.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+line - obb                                                                                                                            =
+=======================================================================================================================================
+*/
+bool lineseg_t::Intersects( const obb_t& obb ) const
+{
+	return obb.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+line - any                                                                                                                            =
+=======================================================================================================================================
+*/
+bool lineseg_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+
+/**
+=======================================================================================================================================
+ray_t                                                                                                                                 =
+=======================================================================================================================================
+*/
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+ray_t ray_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	ray_t ray;
+
+	mat4_t semi_transf( rotate*scale );
+
+	ray.dir = semi_transf * dir;
+	ray.dir.Normalize();
+
+	ray.origin = semi_transf * origin;
+	ray.origin += translate;
+
+	return ray;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void ray_t::Render()
+{
+	const float dist = 100.0f;
+	glColor3fv( &vec3_t( 1.0f, 1.0f, 0.0f )[0] );
+
+	// render a dotted without depth
+	glDisable( GL_DEPTH_TEST );
+
+	glBegin( GL_LINES );
+		glVertex3fv( &origin[0] );
+		glVertex3fv( &(dir*dist+origin)[0] );
+	glEnd();
+
+	glPointSize( 4.0f );
+	glBegin( GL_POINTS );
+		glVertex3fv( &origin[0] );
+	glEnd();
+
+	// render with depth
+	glBegin( GL_LINES );
+		glVertex3fv( &origin[0] );
+		glVertex3fv( &(dir*dist+origin)[0] );
+	glEnd();
+
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+ray - any                                                                                                                             =
+=======================================================================================================================================
+*/
+bool ray_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+ray - sphere                                                                                                                          =
+=======================================================================================================================================
+*/
+bool ray_t::Intersects( const bsphere_t& sphere ) const
+{
+	return sphere.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+ray - aabb                                                                                                                            =
+=======================================================================================================================================
+*/
+bool ray_t::Intersects( const aabb_t& box ) const
+{
+	return box.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+ray - obb                                                                                                                             =
+=======================================================================================================================================
+*/
+bool ray_t::Intersects( const obb_t& obb ) const
+{
+	return obb.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+ray - any                                                                                                                             =
+=======================================================================================================================================
+*/
+bool ray_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/**
+=======================================================================================================================================
+plane_t                                                                                                                               =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+from plane eqtuation                                                                                                                  =
+=======================================================================================================================================
+*/
+void plane_t::Set( float a, float b, float c, float d )
+{
+	// normalize for cheap distance checks
+	float lensq = a*a + b*b + c*c;
+	// length of normal had better not be zero
+	DEBUG_ERR( IsZero( lensq ) );
+
+	// recover gracefully
+	if ( IsZero( lensq ) )
+	{
+		normal = vec3_t( 1.0, 0.0, 0.0 );
+		offset = 0.0f;
+	}
+	else
+	{
+		float recip = InvSqrt(lensq);
+		normal = vec3_t( a*recip, b*recip, c*recip );
+		offset = d*recip;
+	}
+}
+
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+from 3 points                                                                                                                         =
+=======================================================================================================================================
+*/
+void plane_t::Set( const vec3_t& p0, const vec3_t& p1, const vec3_t& p2 )
+{
+	// get plane vectors
+	vec3_t u = p1 - p0;
+	vec3_t v = p2 - p0;
+
+	normal = u.Cross(v);
+
+	// length of normal had better not be zero
+	DEBUG_ERR( IsZero( normal.LengthSquared() ) );
+
+	normal.Normalize();
+	offset = normal.Dot(p0); // ToDo: correct??
+
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+plane_t plane_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	plane_t plane;
+
+	// the normal
+	plane.normal = rotate*normal;
+
+	// the offset
+	vec3_t new_trans = rotate.Transposed() * translate;
+	plane.offset = offset*scale + new_trans.Dot( normal );
+
+	return plane;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void plane_t::Render()
+{
+	glPushMatrix();
+
+	vec3_t translate( normal*offset );
+	mat3_t rotate( quat_t( vec3_t( 0.0, 0.0, 1.0 ), normal ) );
+	mat4_t transform( translate, rotate );
+	r::MultMatrix( transform );
+
+	glColor4fv( &vec4_t(1.0f, 1.0f, 1.0f, 0.5f)[0] );
+
+	const float size = 10.0f;
+
+	glBegin( GL_QUADS );
+		glVertex3fv( &vec3_t(size, size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(-size, size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(-size, -size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(size, -size, 0.0f)[0] );
+	glEnd();
+
+	glColor4fv( &vec4_t(1.0f, 1.0f, 1.0f, 0.2f)[0] );
+	glBegin( GL_QUADS );
+		glVertex3fv( &vec3_t(size, -size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(-size, -size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(-size, size, 0.0f)[0] );
+		glVertex3fv( &vec3_t(size, size, 0.0f)[0] );
+	glEnd();
+
+	glPopMatrix();
+
+	glDisable( GL_DEPTH_TEST );
+	glColor3fv( &vec3_t(1, 1, 0)[0] );
+	glBegin( GL_LINES );
+		glVertex3fv( &(normal*offset)[0] );
+		glVertex3fv( &(normal*(offset+1))[0] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+plane - any                                                                                                                           =
+=======================================================================================================================================
+*/
+bool plane_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+plane - any                                                                                                                           =
+=======================================================================================================================================
+*/
+bool plane_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/**
+=======================================================================================================================================
+bounding sphere                                                                                                                       =
+=======================================================================================================================================
+*/
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+from a vec3 array                                                                                                                     =
+=======================================================================================================================================
+*/
+void bsphere_t::Set( const void* pointer, uint stride, int count )
+{
+	void* tmp_pointer = (void*)pointer;
+	vec3_t min( *(vec3_t*)tmp_pointer ),
+	       max( *(vec3_t*)tmp_pointer );
+
+	// for all the vec3 calc the max and min
+	for( int i=1; i<count; i++ )
+	{
+		tmp_pointer = (char*)tmp_pointer + stride;
+
+		const vec3_t& tmp = *((vec3_t*)tmp_pointer);
+
+		for( int j=0; j<3; j++ )
+		{
+			if( tmp[j] > max[j] )
+				max[j] = tmp[j];
+			else if( tmp[j] < min[j] )
+				min[j] = tmp[j];
+		}
+	}
+
+	center = (min+max) * 0.5; // average
+
+	tmp_pointer = (void*)pointer;
+	float max_dist = (*((vec3_t*)tmp_pointer) - center).LengthSquared(); // max distance between center and the vec3 arr
+	for( int i=1; i<count; i++ )
+	{
+		tmp_pointer = (char*)tmp_pointer + stride;
+
+		const vec3_t& vertco = *((vec3_t*)tmp_pointer);
+		float dist = (vertco - center).LengthSquared();
+		if( dist > max_dist )
+			max_dist = dist;
+	}
+
+	radius = Sqrt( max_dist );
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void bsphere_t::Render()
+{
+	glPushMatrix();
+
+	glTranslatef( center.x, center.y, center.z );
+
+	glColor4fv( &vec4_t(1.0, 1.0, 1.0, 0.2)[0] );
+
+	r::dbg::RenderSphere( radius, 24 );
+
+	glPopMatrix();
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+bsphere_t bsphere_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	bsphere_t ret;
+
+	ret.center = ( rotate * (center * scale) ) + translate;
+	ret.radius = radius * scale;
+	return ret;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - any                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - sphere                                                                                                                       =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const bsphere_t& other ) const
+{
+	float tmp = radius + other.radius;
+	return (center-other.center).LengthSquared() <= tmp*tmp ;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - aabb                                                                                                                         =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const aabb_t& box ) const
+{
+	return box.Intersects(*this);
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - ray                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const ray_t& ray ) const
+{
+	vec3_t w( center - ray.origin );
+	const vec3_t& v = ray.dir;
+	float proj = v.Dot( w );
+	float wsq = w.LengthSquared();
+	float rsq = radius*radius;
+
+	if( proj < 0.0 && wsq > rsq )
+		return false;
+
+	float vsq = v.LengthSquared();
+
+	return (vsq*wsq - proj*proj <= vsq*rsq);
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - segment                                                                                                                      =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const lineseg_t& segment ) const
+{
+	const vec3_t& v = segment.dir;
+	vec3_t w0 = center - segment.origin;
+	float w0dv = w0.Dot( v );
+	float rsq = radius * radius;
+
+	if( w0dv < 0.0f ) // if the ang is >90
+		return w0.LengthSquared() <= rsq;
+
+	vec3_t w1 = w0 - v; // aka center - P1, where P1 = seg.origin + seg.dir
+	float w1dv = w1.Dot( v );
+
+	if( w1dv > 0.0f ) // if the ang is <90
+		return w1.LengthSquared() <= rsq;
+
+	vec3_t tmp = w0 - ( v * (w0.Dot(v) / v.LengthSquared()) ); // the big parenthesis is the projection of w0 to v
+	return tmp.LengthSquared() <= rsq;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+sphere - obb                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::Intersects( const obb_t& obb ) const
+{
+	return obb.Intersects( *this );
+}
+
+
+/*
+=======================================================================================================================================
+PlaneTest                                                                                                                             =
+=======================================================================================================================================
+*/
+float bsphere_t::PlaneTest( const plane_t& plane ) const
+{
+	float dist = plane.Test( center );
+
+	if( dist > radius )
+		return dist-radius;
+	else if( -dist > radius )
+		return dist+radius;
+	else
+		return 0.0f;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+sphere - any                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+sphere - sphere                                                                                                                       =
+=======================================================================================================================================
+*/
+bool bsphere_t::SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	normal = sphere.center - center;
+	float rsum = radius + sphere.radius;
+	float distsq = normal.LengthSquared();
+
+	if( distsq <= rsum*rsum )
+	{
+		// calc the depth
+		float dist = Sqrt( distsq );
+		depth = rsum - dist;
+
+		normal.Normalize();
+
+		impact_point = ((center + normal*radius) + (sphere.center - normal*sphere.radius)) * 0.5f;
+
+		RENDER_SEPERATION_TEST
+
+		return true;
+	}
+
+	return false;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+sphere - aabb                                                                                                                         =
+=======================================================================================================================================
+*/
+bool bsphere_t::SeperationTest( const aabb_t& box, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	UNLOCK_RENDER_SEPERATION
+	bool test = box.SeperationTest( *this, normal, impact_point, depth );
+	LOCK_RENDER_SEPERATION
+	impact_point = impact_point + (normal*depth);
+	normal = -normal;
+
+	if( test ) RENDER_SEPERATION_TEST;
+
+	return test;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+sphere - obb                                                                                                                          =
+=======================================================================================================================================
+*/
+bool bsphere_t::SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	UNLOCK_RENDER_SEPERATION
+	bool test = obb.SeperationTest( *this, normal, impact_point, depth );
+	LOCK_RENDER_SEPERATION
+
+	if( !test ) return false;
+
+	impact_point = impact_point + (normal*depth);
+	normal = -normal;
+
+	RENDER_SEPERATION_TEST;
+	return true;
+}
+
+
+/**
+=======================================================================================================================================
+axis aligned bounding box                                                                                                             =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+Calc origin and radius from a vec3 array                                                                                              =
+=======================================================================================================================================
+*/
+void aabb_t::Set( const void* pointer, uint stride, int count )
+{
+	void* tmp_pointer = (void*)pointer;
+	min = *(vec3_t*)tmp_pointer;
+	max = *(vec3_t*)tmp_pointer;
+
+	// for all the vec3 calc the max and min
+	for( int i=1; i<count; i++ )
+	{
+		tmp_pointer = (char*)tmp_pointer + stride;
+
+		vec3_t tmp( *(vec3_t*)tmp_pointer );
+
+		for( int j=0; j<3; j++ )
+		{
+			if( tmp[j] > max[j] )
+				max[j] = tmp[j];
+			else if( tmp[j] < min[j] )
+				min[j] = tmp[j];
+		}
+	}
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+aabb_t aabb_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	aabb_t aabb;
+	aabb.min = min * scale;
+	aabb.max = max * scale;
+
+	aabb.min += translate;
+	aabb.max += translate;
+	return aabb;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void aabb_t::Render()
+{
+	glPushMatrix();
+
+	vec3_t sub( max-min );
+	vec3_t center( (max+min)*0.5f );
+
+	glTranslatef( center.x, center.y, center.z );
+	glScalef( sub.x, sub.y, sub.z );
+
+	glColor3fv( &vec3_t( 1.0f, 1.0f, 1.0f )[0] );
+
+	r::dbg::RenderCube();
+
+	glPopMatrix();
+
+	glBegin( GL_POINTS );
+		glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+		glVertex3fv( &min[0] );
+		glColor3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+		glVertex3fv( &max[0] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - any                                                                                                                            =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - aabb                                                                                                                           =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const aabb_t& other ) const
+{
+	// if separated in x direction
+	if( min.x > other.max.x || other.min.x > max.x )
+		return false;
+
+	// if separated in y direction
+	if( min.y > other.max.y || other.min.y > max.y )
+		return false;
+
+	// if separated in z direction
+	if( min.z > other.max.z || other.min.z > max.z )
+		return false;
+
+	// no separation, must be intersecting
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - sphere                                                                                                                         =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const bsphere_t& sphere ) const
+{
+	const vec3_t& c = sphere.center;
+
+	// find the box's closest point to the sphere
+	vec3_t cp; // Closest Point
+	for( uint i=0; i<3; i++ )
+	{
+		if( c[i] > max[i] ) // if the center is greater than the max then the closest point is the max
+			cp[i] = max[i];
+		else if( c[i] < min[i]  ) // relative to the above
+			cp[i] = min[i];
+		else           // the c lies between min and max
+			cp[i] = c[i];
+	}
+
+	float rsq = sphere.radius * sphere.radius;
+	vec3_t sub = c - cp; // if the c lies totaly inside the box then the sub is the zero,
+	                     //this means that the length is also zero and thus its always smaller than rsq
+
+	if( sub.LengthSquared() <= rsq ) return true;
+
+	return false;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - ray                                                                                                                            =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const ray_t& ray ) const
+{
+	float maxS = -FLT_MAX;
+	float minT = FLT_MAX;
+
+	// do tests against three sets of planes
+	for ( int i = 0; i < 3; ++i )
+	{
+		// ray is parallel to plane
+		if ( IsZero( ray.dir[i] ) )
+		{
+			// ray passes by box
+			if ( ray.origin[i] < min[i] || ray.origin[i] > max[i] )
+				return false;
+		}
+		else
+		{
+			// compute intersection parameters and sort
+			float s = (min[i] - ray.origin[i])/ray.dir[i];
+			float t = (max[i] - ray.origin[i])/ray.dir[i];
+			if ( s > t )
+			{
+				float temp = s;
+				s = t;
+				t = temp;
+			}
+
+			// adjust min and max values
+			if ( s > maxS )
+				maxS = s;
+			if ( t < minT )
+				minT = t;
+			// check for intersection failure
+			if ( minT < 0.0f || maxS > minT )
+				return false;
+		}
+	}
+
+	// done, have intersection
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - segment                                                                                                                        =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const lineseg_t& segment ) const
+{
+	float maxS = -FLT_MAX;
+	float minT = FLT_MAX;
+
+	// do tests against three sets of planes
+	for( int i = 0; i < 3; ++i )
+	{
+		// segment is parallel to plane
+		if( IsZero( segment.dir[i] ) )
+		{
+			// segment passes by box
+			if( (segment.origin)[i] < min[i] || (segment.origin)[i] > max[i] )
+				return false;
+		}
+		else
+		{
+			// compute intersection parameters and sort
+			float s = (min[i] - segment.origin[i])/segment.dir[i];
+			float t = (max[i] - segment.origin[i])/segment.dir[i];
+			if( s > t )
+			{
+				float temp = s;
+				s = t;
+				t = temp;
+			}
+
+			// adjust min and max values
+			if( s > maxS )
+				maxS = s;
+			if( t < minT )
+				minT = t;
+			// check for intersection failure
+			if( minT < 0.0f || maxS > 1.0f || maxS > minT )
+				return false;
+		}
+	}
+
+	// done, have intersection
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+aabb - obb                                                                                                                            =
+=======================================================================================================================================
+*/
+bool aabb_t::Intersects( const obb_t& obb ) const
+{
+	return obb.Intersects(*this);
+}
+
+
+/*
+=======================================================================================================================================
+PlaneTest                                                                                                                             =
+=======================================================================================================================================
+*/
+float aabb_t::PlaneTest( const plane_t& plane ) const
+{
+	vec3_t diag_min, diag_max;
+	// set min/max values for x,y,z direction
+	for( int i=0; i<3; i++ )
+	{
+		if( plane.normal[i] >= 0.0f )
+		{
+			diag_min[i] = min[i];
+			diag_max[i] = max[i];
+		}
+		else
+		{
+			diag_min[i] = max[i];
+			diag_max[i] = min[i];
+		}
+	}
+
+	// minimum on positive side of plane, box on positive side
+	float test = plane.Test( diag_min );
+	if ( test > 0.0f )
+		return test;
+
+	test = plane.Test( diag_max );
+	// min on non-positive side, max on non-negative side, intersection
+	if ( test >= 0.0f )
+		return 0.0f;
+	// max on negative side, box on negative side
+	else
+		return test;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+aabb - any                                                                                                                            =
+=======================================================================================================================================
+*/
+bool aabb_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+aabb - aabb                                                                                                                           =
+=======================================================================================================================================
+*/
+bool aabb_t::SeperationTest( const aabb_t& other, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	// calculete the closest points
+	for( uint i=0; i<3; i++ ) // for 3 axis
+	{
+		if( min[i] > other.max[i] || other.min[i] > max[i] )
+			return false;
+
+		const float& Am = min[i], AM = max[i], Bm = other.min[i], BM = other.max[i];
+
+		if( Bm < Am )
+		{
+			if( BM < Am ) // B is left and outside A
+				return false;
+			else
+				if( BM < AM ) // left
+				{
+					normal[i] = Am - BM;
+					impact_point[i] = (Am+BM) * 0.5f;
+				}
+				else // B overlaps A
+				{
+					float t0 = AM-Bm, t1 = BM-Am;
+					if( t0 < t1 )
+						normal[i] = t0;
+					else
+						normal[i] = -t1;
+
+					impact_point[i] = (Am+AM) * 0.5f;
+				}
+		}
+		else
+		{
+			if( Bm > AM ) // B is right and outside A
+				return false;
+			else
+				if( BM < AM ) // B totaly inside A
+				{
+					float t0 = BM-Am, t1 = AM-Bm;
+					if( t0 < t1 )
+						normal[i] = -t0;
+					else
+						normal[i] = t1;
+
+					impact_point[i] = (Bm+BM) * 0.5f;
+				}
+				else // right
+				{
+					normal[i] = AM - Bm;
+					impact_point[i] = (AM + Bm) * 0.5f;
+				}
+		}
+
+	}
+
+	vec3_t dist( fabs(normal.x), fabs(normal.y), fabs(normal.z) );
+	if( dist.x < dist.y && dist.x < dist.z )
+		normal = vec3_t( normal.x, 0.0f, 0.0f );
+	else if( dist.y < dist.z )
+		normal = vec3_t( 0.0f, normal.y, 0.0f );
+	else
+		normal = vec3_t( 0.0f, 0.0f, normal.z );
+
+	depth = normal.Length();
+
+	normal *= 1.0f/depth; // aka normal.Normalize()
+
+	RENDER_SEPERATION_TEST
+
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+aabb - sphere                                                                                                                         =
+=======================================================================================================================================
+*/
+bool aabb_t::SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	const vec3_t& c = sphere.center;
+	const float r = sphere.radius;
+	vec3_t cp; // closest point of box that its closer to the sphere's center
+
+	for( int i=0; i<3; i++ )
+	{
+		if( c[i] >= max[i] ) // if the center is greater than the max then the closest point is the max
+			cp[i] = max[i];
+		else if( c[i] <= min[i]  ) // relative to the above
+			cp[i] = min[i];
+		else           // the c lies between min and max
+			cp[i] = c[i];
+	}
+
+	vec3_t sub = c - cp; // if the c lies totaly inside the box then the sub is the zero,
+	                     // this means that the length is also zero and thus its always smaller than rsq
+
+	float sublsq = sub.LengthSquared();
+	if( sublsq > r*r ) return false; // if no collision leave before its too late
+
+	if( IsZero(sublsq) ) // this means that the closest point is coincide with the center so the center is totaly inside tha box. We have to revise the calcs
+	{
+		int n_axis = 0; // the axis that the normal will be
+		float min_d = FLT_MAX; // in the end of "for" the min_d holds the min projection dist of c to every cube's facet
+		float coord = 0.0;
+		for( int i=0; i<3; i++ )
+		{
+			// dist between c and max/min in the i axis
+			float dist_c_max = max[i]-c[i];
+			float dist_c_min = c[i]-min[i];
+
+			if( dist_c_max < min_d && dist_c_max < dist_c_min )
+			{
+				min_d = dist_c_max;
+				n_axis = i;
+				coord = max[i];
+			}
+			else if( dist_c_min < min_d )
+			{
+				min_d = dist_c_min;
+				n_axis = i;
+				coord = min[i];
+			}
+		}
+
+		float dif = coord - c[n_axis];
+
+		normal.SetZero();
+		normal[n_axis] = dif / min_d; // aka ... = (dif<0.0f) ? -1.0f : 1.0f;
+
+		depth = r + min_d;
+
+		impact_point = c-(normal*r);
+	}
+	// the c is outside the box
+	else
+	{
+		normal = c - cp;
+
+		depth = r - normal.Length();
+
+		normal.Normalize();
+
+		impact_point = c-(normal*r);
+	}
+
+	RENDER_SEPERATION_TEST
+
+	return true;
+}
+
+
+/**
+=======================================================================================================================================
+object oriented bounding box                                                                                                          =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+Set                                                                                                                                   =
+calc from a vec3 array                                                                                                                =
+=======================================================================================================================================
+*/
+void obb_t::Set( const void* pointer, uint stride, int count )
+{
+	void* tmp_pointer = (void*)pointer;
+	vec3_t min = *(vec3_t*)tmp_pointer;
+	vec3_t max = *(vec3_t*)tmp_pointer;
+
+	// for all the vec3 calc the max and min
+	for( int i=1; i<count; i++ )
+	{
+		tmp_pointer = (char*)tmp_pointer + stride;
+
+		vec3_t tmp( *(vec3_t*)tmp_pointer );
+
+		for( int j=0; j<3; j++ ) // for x y z
+		{
+			if( tmp[j] > max[j] )
+				max[j] = tmp[j];
+			else if( tmp[j] < min[j] )
+				min[j] = tmp[j];
+		}
+	}
+
+	// set the locals
+	center = (max+min)*0.5f;
+	rotation.SetIdent();
+	extends = max-center;
+}
+
+
+/*
+=======================================================================================================================================
+Render                                                                                                                                =
+=======================================================================================================================================
+*/
+void obb_t::Render()
+{
+	glPushMatrix();
+
+	glTranslatef( center.x, center.y, center.z ); // translate
+	r::MultMatrix( mat4_t(rotation) ); // rotate
+	glScalef( extends.x, extends.y, extends.z ); // scale
+
+	glColor3fv( &vec3_t(1.0f, 1.0f, 1.0f)[0] );
+
+	r::dbg::RenderCube( false, 2.0f );
+
+	r::Color3( vec3_t( 0.0, 1.0, 0.0 ) );
+	glBegin( GL_POINTS );
+		glVertex3fv( &vec3_t(1.0, 1.0, 1.0)[0] );
+	glEnd();
+
+	glPopMatrix();
+}
+
+
+/*
+=======================================================================================================================================
+Transformed                                                                                                                           =
+=======================================================================================================================================
+*/
+obb_t obb_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	obb_t res;
+
+	res.extends = extends * scale;
+	res.center = rotate*(center*scale) + translate;
+	res.rotation = rotate * rotation;
+
+	return res;
+}
+
+
+/*
+=======================================================================================================================================
+PlaneTest                                                                                                                             =
+=======================================================================================================================================
+*/
+float obb_t::PlaneTest( const plane_t& plane ) const
+{
+	vec3_t x_normal = rotation.Transposed() * plane.normal;
+	// maximum extent in direction of plane normal
+	float r = fabs(extends.x*x_normal.x)
+					+ fabs(extends.y*x_normal.y)
+					+ fabs(extends.z*x_normal.z);
+	// signed distance between box center and plane
+	float d = plane.Test(center);
+
+	// return signed distance
+	if( fabs(d) < r )
+		return 0.0f;
+	else if( d < 0.0f )
+		return d + r;
+	else
+		return d - r;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - any                                                                                                                             =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const bvolume_t& bv ) const
+{
+	ABSTRACT_INTERSECTION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - obb                                                                                                                             =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const obb_t& other ) const
+{
+	// extent vectors
+	const vec3_t& a = extends;
+	const vec3_t& b = other.extends;
+
+	// test factors
+	float cTest, aTest, bTest;
+	bool parallelAxes = false;
+
+	// transpose of rotation of B relative to A, i.e. (R_b^T * R_a)^T
+	mat3_t Rt = rotation.Transposed() * other.rotation;
+
+	// absolute value of relative rotation matrix
+	mat3_t Rabs;
+	for( uint i = 0; i < 3; ++i )
+	{
+		for( uint j = 0; j < 3; ++j )
+		{
+			Rabs(i,j) = fabs( Rt(i,j ) );
+			// if magnitude of dot product between axes is close to one
+			if ( Rabs(i,j) + EPSILON >= 1.0f )
+			{
+				// then box A and box B have near-parallel axes
+				parallelAxes = true;
+			}
+		}
+	}
+
+	// relative translation (in A's frame)
+	vec3_t c = rotation.Transposed()*(other.center - center);
+
+	// separating axis A0
+	cTest = fabs(c.x);
+	aTest = a.x;
+	bTest = b.x*Rabs(0,0)+b.y*Rabs(0,1)+b.z*Rabs(0,2);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A1
+	cTest = fabs(c.y);
+	aTest = a.y;
+	bTest = b.x*Rabs(1,0)+b.y*Rabs(1,1)+b.z*Rabs(1,2);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A2
+	cTest = fabs(c.z);
+	aTest = a.z;
+	bTest = b.x*Rabs(2,0)+b.y*Rabs(2,1)+b.z*Rabs(2,2);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis B0
+	cTest = fabs( c.x*Rt(0,0) + c.y*Rt(1,0) + c.z*Rt(2,0) );
+	aTest = a.x*Rabs(0,0)+a.y*Rabs(1,0)+a.z*Rabs(2,0);
+	bTest = b.x;
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis B1
+	cTest = fabs( c.x*Rt(0,1) + c.y*Rt(1,1) + c.z*Rt(2,1) );
+	aTest = a.x*Rabs(0,1)+a.y*Rabs(1,1)+a.z*Rabs(2,1);
+	bTest = b.y;
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis B2
+	cTest = fabs( c.x*Rt(0,2) + c.y*Rt(1,2) + c.z*Rt(2,2) );
+	aTest = a.x*Rabs(0,2)+a.y*Rabs(1,2)+a.z*Rabs(2,2);
+	bTest = b.z;
+	if ( cTest > aTest + bTest ) return false;
+
+	// if the two boxes have parallel axes, we're done, intersection
+	if ( parallelAxes ) return true;
+
+	// separating axis A0 x B0
+	cTest = fabs(c.z*Rt(1,0)-c.y*Rt(2,0));
+	aTest = a.y*Rabs(2,0) + a.z*Rabs(1,0);
+	bTest = b.y*Rabs(0,2) + b.z*Rabs(0,1);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A0 x B1
+	cTest = fabs(c.z*Rt(1,1)-c.y*Rt(2,1));
+	aTest = a.y*Rabs(2,1) + a.z*Rabs(1,1);
+	bTest = b.x*Rabs(0,2) + b.z*Rabs(0,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A0 x B2
+	cTest = fabs(c.z*Rt(1,2)-c.y*Rt(2,2));
+	aTest = a.y*Rabs(2,2) + a.z*Rabs(1,2);
+	bTest = b.x*Rabs(0,1) + b.y*Rabs(0,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A1 x B0
+	cTest = fabs(c.x*Rt(2,0)-c.z*Rt(0,0));
+	aTest = a.x*Rabs(2,0) + a.z*Rabs(0,0);
+	bTest = b.y*Rabs(1,2) + b.z*Rabs(1,1);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A1 x B1
+	cTest = fabs(c.x*Rt(2,1)-c.z*Rt(0,1));
+	aTest = a.x*Rabs(2,1) + a.z*Rabs(0,1);
+	bTest = b.x*Rabs(1,2) + b.z*Rabs(1,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A1 x B2
+	cTest = fabs(c.x*Rt(2,2)-c.z*Rt(0,2));
+	aTest = a.x*Rabs(2,2) + a.z*Rabs(0,2);
+	bTest = b.x*Rabs(1,1) + b.y*Rabs(1,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A2 x B0
+	cTest = fabs(c.y*Rt(0,0)-c.x*Rt(1,0));
+	aTest = a.x*Rabs(1,0) + a.y*Rabs(0,0);
+	bTest = b.y*Rabs(2,2) + b.z*Rabs(2,1);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A2 x B1
+	cTest = fabs(c.y*Rt(0,1)-c.x*Rt(1,1));
+	aTest = a.x*Rabs(1,1) + a.y*Rabs(0,1);
+	bTest = b.x*Rabs(2,2) + b.z*Rabs(2,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// separating axis A2 x B2
+	cTest = fabs(c.y*Rt(0,2)-c.x*Rt(1,2));
+	aTest = a.x*Rabs(1,2) + a.y*Rabs(0,2);
+	bTest = b.x*Rabs(2,1) + b.y*Rabs(2,0);
+	if ( cTest > aTest + bTest ) return false;
+
+	// all tests failed, have intersection
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - ray                                                                                                                             =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const ray_t& ray ) const
+{
+	aabb_t aabb_( -extends, extends );
+	ray_t newray;
+	mat3_t rottrans = rotation.Transposed();
+
+	newray.origin = rottrans * ( ray.origin - center );
+	newray.dir = rottrans * ray.dir;
+
+	return aabb_.Intersects( newray );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - segment                                                                                                                         =
+ToDo: not working good                                                                                                                =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const lineseg_t& segment ) const
+{
+	float maxS = -FLT_MAX;
+	float minT = FLT_MAX;
+
+	// compute difference vector
+	vec3_t diff = center - segment.origin;
+
+	// for each axis do
+	for( int i = 0; i < 3; ++i )
+	{
+		// get axis i
+		vec3_t axis = rotation.GetColumn( i );
+
+		// project relative vector onto axis
+		float e = axis.Dot( diff );
+		float f = segment.dir.Dot( axis );
+
+		// ray is parallel to plane
+		if( IsZero( f ) )
+		{
+			// ray passes by box
+			if( -e - extends[i] > 0.0f || -e + extends[i] > 0.0f )
+				return false;
+			continue;
+		}
+
+		float s = (e - extends[i])/f;
+		float t = (e + extends[i])/f;
+
+		// fix order
+		if( s > t )
+		{
+			float temp = s;
+			s = t;
+			t = temp;
+		}
+
+		// adjust min and max values
+		if( s > maxS )
+			maxS = s;
+		if( t < minT )
+			minT = t;
+
+		// check for intersection failure
+		if( minT < 0.0f || maxS > 1.0f || maxS > minT )
+			return false;
+	}
+
+	// done, have intersection
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - sphere                                                                                                                          =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const bsphere_t& sphere ) const
+{
+	aabb_t aabb_( -extends, extends ); // aabb_ is in "this" frame
+	vec3_t new_center = rotation.Transposed() * (sphere.center - center);
+	bsphere_t sphere_( new_center, sphere.radius ); // sphere1 to "this" fame
+
+	return aabb_.Intersects( sphere_ );
+}
+
+
+/*
+=======================================================================================================================================
+Intersects                                                                                                                            =
+obb - aabb                                                                                                                            =
+=======================================================================================================================================
+*/
+bool obb_t::Intersects( const aabb_t& aabb ) const
+{
+	vec3_t center_ = (aabb.max + aabb.min) * 0.5f;
+	vec3_t extends_ = (aabb.max - aabb.min) * 0.5f;
+	obb_t obb_( center_, mat3_t::ident, extends_ );
+
+	return Intersects( obb_ );
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+obb - any                                                                                                                             =
+=======================================================================================================================================
+*/
+bool obb_t::SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	ABSTRACT_SEPERATION_CODE
+}
+
+
+/*
+=======================================================================================================================================
+SeperationTest                                                                                                                        =
+obb - sphere                                                                                                                          =
+=======================================================================================================================================
+*/
+bool obb_t::SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const
+{
+	aabb_t aabb_( -extends, extends ); // aabb_ is in "this" frame
+	vec3_t new_center = rotation.Transposed() * (sphere.center - center);
+	bsphere_t sphere_( new_center, sphere.radius ); // sphere_ to "this" fame
+
+	UNLOCK_RENDER_SEPERATION
+	bool test = aabb_.SeperationTest( sphere_, normal, impact_point, depth );
+	LOCK_RENDER_SEPERATION
+
+	if( !test ) return false;
+
+	impact_point = (rotation*impact_point) + center;
+	normal = rotation * normal;
+
+	RENDER_SEPERATION_TEST
+
+	return true;
+}
+
+
+
+
+
+
+

+ 325 - 0
src/old_src/collision.h

@@ -0,0 +1,325 @@
+#ifndef _COLLISION_H_
+#define _COLLISION_H_
+
+/*
+Info on how seperation tests work.
+We have: bvolume1.SeperationTest( bvolume2, normal, impact_point, depth );
+This expresion returns the normal, impact_point and depth of the collision between bvolume1 and bvolume2.
+The normal shows the direction we have to move bvolume2 in order to seperate the 2 volumes. The depth shows the distance we have to
+move bvolume2 for the seperation. The impact_point is a point between inside the collision area.
+*/
+
+#include <float.h>
+#include "common.h"
+#include "math.h"
+
+class lineseg_t;
+class ray_t;
+class plane_t;
+class bsphere_t;
+class aabb_t;
+class obb_t;
+
+
+/*
+=======================================================================================================================================
+bvolume_t (A)                                                                                                                         =
+=======================================================================================================================================
+*/
+class bvolume_t
+{
+	public:
+		enum type_e
+		{
+			LINE_SEG,
+			RAY,
+			PLANE,
+			BSPHERE,
+			AABB,
+			OBB,
+			BVOLUMES_NUM
+		};
+
+		type_e type;
+
+		bvolume_t( type_e type_ ): type(type_) {}
+
+		virtual void Render() = 0;
+
+		//if the bounding volume intersects with the plane then returns 0, else the func returns the distance. If the distance is <0 then
+		//the b.v. lies behind the plane and if >0 then in front of it
+		virtual float PlaneTest( const plane_t& plane ) const = 0;
+
+		virtual bool Intersects( const bvolume_t& bv ) const = 0;
+		virtual bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const = 0;
+};
+
+
+/*
+=======================================================================================================================================
+line segment                                                                                                                          =
+=======================================================================================================================================
+*/
+class lineseg_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t origin; // P0
+		vec3_t dir;    // P1 = origin+dir so dir = P1-origin
+
+		// constructors & distructors
+		lineseg_t(): bvolume_t(LINE_SEG) {}
+		lineseg_t( const lineseg_t& b ): bvolume_t(LINE_SEG) { (*this)=b; }
+		lineseg_t( const vec3_t& origin_, const vec3_t& dir_ ): bvolume_t(LINE_SEG) { origin=origin_; dir=dir_; }
+
+		// operators
+		lineseg_t& operator =( const lineseg_t& b ) { origin=b.origin; dir=b.dir; return (*this); }
+
+		// std funcs
+		lineseg_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const { DEBUG_ERR("N.A."); return 0.0f; };
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const { DEBUG_ERR("N.A."); return false; };
+		bool Intersects( const lineseg_t& segment ) const { DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+
+		// other funcs
+		/**
+		1) If t_c<0 then outside the line segment and close to origin. If t_c>1 again outside the line segment and closer to dir.
+		If >0 or <1 then inside the segment
+		2) When we talk about distances we calc the distance between the point|line|ray etc and the P0 OR P1. For example the dist
+		between a point and P0 or P1 depending of t_c
+		*/
+		float  LengthSquared() const { return dir.LengthSquared(); }
+		float  Length() const { return dir.Length(); }
+		float  DistanceSquared( const lineseg_t& seg, float& s_c, float& t_c ) const;   // dist with another segment
+		float  DistanceSquared( const ray_t& ray, float& s_c, float& t_c ) const;       // with a ray
+		float  DistanceSquared( const vec3_t& point, float& t_c ) const;                // with a point.
+		void   ClosestPoints( const lineseg_t& seg, vec3_t& point0, vec3_t& point1 ) const; // closest points between this and another seg
+		void   ClosestPoints( const ray_t& ray, vec3_t& point0, vec3_t& point1 ) const;     // with a ray
+		vec3_t ClosestPoints( const vec3_t& point ) const;                                  // with a poin
+};
+
+
+/*
+=======================================================================================================================================
+ray                                                                                                                                   =
+=======================================================================================================================================
+*/
+class ray_t: bvolume_t
+{
+	public:
+		// data members
+		vec3_t origin;
+		vec3_t dir;
+
+		// constructors & distructors
+		ray_t(): bvolume_t(RAY) {}
+		ray_t( const ray_t& b ): bvolume_t(RAY) { (*this)=b; }
+		ray_t( const vec3_t& origin_, const vec3_t& dir_ ): bvolume_t(RAY), origin(origin_), dir(dir_) {}
+
+		// operators
+		ray_t& operator =( const ray_t& b ) { origin=b.origin; dir=b.dir; return (*this); }
+
+		// std funcs
+		ray_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const { DEBUG_ERR("N.A."); return 0.0f; };
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const { DEBUG_ERR("N.A."); return false; };
+		bool Intersects( const lineseg_t& segment ) const { DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+
+		// other funcs
+		float  DistanceSquared( const ray_t& ray, float& s_c, float& t_c ) const;   // this and another ray
+		void   ClosestPoints( const ray_t& ray, vec3_t& point0, vec3_t& point1 ) const;   // this and another ray
+		vec3_t ClosestPoint( const vec3_t& point ) const;                                 // this and point
+};
+
+
+/*
+=======================================================================================================================================
+plane                                                                                                                                 =
+=======================================================================================================================================
+*/
+class plane_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t normal;
+		float  offset;
+
+		// constructors & distructors
+		plane_t(): bvolume_t(PLANE) {}
+		plane_t( const plane_t& b ): bvolume_t(PLANE) { (*this)=b; }
+		plane_t( const vec3_t& normal_, float offset_ ): bvolume_t(PLANE), normal(normal_), offset(offset_) {}
+		plane_t( const vec3_t& p0, const vec3_t& p1, const vec3_t& p2 ): bvolume_t(PLANE) { Set(p0,p1,p2); }
+		plane_t( float a, float b, float c, float d ): bvolume_t(PLANE) { Set(a,b,c,d); }
+
+		// operators
+		plane_t& operator =( const plane_t& b ) { normal=b.normal; offset=b.offset; return (*this); }
+
+		// std funcs
+		plane_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const { DEBUG_ERR("N.A."); return 0.0f; };
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const { DEBUG_ERR("N.A."); return false; };
+		bool Intersects( const lineseg_t& segment ) const { DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const bsphere_t& sphere ) const{ DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const aabb_t& aabb ) const { DEBUG_ERR("N.A.") return false; };
+		bool Intersects( const obb_t& obb ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("N.A.") return false; };
+
+		// other funcs
+		void Set( const vec3_t& p0, const vec3_t& p1, const vec3_t& p2 ); // set the plane from 3 vectors
+		void Set( float a, float b, float c, float d ); // set from plane where plane equation is ax+by+cz+d
+
+		float Test( const vec3_t& point ) const { return normal.Dot(point) - offset; } // it gives the distance between the point and plane.
+		                                                                               // if >0 then the point lies in front of the plane,
+		                                                                               // if <0 then it is behind and if =0 then it is co-planar
+		float Distance( const vec3_t& point ) const { return fabs( Test(point) ); }
+		vec3_t ClosestPoint( const vec3_t& point ) const { return point - normal*Test(point); }; // returns the perpedicular of the point in
+		                                                                                         // this plane. Plane's normal and returned-point
+		                                                                                         // are perpedicular
+};
+
+
+/*
+=======================================================================================================================================
+bounding sphere                                                                                                                       =
+=======================================================================================================================================
+*/
+class bsphere_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t center;
+		float radius;
+
+		// constructors & distractor
+		bsphere_t(): bvolume_t(BSPHERE) {}
+		bsphere_t( const bsphere_t& other ): bvolume_t(BSPHERE) { (*this) = other; }
+		bsphere_t( const vec3_t& center_, float radius_ ): bvolume_t(BSPHERE), center(center_), radius(radius_) {}
+
+		// operators
+		bsphere_t& operator =( const bsphere_t& other ) { center=other.center; radius=other.radius; return (*this); }
+
+		// std funcs
+		bsphere_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const;
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const;
+		bool Intersects( const lineseg_t& segment ) const;
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+
+		// other funcs
+		void Set( const void* pointer, uint stride, int count );
+};
+
+
+/*
+=======================================================================================================================================
+axis aligned bounding box                                                                                                             =
+=======================================================================================================================================
+*/
+class aabb_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t min;
+		vec3_t max;
+
+		// constructors & destractor
+		aabb_t(): bvolume_t(AABB) {}
+		aabb_t( const aabb_t& other ): bvolume_t(AABB) { (*this) = other; }
+		aabb_t( const vec3_t& min_, const vec3_t& max_ ): bvolume_t(AABB), min(min_), max(max_) { DEBUG_ERR( max.x<min.x || max.y<min.y || max.z<min.z ) }
+
+		// operators
+		aabb_t& operator =( const aabb_t& other ) { min=other.min; max=other.max; return (*this); }
+
+		// std funcs
+		aabb_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void Render();
+		float PlaneTest( const plane_t& plane ) const;
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const;
+		bool Intersects( const lineseg_t& segment ) const;
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("ToDo") return false; };
+
+		// other funcs
+		void Set( const void* pointer, uint stride, int count ); // set from vec3 array
+};
+
+
+/*
+=======================================================================================================================================
+object oriented bounding box                                                                                                          =
+=======================================================================================================================================
+*/
+class obb_t: public bvolume_t
+{
+	public:
+		// data members
+		vec3_t center;
+		mat3_t rotation;
+		vec3_t extends;
+
+		// constructors & destractor
+		obb_t(): bvolume_t(OBB) {}
+		obb_t( const obb_t& other ): bvolume_t(OBB) { (*this)=other; }
+		obb_t( const vec3_t& c_, const mat3_t& r_, const vec3_t& e_ ): bvolume_t(OBB) { center=c_; rotation=r_; extends=e_; }
+
+		// operators
+		obb_t& operator =( const obb_t& other ) { center=other.center; rotation=other.rotation; extends=other.extends; return (*this); }
+
+		// std funcs
+		obb_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void  Render();
+		float PlaneTest( const plane_t& plane ) const;
+		bool Intersects( const bvolume_t& bv ) const;
+		bool Intersects( const ray_t& ray ) const;
+		bool Intersects( const lineseg_t& segment ) const;
+		bool Intersects( const bsphere_t& sphere ) const;
+		bool Intersects( const aabb_t& aabb ) const;
+		bool Intersects( const obb_t& obb ) const;
+		bool SeperationTest( const bvolume_t& bv, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const bsphere_t& sphere, vec3_t& normal, vec3_t& impact_point, float& depth ) const;
+		bool SeperationTest( const aabb_t& aabb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("ToDo") return false; };
+		bool SeperationTest( const obb_t& obb, vec3_t& normal, vec3_t& impact_point, float& depth ) const { DEBUG_ERR("ToDo") return false; };
+
+		// other funcs
+		void Set( const void* pointer, uint stride, int count ); // set from vec3 array
+};
+
+
+#endif

+ 261 - 0
src/old_src/deferred shading, calculate fragpos from depth/light_pass_generic.frag

@@ -0,0 +1,261 @@
+uniform sampler2D normal_rt, diffuse_rt, specular_rt, depth_rt;
+uniform vec2 planes;
+
+#if defined(_PROJECTED_TXTR_LIGHT_)
+uniform sampler2D light_txtr;
+#endif
+
+#if defined(_PROJECTED_TXTR_LIGHT_SHADOW_)
+uniform sampler2DShadow shadow_depth_map;
+uniform float shadow_resolution;
+#endif
+
+varying vec2 txtr_coord;
+varying vec3 vpos;
+
+
+/*
+=======================================================================================================================================
+Discard                                                                                                                               =
+what to do if the fragment shouldnt be processed                                                                                      =
+=======================================================================================================================================
+*/
+void Discard()
+{
+	//gl_FragData[0] = vec4(1.0, 0.0, 1.0, 1.0 );
+	discard;
+}
+
+
+/*
+=======================================================================================================================================
+FragPosVSpace                                                                                                                         =
+calc frag pos in view space                                                                                                           =
+=======================================================================================================================================
+*/
+vec3 FragPosVSpace()
+{
+	float _depth = texture2D( depth_rt, txtr_coord ).r;
+
+	if( _depth == 1.0 ) Discard();
+
+	vec3 _frag_pos_vspace;
+	vec3 _vposn = normalize(vpos);
+	_frag_pos_vspace.z = -planes.y/(planes.x+_depth);
+	_frag_pos_vspace.xy = _vposn.xy/_vposn.z*_frag_pos_vspace.z;
+	return _frag_pos_vspace;
+}
+
+
+/*
+=======================================================================================================================================
+Attenuation                                                                                                                           =
+=======================================================================================================================================
+*/
+float Attenuation( in float _frag_light_dist )
+{
+	float _inv_light_radius = gl_LightSource[0].position.w;
+	return clamp(1.0 - _inv_light_radius * sqrt(_frag_light_dist), 0.0, 1.0);
+	//return 1.0 - _frag_light_dist * _inv_light_radius;
+}
+
+
+/*
+=======================================================================================================================================
+PCF                                                                                                                                   =
+it returns a blured shadow                                                                                                            =
+=======================================================================================================================================
+*/
+#if defined(_PROJECTED_TXTR_LIGHT_SHADOW_)
+float PCF_Off( in vec3 _shadow_uv )
+{
+	return shadow2D(shadow_depth_map, _shadow_uv ).r;
+}
+
+
+float PCF_Low( in vec3 _shadow_uv )
+{
+	float _shadow_col = shadow2D(shadow_depth_map, _shadow_uv ).r;
+	float _map_scale = 1.0 / shadow_resolution;
+
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale,  	     0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale,  	     0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(        0.0,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(        0.0, -_map_scale, 0.0)).r;
+	_shadow_col /= 9.0;
+
+	return _shadow_col;
+}
+
+
+float PCF_Medium( in vec3 _shadow_uv )
+{
+	float _shadow_col = shadow2D(shadow_depth_map, _shadow_uv ).r;
+	float _map_scale = 1.0 / shadow_resolution;
+
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale,         0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale,         0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(        0.0,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(        0.0, -_map_scale, 0.0)).r;
+
+	_map_scale *= 2.0;
+
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale,         0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale,         0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(        0.0,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(        0.0, -_map_scale, 0.0)).r;
+
+	_shadow_col *= 0.058823529; // aka: _shadow_col /= 17.0;
+	return _shadow_col;
+}
+
+
+float PCF_High( in vec3 _shadow_uv )
+{
+	float _shadow_col = shadow2D(shadow_depth_map, _shadow_uv ).r;
+	float _map_scale = 1.0 / shadow_resolution;
+
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3( _map_scale,  	     0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale,  	     0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(        0.0,  _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(        0.0, -_map_scale, 0.0)).r;
+
+
+	float _map_scale_2 = 2.0 * _map_scale;
+
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(_map_scale_2, _map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(_map_scale, _map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(0.0, _map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale, _map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale_2, _map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale_2, _map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale_2, 0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale_2, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale_2, -_map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(-_map_scale, -_map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(0.0, -_map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(_map_scale, -_map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(_map_scale_2, -_map_scale_2, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(_map_scale_2, -_map_scale, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(_map_scale_2, 0.0, 0.0)).r;
+	_shadow_col += shadow2D(shadow_depth_map, _shadow_uv.xyz + vec3(_map_scale_2, _map_scale, 0.0)).r;
+
+	_shadow_col /= 25.0;
+	return _shadow_col;
+}
+#endif
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+void main()
+{
+	// get frag pos in view space
+	vec3 _frag_pos_vspace = FragPosVSpace();
+
+	// get lambert term
+	vec3 _light_pos_eyespace = gl_LightSource[0].position.xyz;
+	vec3 _light_frag_vec = _light_pos_eyespace - _frag_pos_vspace;
+
+	float _frag_light_dist = dot( _light_frag_vec, _light_frag_vec ); // instead of using normalize(_frag_light_dist) we brake the operation...
+	vec3 _light_dir = _light_frag_vec * inversesqrt(_frag_light_dist); // ...because we want frag_light_dist for the calc of the attenuation
+
+	// read the render targets
+	vec3 _normal = ( texture2D( normal_rt, txtr_coord ).rgb - 0.5 ) * 2.0;  // read the normal and convert from [0,1] to [-1,1]
+
+	// the lambert term
+	float _lambert_term = dot( _normal, _light_dir );
+
+	if( _lambert_term < 0.0 ) Discard();
+
+	// diffuce lighting
+	vec3 _diffuse = texture2D( diffuse_rt, txtr_coord ).rgb;
+	_diffuse = (_diffuse * gl_LightSource[0].diffuse.rgb);
+	vec3 _color = _diffuse * _lambert_term;
+
+	// specular lighting
+	vec4 _specular_mix = texture2D( specular_rt, txtr_coord );
+	vec3 _specular = _specular_mix.xyz;
+	float _shininess = _specular_mix.w * 128.0;
+	vec3 _eye_vec = normalize( -_frag_pos_vspace );
+	vec3 _h = normalize( _light_dir + _eye_vec );
+	float _spec_intensity = pow(max(0.0, dot(_normal, _h)), _shininess);
+	_color += _specular * vec3(gl_LightSource[0].specular) * (_spec_intensity * _lambert_term);
+
+
+#if defined(_POINT_LIGHT_)
+
+	gl_FragData[0] = vec4( _color * Attenuation(_frag_light_dist), 1.0 );
+
+#elif defined(_PROJECTED_TXTR_LIGHT_)
+
+#if defined(_PROJECTED_TXTR_LIGHT_NO_SHADOW_)
+
+	vec4 _txtr_coord2 = gl_TextureMatrix[0] * vec4(_frag_pos_vspace, 1.0);
+	vec3 _txtr_coord3 = _txtr_coord2.xyz / _txtr_coord2.w;
+
+	if
+	(
+		_txtr_coord2.w > 0.0 &&
+		_txtr_coord2.w < 1.0/gl_LightSource[0].position.w &&
+		_txtr_coord3.x >= 0.0 &&
+		_txtr_coord3.x <= 1.0 &&
+		_txtr_coord3.y >= 0.0 &&
+		_txtr_coord3.y <= 1.0
+	)
+	{
+		vec3 _texel = texture2DProj( light_txtr, _txtr_coord2.xyz ).rgb;
+		vec3 _texel_with_lambert = _texel * _lambert_term; // make that mul because we dont want the faces that are not facing the light
+																											 // ... to have the texture applied to them
+		float _att = Attenuation(_frag_light_dist);
+		gl_FragData[0] = vec4( _color * _texel_with_lambert * _att, 1.0 );
+	}
+	else
+		Discard();
+
+#elif defined(_PROJECTED_TXTR_LIGHT_SHADOW_)
+	vec4 _txtr_coord2 = gl_TextureMatrix[0] * vec4(_frag_pos_vspace, 1.0);
+	vec3 _shadow_uv = _txtr_coord2.xyz / _txtr_coord2.w;
+
+	if
+	(
+		_txtr_coord2.w > 0.0 && // cat behind
+		_txtr_coord2.w < 1.0/gl_LightSource[0].position.w && // cat the far front
+		_shadow_uv.x >= 0.0 && // cat left
+		_shadow_uv.x <= 1.0 && // cat right
+		_shadow_uv.y >= 0.0 && // cat down
+		_shadow_uv.y <= 1.0   // cat up
+	)
+	{
+		float _shadow_color = PCF_Medium( _shadow_uv );
+		float _att = Attenuation(_frag_light_dist);
+		vec3 _texel = texture2DProj( light_txtr, _txtr_coord2.xyz ).rgb;
+		gl_FragData[0] = vec4(_texel * _color * (_shadow_color * _att), 1.0);
+	}
+	else
+		Discard();
+#endif
+
+#endif
+
+	//gl_FragData[0] = vec4( _normal*0.5 + 0.5, 1.0 );
+}

+ 10 - 0
src/old_src/deferred shading, calculate fragpos from depth/light_pass_generic.vert

@@ -0,0 +1,10 @@
+attribute vec3 view_vector;
+varying vec3 vpos;
+varying vec2 txtr_coord;
+
+void main()
+{
+	vpos = view_vector;
+	txtr_coord = gl_MultiTexCoord0.xy;
+  gl_Position = ftransform();
+}

+ 17 - 0
src/old_src/deferred shading, calculate fragpos from depth/light_pass_point.shdr

@@ -0,0 +1,17 @@
+VERTEX_SHADER "shaders/light_pass_generic.vert"
+FRAGMENT_SHADER "shaders/light_pass_generic.frag"
+
+PREPROCESSOR_DEFINES
+{
+	"#define _POINT_LIGHT_"
+}
+
+UNIFORM_VARS
+{
+	// puth the uniform vars with this order ONLY (or prepere to make changes in the cpp)
+	"normal_rt"
+	"diffuse_rt"
+	"specular_rt"
+	"depth_rt"
+}
+

+ 18 - 0
src/old_src/deferred shading, calculate fragpos from depth/light_pass_proj_nos.shdr

@@ -0,0 +1,18 @@
+VERTEX_SHADER "shaders/light_pass_generic.vert"
+FRAGMENT_SHADER "shaders/light_pass_generic.frag"
+
+PREPROCESSOR_DEFINES
+{
+	"#define _PROJECTED_TXTR_LIGHT_"
+	"#define _PROJECTED_TXTR_LIGHT_NO_SHADOW_"
+}
+
+UNIFORM_VARS
+{
+	// puth the uniform vars with this order ONLY (or prepere to make changes in the cpp)
+	"normal_rt"
+	"diffuse_rt"
+	"specular_rt"
+	"depth_rt"
+}
+

+ 18 - 0
src/old_src/deferred shading, calculate fragpos from depth/light_pass_proj_s.shdr

@@ -0,0 +1,18 @@
+VERTEX_SHADER "shaders/light_pass_generic.vert"
+FRAGMENT_SHADER "shaders/light_pass_generic.frag"
+
+PREPROCESSOR_DEFINES
+{
+	"#define _PROJECTED_TXTR_LIGHT_"
+	"#define _PROJECTED_TXTR_LIGHT_SHADOW_"
+}
+
+UNIFORM_VARS
+{
+	// puth the uniform vars with this order ONLY (or prepere to make changes in the cpp)
+	"normal_rt"
+	"diffuse_rt"
+	"specular_rt"
+	"depth_rt"
+}
+

+ 75 - 0
src/old_src/deferred shading, calculate fragpos from depth/mat_pass_generic.frag

@@ -0,0 +1,75 @@
+varying vec3 normal;
+
+#if defined( _HAS_DIFFUSE_MAP_ )
+uniform sampler2D diffuse_map;
+#endif
+
+#if defined( _HAS_NORMAL_MAP_ )
+uniform sampler2D normal_map;
+varying vec3 tangent_v;
+#endif
+
+#if defined( _HAS_DIFFUSE_MAP_ ) || defined( _HAS_NORMAL_MAP_ )
+varying vec2 txtr_coords;
+#endif
+
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+void main()
+{
+		// DIFFUSE COLOR
+#if defined( _HAS_DIFFUSE_MAP_ )
+	vec4 _diffuse = texture2D( diffuse_map, txtr_coords );
+
+	#if defined( _GRASS_LIKE_ )
+		if( _diffuse.a == 0.0 ) discard;
+	#endif
+
+	gl_FragData[1] = _diffuse;
+#else
+	gl_FragData[1] = gl_Color;//gl_FrontMaterial.diffuse;
+#endif
+
+
+	// NORMAL
+#if defined( _HAS_NORMAL_MAP_ )
+	vec3 _n = normalize( normal );
+	vec3 _t = normalize( tangent_v );
+	vec3 _b = cross(_n, _t);
+
+	mat3 _tbn_mat = mat3(_t.x, _b.x, _n.x, _t.y, _b.y, _n.y, _t.z, _b.z, _n.z);
+
+	vec3 _ntex = ( texture2D( normal_map, txtr_coords ).rgb - 0.5 ) * 2.0;
+
+	vec3 _ncol = normalize( _ntex * _tbn_mat ) * 0.5 + 0.5;
+	gl_FragData[0] = vec4(_ncol, 1.0);
+#else
+	vec3 _ncol = normalize(normal) * 0.5 + 0.5; // normalize and convert from [-1,1] to color space, aka [0,1]
+	gl_FragData[0] = vec4(_ncol, 1.0);
+#endif
+
+	// SPECULAR COLOR
+	gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess/128.0);
+
+
+	/*vec3 _normal = normalize(normal);
+	_normal = Normal2Color(_normal);
+	vec3 _nx = float_to_color(_normal.x);
+	vec3 _ny = float_to_color(_normal.y);
+	vec3 _nz = float_to_color(_normal.z);
+
+	gl_FragData[0] = vec4(_nx, _nz.x);
+
+	gl_FragData[1] = gl_Color;
+
+	gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, _nz.z);
+
+	gl_FragData[3] = vec4( _ny, _nz.y);*/
+
+}
+

+ 32 - 0
src/old_src/deferred shading, calculate fragpos from depth/mat_pass_generic.vert

@@ -0,0 +1,32 @@
+/*
+This a generic shader to fill the deferred shading buffers. You can always build your own if you dont need to write in all the
+buffers.
+*/
+varying vec3 normal;
+
+#if defined( _HAS_DIFFUSE_MAP_ ) || defined( _HAS_NORMAL_MAP_ )
+varying vec2 txtr_coords;
+#endif
+
+#if defined( _HAS_NORMAL_MAP_ )
+attribute vec3 tangent;
+varying vec3 tangent_v;
+#endif
+
+void main()
+{
+	normal = gl_NormalMatrix * gl_Normal;
+
+#if defined( _HAS_DIFFUSE_MAP_ ) || defined( _HAS_NORMAL_MAP_ )
+	txtr_coords = gl_MultiTexCoord0.xy;
+#else
+	gl_FrontColor = gl_Color;
+#endif
+
+#if defined( _HAS_NORMAL_MAP_ )
+	tangent_v = tangent;
+#endif
+
+	gl_Position = ftransform();
+}
+

+ 525 - 0
src/old_src/deferred shading, calculate fragpos from depth/r_deferred.cpp

@@ -0,0 +1,525 @@
+#include "renderer.h"
+
+#include "texture.h"
+#include "lights.h"
+#include "scene.h"
+#include "assets.h"
+#include "collision.h"
+
+namespace r {
+
+namespace shadows
+{
+	extern texture_t depth_map;
+	extern void RenderSceneOnlyDepth( const camera_t& cam );
+}
+
+
+namespace dfr {
+
+/*
+=======================================================================================================================================
+VARS                                                                                                                                  =
+=======================================================================================================================================
+*/
+
+static GLenum mat_pass_color_attachments[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT };
+const int mat_pass_color_attachments_num = 3;
+
+static GLenum illum_pass_color_attachments[] = { GL_COLOR_ATTACHMENT0_EXT };
+const int illum_pass_color_attachments_num = 1;
+
+// FBOs
+static uint mat_pass_fbo_id = 0, illum_pass_fbo_id = 0;
+
+// framebuffer attachable images
+const int MAT_PASS_FBO_ATTACHED_IMGS_NUM = 4;
+
+static texture_t ipfai_illum_scene;
+
+texture_t mpfai_normal, mpfai_diffuse, mpfai_specular, mpfai_depth;
+
+// shaders
+static shader_prog_t* shdr_ambient_pass;
+static shader_prog_t* shdr_point_light_pass;
+static shader_prog_t* shdr_proj_light_nos_pass;
+static shader_prog_t* shdr_proj_light_s_pass;
+static shader_prog_t* shdr_post_proc_stage;
+
+// default material
+static material_t* dflt_material;
+
+
+// the bellow are used to speedup the calculation of the frag pos (view space) inside the shader. This is done by precompute the
+// view vectors each for one corner of the screen and tha planes used to compute the frag_pos_view_space.z from the depth value.
+static vec3_t view_vectors[4];
+static vec2_t planes;
+
+
+// to draw the quad in the screen
+static float quad_points [][2] = { {r::w,r::h}, {0,r::h}, {0,0}, {r::w,0} };
+static float quad_uvs [][2] = { {1.0,1.0}, {0.0,1.0}, {0.0,0.0}, {1.0,0.0} };
+
+
+/*
+=======================================================================================================================================
+InitMatPassFBO                                                                                                                        =
+=======================================================================================================================================
+*/
+static void InitMatPassFBO()
+{
+	// create FBO
+	glGenFramebuffersEXT( 1, &mat_pass_fbo_id );
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mat_pass_fbo_id );
+
+	// create buffers
+	const int internal_format = GL_RGBA_FLOAT32_ATI;
+	mpfai_normal.CreateEmpty( r::w, r::h, internal_format, GL_RGBA, GL_UNSIGNED_BYTE );
+	mpfai_diffuse.CreateEmpty( r::w, r::h, internal_format, GL_RGBA, GL_UNSIGNED_BYTE );
+	mpfai_specular.CreateEmpty( r::w, r::h, internal_format, GL_RGBA, GL_UNSIGNED_BYTE );
+
+	mpfai_depth.CreateEmpty( r::w, r::h, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT );
+
+	// attach the buffers to the FBO
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mpfai_normal.gl_id, 0 );
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mpfai_diffuse.gl_id, 0 );
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, mpfai_specular.gl_id, 0 );
+
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,  GL_TEXTURE_2D, mpfai_depth.gl_id, 0 );
+
+	// test if success
+	if( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT )
+		FATAL( "Cannot create deferred shading material pass FBO" );
+
+	// unbind
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
+
+
+/*
+=======================================================================================================================================
+InitIllumPassFBO                                                                                                                      =
+=======================================================================================================================================
+*/
+static void InitIllumPassFBO()
+{
+	// create FBO
+	glGenFramebuffersEXT( 1, &illum_pass_fbo_id );
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, illum_pass_fbo_id );
+
+	// create the txtrs
+	ipfai_illum_scene.CreateEmpty( r::w, r::h, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE );
+
+	// attach
+	glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ipfai_illum_scene.gl_id, 0 );
+
+	// test if success
+	if( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT )
+		FATAL( "Cannot create deferred shading illumination pass FBO" );
+
+	// unbind
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
+
+/*
+=======================================================================================================================================
+Init                                                                                                                                  =
+=======================================================================================================================================
+*/
+void Init()
+{
+	// the shaders
+	shdr_ambient_pass = ass::LoadShdr( "shaders/ambient_pass.shdr" );
+	shdr_point_light_pass = ass::LoadShdr( "shaders/light_pass_point.shdr" );
+	shdr_proj_light_nos_pass = ass::LoadShdr( "shaders/light_pass_proj_nos.shdr" );
+	shdr_proj_light_s_pass = ass::LoadShdr( "shaders/light_pass_proj_s.shdr" );
+	shdr_post_proc_stage = ass::LoadShdr( "shaders/post_proc_stage.shdr" );
+
+	// the default material
+	dflt_material = ass::LoadMat( "materials/dflt.mat" );
+
+	// init FBOs
+	InitMatPassFBO();
+	InitIllumPassFBO();
+}
+
+
+/*
+=======================================================================================================================================
+CalcViewVector                                                                                                                        =
+=======================================================================================================================================
+*/
+static void CalcViewVector( const camera_t& cam )
+{
+	int pixels[4][2]={ {r::w,r::h}, {0,r::h}, { 0,0 }, {r::w,0} }; // from righ up and CC wise to right down, Just like we render the quad
+	int viewport[4]={ 0, 0, r::w, r::h };
+
+	mat3_t view_rotation = cam.GetViewMatrix().GetRotationPart();
+
+	for( int i=0; i<4; i++ )
+	{
+		/* Original Code:
+		r::UnProject( pixels[i][0], pixels[i][1], 10, cam.GetViewMatrix(), cam.GetProjectionMatrix(), viewport,
+		              view_vectors[i].x, view_vectors[i].y, view_vectors[i].z );
+		view_vectors[i] = cam.GetViewMatrix() * view_vectors[i];
+		The original code is the above 3 lines. The optimized follows:*/
+
+		mat4_t inv_pm = cam.GetProjectionMatrix().Inverted();
+
+		vec4_t vec;
+		vec.x = (2.0*(pixels[i][0]-viewport[0]))/viewport[2] - 1.0;
+		vec.y = (2.0*(pixels[i][1]-viewport[1]))/viewport[3] - 1.0;
+		vec.z = 2.0*10.0 - 1.0;
+		vec.w = 1.0;
+
+		view_vectors[i] = vec3_t(inv_pm * vec);
+		// end of optimized code
+	}
+}
+
+
+/*
+=======================================================================================================================================
+CalcPlanes                                                                                                                            =
+=======================================================================================================================================
+*/
+static void CalcPlanes( const camera_t& cam )
+{
+	planes.x = -cam.GetZFar() / (cam.GetZFar() - cam.GetZNear());
+	planes.y = -cam.GetZFar() * cam.GetZNear() / (cam.GetZFar() - cam.GetZNear());
+}
+
+
+/*
+=======================================================================================================================================
+MaterialStage                                                                                                                         =
+=======================================================================================================================================
+*/
+void MaterialStage( const camera_t& cam )
+{
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mat_pass_fbo_id );
+	glDrawBuffers( mat_pass_color_attachments_num, mat_pass_color_attachments );
+
+	glClear( GL_DEPTH_BUFFER_BIT );
+	r::SetProjectionViewMatrices( cam );
+	r::SetViewport( 0, 0, r::w, r::h );
+
+	scene::skybox.Render( cam.GetViewMatrix().GetRotationPart() );
+
+	for( uint i=0; i<scene::objects.size(); i++ )
+	{
+		object_t* obj = scene::objects[i];
+
+		if( !obj->material ) continue;
+
+
+		obj->material->UseMaterialPass();
+
+
+		scene::objects[i]->Render();
+	}
+
+	r::NoShaders();
+
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
+
+
+/*
+=======================================================================================================================================
+AmbientPass                                                                                                                           =
+=======================================================================================================================================
+*/
+static void AmbientPass( const camera_t& cam, const vec3_t& color )
+{
+	glDisable( GL_BLEND );
+
+	// set the shader
+	shdr_ambient_pass->Bind();
+
+	glUniform3fv( shdr_ambient_pass->GetUniLocation("ambient_color"), 1, &((vec3_t)color)[0] );
+
+	mpfai_diffuse.BindToTxtrUnit(0);  glUniform1i( shdr_ambient_pass->GetUniLocation("ambient_map"), 0 );
+	mpfai_depth.BindToTxtrUnit(1);  glUniform1i( shdr_ambient_pass->GetUniLocation("depth_map"), 1 );
+
+	glBegin( GL_QUADS );
+		glTexCoord2fv( quad_uvs[0] );
+		glVertex2fv( quad_points[0] );
+		glTexCoord2fv( quad_uvs[1] );
+		glVertex2fv( quad_points[1] );
+		glTexCoord2fv( quad_uvs[2] );
+		glVertex2fv( quad_points[2] );
+		glTexCoord2fv( quad_uvs[3] );
+		glVertex2fv( quad_points[3] );
+	glEnd();
+}
+
+
+/*
+=======================================================================================================================================
+PointLightPass                                                                                                                        =
+=======================================================================================================================================
+*/
+static void PointLightPass( const camera_t& cam, const point_light_t& pointl )
+{
+	//** make a check wether the point light passes the frustum test **
+	bsphere_t sphere( pointl.world_translation, pointl.radius );
+	if( !cam.InsideFrustum( sphere ) ) return;
+//	proj_light_t* projl = (proj_light_t*)scene::objects[7];
+//	if( !projl->camera.InsideFrustum( sphere ) ) return;
+
+
+	//** bind the shader **
+	shdr_point_light_pass->Bind();
+
+	// bind the framebuffer attachable images
+	mpfai_normal.BindToTxtrUnit(0);
+	mpfai_diffuse.BindToTxtrUnit(1);
+	mpfai_specular.BindToTxtrUnit(2);
+	mpfai_depth.BindToTxtrUnit(3);
+	glUniform1i( shdr_point_light_pass->uniform_locations[0], 0 );
+	glUniform1i( shdr_point_light_pass->uniform_locations[1], 1 );
+	glUniform1i( shdr_point_light_pass->uniform_locations[2], 2 );
+	glUniform1i( shdr_point_light_pass->uniform_locations[3], 3 );
+
+	// set other shader params
+	glUniform2fv( shdr_point_light_pass->GetUniLocation("planes"), 1, &planes[0] );
+
+	vec3_t light_pos_eye_space = cam.GetViewMatrix() * pointl.world_translation;
+
+	glLightfv( GL_LIGHT0, GL_POSITION, &vec4_t(light_pos_eye_space, 1/pointl.radius)[0] );
+	glLightfv( GL_LIGHT0, GL_DIFFUSE,  &(vec4_t( pointl.GetDiffuseColor(), 1.0 ))[0] );
+	glLightfv( GL_LIGHT0, GL_SPECULAR,  &(vec4_t( pointl.GetSpecularColor(), 1.0 ))[0] );
+
+	//** render quad **
+	int loc = shdr_point_light_pass->GetAttrLocation( "view_vector" );
+
+	glBegin( GL_QUADS );
+		glVertexAttrib3fv( loc, &(view_vectors[0])[0] );
+		glTexCoord2fv( quad_uvs[0] );
+		glVertex2fv( quad_points[0] );
+		glVertexAttrib3fv( loc, &(view_vectors[1])[0] );
+		glTexCoord2fv( quad_uvs[1] );
+		glVertex2fv( quad_points[1] );
+		glVertexAttrib3fv( loc, &(view_vectors[2])[0] );
+		glTexCoord2fv( quad_uvs[2] );
+		glVertex2fv( quad_points[2] );
+		glVertexAttrib3fv( loc, &(view_vectors[3])[0] );
+		glTexCoord2fv( quad_uvs[3] );
+		glVertex2fv( quad_points[3] );
+	glEnd();
+
+}
+
+
+/*
+=======================================================================================================================================
+ProjLightPass                                                                                                                         =
+=======================================================================================================================================
+*/
+static void ProjLightPass( const camera_t& cam, const proj_light_t& light )
+{
+	//** first of all check if the light's camera is inside the frustum **
+	if( !cam.InsideFrustum( light.camera ) ) return;
+
+	//** secondly generate the shadow map (if needed) **
+	if( light.casts_shadow )
+	{
+		shadows::RenderSceneOnlyDepth( light.camera );
+
+		glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, illum_pass_fbo_id );
+		glDrawBuffers( illum_pass_color_attachments_num, illum_pass_color_attachments );
+
+		glEnable( GL_BLEND );
+		glBlendFunc( GL_ONE, GL_ONE );
+
+		glDisable( GL_DEPTH_TEST );
+	}
+
+	//** set texture matrix for shadowmap projection **
+	const float mBias[] = {0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0};
+	glActiveTexture( GL_TEXTURE0 );
+	glMatrixMode( GL_TEXTURE );
+	glLoadMatrixf( mBias );
+	r::MultMatrix( light.camera.GetProjectionMatrix() );
+	r::MultMatrix( light.camera.GetViewMatrix() );
+	r::MultMatrix( cam.world_transformation );
+	glMatrixMode(GL_MODELVIEW);
+
+	//** set the shader and uniforms **
+	{
+		const shader_prog_t* shdr; // because of the huge name
+
+		if( light.casts_shadow )  shdr = shdr_proj_light_s_pass;
+		else                      shdr = shdr_proj_light_nos_pass;
+
+		shdr->Bind();
+
+		// bind the framebuffer attachable images
+		mpfai_normal.BindToTxtrUnit(0);
+		mpfai_diffuse.BindToTxtrUnit(1);
+		mpfai_specular.BindToTxtrUnit(2);
+		mpfai_depth.BindToTxtrUnit(3);
+		glUniform1i( shdr->uniform_locations[0], 0 );
+		glUniform1i( shdr->uniform_locations[1], 1 );
+		glUniform1i( shdr->uniform_locations[2], 2 );
+		glUniform1i( shdr->uniform_locations[3], 3 );
+
+		DEBUG_ERR( light.texture == NULL ); // No texture attached to the light
+
+		light.texture->BindToTxtrUnit( MAT_PASS_FBO_ATTACHED_IMGS_NUM );
+		glUniform1i( shdr->GetUniLocation("light_txtr"), MAT_PASS_FBO_ATTACHED_IMGS_NUM );
+
+		// the planes
+		glUniform2fv( shdr->GetUniLocation("planes"), 1, &planes[0] );
+
+		// the pos and max influence distance
+		vec3_t light_pos_eye_space = cam.GetViewMatrix() * light.world_translation;
+		glLightfv( GL_LIGHT0, GL_POSITION, &vec4_t(light_pos_eye_space, 1.0/light.GetDistance())[0] );
+
+		// the colors
+		glLightfv( GL_LIGHT0, GL_DIFFUSE,  &(vec4_t( light.GetDiffuseColor(), 1.0 ))[0] );
+		glLightfv( GL_LIGHT0, GL_SPECULAR,  &(vec4_t( light.GetSpecularColor(), 1.0 ))[0] );
+
+		// the shadow stuff
+		// render depth to texture and then bind it
+		if( light.casts_shadow )
+		{
+			shadows::depth_map.BindToTxtrUnit( MAT_PASS_FBO_ATTACHED_IMGS_NUM+1 );
+			glUniform1i( shdr->GetUniLocation("shadow_depth_map"), MAT_PASS_FBO_ATTACHED_IMGS_NUM+1 );
+
+			glUniform1f( shdr->GetUniLocation("shadow_resolution"), shadows::shadow_resolution );
+		}
+	}
+
+	// render quad
+	int loc = shdr_proj_light_nos_pass->GetAttrLocation( "view_vector" );
+
+	glBegin( GL_QUADS );
+		glVertexAttrib3fv( loc, &(view_vectors[0])[0] );
+		glTexCoord2fv( quad_uvs[0] );
+		glVertex2fv( quad_points[0] );
+		glVertexAttrib3fv( loc, &(view_vectors[1])[0] );
+		glTexCoord2fv( quad_uvs[1] );
+		glVertex2fv( quad_points[1] );
+		glVertexAttrib3fv( loc, &(view_vectors[2])[0] );
+		glTexCoord2fv( quad_uvs[2] );
+		glVertex2fv( quad_points[2] );
+		glVertexAttrib3fv( loc, &(view_vectors[3])[0] );
+		glTexCoord2fv( quad_uvs[3] );
+		glVertex2fv( quad_points[3] );
+	glEnd();
+
+	// restore texture matrix
+	glMatrixMode( GL_TEXTURE );
+	glLoadIdentity();
+	glMatrixMode(GL_MODELVIEW);
+}
+
+
+/*
+=======================================================================================================================================
+IlluminationStage                                                                                                                     =
+=======================================================================================================================================
+*/
+void IlluminationStage( const camera_t& cam )
+{
+	// FBO
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, illum_pass_fbo_id );
+	glDrawBuffers( illum_pass_color_attachments_num, illum_pass_color_attachments );
+
+	// OGL stuff
+	glMatrixMode( GL_PROJECTION );
+	glLoadIdentity();
+	glOrtho( 0.0, r::w, 0.0, r::h, -1.0, 1.0 );
+
+	glMatrixMode( GL_MODELVIEW );
+	glLoadIdentity();
+
+	glDisable( GL_DEPTH_TEST );
+	glPolygonMode( GL_FRONT, GL_FILL );
+
+	// ambient pass
+	AmbientPass( cam, scene::GetAmbientColor() );
+
+	// light passes
+	glEnable( GL_BLEND );
+	glBlendFunc( GL_ONE, GL_ONE );
+
+	CalcViewVector( cam );
+	CalcPlanes( cam );
+
+	// for all lights
+	for( uint i=0; i<scene::lights.size(); i++ )
+	{
+		const light_t& light = *scene::lights[i];
+		switch( light.GetType() )
+		{
+			case light_t::POINT:
+			{
+				const point_light_t& pointl = static_cast<const point_light_t&>(light);
+				PointLightPass( cam, pointl );
+				break;
+			}
+
+			case light_t::PROJ_TXTR:
+			{
+				const proj_light_t& projl = static_cast<const proj_light_t&>(light);
+				ProjLightPass( cam, projl );
+				break;
+			}
+
+			default:
+				FATAL( "Check code" );
+		}
+	}
+
+	// FBO
+	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
+
+
+/*
+=======================================================================================================================================
+PostProcStage                                                                                                                         =
+=======================================================================================================================================
+*/
+void PostProcStage( const camera_t& cam )
+{
+	// set GL
+	glDisable( GL_DEPTH_TEST );
+	glDisable( GL_BLEND );
+	glPolygonMode( GL_FRONT, GL_FILL );
+
+	glMatrixMode( GL_PROJECTION );
+	glLoadIdentity();
+	glOrtho( 0.0, r::w, 0.0, r::h, -1.0, 1.0 );
+
+	// set shader
+	shdr_post_proc_stage->Bind();
+
+	ipfai_illum_scene.BindToTxtrUnit(0);
+	glUniform1i( shdr_post_proc_stage->GetUniLocation("illum_scene_map"), 0 );
+	mpfai_depth.BindToTxtrUnit(1);
+	glUniform1i( shdr_post_proc_stage->GetUniLocation("depth_map"), 1 );
+
+	glUniform2fv( shdr_post_proc_stage->GetUniLocation("camerarange"), 1, &(vec2_t(cam.GetZNear(), cam.GetZFar()))[0] );
+	glUniform2fv( shdr_post_proc_stage->GetUniLocation("screensize"), 1, &(vec2_t(r::w, r::w))[0] );
+
+	glBegin( GL_QUADS );
+		glTexCoord2fv( quad_uvs[0] );
+		glVertex2fv( quad_points[0] );
+		glTexCoord2fv( quad_uvs[1] );
+		glVertex2fv( quad_points[1] );
+		glTexCoord2fv( quad_uvs[2] );
+		glVertex2fv( quad_points[2] );
+		glTexCoord2fv( quad_uvs[3] );
+		glVertex2fv( quad_points[3] );
+	glEnd();
+
+	shdr_post_proc_stage->UnBind();
+}
+
+
+
+}} // end namespaces

+ 393 - 0
src/old_src/geometry.cpp

@@ -0,0 +1,393 @@
+#include <iostream>
+#include <fstream>
+#include "geometry.h"
+#include "shaders.h"
+using namespace std;
+
+/*
+=================================================================================================================================================================================
+CalcFaceNormals                                                                                                                                                 =
+=================================================================================================================================================================
+*/
+void mesh_data_t::CalcFaceNormals()
+{
+	for( int i=0; i<tris.size; i++ )
+	{
+		triangle_t& tri = tris[i];
+		const vec3_t& v0 = verts[ tri.vert_ids[0] ].coords;
+		const vec3_t& v1 = verts[ tri.vert_ids[1] ].coords;
+		const vec3_t& v2 = verts[ tri.vert_ids[2] ].coords;
+
+		tri.normal = ( v1 - v0 ) * ( v2 - v1 );
+
+		tri.normal.Normalize();
+	}
+}
+
+
+/*
+=================================================================================================================================================================
+CalcVertNormals                                                                                                                                                 =
+=================================================================================================================================================================
+*/
+void mesh_data_t::CalcVertNormals()
+{
+	for( int i=0; i<verts.size; i++ )
+		verts[i].normal.LoadZero();
+
+	for( int i=0; i<tris.size; i++ )
+	{
+		triangle_t& tri = tris[i];
+		verts[ tri.vert_ids[0] ].normal += tri.normal;
+		verts[ tri.vert_ids[1] ].normal += tri.normal;
+		verts[ tri.vert_ids[2] ].normal += tri.normal;
+	}
+
+	for( int i=0; i<verts.size; i++ )
+		verts[i].normal.Normalize();
+}
+
+
+
+/*
+=================================================================================================================================================================================
+CalcFaceTangents                                                                                                                                                =
+=================================================================================================================================================================
+*/
+void mesh_data_t::CalcFaceTangents()
+{
+	for( int i=0; i<tris.size; i++ )
+	{
+		const triangle_t& tri = tris[i];
+		const vec3_t& v0 = verts[ tri.vert_ids[0] ].coords;
+		const vec3_t& v1 = verts[ tri.vert_ids[1] ].coords;
+		const vec3_t& v2 = verts[ tri.vert_ids[2] ].coords;
+		vec3_t edge01 = v1 - v0;
+		vec3_t edge02 = v2 - v0;
+
+		vec2_t uvedge01 = uvs[i][1] - uvs[i][0];
+		vec2_t uvedge02 = uvs[i][2] - uvs[i][0];
+
+		uvedge01.Normalize();
+		uvedge02.Normalize();
+
+
+		float det = (uvedge01.X * uvedge02.Y) - (uvedge01.Y * uvedge02.X);
+		DEBUG_ERR( IsZero(det) );
+		det = 1.0f / det;
+
+		vec3_t t = ( edge01 * uvedge02.Y - edge02 * uvedge01.Y ) * det;
+		vec3_t b = ( edge02 * uvedge01.X - edge01 * uvedge02.X ) * det;
+		t.Normalize();
+		b.Normalize();
+
+		//face_tangents[i] = t;
+
+		vec3_t bitangent( tri.normal * t );
+    float handedness = ( bitangent.Dot( b ) < 0.0f) ? -1.0f : 1.0f;
+
+		face_tangents[i] = vec4_t( t.X, t.Y, t.Z, handedness );
+
+	}
+
+}
+
+
+/*
+=================================================================================================================================================================================
+CalcVertTangents                                                                                                                                                =
+=================================================================================================================================================================
+*/
+void mesh_data_t::CalcVertTangents()
+{
+	for( int i=0; i<vert_tangents.size; i++ )
+		vert_tangents[i].LoadZero();
+
+	for( int i=0; i<tris.size; i++ )
+	{
+		const vec4_t& ft = face_tangents[i];
+		const triangle_t& tri = tris[i];
+
+		vert_tangents[ tri.vert_ids[0] ] += ft;
+		vert_tangents[ tri.vert_ids[1] ] += ft;
+		vert_tangents[ tri.vert_ids[2] ] += ft;
+	}
+
+	for( int i=0; i<vert_tangents.size; i++ )
+	{
+		/*vec3_t v3( vert_tangents[i].X, vert_tangents[i].Y, vert_tangents[i].Z );
+		v3.Normalize();
+		vert_tangents[i] = vec4_t( v3.X, v3.Y, v3.Z, vert_tangents[i].W );*/
+
+		vert_tangents[i] = vec4_t( vec3_t(vert_tangents[i]).Normalized(), vert_tangents[i].W );
+	}
+//    vec3_t* tan1 = new vec3_t[verts.size * 2];
+//    vec3_t* tan2 = tan1 + verts.size;
+//    ZeroMemory(tan1, vertexCount * sizeof(Vector3D) * 2);
+//    memset( tan1, 0, verts.size * 2 );
+//
+//    for (long a = 0; a < tris.size; a++)
+//    {
+//			triangle_t* triangle = &tris[a];
+//        long i1 = triangle->ids[0];
+//        long i2 = triangle->ids[1];
+//        long i3 = triangle->ids[2];
+//
+//        const vec3_t& v1 = verts[i1];
+//        const vec3_t& v2 = verts[i2];
+//        const vec3_t& v3 = verts[i3];
+//
+//        const vec2_t& w1 = uvs texcoord[i1];
+//        const vec2_t& w2 = texcoord[i2];
+//        const vec2_t& w3 = texcoord[i3];
+//
+//        float x1 = v2.x - v1.x;
+//        float x2 = v3.x - v1.x;
+//        float y1 = v2.y - v1.y;
+//        float y2 = v3.y - v1.y;
+//        float z1 = v2.z - v1.z;
+//        float z2 = v3.z - v1.z;
+//
+//        float s1 = w2.x - w1.x;
+//        float s2 = w3.x - w1.x;
+//        float t1 = w2.y - w1.y;
+//        float t2 = w3.y - w1.y;
+//
+//        float r = 1.0F / (s1 * t2 - s2 * t1);
+//        Vector3D sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
+//                (t2 * z1 - t1 * z2) * r);
+//        Vector3D tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
+//                (s1 * z2 - s2 * z1) * r);
+//
+//        tan1[i1] += sdir;
+//        tan1[i2] += sdir;
+//        tan1[i3] += sdir;
+//
+//        tan2[i1] += tdir;
+//        tan2[i2] += tdir;
+//        tan2[i3] += tdir;
+//
+//        triangle++;
+//    }
+//
+//    for (long a = 0; a < vertexCount; a++)
+//    {
+//        const Vector3D& n = normal[a];
+//        const Vector3D& t = tan1[a];
+//
+//        // Gram-Schmidt orthogonalize
+//        tangent[a] = (t - n * Dot(n, t)).Normalize();
+//
+//        // Calculate handedness
+//        tangent[a].w = (Dot(Cross(n, t), tan2[a]) < 0.0F) ? -1.0F : 1.0F;
+//    }
+//
+//    delete[] tan1;
+
+}
+
+
+/*
+=================================================================================================================================================================
+Load                                                                                                                                                            =
+=================================================================================================================================================================
+*/
+int mesh_data_t::Load( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str[400];
+	int i, num;
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return 0;
+	}
+
+	// verts
+	file >> str >> num;
+	verts.Malloc( num );
+
+	for( i=0; i< verts.size; i++ )
+	{
+		file >> str >> str >> str >> verts[i].coords.X >> verts[i].coords.Y >> verts[i].coords.Z;
+	}
+
+	// tris
+	file >> str >> num;
+	tris.Malloc( num );
+
+	for( i=0; i<tris.size; i++ )
+	{
+		file >> str >> str >> str >> tris[i].vert_ids[0] >> tris[i].vert_ids[1] >> tris[i].vert_ids[2];
+	}
+
+	// uvs
+	file >> str >> num;
+	uvs.Malloc( num );
+
+	for( i=0; i<uvs.size; i++ )
+	{
+		file >> str >> str >> uvs[i][0].X >> uvs[i][0].Y >> uvs[i][1].X >> uvs[i][1].Y >> uvs[i][2].X >> uvs[i][2].Y;
+	}
+
+	CalcAllNormals();
+
+	face_tangents.Malloc( tris.size );
+	vert_tangents.Malloc( verts.size );
+	CalcAllTangents();
+
+	// populate vert list
+	vert_list.Malloc( tris.size * 3 );
+	for( i=0; i<tris.size; i++ )
+	{
+		vert_list[i*3+0] = tris[i].vert_ids[0];
+		vert_list[i*3+1] = tris[i].vert_ids[1];
+		vert_list[i*3+2] = tris[i].vert_ids[2];
+	}
+
+	file.close();
+
+	return 1;
+}
+
+
+/*
+=================================================================================================================================================================
+Render                                                                                                                                                          =
+=================================================================================================================================================================
+*/
+void mesh_t::Render()
+{
+	int i, j;
+
+
+	// set gl state
+	glPolygonMode( GL_FRONT, GL_FILL );
+	glEnable( GL_LIGHTING );        // remove if pixel shaders enabled
+	glEnable( GL_DEPTH_TEST );
+	glDisable( GL_BLEND );
+	//glEnable( GL_BLEND );
+	glEnable( GL_TEXTURE_2D );
+
+
+	// transform
+	glPushMatrix();
+	UpdateWorldTransform();
+	mat4_t transf( TRS( world_translate, world_rotate, world_scale) );
+	transf.Transpose();
+	glMultMatrixf( &transf(0,0) );
+
+	// render
+	extern shader_prog_t shaderp;
+	GLuint loc = shaderp.GetAttrLocation( "tangent" );
+
+	glBegin( GL_TRIANGLES );
+		for( i=0; i<mesh_data->tris.size; i++ )
+		{
+			triangle_t& tri = mesh_data->tris[i];
+
+			//glNormal3fv( &tri.normal[0] );
+			//glVertexAttrib4fv( loc, &mesh_data->face_tangents[ i ][0] );
+
+			vec2_t* uv = mesh_data->uvs[i];
+			for( j=0; j<3; j++ )
+			{
+				const int vert_id = tri.vert_ids[j];
+				vertex_t& vert = mesh_data->verts[ vert_id ];
+
+				//glVertexAttrib4fv( loc, &mesh_data->vert_tangents[ vert_id ][0] );
+				glNormal3fv( &vert.normal[0] );
+
+				glTexCoord2fv( &uv[j][0] );
+				glVertex3fv( &vert.coords[0] );
+			}
+		}
+	glEnd();
+
+
+	r::NoShaders();
+
+	// vert normals
+	if( 0 )
+	{
+		glColor3f( 0.0, 0.0, 1.0 );
+		glDisable( GL_LIGHTING );
+		glDisable( GL_TEXTURE_2D );
+
+		glBegin( GL_LINES );
+			for( i=0; i<mesh_data->tris.size; i++ )
+			{
+				triangle_t* tri = &mesh_data->tris[i];
+				for( j=0; j<3; j++ )
+				{
+					vertex_t* vert = &mesh_data->verts[tri->vert_ids[j]];
+
+					vec3_t vec0;
+					vec0 = (vert->normal * 0.1f) + vert->coords;
+
+					glVertex3fv( &vert->coords[0] );
+					glVertex3fv( &vec0[0] );
+				}
+			}
+		glEnd();
+	}
+
+	// tri normals
+	if( 0 )
+	{
+		glDisable( GL_LIGHTING );
+		glDisable( GL_TEXTURE_2D );
+		glLineWidth( 1.0f );
+
+		glBegin( GL_LINES );
+			for( i=0; i<mesh_data->tris.size; i++ )
+			{
+				triangle_t* tri = &mesh_data->tris[i];
+
+				vec3_t vec1;
+				vec1 = mesh_data->verts[ tri->vert_ids[0] ].coords;
+				vec1 = ( vec1 + mesh_data->verts[ tri->vert_ids[1] ].coords ) / 2.0f;
+				vec1 = ( vec1 + mesh_data->verts[ tri->vert_ids[2] ].coords ) / 2.0f;
+
+				vec3_t vec2( tri->normal );
+				vec2 = tri->normal;
+				vec2 *= 0.09;
+				vec2 += vec1;
+
+				glColor3f( 0.0, 1.0, 0.0 );
+				glVertex3fv( &vec1[0] );
+				glColor3f( 0.0, 0.0, 1.0 );
+				glVertex3fv( &vec2[0] );
+			}
+		glEnd();
+	}
+
+	// render axis
+	if( 0 ) RenderAxis();
+
+	glPopMatrix();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 40 - 0
src/old_src/geometry.h

@@ -0,0 +1,40 @@
+#ifndef _GEOMETRY_H_
+#define _GEOMETRY_H_
+
+#include "primitives.h"
+
+class mesh_data_t
+{
+	public:
+		array_t<vertex_t>   verts;
+		array_t<triangle_t> tris;
+		array_t<vec2_t[3]>  uvs;
+		char                name[100];
+
+		array_t<vec4_t>     face_tangents;
+		array_t<vec4_t>     vert_tangents;
+
+		array_t<int>        vert_list;
+
+		mesh_data_t() {}
+		~mesh_data_t() { verts.Free(); tris.Free(); uvs.Free(); face_tangents.Free(); vert_tangents.Free(); vert_list.Free();};
+
+		int  Load( const char* filename );
+		void CalcFaceNormals();
+		void CalcVertNormals();
+		void CalcAllNormals() { CalcFaceNormals(); CalcVertNormals(); }
+		void CalcFaceTangents();
+		void CalcVertTangents();
+		void CalcAllTangents() { CalcFaceTangents(); CalcVertTangents(); }
+};
+
+
+class mesh_t: public object_t
+{
+	public:
+		mesh_data_t* mesh_data;
+		void Render();
+};
+
+
+#endif

+ 70 - 0
src/old_src/gl_wapper.h

@@ -0,0 +1,70 @@
+#ifndef _GL_WRAPPER_H_
+#define _GL_WRAPPER_H_
+
+#include "common.h"
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include "math.h"
+
+namespace gl {
+
+// basic
+inline void Begin( uint mode ) { glBegin(mode); }
+inline void End() { glEnd(); }
+inline void GetIntegerv( uint pname, int* params ) { glGetIntegerv(pname, params); }
+inline void CullFace( uint mode ) { glCullFace(mode); }
+
+// enable disable
+inline void Enable( uint cap ) { glEnable(cap); }
+inline void Disable( uint cap ) { glDisable(cap); }
+
+// matrices
+inline void MultMatrixf( const mat4_t& m4 ) { glMultMatrixf( &(m4.Transposed())(0,0) ); }
+inline void LoadMatrixf( const mat4_t& m4 ) { glLoadMatrixf( &(m4.Transposed())(0,0) ); }
+inline void LoadIdentity() { glLoadIdentity(); }
+inline void MatrixMode( uint x ) { glMatrixMode(x); }
+inline void Viewport( uint x, uint y, uint w, uint h ) { glViewport(x,y,w,h); }
+inline void PushMatrix() { glPushMatrix(); }
+inline void PopMatrix() { glPopMatrix(); }
+
+// textures
+inline void GenTextures(uint n, uint* textures) { glGenTextures(n, textures); }
+inline void TexImage2D(uint target, int level, int internalFormat, uint width, uint height, int border, uint format, uint type,
+	const void* data ) { glTexImage2D(	target, level, internalFormat, width, height, border, format, type, data ); }
+inline void TexParameteri(uint target, uint pname, int param ) { glTexParameteri( target, pname, param ); }
+
+// shaders
+inline void UseProgram( uint program ) { glUseProgram(program); }
+inline void ShaderSource( uint shader, uint count, const char** string, const int* length ) { glShaderSource(shader,count,string,length); }
+inline void GetShaderiv( uint shader, uint pname, int* params) { glGetShaderiv(shader, pname, params); }
+inline void GetShaderInfoLog( uint shader, uint maxLength, int* length, char* infoLog) {glGetShaderInfoLog(shader, maxLength, length, infoLog);}
+inline uint CreateProgram() { return glCreateProgram(); }
+inline void LinkProgram( uint program ) { glLinkProgram(program); }
+inline void GetProgramiv( uint program, uint pname, int* params) { glGetProgramiv( program, pname, params); }
+inline void GetProgramInfoLog( uint program, uint maxLength, int* length, char* infoLog ) { glGetProgramInfoLog( program, maxLength, length, infoLog ); }
+inline int GetUniformLocation( uint program, const char* name ) { return glGetUniformLocation( program, name ); }
+inline int GetAttribLocation( uint program, const char* name ) { return glGetAttribLocation( program, name ); }
+
+// color
+inline void Color3f( float r, float g, float b ) { glColor3f( r,g,b ); }
+inline void Color3fv( const vec3_t& v ) { glColor3fv( &((vec3_t&)v)[0] ); }
+inline void Color4f( float r, float g, float b, float a ) { glColor4f( r,g,b,a ); }
+inline void Color4fv( const vec4_t& v ) { glColor4fv( &((vec4_t&)v)[0] ); }
+
+// buffers
+inline void ClearColor( float red, float green, float blue, float alpha ) { glClearColor(red,green,blue,alpha); }
+inline void Clear( uint mask ) { glClear(mask); }
+
+// vertex
+inline void Vertex3f( float x, float y, float z ) { glVertex3f(x,y,z); }
+inline void Vertex3fv( const vec3_t& v ) { glVertex3fv( &((vec3_t&)v)[0] ); }
+inline void Normal3f( float x, float y, float z ) { glNormal3f(x,y,z); }
+inline void Normal3fv( const vec3_t& v ) { glNormal3fv( &((vec3_t&)v)[0] ); }
+inline void TexCoord2f( float s, float t ) { glTexCoord2f(s,t); }
+inline void TexCoord2fv( const vec2_t& v ) { glTexCoord2fv( &((vec2_t&)v)[0] ); }
+
+
+
+} // end namespace
+#endif

+ 232 - 0
src/old_src/main_animation.cpp

@@ -0,0 +1,232 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "level.h"
+
+const float fovy = ToRad(60.0);
+camera_t main_cam( r::aspect_ratio*fovy, fovy, 0.5, 100.0 );
+camera_t other_cam( ToRad(60.0), ToRad(60.0), 1.0, 10.0 );
+
+
+light_t lights[1];
+
+model_data_t mdata;
+model_t model;
+skeleton_anim_t anim;
+texture_t txtr, txtr1;
+
+float frame_asd = 0.0;
+
+texture_t render_target;
+
+class cube_t: public object_t
+{
+	public:
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( /*model.world_transformation */ world_transformation );
+
+			r::SetGLState_Solid();
+			glEnable( GL_TEXTURE_2D );
+
+			glActiveTexture( GL_TEXTURE0 );
+			glBindTexture( GL_TEXTURE_2D, render_target.gl_id );
+
+			//glEnable( GL_BLEND );
+
+			r::Color4( vec4_t(1.0, 1.0, 1.0, 1) );
+			r::RenderCube();
+
+			glPopMatrix();
+		}
+}cube;
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	//mem::Enable( mem::THREADS );
+	MathSanityChecks();
+	hndl::InitWindow( r::w, r::h, "mAlice Engine" );
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+
+	other_cam.MoveLocalY( 2.5 );
+	other_cam.MoveLocalZ( 5.0f );
+	other_cam.RotateLocalY( ToRad(-30.0) );
+	other_cam.MoveLocalX( -3.0f );
+
+	ass::LoadMat( "materials/imp/imp.mat" );
+
+	// initialize the TESTS
+	lights[0].SetAmbient( vec4_t( 0.4, 0.4, 0.4, 1.0 ) );
+	lights[0].SetDiffuse( vec4_t( 1.5, 1.5, 1.0, 1.0 ) );
+	lights[0].local_translation = vec3_t( -1.0, 1.0, 0.0 );
+	lights[0].type = light_t::DIRECTIONAL;
+	//lights[0].SetCutOff( 0.0 );
+	//lights[0].SetExp( 120.0 );
+
+
+	txtr.Load( "models/imp/imp_d.tga" );
+	txtr1.Load( "models/imp/imp_local.tga" );
+	mdata.Load( "models/test/imp.mdl" );
+	model.Init( &mdata );
+//	model.local_translation = vec3_t( 1.0, 0.0, 0.0 );
+	model.local_rotation.Set( euler_t( -PI/2, 0.0, 0.0) );
+	//model.SetChilds( 1, &cube );
+	//model.GetBone("arm.L.001")->AddChilds( 1, &cube );
+	anim.Load( "models/test/walk.imp.anim" );
+	model.Play( &anim, 0, 0.7, model_t::START_IMMEDIATELY );
+
+
+	render_target.Load( "gfx/no_tex.tga" );
+
+
+	//cube.local_translation = vec3_t( 2.2, 0.05, 1.75 );
+	cube.local_translation = vec3_t( 3.2, 0.05, 1.75 );
+	cube.local_scale = 2.0;
+	//cube.local_rotation.Set( euler_t( ToRad(-10.0), 0.0, ToRad(-25.0)) );
+	//cube.local_scale = 0.5;
+	//cube.parent = model.GetBone("arm.L.001");
+
+
+	lvl::Register( (model_t*)&model );
+	lvl::Register( (object_t*)&cube );
+	lvl::Register( &main_cam );
+	lvl::Register( &other_cam );
+	lvl::Register( (light_t*)&lights[0] );
+
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_2 ] ) mover = &model;
+		if( i::keys[ SDLK_3 ] ) mover = &lights[0];
+		if( i::keys[ SDLK_4 ] ) mover = &other_cam;
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		mover->local_rotation.Reorthogonalize();
+
+		lvl::InterpolateAllModels();
+		lvl::UpdateAllWorldTrfs();
+		lvl::UpdateAllLights();
+		lvl::UpdateAllFrustumPlanes();
+
+
+
+		// render to txtr
+			glClearColor( 0.0, 0.0, 0.1, 1.0 );
+			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+			const int width = 128;
+			float a = 1;
+			r::SetViewport( 0, 0, width, width/a );
+			r::SetProjectionMatrix( other_cam );
+			r::SetViewMatrix( other_cam );
+
+			lvl::RenderAll();
+
+			glActiveTexture( GL_TEXTURE0 );
+			glBindTexture( GL_TEXTURE_2D, render_target.gl_id );
+			glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, width, width/a, 0 );
+		// end render to txtr
+
+
+		glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+		r::SetViewport( 0, 0, r::w, r::h );
+		r::SetProjectionMatrix( main_cam );
+		r::SetViewMatrix( main_cam );
+
+		r::RenderGrid();
+
+		// render rest
+		model.Deform();
+		lvl::RenderAll();
+
+
+		r::SetGLState_Solid();
+		material_t* mat = ass::LoadMat( "materials/grass0/grass0.mat" );
+		mat->Use();
+		float size = 0.5f;
+		glBegin(GL_QUADS);
+			glNormal3f( 0.0f, 0.0f, 1.0f);
+			glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size,  size);
+			glTexCoord2f(1.0, 0.0); glVertex3f( size, -size,  size);
+			glTexCoord2f(1.0, 1.0); glVertex3f( size,  size,  size);
+			glTexCoord2f(0.0, 1.0); glVertex3f(-size,  size,  size);
+		glEnd();
+
+
+
+		// print some debug stuff
+		hud::SetColor( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	cout << "Appl quits after " << hndl::GetTicks() << " ticks" << endl;
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 464 - 0
src/old_src/main_dualparabolic.cpp

@@ -0,0 +1,464 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "mesh.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "scene.h"
+#include "scanner.h"
+#include "skybox.h"
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 100.0 );
+
+class cube_t: public mesh_t
+{
+	public:
+		cube_t()
+		{
+			translation_lspace = vec3_t( 3.2, 0.05, 1.75 );
+			scale_lspace = 2.0;
+			object_t::SetName( "cube" );
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( transformation_wspace );
+
+			r::Color4( vec4_t(1.0, 1.0, 0.0, 1) );
+
+			r::RenderCube( true );
+
+			glPopMatrix();
+		}
+
+		void RenderDepth()
+		{
+			glPushMatrix();
+			r::MultMatrix( transformation_wspace );
+
+			r::RenderCube();
+
+			glPopMatrix();
+		}
+
+		void UpdateWorldStuff()
+		{
+			UpdateWorldTransform();
+		};
+}cube;
+
+
+class shpere_t: public mesh_t
+{
+	public:
+		shpere_t()
+		{
+			translation_lspace = vec3_t( -1.2, 1.05, -1.75 );
+			scale_lspace = 1.5;
+			object_t::SetName( "sphere" );
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( transformation_wspace );
+
+			r::Color4( vec4_t(1.0, 0.5, 0.25, 1) );
+
+			r::RenderSphere( 1.0, 32 );
+
+			glPopMatrix();
+		}
+
+		void RenderDepth()
+		{
+			glPushMatrix();
+			r::MultMatrix( transformation_wspace );
+			r::RenderSphere( 1.0, 32 );
+			glPopMatrix();
+		}
+
+		void UpdateWorldStuff()
+		{
+			UpdateWorldTransform();
+		};
+}sphere;
+
+
+class flore_t: public mesh_t
+{
+	public:
+
+		flore_t()
+		{
+			scale_lspace = 10.0;
+			object_t::SetName( "flore" );
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( transformation_wspace );
+
+			r::Color4( vec4_t(.6, .6, 1., 1) );
+			//r::Color4( vec4_t::one * 0.5 );
+
+			GLuint loc = material->shader->GetAttrLocation( "tangent" );
+			vec4_t tangent = vec4_t(1,0,0,0);
+
+			float f = 8.0;
+			glNormal3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+			glBegin( GL_QUADS );
+				glTexCoord2f( f, f );
+				glVertexAttrib4fv( loc, &tangent[0] );
+				glVertex3f( 1.0, 0.0, -1.0 );
+				glTexCoord2f( f, 0 );
+				glVertexAttrib4fv( loc, &tangent[0] );
+				glVertex3f( -1.0, 0.0, -1.0 );
+				glTexCoord2f( 0, 0 );
+				glVertexAttrib4fv( loc, &tangent[0] );
+				glVertex3f( -1.0, 0.0, 1.0 );
+				glTexCoord2f( 0, f );
+				glVertexAttrib4fv( loc, &tangent[0] );
+				glVertex3f( 1.0, 0.0, 1.0 );
+			glEnd();
+
+//			glNormal3fv( &(-vec3_t( 0.0, 1.0, 0.0 ))[0] );
+//			glBegin( GL_QUADS );
+//				glVertex3f( 1.0, 0.0, 1.0 );
+//				glVertex3f( -1.0, 0.0, 1.0 );
+//				glVertex3f( -1.0, 0.0, -1.0 );
+//				glVertex3f( 1.0, 0.0, -1.0 );
+//			glEnd();
+
+			glPopMatrix();
+		}
+
+		void RenderDepth()
+		{
+			glPushMatrix();
+			r::MultMatrix( transformation_wspace );
+			glBegin( GL_QUADS );
+				glVertex3f( 1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, 1.0 );
+				glVertex3f( 1.0, 0.0, 1.0 );
+			glEnd();
+			glPopMatrix();
+		}
+
+		void UpdateWorldStuff()
+		{
+			UpdateWorldTransform();
+		};
+}flore;
+
+mesh_t imp, mcube;
+
+point_light_t point_lights[10];
+proj_light_t projlights[2];
+
+shader_prog_t shdr_parab;
+
+texture_t parab_tex;
+#define PARABOLOID_SIZE 512
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	MathSanityChecks();
+
+	hndl::InitWindow( r::w, r::h, "AnKi Engine" );
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( .5 );
+	main_cam.MoveLocalZ( 10.5f );
+	main_cam.camera_data_user_class_t::SetName("main_cam");
+
+	point_lights[0].SetSpecularColor( vec3_t( 0.4, 0.4, 0.4) );
+	point_lights[0].SetDiffuseColor( vec3_t( 1.0, 1.0, 1.0) );
+	point_lights[0].translation_lspace = vec3_t( -1.0, 0.3, 1.0 );
+	point_lights[0].radius = 4.0;
+	point_lights[1].SetSpecularColor( vec3_t( 0.0, 0.0, 1.0) );
+	point_lights[1].SetDiffuseColor( vec3_t( 3.0, 0.1, 0.1) );
+	point_lights[1].translation_lspace = vec3_t( 2.5, 1.4, 1.0 );
+	point_lights[1].radius = 3.0;
+	projlights[0].camera.SetAll( ToRad(60), ToRad(60), 0.1, 20.0 );
+	projlights[0].texture = ass::LoadTxtr( "gfx/lights/flashlight.tga" );
+	projlights[0].SetSpecularColor( vec3_t( 1.0, 1.0, 1.0) );
+	projlights[0].SetDiffuseColor( vec3_t( 3.0, 3.0, 4.0)/1.0 );
+	projlights[0].translation_lspace = vec3_t( 1.3, 1.3, 3.0 );
+	projlights[0].rotation_lspace.RotateYAxis(ToRad(20));
+	projlights[0].casts_shadow = true;
+	projlights[1].camera.SetAll( ToRad(60), ToRad(60), 0.1, 20.0 );
+	projlights[1].texture = ass::LoadTxtr( "gfx/lights/impflash.tga" );
+	projlights[1].SetSpecularColor( vec3_t( 1.0, 1.0, 0.0) );
+	projlights[1].SetDiffuseColor( vec3_t( 1.0, 1.0, 1.0) );
+//	projlights[1].translation_lspace = vec3_t( -1.3, 1.3, 3.0 );
+	projlights[1].rotation_lspace.RotateYAxis(ToRad(180));
+//	projlights[1].casts_shadow = true;
+
+	projlights[0].MakeParent( &projlights[1] );
+
+
+	shdr_parab.LoadCompileLink( "shaders/paraboloid.vert", "shaders/paraboloid.frag" );
+
+	imp.Load( "models/imp/imp.mesh" );
+	//imp.Load( "maps/temple/column.mesh" );
+	imp.translation_lspace = vec3_t( 0.0, 2.11, 0.0 );
+	imp.scale_lspace = 0.7;
+	imp.rotation_lspace.RotateXAxis( -PI/2 );
+
+	mcube.Load( "meshes/horse/horse.mesh" );
+	mcube.translation_lspace = vec3_t( -2, 0, 1 );
+	mcube.scale_lspace = 0.5;
+	mcube.rotation_lspace.RotateXAxis(ToRad(-90));
+
+	cube.material = ass::LoadMat( "materials/default.mat" );
+	sphere.material = ass::LoadMat( "materials/default.mat" );
+	flore.material = ass::LoadMat( "materials/checkboard.mat" );
+
+	scene::Register( &sphere );
+	scene::Register( &cube );
+	scene::Register( &flore );
+	scene::Register( &imp );
+	scene::Register( &mcube );
+	scene::Register( &main_cam );
+	scene::Register( &point_lights[0] );
+	scene::Register( &point_lights[1] );
+	scene::Register( &projlights[0] );
+	scene::Register( &projlights[1] );
+
+	glMaterialfv( GL_FRONT, GL_AMBIENT, &vec4_t( 0.1, 0.1, 0.1, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_DIFFUSE, &vec4_t( 0.5, 0.0, 0.0, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_SPECULAR, &vec4_t( 1., 1., 1., 0.1 )[0] );
+	glMaterialf( GL_FRONT, GL_SHININESS, 100.0 );
+
+	const char* skybox_fnames [] = { "env/hellsky2_forward.tga", "env/hellsky2_back.tga", "env/hellsky2_left.tga", "env/hellsky2_right.tga",
+																	 "env/hellsky2_up.tga", "env/hellsky2_down.tga" };
+	scene::skybox.Load( skybox_fnames );
+
+	flore.material->diffuse_map->TexParameter( GL_TEXTURE_WRAP_S, GL_REPEAT );
+	flore.material->diffuse_map->TexParameter( GL_TEXTURE_WRAP_T, GL_REPEAT );
+
+	parab_tex.CreateEmpty( PARABOLOID_SIZE*2, PARABOLOID_SIZE, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE );
+
+	/************************************************************************************************************************************
+	*																													MAIN LOOP                                                                 *
+	*************************************************************************************************************************************/
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_2 ] ) mover = &point_lights[0];
+		if( i::keys[ SDLK_3 ] ) mover = &projlights[0];
+		if( i::keys[ SDLK_4 ] ) mover = &point_lights[1];
+		if( i::keys[ SDLK_5 ] ) mover = &projlights[1];
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->scale_lspace += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->scale_lspace -= scale ;
+
+		if( i::keys[SDLK_k] ) main_cam.LookAtPoint( point_lights[0].translation_wspace );
+
+		mover->rotation_lspace.Reorthogonalize();
+
+		scene::InterpolateAllModels();
+		scene::UpdateAllWorldStuff();
+
+
+
+
+
+
+
+
+
+
+
+
+
+//		glClearColor( 0.5, 0.0, 0.0, 1.0 );
+//		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+//
+//		r::SetViewport( 0, 0, PARABOLOID_SIZE, PARABOLOID_SIZE );
+//		r::SetProjectionViewMatrices( projlights[0].camera );
+//
+//		//scene::skybox.Render( main_cam.GetViewMatrix().GetRotationPart() );
+//
+//		glEnable( GL_DEPTH_TEST );
+//		shdr_parab.Bind();
+//		//glUniformMatrix4fv( shdr_parab.GetUniLocation("matrix"), 1, false, &(main_cam.GetViewMatrix().Inverted())[0] );
+//
+//		for( uint i=0; i<scene::meshes.size(); i++ )
+//		{
+//			mesh_t* mesh = scene::meshes[i];
+//
+//			if( mesh->material->diffuse_map )
+//				mesh->material->diffuse_map->Bind(0);
+//
+//			mesh->Render();
+//		}
+//		r::NoShaders();
+//
+//		parab_tex.Bind();
+//		glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0.0, 0.0, 0.0, 0.0, PARABOLOID_SIZE, PARABOLOID_SIZE );
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+//
+//		r::SetViewport( 0, 0, PARABOLOID_SIZE, PARABOLOID_SIZE );
+//		r::SetProjectionViewMatrices( projlights[1].camera );
+//
+//		//scene::skybox.Render( main_cam.GetViewMatrix().GetRotationPart() );
+//
+//		glEnable( GL_DEPTH_TEST );
+//		shdr_parab.Bind();
+//		//glUniformMatrix4fv( shdr_parab.GetUniLocation("matrix"), 1, false, &(main_cam.GetViewMatrix().Inverted())[0] );
+//
+//		for( uint i=0; i<scene::meshes.size(); i++ )
+//		{
+//			mesh_t* mesh = scene::meshes[i];
+//
+//			if( mesh->material->diffuse_map )
+//				mesh->material->diffuse_map->Bind(0);
+//
+//			mesh->Render();
+//		}
+//		r::NoShaders();
+//
+//		parab_tex.Bind();
+//		glCopyTexSubImage2D( GL_TEXTURE_2D, 0, PARABOLOID_SIZE-1, 0.0, 0.0, 0.0, PARABOLOID_SIZE, PARABOLOID_SIZE );
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//		glClearColor( 0.2, 0.2, 0.2, 1.0 );
+//		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+//		r::SetViewport( 0, 0, r::w, r::h );
+//		r::SetProjectionViewMatrices( main_cam );
+//
+//		r::NoShaders();
+//		r::RenderGrid();
+//
+//		parab_tex.Bind();
+//		glEnable( GL_TEXTURE_2D );
+//		r::RenderQuad( 4.0, 2.0 );
+
+
+
+		glClearColor( 0.5, 0.0, 0.0, 1.0 );
+		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+		r::SetViewport( 0, 0, r::w, r::w );
+		r::SetProjectionViewMatrices( main_cam );
+
+
+		//scene::skybox.Render( main_cam.GetViewMatrix().GetRotationPart() );
+
+		glEnable( GL_DEPTH_TEST );
+		shdr_parab.Bind();
+		r::RenderGrid();
+		//glUniformMatrix4fv( shdr_parab.GetUniLocation("matrix"), 1, false, &(main_cam.GetViewMatrix().Inverted())[0] );
+
+		for( uint i=0; i<scene::meshes.size(); i++ )
+		{
+			mesh_t* mesh = scene::meshes[i];
+
+			if( mesh->material->diffuse_map )
+				mesh->material->diffuse_map->Bind(0);
+
+			mesh->Render();
+		}
+		r::NoShaders();
+
+
+		r::dbg::RenderDebug( main_cam );
+
+		// print some debug stuff
+		hud::SetColor( vec4_t(1.0, 1.0, 1.0, 1.0) );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		if( i::keys[SDLK_F12] == 1 ) r::TakeScreenshot("gfx/screenshot.tga");
+//		char str[128];
+//		sprintf( str, "capt/%05d.tga", r::frames_num );
+//		r::TakeScreenshot(str);
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	INFO( "Appl quits after " << hndl::GetTicks() << " ticks" );
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 194 - 0
src/old_src/main_normalmaping.cpp

@@ -0,0 +1,194 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "scene.h"
+#include "scanner.h"
+#include "skybox.h"
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.1, 100.0 );
+
+
+mesh_t imp, mcube;
+
+point_light_t point_lights[1];
+
+shader_prog_t* shdr_norm;
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	MathSanityChecks();
+
+	hndl::InitWindow( r::w, r::h, "GODlike's Engine" );
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+	main_cam.camera_data_user_class_t::SetName("main_cam");
+
+	point_lights[0].SetSpecularColor( vec3_t( 0.4, 0.4, 0.4) );
+	point_lights[0].SetDiffuseColor( vec3_t( 1.0, 1.0, 1.0) );
+	point_lights[0].local_translation = vec3_t( .6, 0., 0.0 );
+	point_lights[0].radius = 4.0;
+
+	imp.Load( "meshes/sarge/sarge.mesh" );
+	imp.local_translation = vec3_t( 0.0, 2.11, 0.0 );
+	imp.local_scale = 0.7;
+	imp.local_rotation.RotateXAxis( -PI/2 );
+
+	mcube.Load( "meshes/cube/cube.mesh" );
+	mcube.local_translation = vec3_t( 0, 0, 0 );
+	mcube.local_scale = 0.5;
+
+	scene::Register( (object_t*)&imp );
+	scene::Register( (object_t*)&mcube );
+	scene::Register( &main_cam );
+	scene::Register( &point_lights[0] );
+
+	glMaterialfv( GL_FRONT, GL_AMBIENT, &vec4_t( 0.1, 0.1, 0.1, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_DIFFUSE, &vec4_t( 0.5, 0.0, 0.0, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_SPECULAR, &vec4_t( 1., 1., 1., 0.1 )[0] );
+	glMaterialf( GL_FRONT, GL_SHININESS, 100.0 );
+
+
+	shdr_norm = ass::LoadShdr( "shaders/old/test_normalmaping.shdr" );
+
+	imp.material->shader = shdr_norm;
+	mcube.material->shader = shdr_norm;
+
+
+	/************************************************************************************************************************************
+	*																													MAIN LOOP                                                                 *
+	*************************************************************************************************************************************/
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.1;
+		float ang = ToRad(2.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_2 ] ) mover = &point_lights[0];
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		if( i::keys[SDLK_k] ) main_cam.LookAtPoint( point_lights[0].world_translation );
+
+		mover->local_rotation.Reorthogonalize();
+
+		scene::InterpolateAllModels();
+		scene::UpdateAllWorldStuff();
+
+
+		glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
+		r::SetProjectionViewMatrices( main_cam );
+		r::SetViewport( 0, 0, r::w, r::h );
+
+		glDisable( GL_BLEND );
+		glEnable( GL_DEPTH_TEST );
+
+		r::PrintLastError();
+
+
+
+		for( uint i=0; i<scene::objects.size(); i++ )
+		{
+			object_t* obj = scene::objects[i];
+			if( obj->type == object_t::MESH )
+			{
+				shdr_norm->Bind();
+
+				glPushMatrix();
+				glLoadIdentity();
+
+				obj->material->diffuse_map->BindToTxtrUnit(0);
+				glUniform1i( shdr_norm->GetUniLocation("diffuse_map"), 0 );
+				obj->material->normal_map->BindToTxtrUnit(1);
+				glUniform1i( shdr_norm->GetUniLocation("normal_map"), 1 );
+
+				vec3_t light_pos_eye_space = main_cam.GetViewMatrix() * point_lights[0].world_translation;
+				glLightfv( GL_LIGHT0, GL_POSITION, &vec4_t(light_pos_eye_space, 1.0)[0] );
+
+				glLightfv( GL_LIGHT0, GL_DIFFUSE,  &(vec4_t( point_lights[0].GetDiffuseColor(), 1.0 ))[0] );
+				glLightfv( GL_LIGHT0, GL_SPECULAR,  &(vec4_t( point_lights[0].GetSpecularColor(), 1.0 ))[0] );
+
+				glPopMatrix();
+
+				obj->Render();
+
+				mesh_t* mesh = static_cast<mesh_t*>( obj );
+				r::NoShaders();
+				//mesh->RenderNormals();
+				//mesh->RenderTangents();
+			}
+			else
+			{
+				r::NoShaders();
+				obj->Render();
+			}
+		}
+
+
+		// print some debug stuff
+		hud::SetColor( vec4_t(1.0, 1.0, 1.0, 1.0) );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		if( i::keys[SDLK_F12] ) r::TakeScreenshot( "gfx/screenshot.tga" );
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	INFO( "Appl quits after " << hndl::GetTicks() << " ticks" );
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 190 - 0
src/old_src/main_parallax.cpp

@@ -0,0 +1,190 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "mesh.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "scene.h"
+#include "scanner.h"
+#include "skybox.h"
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 100.0 );
+
+point_light_t point_lights[10];
+proj_light_t projlights[2];
+
+mesh_t floor__;
+
+shader_prog_t* shdr_parallax;
+
+texture_t* diffuse_map, * normal_map, * height_map;
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	MathSanityChecks();
+
+	hndl::InitWindow( r::w, r::h, "AnKi Engine" );
+	r::Init();
+	hud::Init();
+
+
+	main_cam.MoveLocalZ( 2 );
+	main_cam.camera_data_user_class_t::SetName("main_cam");
+
+	point_lights[0].SetSpecularColor( vec3_t( 0.4, 0.4, 0.4) );
+	point_lights[0].SetDiffuseColor( vec3_t( 1.0, .0, .0)*10 );
+	//point_lights[0].translation_lspace = vec3_t( -1.0, 0.3, 1.0 );
+	point_lights[0].radius = 4.0;
+
+
+	floor__.Load( "meshes/test3/Plane.mesh" );
+	diffuse_map = ass::LoadTxtr( "textures/stone.001.diff.tga" );
+	normal_map = ass::LoadTxtr( "textures/stone.001.norm.tga" );
+	height_map = ass::LoadTxtr( "textures/stone.001.height.tga" );
+
+	shdr_parallax = ass::LoadShdr( "shaders/old/parallax.shdr" );
+
+
+	scene::Register( &floor__ );
+	scene::Register( &point_lights[0] );
+	scene::Register( &main_cam );
+
+	/************************************************************************************************************************************
+	*																													MAIN LOOP                                                                 *
+	*************************************************************************************************************************************/
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_2 ] ) mover = &point_lights[0];
+		if( i::keys[ SDLK_3 ] ) mover = &floor__;
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->scale_lspace += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->scale_lspace -= scale ;
+
+		if( i::keys[SDLK_k] ) main_cam.LookAtPoint( point_lights[0].translation_wspace );
+
+		mover->rotation_lspace.Reorthogonalize();
+
+		scene::InterpolateAllModels();
+		scene::UpdateAllWorldStuff();
+
+
+		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+		glEnable( GL_DEPTH_TEST );
+		r::SetViewport( 0, 0, r::w, r::h );
+		r::SetProjectionViewMatrices( main_cam );
+		r::NoShaders();
+
+		//r::RenderGrid();
+
+		shdr_parallax->Bind();
+
+		shdr_parallax->LocTexUnit( "texture", *(diffuse_map), 0 );
+		shdr_parallax->LocTexUnit( "heightMap", *(height_map), 1 );
+		shdr_parallax->LocTexUnit( "normalMap", *(normal_map), 2 );
+
+		glUniform3fv( shdr_parallax->GetUniLocation("lightPos"), 1, &(main_cam.GetViewMatrix() * point_lights[0].translation_wspace)[0] );
+		//glUniformMatrix4fv( shdr_parallax->GetUniLocation("model"), 1, true, &floor__.transformation_wspace[0] );
+		//glUniform3fv( shdr_parallax->GetUniLocation("eyePosition"), 1, &(main_cam.translation_wspace)[0] );
+
+
+		//floor__.Render();
+		{
+			glPushMatrix();
+			//floor__.transformation_wspace.Set( m3 );
+			r::MultMatrix( floor__.transformation_wspace );
+
+			//GLuint loc = shdr_parallax->GetAttrLocation( "tangent" );
+
+			glEnableClientState( GL_VERTEX_ARRAY );
+			glEnableClientState( GL_NORMAL_ARRAY );
+			glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+			//glEnableVertexAttribArray( loc );
+
+			glVertexPointer( 3, GL_FLOAT, sizeof(vertex_t), &floor__.mesh_data->verts[0].coords[0] );
+			glNormalPointer( GL_FLOAT, sizeof(vertex_t), &floor__.mesh_data->verts[0].normal[0] );
+			glTexCoordPointer( 2, GL_FLOAT, 0, &floor__.mesh_data->uvs[0] );
+			//glVertexAttribPointer( loc, 4, GL_FLOAT, 0, 0, &floor__.mesh_data->vert_tangents[0] );
+
+			glDrawElements( GL_TRIANGLES, floor__.mesh_data->vert_list.size(), GL_UNSIGNED_SHORT, &floor__.mesh_data->vert_list[0] );
+
+			glDisableClientState( GL_VERTEX_ARRAY );
+			glDisableClientState( GL_NORMAL_ARRAY );
+			glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+			//glDisableVertexAttribArray( loc );
+
+			glPopMatrix();
+		}
+
+
+
+		r::dbg::RunStage( main_cam );
+
+
+		// print some debug stuff
+		hud::SetColor( vec4_t(1.0, 1.0, 1.0, 1.0) );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		if( i::keys[SDLK_F12] == 1 ) r::TakeScreenshot("gfx/screenshot.tga");
+//		char str[128];
+//		sprintf( str, "capt/%05d.tga", r::frames_num );
+//		r::TakeScreenshot(str);
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	INFO( "Appl quits after " << hndl::GetTicks() << " ticks" );
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 364 - 0
src/old_src/main_particles.cpp

@@ -0,0 +1,364 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+using namespace std;
+
+
+light_t light0;
+light_t light1;
+
+shader_prog_t shaderp;
+
+bsphere_t bsph;
+bsphere_t bsph1;
+
+aabb_t aabb;
+aabb_t aabb1;
+
+plane_t plane;
+
+ray_t ray;
+
+lineseg_t seg;
+
+obb_t obb;
+obb_t obb1;
+
+texture_t tex_normal[3];
+texture_t tex_color[3];
+
+mesh_data_t mesh_d[3];
+mesh_t mesh[3];
+
+
+class test_obj_t: public object_t
+{
+	public:
+		void Render()
+		{
+			UpdateWorldTransform();
+			glPushMatrix();
+
+			mat4_t transform( mat4_t::TRS(world_translate, world_rotate, world_scale) );
+			transform.Transpose();
+			glMultMatrixf( &transform(0,0) );
+
+			r::SetGLState_Solid();
+			glColor3fv( &vec3_t( 0.0, 1.0, 0.0 ).Normalized()[0] );
+
+			r::RenderCube();
+
+			r::SetGLState_Solid();
+			glPopMatrix();
+		}
+} test;
+
+
+class _t
+{
+	public:
+		int x;
+		_t(): x(10) {}
+		_t( int x_ ): x(x_) {}
+		~_t() {}
+};
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	array_t<_t> asdfasdf;
+	asdfasdf.Malloc( 2 );
+	INFO( asdfasdf[0].x );
+
+	mem::PrintInfo( mem::PRINT_HEADER );
+	mem::Enable( mem::PRINT_ERRORS | mem::THREADS );
+	MathCompilerTest();
+	hndl::InitWindow( r::w, r::h, "Malice Engine" );
+	mem::PrintInfo( mem::PRINT_HEADER );
+	r::Init();
+	hud::Init();
+
+	cam.CalcCullingPlanes();
+	cam.MoveY( 2.5 );
+	cam.MoveZ( 5.0f );
+
+	particle_emitter_t pem;
+	pem.Init();
+
+	/*
+	=======================================================================================================================================
+	initialize the TESTS                                                                                                                  =
+	=======================================================================================================================================
+	*/
+	tex_normal[0].Load( "meshes/sarge/body_local.tga" );
+	tex_color[0].Load( "meshes/sarge/body.tga" );
+	mesh_d[0].Load( "meshes/sarge/mesh.txt" );
+	mesh[0].mesh_data = &mesh_d[0];
+	mesh[0].local_translate = vec3_t( -5.0, -1, 10 );
+
+	tex_normal[1].Load( "meshes/test/normal.tga" );
+	tex_color[1].Load( "meshes/test/color.tga" );
+	mesh_d[1].Load( "meshes/test/mesh.txt" );
+	mesh[1].mesh_data = &mesh_d[1];
+	mesh[1].local_translate = vec3_t( -2.0, 0, 0 );
+
+
+	tex_normal[2].Load( "meshes/test2/normal.tga" );
+	tex_color[2].Load( "meshes/test2/color.tga" );
+	mesh_d[2].Load( "meshes/test2/mesh.txt" );
+	mesh[2].mesh_data = &mesh_d[2];
+	mesh[2].local_translate = vec3_t( 3.0, 0, 0 );
+
+
+	bsph.Set( &mesh[0].mesh_data->verts[0], sizeof(vertex_t), mesh[0].mesh_data->verts.size );
+
+	aabb.Set( &mesh[0].mesh_data->verts[0], sizeof(vertex_t), mesh[0].mesh_data->verts.size );
+
+
+	bsph1.radius = 1.0f;
+	bsph1.center = vec3_t( -5.0, 0.0, 10.0 );
+
+	plane.normal = vec3_t(0.0, 0.0, 1.0).Normalized();
+	plane.offset = -10.0f;
+
+	aabb1.min = vec3_t( -10, 1, 10 );
+	aabb1.max = vec3_t( -9, 3, 12 );
+
+	ray = ray_t( vec3_t(0, 1, 0), vec3_t(0, 0, -1).Normalized() );
+
+	seg = lineseg_t( vec3_t(0, 4, -1.0), vec3_t(0, 0, -3) );
+
+	obb.Set( &mesh[0].mesh_data->verts[0], sizeof(vertex_t), mesh[0].mesh_data->verts.size );
+	obb1.center = vec3_t(0, 0, 10.0f);  obb1.extends = vec3_t(0.5, 2, 1); obb1.rotation.LoadEuler( euler_t(PI/8, 0, 0) );
+
+	// shaders
+	//shaderp.LoadCompileLink( "shaders/test.vert", "shaders/test.frag" ); LALA
+	//shaderp.LoadCompileLink( "shaders/spec3l.vert", "shaders/spec3l.frag" );
+	//                                                                        /
+
+
+	// lights                                                                 /
+	light0.SetAmbient( vec4_t( 0.1, 0.1, 0.1, 1.0 ) );
+	light0.SetDiffuse( vec4_t( 0.5, 0.5, 0.5, 1 ) );
+	light0.SetSpecular( vec4_t( 1.5, 1.5, 1.5, 1.0 ) );
+	light0.local_translate = vec3_t( 0, 1.2, 4.0 );
+
+	light1.SetAmbient( vec4_t( 0.3, 0.1, 0.1, 1.0 ) );
+	light1.SetDiffuse( vec4_t( 0.0, 0.0, 0.0, 1.0 ) );
+	light1.SetSpecular( vec4_t( 1.0, 1.1, .1, 1.0 ) );
+	light1.local_translate = vec3_t( 3., 1.2, 5. );
+
+	//                                                                        /
+
+	//light0.parent = &cam;
+
+	do
+	{
+		StartBench();
+
+		i::HandleEvents();
+		r::Run();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &cam;
+		else if( i::keys[ SDLK_2 ] ){ mover = &mesh[0];}
+		else if( i::keys[ SDLK_3 ] ) mover = &light0;
+		else if( i::keys[ SDLK_4 ] ) mover = &test;
+
+		if( mover == &mesh[0] ) dist=0.04;
+
+		if( i::keys[SDLK_a] ) mover->MoveX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		mover->local_rotate.Reorthogonalize();
+
+		cam.Render();
+
+
+		light0.Render();
+		light1.Render();
+
+		r::RenderGrid();
+
+		//pem.Render();
+
+		///////////////////////////////////////////////////////////////////////
+
+
+		//test.Render();
+
+
+
+
+		// multitexture
+
+		//shaderp.Use(); LALA
+
+
+		glMaterialfv( GL_FRONT, GL_SPECULAR, &vec4_t( .8, 0.5, 0.5, 1.0)[0] );
+		glMaterialfv( GL_FRONT, GL_DIFFUSE, &vec4_t(1, 1, 1, 1.0)[0] );
+		glMaterialfv( GL_FRONT, GL_AMBIENT, &vec4_t(1, 1, 1, 1.0)[0] );
+		glMaterialf( GL_FRONT, GL_SHININESS, 7.0 );
+
+		glActiveTextureARB(GL_TEXTURE1_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_normal[0].id);
+		glActiveTextureARB(GL_TEXTURE0_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_color[0].id);
+
+
+		//glUniform1i( shaderp.GetUniLocation("color_map"), 0 ); LALA
+		//glUniform1i( shaderp.GetUniLocation("normal_map"), 1 ); LALA
+
+
+//		int light_ids[3] = {0, -1, -1};
+//		glUniform1iv( shaderp.GetUniLocation("light_ids"), 3, light_ids );
+
+
+		// material and shader
+
+
+		mesh[0].Render();
+
+
+		glActiveTextureARB(GL_TEXTURE1_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_normal[1].id);
+		glActiveTextureARB(GL_TEXTURE0_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_color[1].id);
+
+		//shaderp.Use(); LALA
+		mesh[1].Render();
+
+
+
+		// render mesh 2
+		glActiveTextureARB(GL_TEXTURE1_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_normal[2].id);
+		glActiveTextureARB(GL_TEXTURE0_ARB);
+		glBindTexture(GL_TEXTURE_2D, tex_color[2].id);
+
+		//shaderp.Use(); LALA
+		mesh[2].Render();
+
+		r::NoShaders();
+
+
+		//////////////////////////////////////////////////////////////////////
+
+		//plane.Render();
+
+		bsphere_t bshp_trf( bsph.Transformed( mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale ) );
+		bshp_trf.Render();
+		bsph1.Render();
+
+		aabb_t aabb_transf( aabb.Transformed( mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale ) );
+		//aabb_transf.Render();
+		aabb1.Render();
+
+		ray_t ray_transf( ray.Transformed( mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale ) );
+		ray_transf.Render();
+
+		lineseg_t seg_transf( seg.Transformed( mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale ) );
+		seg_transf.Render();
+		//bvolume_t* bv = &seg_transf;
+		//bv->Render();
+
+
+		//obb.Render();
+		obb_t obb_transf( obb.Transformed(mesh[0].world_translate, mesh[0].world_rotate, mesh[0].world_scale) );
+		//obb_transf.Render();
+		obb1.Render();
+
+
+
+		hud::SetPos( -0.98, 0.6 );
+		hud::SetFontWidth( 0.03 );
+		hud::SetColor( &vec4_t(1,1,1,1)[0] );
+		if( bsph1.Intersects(bshp_trf) )  hud::Printf( "collision sphere-sphere\n" );
+		if( aabb1.Intersects(ray_transf) )  hud::Printf( "collision ray-aabb\n" );
+		if( bsph1.Intersects( ray_transf ) )  hud::Printf( "collision ray-sphere\n" );
+		if( obb1.Intersects(obb_transf) )  hud::Printf( "collision obb-obb\n" );
+		if( bsph1.Intersects(seg_transf) )  hud::Printf( "collision seg-sphere\n" );
+		if( aabb1.Intersects(seg_transf) )  hud::Printf( "collision seg-aabb\n" );
+		if( aabb1.Intersects(bshp_trf) )  hud::Printf( "collision aabb-sphere\n" );
+		if( obb1.Intersects( bshp_trf ) )  hud::Printf( "collision obb-sphere\n" );
+
+		hud::SetColor( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+		if( obb1.Intersects( ray_transf ) )  hud::Printf( "collision obb-ray\n" );
+		if( obb1.Intersects( seg_transf ) )  hud::Printf( "collision obb-segment\n" );
+		hud::SetColor( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+
+		vec3_t normal, impact_p;
+		float depth;
+		//aabb1.SeparationTest( aabb_transf, normal, impact_p, depth );
+		//bsph1.SeparationTest( bshp_trf, normal, impact_p, depth );
+		//aabb1.SeparationTest( bshp_trf, normal, impact_p, depth );
+		bshp_trf.SeperationTest( obb1, normal, impact_p, depth );
+		//bshp_trf.SeperationTest( aabb1, normal, impact_p, depth );
+
+		hud::SetColor( &vec4_t(0.0, 1.0, 0.0, 0.5)[0] );
+		hud::SetFontWidth( 0.035 );
+
+
+//		hud::Printf( "plane-aabb dist: %f\n", aabb_transf.PlaneTest(plane) );
+//		hud::Printf( "plane-shpere dist: %f\n", bshp_trf.PlaneTest(plane) );
+//		hud::Printf( "plane-obb dist: %f\n", obb_transf.PlaneTest(plane) );
+
+		//test.Render();
+
+
+		/////////////////////////////////////////////////////////////////////
+
+		// print some debug stuff
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+		HudPrintMemInfo();
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		hndl::WaitForNextTick();
+	}while( true );
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 270 - 0
src/old_src/main_project_txtr.cpp

@@ -0,0 +1,270 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "level.h"
+#include "scanner.h"
+
+light_t lights[1];
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 100.0 );
+camera_t light_cam( ToRad(90.0), ToRad(90.0), 0.10, 10.0 );
+
+class cube_t: public object_t
+{
+	public:
+		cube_t()
+		{
+			local_translation = vec3_t( 3.2, 0.05, 1.75 );
+			local_scale = 2.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1.0, 0.0, 1) );
+			r::RenderCube( true );
+
+			glPopMatrix();
+		}
+}cube;
+
+
+class shpere_t: public object_t
+{
+	public:
+		shpere_t()
+		{
+			local_translation = vec3_t( -1.2, 1.05, -1.75 );
+			local_scale = 1.5;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 0.5, 0.25, 1) );
+			r::RenderSphere( 1.0, 32 );
+
+			glPopMatrix();
+		}
+}sphere;
+
+
+class flore_t: public object_t
+{
+	public:
+		flore_t()
+		{
+			local_scale = 10.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1., 1., 1) );
+
+			glNormal3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+			glBegin( GL_QUADS );
+				glVertex3f( 1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, 1.0 );
+				glVertex3f( 1.0, 0.0, 1.0 );
+			glEnd();
+
+			glPopMatrix();
+		}
+}flore;
+
+
+texture_t* proj;
+
+shader_prog_t* shdr, *shdr1;
+
+#define SHADOW_QUALITY 512
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	//mem::Enable( mem::THREADS );
+	MathSanityChecks();
+
+	hndl::InitWindow( r::w, r::h, "mAlice Engine" );
+	scn::Init();
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+
+	/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// initialize the TESTS
+	lights[0].SetAmbient( vec4_t( 0.4, 0.9, 0.4, 1.0 ) );
+	lights[0].SetDiffuse( vec4_t( 1.0, 1.0, 1.0, 1.0 ) );
+	lights[0].local_translation = vec3_t( -1.0, 1.0, 1.0 );
+	lights[0].type = light_t::DIRECTIONAL;
+	//lights[0].SetCutOff( 0.0 );
+	//lights[0].SetExp( 120.0 );
+
+	proj = ass::LoadTxtr( "gfx/flashlight.tga" );
+
+	lights[0].MakeParent( &light_cam );
+	//light_cam.RotateLocalY( -PI/2 );
+
+	shdr = ass::LoadShdr( "shaders/test.shdr" );
+	//shdr1 = ass::LoadShdr( "shaders/glass.shader" );
+
+	glMaterialfv( GL_FRONT, GL_AMBIENT, &vec4_t( 0.1, 0.1, 0.1, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_DIFFUSE, &vec4_t( 0.5, 0.0, 0.0, 0.1 )[0] );
+	glMaterialfv( GL_FRONT, GL_SPECULAR, &vec4_t( 1., 1., 1., 0.1 )[0] );
+	glMaterialf( GL_FRONT, GL_SHININESS, 120.0 );
+
+	/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+	lvl::Register( (object_t*)&cube );
+	lvl::Register( (object_t*)&sphere );
+	lvl::Register( (object_t*)&flore );
+	lvl::Register( &lights[0] );
+	lvl::Register( &main_cam );
+	lvl::Register( &light_cam );
+
+	light_cam.MakeParent( &main_cam );
+
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_3 ] ) mover = &lights[0];
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		mover->local_rotation.Reorthogonalize();
+
+		lvl::InterpolateAllModels();
+		//lvl::UpdateAllLights();
+		lvl::UpdateAllWorldTrfs();
+		lvl::UpdateAllCameras();
+
+		// RENDER
+		glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		r::SetProjectionViewMatrices( main_cam );
+		r::SetViewport( 0, 0, r::w, r::h );
+		lvl::UpdateAllLights();
+
+		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+		glDisable(GL_POLYGON_OFFSET_FILL);
+
+		//r::RenderGrid();
+		r::SetGLState_Solid();
+		glEnable( GL_LIGHTING );
+
+		shdr->Bind();
+
+		//glUniform1i( shdr->GetUniLocation("t0"), 0 );
+
+		glActiveTexture( GL_TEXTURE0 + 0 );
+		proj->Bind();
+
+		const float mBias[] = {0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0};
+		glMatrixMode( GL_TEXTURE );
+		glLoadMatrixf( mBias );
+		r::MultMatrix( light_cam.projection_mat );
+		r::MultMatrix( light_cam.view_mat );
+		r::MultMatrix( main_cam.world_transformation );
+		glMatrixMode(GL_MODELVIEW);
+
+		lvl::RenderAll();
+
+		shdr1->UnBind();
+		glMatrixMode( GL_TEXTURE );
+		glLoadIdentity();
+		glMatrixMode(GL_MODELVIEW);
+
+		// Debug stuff
+//		r::SetGLState_Solid();
+//		glEnable( GL_TEXTURE_2D );
+//		glDisable( GL_LIGHTING );
+//		depth_map.Bind();
+//		float size = 2.0f;
+//		r::Color3( vec3_t( 1.0, 1.0, 1.0 ) );
+//		glBegin(GL_QUADS);
+//			glNormal3f( 0.0f, 0.0f, 1.0f);
+//			glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size,  -5);
+//			glTexCoord2f(1.0, 0.0); glVertex3f( size, -size,  -5);
+//			glTexCoord2f(1.0, 1.0); glVertex3f( size,  size,  -5);
+//			glTexCoord2f(0.0, 1.0); glVertex3f(-size,  size,  -5);
+//		glEnd();
+		// END RENDER
+
+
+		// print some debug stuff
+		hud::SetColor( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	cout << "Appl quits after " << hndl::GetTicks() << " ticks" << endl;
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 274 - 0
src/old_src/main_projection_test.cpp

@@ -0,0 +1,274 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "level.h"
+#include "scanner.h"
+#include "fbos.h"
+#include "skybox.h"
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 200.0 );
+
+class cube_t: public object_t
+{
+	public:
+		cube_t()
+		{
+			local_translation = vec3_t( 3.2, 0.05, 1.75 );
+			local_scale = 2.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1.0, 0.0, 1) );
+
+			r::RenderCube( true );
+
+			glPopMatrix();
+		}
+}cube;
+
+
+class shpere_t: public object_t
+{
+	public:
+		shpere_t()
+		{
+			local_translation = vec3_t( -1.2, 1.05, -1.75 );
+			local_scale = 1.5;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 0.5, 0.25, 1) );
+
+			r::RenderSphere( 1.0, 32 );
+
+			glPopMatrix();
+		}
+}sphere;
+
+
+class flore_t: public object_t
+{
+	public:
+		flore_t()
+		{
+			local_scale = 10.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1., 1., 1) );
+
+			glNormal3fv( &vec3_t( 0.0, 1.0, 0.0 )[0] );
+			glBegin( GL_QUADS );
+				glVertex3f( 1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, 1.0 );
+				glVertex3f( 1.0, 0.0, 1.0 );
+			glEnd();
+
+			glPopMatrix();
+		}
+}flore;
+
+
+vec3_t point( 1.0, 2.0, 0.5 );
+
+
+skybox_t skybox;
+
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	//mem::Enable( mem::THREADS );
+	MathSanityChecks();
+
+	hndl::InitWindow( r::w, r::h, "GODlike's Engine" );
+	scn::Init();
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+
+	lvl::Register( (object_t*)&cube );
+	lvl::Register( (object_t*)&sphere );
+	lvl::Register( (object_t*)&flore );
+	lvl::Register( &main_cam );
+
+	const char* skybox_fnames [] = { "env/hellsky4_forward.tga", "env/hellsky4_back.tga", "env/hellsky4_left.tga", "env/hellsky4_right.tga",
+																	 "env/hellsky4_up.tga", "env/hellsky4_down.tga" };
+	skybox.Load( skybox_fnames );
+
+
+	/************************************************************************************************************************************
+	*																													MAIN LOOP                                                                 *
+	*************************************************************************************************************************************/
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		if( i::keys[SDLK_k] ) main_cam.LookAtPoint( point );
+
+		mover->local_rotation.Reorthogonalize();
+
+		lvl::InterpolateAllModels();
+		lvl::UpdateAllWorldTrfs();
+		lvl::UpdateAllCameras();
+
+		r::SetProjectionViewMatrices( main_cam );
+		r::SetViewport( 0, 0, r::w, r::h );
+		glClearColor( 0.1f, 0.1f, 0.2f, 0.0f );
+		glClear( GL_DEPTH_BUFFER_BIT );
+
+		skybox.Render( main_cam.view_mat.GetRotationPart() );
+
+		r::NoShaders();
+
+		glDisable( GL_BLEND );
+		glEnable( GL_DEPTH_TEST );
+		glDisable( GL_TEXTURE_2D );
+
+		lvl::RenderAll();
+
+		r::RenderGrid();
+
+		glPointSize( 10.0 );
+		glBegin( GL_POINTS );
+			r::Color3( vec3_t(1.0, 0.0, 1.0) );
+			glVertex3fv( &point[0] );
+		glEnd();
+
+
+		///                                                                                            /
+		vec4_t pos_viewspace = main_cam.view_mat * vec4_t(point, 1.0);
+		vec4_t pos_clipspace = main_cam.projection_mat * pos_viewspace;
+		vec4_t point_scrspace = pos_clipspace / pos_clipspace.w;
+
+
+		float depth;
+		glReadPixels( i::mouse_pos.x, r::h-i::mouse_pos.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
+
+
+		int viewpoint[] = {0, 0, r::w, r::h};
+		vec3_t point_rc; // point recreated
+		r::UnProject( i::mouse_pos.x, (float)viewpoint[3]-i::mouse_pos.y, depth, main_cam.view_mat, main_cam.projection_mat, viewpoint, point_rc.x, point_rc.y, point_rc.z );
+
+
+		/// test for deffered
+		// do some crap for pos_eyespace
+		vec3_t v[4];
+		{
+			//int pixels[4][2]={ { 0,0 },{0,r::h},{r::w,r::h},{r::w,0} };
+			int pixels[4][2]={ {r::w,r::h}, {0,r::h}, { 0,0 }, {r::w,0} };
+			int viewport[4]={ 0,0,r::w,r::h };
+
+			mat3_t view_rotation = main_cam.view_mat.GetRotationPart();
+
+			float d[3];
+			for( int i=0; i<4; i++ )
+			{
+				r::UnProject( pixels[i][0],pixels[i][1],10, main_cam.view_mat, main_cam.projection_mat, viewport, d[0],d[1],d[2] );
+				v[i] = vec3_t ( d[0], d[1], d[2] );
+				v[i] -= main_cam.world_translation;
+				v[i].Normalize();
+				v[i] = v[i]*view_rotation;
+			}
+		}
+
+		// operations that happen in the shader:
+		vec2_t planes;
+		planes.x = -main_cam.zfar / (main_cam.zfar - main_cam.znear);
+		planes.y = -main_cam.zfar * main_cam.znear / (main_cam.zfar - main_cam.znear);
+		point_rc.z = - planes.y / (planes.x + depth);
+
+		//vec3_t view(  )
+
+		//pos.xy = view.xy / view.z*pos.z;
+
+
+		/// print some debug stuff
+		hud::SetColor( vec4_t(1.0, 1.0, 1.0, 1.0) );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		hud::Printf( "mouse: %f %f\n", i::mouse_pos.x, i::mouse_pos.y );
+		hud::Printf( "depth: %f\n", depth );
+		hud::Printf( "wspac: %f %f %f %f\n", point.x, point.y, point.z, 1.0 );
+		hud::Printf( "vspac: %f %f %f %f\n", pos_viewspace.x, pos_viewspace.y, pos_viewspace.z, pos_viewspace.w );
+		hud::Printf( "vsp_r: %f %f %f\n", point_rc.x, point_rc.y, point_rc.z );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	INFO( "Appl quits after " << hndl::GetTicks() << " ticks" );
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 287 - 0
src/old_src/main_shadows.cpp

@@ -0,0 +1,287 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include "common.h"
+
+#include "input.h"
+#include "camera.h"
+#include "math.h"
+#include "renderer.h"
+#include "hud.h"
+#include "handlers.h"
+#include "particles.h"
+#include "primitives.h"
+#include "texture.h"
+#include "geometry.h"
+#include "shaders.h"
+#include "lights.h"
+#include "collision.h"
+#include "model.h"
+#include "spatial.h"
+#include "material.h"
+#include "assets.h"
+#include "level.h"
+
+light_t lights[1];
+
+camera_t main_cam( r::aspect_ratio*ToRad(60.0), ToRad(60.0), 0.5, 100.0 );
+camera_t light_cam( ToRad(60.0), ToRad(60.0), 0.10, 10.0 );
+
+class cube_t: public object_t
+{
+	public:
+		cube_t()
+		{
+			local_translation = vec3_t( 3.2, 0.05, 1.75 );
+			local_scale = 2.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1.0, 0.0, 1) );
+			r::RenderCube( true );
+
+			glPopMatrix();
+		}
+}cube;
+
+
+class shpere_t: public object_t
+{
+	public:
+		shpere_t()
+		{
+			local_translation = vec3_t( -1.2, 1.05, -1.75 );
+			local_scale = 1.5;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 0.5, 0.25, 1) );
+			r::RenderSphere( 1.0, 32 );
+
+			glPopMatrix();
+		}
+}sphere;
+
+
+class flore_t: public object_t
+{
+	public:
+		flore_t()
+		{
+			local_scale = 100.0;
+		}
+
+		void Render()
+		{
+			glPushMatrix();
+			r::MultMatrix( world_transformation );
+
+			r::Color4( vec4_t(1.0, 1., 1., 1) );
+
+			glBegin( GL_QUADS );
+				glVertex3f( 1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, -1.0 );
+				glVertex3f( -1.0, 0.0, 1.0 );
+				glVertex3f( 1.0, 0.0, 1.0 );
+			glEnd();
+
+			glPopMatrix();
+		}
+}flore;
+
+
+texture_t depth_map;
+
+shader_prog_t* shdr;
+
+#define SHADOW_QUALITY 512
+
+/*
+=======================================================================================================================================
+main                                                                                                                                  =
+=======================================================================================================================================
+*/
+int main( int argc, char* argv[] )
+{
+	//mem::Enable( mem::THREADS );
+	MathSanityChecks();
+	hndl::InitWindow( r::w, r::h, "mAlice Engine" );
+	r::Init();
+	hud::Init();
+
+	main_cam.MoveLocalY( 2.5 );
+	main_cam.MoveLocalZ( 5.0f );
+
+	/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// initialize the TESTS
+	lights[0].SetAmbient( vec4_t( 0.4, 0.4, 0.4, 1.0 ) );
+	lights[0].SetDiffuse( vec4_t( 1.5, 1.5, 1.0, 1.0 ) );
+	lights[0].local_translation = vec3_t( -1.0, 1.0, 1.0 );
+	lights[0].type = light_t::DIRECTIONAL;
+	//lights[0].SetCutOff( 0.0 );
+	//lights[0].SetExp( 120.0 );
+
+	depth_map.CreateEmpty( SHADOW_QUALITY, SHADOW_QUALITY, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT );
+	depth_map.TexParameter( GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
+	depth_map.TexParameter( GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );
+	depth_map.TexParameter( GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+	depth_map.TexParameter( GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+	lights[0].MakeParent( &light_cam );
+	//light_cam.RotateLocalY( -PI/2 );
+
+	shdr = ass::LoadShdr( "shaders/test.shader" );
+
+	/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+	lvl::Register( (object_t*)&cube );
+	lvl::Register( (object_t*)&sphere );
+	lvl::Register( (object_t*)&flore );
+	lvl::Register( &lights[0] );
+	lvl::Register( &main_cam );
+	lvl::Register( &light_cam );
+
+	do
+	{
+		StartBench();
+		i::HandleEvents();
+		r::PrepareNextFrame();
+
+		float dist = 0.2;
+		float ang = ToRad(3.0);
+		float scale = 0.01;
+
+		// move the camera
+		static object_t* mover = &main_cam;
+
+		if( i::keys[ SDLK_1 ] ) mover = &main_cam;
+		if( i::keys[ SDLK_3 ] ) mover = &lights[0];
+
+		if( i::keys[SDLK_a] ) mover->MoveLocalX( -dist );
+		if( i::keys[SDLK_d] ) mover->MoveLocalX( dist );
+		if( i::keys[SDLK_LSHIFT] ) mover->MoveLocalY( dist );
+		if( i::keys[SDLK_SPACE] ) mover->MoveLocalY( -dist );
+		if( i::keys[SDLK_w] ) mover->MoveLocalZ( -dist );
+		if( i::keys[SDLK_s] ) mover->MoveLocalZ( dist );
+		if( i::keys[SDLK_UP] ) mover->RotateLocalX( ang );
+		if( i::keys[SDLK_DOWN] ) mover->RotateLocalX( -ang );
+		if( i::keys[SDLK_LEFT] ) mover->RotateLocalY( ang );
+		if( i::keys[SDLK_RIGHT] ) mover->RotateLocalY( -ang );
+		if( i::keys[SDLK_q] ) mover->RotateLocalZ( ang );
+		if( i::keys[SDLK_e] ) mover->RotateLocalZ( -ang );
+		if( i::keys[SDLK_PAGEUP] ) mover->local_scale += scale ;
+		if( i::keys[SDLK_PAGEDOWN] ) mover->local_scale -= scale ;
+
+		mover->local_rotation.Reorthogonalize();
+
+		lvl::InterpolateAllModels();
+		lvl::UpdateAllLights();
+		lvl::UpdateAllWorldTrfs();
+		lvl::UpdateAllCameras();
+
+
+
+		/// RENDER 2 TXTR
+		glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+		r::SetProjectionViewMatrices( light_cam );
+		r::SetViewport( 0, 0, SHADOW_QUALITY, SHADOW_QUALITY );
+
+		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+		glPolygonOffset(4.0f, 8.0f);
+		glEnable(GL_POLYGON_OFFSET_FILL);
+
+		r::SetGLState_Solid();
+		glDisable( GL_TEXTURE_2D );
+		glDisable( GL_LIGHTING );
+		lvl::RenderAll();
+
+		glActiveTexture( GL_TEXTURE0 );
+		depth_map.Bind();
+		glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, SHADOW_QUALITY, SHADOW_QUALITY);
+
+		/// END RENDER 2 TXTR
+
+
+		// RENDER
+		glClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		r::SetProjectionViewMatrices( main_cam );
+		r::SetViewport( 0, 0, r::w, r::h );
+		lvl::UpdateAllLights();
+
+		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+		glDisable(GL_POLYGON_OFFSET_FILL);
+
+		//r::RenderGrid();
+		r::SetGLState_Solid();
+
+		shdr->TurnOn();
+
+		glActiveTexture( GL_TEXTURE0 + 0 );
+		depth_map.Bind();
+
+		const float mBias[] = {0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0};
+
+		glMatrixMode(GL_TEXTURE);
+		glLoadMatrixf( mBias );
+		r::MultMatrix( light_cam.projection_mat );
+		r::MultMatrix( light_cam.view_mat );
+		r::MultMatrix( main_cam.world_transformation );
+
+		glMatrixMode(GL_MODELVIEW);
+
+		glUniform1i( shdr->GetUniLocation( "s0" ), 0 );
+
+		lvl::RenderAll();
+
+		shdr->TurnOff();
+		glMatrixMode( GL_TEXTURE );
+		glLoadIdentity();
+		glMatrixMode(GL_MODELVIEW);
+
+		// Debug stuff
+//		r::SetGLState_Solid();
+//		glEnable( GL_TEXTURE_2D );
+//		glDisable( GL_LIGHTING );
+//		depth_map.Bind();
+//		float size = 2.0f;
+//		r::Color3( vec3_t( 1.0, 1.0, 1.0 ) );
+//		glBegin(GL_QUADS);
+//			glNormal3f( 0.0f, 0.0f, 1.0f);
+//			glTexCoord2f(0.0, 0.0); glVertex3f(-size, -size,  -5);
+//			glTexCoord2f(1.0, 0.0); glVertex3f( size, -size,  -5);
+//			glTexCoord2f(1.0, 1.0); glVertex3f( size,  size,  -5);
+//			glTexCoord2f(0.0, 1.0); glVertex3f(-size,  size,  -5);
+//		glEnd();
+		// END RENDER
+
+
+		// print some debug stuff
+		hud::SetColor( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+		hud::SetPos( -0.98, 0.95 );
+		hud::SetFontWidth( 0.03 );
+		hud::Printf( "frame:%d time:%dms\n", r::frames_num, StopBench() );
+
+		if( i::keys[SDLK_ESCAPE] ) break;
+		if( i::keys[SDLK_F11] ) hndl::TogleFullScreen();
+		SDL_GL_SwapBuffers();
+		r::PrintLastError();
+		hndl::WaitForNextFrame();
+		//if( r::frames_num == 5000 ) break;
+	}while( true );
+
+	cout << "Appl quits after " << hndl::GetTicks() << " ticks" << endl;
+
+	hndl::QuitApp( EXIT_SUCCESS );
+	return 0;
+}

+ 2365 - 0
src/old_src/math.cpp

@@ -0,0 +1,2365 @@
+#include "math.h"
+
+#define ME (*this)
+
+
+/**
+=======================================================================================================================================
+misc                                                                                                                                  =
+=======================================================================================================================================
+*/
+
+// MathSanityChecks
+// test if the compiler keeps the correct sizes for the classes
+void MathSanityChecks()
+{
+	const int fs = sizeof(float); // float size
+	if( sizeof(vec2_t)!=fs*2 || sizeof(vec3_t)!=fs*3 || sizeof(vec4_t)!=fs*4 || sizeof(quat_t)!=fs*4 || sizeof(euler_t)!=fs*3 ||
+	    sizeof(mat3_t)!=fs*9 || sizeof(mat4_t)!=fs*16 )
+		FATAL("Your compiler does class alignment. Quiting");
+}
+
+
+// 1/sqrt(f)
+float InvSqrt( float f )
+{
+#ifdef WIN32
+	float fhalf = 0.5f*f;
+	int i = *(int*)&f;
+	i = 0x5F3759DF - (i>>1);
+	f = *(float*)&i;
+	f *= 1.5f - fhalf*f*f;
+	return f;
+#elif defined( _DEBUG_ )
+	return 1/sqrtf(f);
+#else
+	float fhalf = 0.5f*f;
+	asm
+	(
+		"mov %1, %%eax;"
+		"sar %%eax;"
+		"mov $0x5F3759DF, %%ebx;"
+		"sub %%eax, %%ebx;"
+		"mov %%ebx, %0"
+		:"=g"(f)
+		:"g"(f)
+		:"%eax", "%ebx"
+	);
+	f *= 1.5f - fhalf*f*f;
+	return f;
+#endif
+}
+
+
+// PolynomialSinQuadrant
+// used in SinCos
+#if !defined(_DEBUG_)
+static float PolynomialSinQuadrant(float a)
+{
+	return a * ( 1.0f + a * a * (-0.16666f + a * a * (0.0083143f - a * a * 0.00018542f)));
+}
+#endif
+
+
+// Sine and Cosine
+void SinCos( float a, float& sina, float& cosa )
+{
+#ifdef _DEBUG_
+	sina = sin(a);
+	cosa = cos(a);
+#else
+	bool negative = false;
+	if (a < 0.0f)
+	{
+		a = -a;
+		negative = true;
+	}
+	const float k_two_over_pi = 1.0f / (PI/2.0f);
+	float float_a = k_two_over_pi * a;
+	int int_a = (int)float_a;
+
+	const float k_rational_half_pi = 201 / 128.0f;
+	const float k_remainder_half_pi = 4.8382679e-4f;
+
+	float_a = (a - k_rational_half_pi * int_a) - k_remainder_half_pi * int_a;
+
+	float float_a_minus_half_pi = (float_a - k_rational_half_pi) - k_remainder_half_pi;
+
+	switch( int_a & 3 )
+	{
+	case 0: // 0 - Pi/2
+		sina = PolynomialSinQuadrant(float_a);
+		cosa = PolynomialSinQuadrant(-float_a_minus_half_pi);
+		break;
+	case 1: // Pi/2 - Pi
+		sina = PolynomialSinQuadrant(-float_a_minus_half_pi);
+		cosa = PolynomialSinQuadrant(-float_a);
+		break;
+	case 2: // Pi - 3Pi/2
+		sina = PolynomialSinQuadrant(-float_a);
+		cosa = PolynomialSinQuadrant(float_a_minus_half_pi);
+		break;
+	case 3: // 3Pi/2 - 2Pi
+		sina = PolynomialSinQuadrant(float_a_minus_half_pi);
+		cosa = PolynomialSinQuadrant(float_a);
+		break;
+	};
+
+	if( negative )
+		sina = -sina;
+#endif
+}
+
+
+/*
+=======================================================================================================================================
+vec2_t                                                                                                                                =
+=======================================================================================================================================
+*/
+vec2_t vec2_t::zero = vec2_t(0.0, 0.0);
+
+// constructor [vec3]
+vec2_t::vec2_t( const vec3_t& v )
+{
+	x = v.x;
+	y = v.y;
+}
+
+// constructor [vec4]
+vec2_t::vec2_t( const vec4_t& v )
+{
+	x = v.x;
+	y = v.y;
+}
+
+// copy
+vec2_t& vec2_t::operator =( const vec2_t & b )
+{
+	x = b.x;
+	y = b.y;
+	return ME;
+}
+
+// +
+vec2_t vec2_t::operator +( const vec2_t& b ) const
+{
+	return vec2_t( x+b.x, y+b.y );
+}
+
+// +=
+vec2_t& vec2_t::operator +=( const vec2_t& b )
+{
+	x += b.x;
+	y += b.y;
+	return ME;
+}
+
+// -
+vec2_t vec2_t::operator -( const vec2_t& b ) const
+{
+	return vec2_t( x-b.x, y-b.y );
+}
+
+// -=
+vec2_t& vec2_t::operator -=( const vec2_t& b )
+{
+	x -= b.x;
+	y -= b.y;
+	return ME;
+}
+
+// negative
+vec2_t vec2_t::operator -() const
+{
+	return vec2_t( -x, -y );
+}
+
+// *
+vec2_t vec2_t::operator *( const vec2_t& b ) const
+{
+	return vec2_t( x*b.x, y*b.y );
+}
+
+// *=
+vec2_t& vec2_t::operator *=( const vec2_t& b )
+{
+	x *= b.x;
+	y *= b.y;
+	return ME;
+}
+
+// /
+vec2_t vec2_t::operator /( const vec2_t& b ) const
+{
+	return vec2_t( x/b.x, y/b.y );
+}
+
+// /=
+vec2_t& vec2_t::operator /=( const vec2_t& b )
+{
+	x /= b.x;
+	y /= b.y;
+	return ME;
+}
+
+// scale
+vec2_t vec2_t::operator *( float f ) const
+{
+	return vec2_t( x*f, y*f );
+}
+
+// scale
+vec2_t& vec2_t::operator *=( float f )
+{
+	x *= f;
+	y *= f;
+	return ME;
+}
+
+// scale
+vec2_t vec2_t::operator /( float f ) const
+{
+	DEBUG_ERR( IsZero(f) ); // division by zero
+	return vec2_t( x/f,  y/f );
+}
+
+// scale
+vec2_t& vec2_t::operator /=( float f )
+{
+	DEBUG_ERR( IsZero(f) ); // division by zero
+	x /= f;
+	y /= f;
+	return ME;
+}
+
+// ==
+bool vec2_t::operator ==( const vec2_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) ) ? true : false;
+}
+
+// !=
+bool vec2_t::operator !=( const vec2_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) ) ? false : true;
+}
+
+// Length
+float vec2_t::Length() const
+{
+	return Sqrt( x*x + y*y );
+}
+
+// set to zero
+void vec2_t::SetZero()
+{
+	x = y = 0.0f;
+}
+
+// Normalize
+void vec2_t::Normalize()
+{
+	ME *= InvSqrt( x*x + y*y );
+}
+
+// Normalized (return the normalized)
+vec2_t vec2_t::Normalized() const
+{
+	return ME * InvSqrt( x*x + y*y );
+}
+
+// Dot
+float vec2_t::Dot( const vec2_t& b ) const
+{
+	return x*b.x + y*b.y;
+}
+
+// Print
+void vec2_t::Print() const
+{
+	for( int i=0; i<2; i++ )
+		cout << fixed << ME[i] << ' ';
+	cout << "\n" << endl;
+}
+
+
+/*
+=======================================================================================================================================
+vec3_t                                                                                                                                =
+=======================================================================================================================================
+*/
+vec3_t vec3_t::zero(0.0f, 0.0f, 0.0f);
+vec3_t vec3_t::one(1.0f, 1.0f, 1.0f);
+vec3_t vec3_t::i(1.0f, 0.0f, 0.0f);
+vec3_t vec3_t::j(0.0f, 1.0f, 0.0f);
+vec3_t vec3_t::k(0.0f, 0.0f, 1.0f);
+
+// constructor [vec4]
+vec3_t::vec3_t( const vec4_t& v4 )
+{
+	x = v4.x;
+	y = v4.y;
+	z = v4.z;
+}
+
+// constructor [quaternion]
+vec3_t::vec3_t( const quat_t& q )
+{
+	x = q.x;
+	y = q.y;
+	z = q.z;
+}
+
+// copy
+vec3_t& vec3_t::operator =( const vec3_t& b )
+{
+	x = b.x;
+	y = b.y;
+	z = b.z;
+	return ME;
+}
+
+// +
+vec3_t vec3_t::operator +( const vec3_t& b ) const
+{
+	return vec3_t( x+b.x, y+b.y, z+b.z );
+}
+
+// +=
+vec3_t& vec3_t::operator +=( const vec3_t& b )
+{
+	x += b.x;
+	y += b.y;
+	z += b.z;
+	return ME;
+}
+
+// -
+vec3_t vec3_t::operator -( const vec3_t& b ) const
+{
+	return vec3_t( x-b.x, y-b.y, z-b.z );
+}
+
+// -=
+vec3_t& vec3_t::operator -=( const vec3_t& b )
+{
+	x -= b.x;
+	y -= b.y;
+	z -= b.z;
+	return ME;
+}
+
+// *
+vec3_t vec3_t::operator *( const vec3_t& b ) const
+{
+	return vec3_t( x*b.x, y*b.y, z*b.z );
+}
+
+// *=
+vec3_t& vec3_t::operator *=( const vec3_t& b )
+{
+	x *= b.x;
+	y *= b.y;
+	z *= b.z;
+	return ME;
+}
+
+// /
+vec3_t vec3_t::operator /( const vec3_t& b ) const
+{
+	return vec3_t( x/b.x, y/b.y, z/b.z );
+}
+
+// /=
+vec3_t& vec3_t::operator /=( const vec3_t& b )
+{
+	x /= b.x;
+	y /= b.y;
+	z /= b.z;
+	return ME;
+}
+
+// negative
+vec3_t vec3_t::operator -() const
+{
+	return vec3_t( -x, -y, -z );
+}
+
+// scale
+vec3_t vec3_t::operator *( float f ) const
+{
+	return vec3_t( x*f, y*f, z*f );
+}
+
+// scale
+vec3_t& vec3_t::operator *=( float f )
+{
+	x*=f;  y*=f;  z*=f;
+	return ME;
+}
+
+// down-scale
+vec3_t vec3_t::operator /( float f ) const
+{
+	DEBUG_ERR( IsZero(f) ); // division by zero
+	return vec3_t( x/f, y/f, z/f );
+}
+
+// down-scale
+vec3_t& vec3_t::operator /=( float f )
+{
+	DEBUG_ERR( IsZero(f) ); // division by zero
+	x /= f;
+	y /= f;
+	z /= f;
+	return ME;
+}
+
+// vec3 * mat3
+vec3_t vec3_t::operator *( const mat3_t& m3 ) const
+{
+	return vec3_t(
+		x*m3(0,0) + y*m3(1,0) + z*m3(2,0),
+		x*m3(0,1) + y*m3(1,1) + z*m3(2,1),
+		x*m3(0,2) + y*m3(1,2) + z*m3(2,2)
+	);
+}
+
+// ==
+bool vec3_t::operator ==( const vec3_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? true : false;
+}
+
+// !=
+bool vec3_t::operator !=( const vec3_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? false : true;
+}
+
+// Dot
+float vec3_t::Dot( const vec3_t& b ) const
+{
+	return x*b.x + y*b.y + z*b.z;
+}
+
+// cross prod
+vec3_t vec3_t::Cross( const vec3_t& b ) const
+{
+	return vec3_t( y*b.z-z*b.y, z*b.x-x*b.z, x*b.y-y*b.x );
+}
+
+// Length
+float vec3_t::Length() const
+{
+	return Sqrt( x*x + y*y + z*z );
+}
+
+// LengthSquared
+float vec3_t::LengthSquared() const
+{
+	return x*x + y*y + z*z;
+}
+
+// Normalize
+void vec3_t::Normalize()
+{
+	ME *= InvSqrt( x*x + y*y + z*z );
+}
+
+// Normalized (return the normalized)
+vec3_t vec3_t::Normalized() const
+{
+	return ME * InvSqrt( x*x + y*y + z*z );
+}
+
+// Project
+vec3_t vec3_t::Project( const vec3_t& to_this ) const
+{
+	return to_this * ( ME.Dot(to_this)/(to_this.Dot(to_this)) );
+}
+
+// Rotated
+vec3_t vec3_t::Rotated( const quat_t& q ) const
+{
+	DEBUG_ERR( !IsZero(1.0f-q.Length()) ); // Not normalized quat
+
+	/* Old code:
+	float vmult = 2.0f*(q.x*x + q.y*y + q.z*z);
+	float crossmult = 2.0*q.w;
+	float pmult = crossmult*q.w - 1.0;
+
+	return vec3_t( pmult*x + vmult*q.x + crossmult*(q.y*z - q.z*y),
+							   pmult*y + vmult*q.y + crossmult*(q.z*x - q.x*z),
+	               pmult*z + vmult*q.z + crossmult*(q.x*y - q.y*x) );*/
+
+	vec3_t q_xyz = vec3_t( q );
+	return ME + q_xyz.Cross( q_xyz.Cross( ME ) + ME*q.w ) * 2.0;
+}
+
+// Rotate
+void vec3_t::Rotate( const quat_t& q )
+{
+	ME = Rotated(q);
+}
+
+// Print
+void vec3_t::Print() const
+{
+	for( int i=0; i<3; i++ )
+		cout << fixed << ME[i] << " ";
+	cout << "\n" << endl;
+}
+
+// Lerp
+vec3_t vec3_t::Lerp( const vec3_t& v1, float t ) const
+{
+	return (ME*(1.0f-t))+(v1*t);
+}
+
+// Transformed [mat3]
+vec3_t vec3_t::Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const
+{
+	return (rotate * (ME * scale)) + translate;
+}
+
+// Transformed [mat3] no scale
+vec3_t vec3_t::Transformed( const vec3_t& translate, const mat3_t& rotate ) const
+{
+	return (rotate * ME) + translate;
+}
+
+// Transformed [quat]
+vec3_t vec3_t::Transformed( const vec3_t& translate, const quat_t& rotate, float scale ) const
+{
+	return (ME * scale).Rotated(rotate) + translate;
+}
+
+
+/*
+=======================================================================================================================================
+vec4_t                                                                                                                                =
+=======================================================================================================================================
+*/
+vec4_t vec4_t::zero = vec4_t(0.0, 0.0, 0.0, 0.0);
+vec4_t vec4_t::one = vec4_t(1.0, 1.0, 1.0, 1.0);
+vec4_t vec4_t::i = vec4_t(1.0, 0.0, 0.0, 0.0);
+vec4_t vec4_t::j = vec4_t(0.0, 1.0, 0.0, 0.0);
+vec4_t vec4_t::k = vec4_t(0.0, 0.0, 1.0, 0.0);
+vec4_t vec4_t::l = vec4_t(0.0, 0.0, 0.0, 1.0);
+
+// copy
+vec4_t& vec4_t::operator =( const vec4_t& b )
+{
+	x = b.x;
+	y = b.y;
+	z = b.z;
+	w = b.w;
+	return ME;
+}
+
+// +
+vec4_t vec4_t::operator +( const vec4_t& b ) const
+{
+	return vec4_t( x+b.x, y+b.y, z+b.z, w+b.w );
+}
+
+// +=
+vec4_t& vec4_t::operator +=( const vec4_t& b )
+{
+	x += b.x;
+	y += b.y;
+	z += b.z;
+	w += b.w;
+	return ME;
+}
+
+// -
+vec4_t vec4_t::operator -( const vec4_t& b ) const
+{
+	return vec4_t( x-b.x, y-b.y, z-b.z, w-b.w );
+}
+
+// -=
+vec4_t& vec4_t::operator -=( const vec4_t& b )
+{
+	x -= b.x;
+	y -= b.y;
+	z -= b.z;
+	w -= b.w;
+	return ME;
+}
+
+// negative
+vec4_t vec4_t::operator -() const
+{
+	return vec4_t( -x, -y, -z, -w );
+}
+
+// *
+vec4_t vec4_t::operator *( const vec4_t& b ) const
+{
+	return vec4_t( x*b.x, y*b.y, z*b.z, w*b.w );
+}
+
+// *=
+vec4_t& vec4_t::operator *=( const vec4_t& b )
+{
+	x *= b.x;
+	y *= b.y;
+	z *= b.z;
+	w *= b.w;
+	return ME;
+}
+
+// /
+vec4_t vec4_t::operator /( const vec4_t& b ) const
+{
+	return vec4_t( x/b.x, y/b.y, z/b.z, w/b.w );
+}
+
+// /=
+vec4_t& vec4_t::operator /=( const vec4_t& b )
+{
+	x /= b.x;
+	y /= b.y;
+	z /= b.z;
+	w /= b.w;
+	return ME;
+}
+
+// scale
+vec4_t vec4_t::operator *( float f ) const
+{
+	return vec4_t( x*f, y*f, z*f, w*f );
+}
+
+// scale
+vec4_t& vec4_t::operator *=( float f )
+{
+	x *= f;
+	y *= f;
+	z *= f;
+	w *= f;
+	return ME;
+}
+
+// down-scale
+vec4_t vec4_t::operator /( float f ) const
+{
+	DEBUG_ERR( IsZero(f) ); // Division by zero
+	return vec4_t( x/f, y/f, z/f, w/f );
+}
+
+// down-scale
+vec4_t& vec4_t::operator /=( float f )
+{
+	DEBUG_ERR( IsZero(f) ); // Division by zero
+	x /= f;
+	y /= f;
+	z /= f;
+	w /= f;
+	return ME;
+}
+
+// vec4 * mat4
+vec4_t vec4_t::operator *( const mat4_t& m4 ) const
+{
+	return vec4_t(
+		x*m4(0,0) + y*m4(1,0) + z*m4(2,0) + w*m4(3,0),
+		x*m4(0,1) + y*m4(1,1) + z*m4(2,1) + w*m4(3,1),
+		x*m4(0,2) + y*m4(1,2) + z*m4(2,2) + w*m4(3,2),
+		x*m4(0,3) + y*m4(1,3) + z*m4(2,3) + w*m4(3,3)
+	);
+}
+
+// ==
+bool vec4_t::operator ==( const vec4_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) && IsZero(w-b.w) ) ? true : false;
+}
+
+// !=
+bool vec4_t::operator !=( const vec4_t& b ) const
+{
+	return ( IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) && IsZero(w-b.w) ) ? false : true;
+}
+
+// Dot
+float vec4_t::Dot( const vec4_t& b ) const
+{
+	return x*b.x + y*b.y + z*b.z + w*b.w;
+}
+
+// Length
+float vec4_t::Length() const
+{
+	return Sqrt( x*x + y*y + z*z + w*w );
+}
+
+// Normalize
+void vec4_t::Normalize()
+{
+	ME *= InvSqrt( x*x +y*y + z*z + w*w );
+}
+
+// SetZero
+void vec4_t::SetZero()
+{
+	w = z = y = x = 0.0;
+}
+
+// Print
+void vec4_t::Print() const
+{
+	for( int i=0; i<4; i++ )
+		cout << fixed << ME[i] << " ";
+	cout << "\n" << endl;
+}
+
+
+/*
+=======================================================================================================================================
+quat_t                                                                                                                                =
+=======================================================================================================================================
+*/
+quat_t quat_t::zero = quat_t( 0.0, 0.0, 0.0, 0.0 );
+quat_t quat_t::ident = quat_t( 1.0, 0.0, 0.0, 0.0 );
+
+
+// copy
+quat_t& quat_t::operator =( const quat_t& b )
+{
+	w = b.w;
+	x = b.x;
+	y = b.y;
+	z = b.z;
+	return ME;
+}
+
+// +
+quat_t quat_t::operator +( const quat_t& b ) const
+{
+	return quat_t( w+b.w, x+b.x, y+b.y, z+b.z );
+}
+
+// +=
+quat_t& quat_t::operator +=( const quat_t& b )
+{
+	w += b.w;
+	x += b.x;
+	y += b.y;
+	z += b.z;
+	return ME;
+}
+
+// -
+quat_t quat_t::operator -( const quat_t& b ) const
+{
+	return quat_t( w-b.w, x-b.x, y-b.y, z-b.z );
+}
+
+// -=
+quat_t& quat_t::operator -=( const quat_t& b )
+{
+	w -= b.w;
+	x -= b.x;
+	y -= b.y;
+	z -= b.z;
+	return ME;
+}
+
+// *
+quat_t quat_t::operator *( const quat_t& b ) const
+{
+	return quat_t(
+		-x * b.x - y * b.y - z * b.z + w * b.w,
+		 x * b.w + y * b.z - z * b.y + w * b.x,
+		-x * b.z + y * b.w + z * b.x + w * b.y,
+		 x * b.y - y * b.x + z * b.w + w * b.z
+	);
+}
+
+// *=
+quat_t& quat_t::operator *=( const quat_t& b )
+{
+	ME = ME*b;
+	return ME;
+}
+
+// quat * float
+quat_t quat_t::operator *( float f ) const
+{
+	return quat_t( w*f, x*f,y*f, z*f );
+}
+
+// quat * float (self)
+quat_t& quat_t::operator *=( float f )
+{
+	w *= f;
+	x *= f;
+	y *= f;
+	z *= f;
+	return ME;
+}
+
+// quat / float
+quat_t quat_t::operator /( float f ) const
+{
+	DEBUG_ERR( IsZero(f) ); // Division by zero
+	return quat_t( w/f, x/f, y/f, z/f );
+}
+
+// quat / float (self)
+quat_t& quat_t::operator /=( float f )
+{
+	DEBUG_ERR( IsZero(f) ); // Division by zero
+	w /= f;
+	x /= f;
+	y /= f;
+	z /= f;
+	return ME;
+}
+
+// ==
+bool quat_t::operator ==( const quat_t& b ) const
+{
+	return ( IsZero(w-b.w) && IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? true : false;
+}
+
+// !=
+bool quat_t::operator !=( const quat_t& b ) const
+{
+	return ( IsZero(w-b.w) && IsZero(x-b.x) && IsZero(y-b.y) && IsZero(z-b.z) ) ? false : true;
+}
+
+// Conjugate
+void quat_t::Conjugate()
+{
+	x = -x;
+	y = -y;
+	z = -z;
+}
+
+// Conjugated
+quat_t quat_t::Conjugated() const
+{
+	return quat_t( w, -x, -y, -z );
+}
+
+// Normalize
+void quat_t::Normalize()
+{
+	ME *= InvSqrt( x*x + y*y + z*z + w*w );
+}
+
+// SetIdent
+void quat_t::SetIdent()
+{
+	ME = ident;
+}
+
+// SetZero
+void quat_t::SetZero()
+{
+	z = y = x = w = 0.0;
+}
+
+// Length
+float quat_t::Length() const
+{
+	return Sqrt( w*w + x*x + y*y + z*z );
+}
+
+// Invert
+void quat_t::Invert()
+{
+	float norm = w*w + x*x + y*y + z*z;
+
+	DEBUG_ERR( IsZero(norm) ); // Norm is zero
+
+	float normi = 1.0f / norm;
+	ME = quat_t( normi*w, -normi*x, -normi*y, -normi*z );
+}
+
+// Print
+void quat_t::Print() const
+{
+	cout << fixed << "(w,x,y,z) = " << w << ' ' << x << ' ' << y << ' ' << z  << '\n' << endl;
+}
+
+// 3x3 to quat
+void quat_t::Set( const mat3_t& a )
+{
+	float trace = a(0, 0) + a(1, 1) + a(2, 2) + 1.0f;
+	if( trace > EPSILON )
+	{
+		float s = 0.5f * InvSqrt(trace);
+		w = 0.25f / s;
+		x = ( a(2, 1) - a(1, 2) ) * s;
+		y = ( a(0, 2) - a(2, 0) ) * s;
+		z = ( a(1, 0) - a(0, 1) ) * s;
+	}
+	else
+	{
+		if( a(0, 0) > a(1, 1) && a(0, 0) > a(2, 2) )
+		{
+			float s = 2.0f * ( Sqrt( 1.0f + a(0, 0) - a(1, 1) - a(2, 2)) );
+			w = (a(1, 2) - a(2, 1) ) / s;
+			x = 0.25f * s;
+			y = (a(0, 1) + a(1, 0) ) / s;
+			z = (a(0, 2) + a(2, 0) ) / s;
+		}
+		else if( a(1, 1) > a(2, 2) )
+		{
+			float s = 2.0f * ( Sqrt( 1.0f + a(1, 1) - a(0, 0) - a(2, 2)) );
+			w = (a(0, 2) - a(2, 0) ) / s;
+			x = (a(0, 1) + a(1, 0) ) / s;
+			y = 0.25f * s;
+			z = (a(1, 2) + a(2, 1) ) / s;
+		}
+		else
+		{
+			float s = 2.0f * ( Sqrt( 1.0f + a(2, 2) - a(0, 0) - a(1, 1) ) );
+			w = (a(0, 1) - a(1, 0) ) / s;
+			x = (a(0, 2) + a(2, 0) ) / s;
+			y = (a(1, 2) + a(2, 1) ) / s;
+			z = 0.25f * s;
+		}
+	}
+
+	Normalize();
+}
+
+// euler to quat
+void quat_t::Set( const euler_t &e )
+{
+	float cx, sx;
+	SinCos( e.heading()*0.5, sx, cx );
+
+	float cy, sy;
+	SinCos( e.attitude()*0.5, sy, cy );
+
+	float cz, sz;
+	SinCos( e.bank()*0.5, sz, cz );
+
+	float cxcy = cx*cy;
+	float sxsy = sx*sy;
+	w = cxcy*cz - sxsy*sz;
+	x = cxcy*sz + sxsy*cz;
+	y = sx*cy*cz + cx*sy*sz;
+	z = cx*sy*cz - sx*cy*sz;
+}
+
+// Set
+// axis_ang
+void quat_t::Set( const axisang_t& axisang )
+{
+	float lengthsq = axisang.axis.LengthSquared();
+	if ( IsZero( lengthsq ) )
+	{
+		SetIdent();
+		return;
+	}
+
+	float rad = axisang.ang * 0.5f;
+
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	float scalefactor = sintheta/ Sqrt(lengthsq);
+
+	w = costheta;
+	x = scalefactor * axisang.axis.x;
+	y = scalefactor * axisang.axis.y;
+	z = scalefactor * axisang.axis.z;
+}
+
+// CalcFromVecVec
+void quat_t::CalcFromVecVec( const vec3_t& from, const vec3_t& to )
+{
+	vec3_t axis( from.Cross(to) );
+	ME = quat_t(  from.Dot(to), axis.x, axis.y, axis.z);
+	Normalize();
+	w += 1.0f;
+
+	if( w <= EPSILON )
+	{
+		if( from.z*from.z > from.x*from.x )
+			ME = quat_t( 0.0f, 0.0f, from.z, -from.y );
+		else
+			ME = quat_t( 0.0f, from.y, -from.x, 0.0f );
+	}
+	Normalize();
+}
+
+// Set
+// vec3
+void quat_t::Set( const vec3_t& v )
+{
+	w = 0.0;
+	x = v.x;
+	y = v.y;
+	z = v.y;
+}
+
+// Set
+// vec4
+void quat_t::Set( const vec4_t& v )
+{
+	w = v.w;
+	x = v.x;
+	y = v.y;
+	z = v.y;
+}
+
+// Dot
+float quat_t::Dot( const quat_t& b ) const
+{
+	return w*b.w + x*b.x + y*b.y + z*b.z;
+}
+
+// SLERP
+quat_t quat_t::Slerp( const quat_t& q1_, float t ) const
+{
+	const quat_t& q0 = ME;
+	quat_t q1( q1_ );
+	float cos_half_theta = q0.w*q1.w + q0.x*q1.x + q0.y*q1.y + q0.z*q1.z;
+	if( cos_half_theta < 0.0 )
+	{
+		q1 *= -1.0f; // quat changes
+		cos_half_theta = -cos_half_theta;
+	}
+	if( fabs(cos_half_theta) >= 1.0f )
+	{
+		return quat_t( q0 );
+	}
+
+	float half_theta = acos( cos_half_theta );
+	float sin_half_theta = Sqrt(1.0f - cos_half_theta*cos_half_theta);
+
+	if( fabs(sin_half_theta) < 0.001f )
+	{
+		return quat_t( q0*0.5f + q1*0.5f );
+	}
+	float ratio_a = sin((1.0f - t) * half_theta) / sin_half_theta;
+	float ratio_b = sin(t * half_theta) / sin_half_theta;
+	quat_t tmp, tmp1, sum;
+	tmp = q0*ratio_a;
+	tmp1 = q1*ratio_b;
+	sum = tmp + tmp1;
+	sum.Normalize();
+	return quat_t( sum );
+}
+
+
+/*
+=======================================================================================================================================
+euler_t                                                                                                                               =
+=======================================================================================================================================
+*/
+
+// cpy
+euler_t& euler_t::operator =( const euler_t& b )
+{
+	memcpy( this, &b, sizeof(euler_t) );
+	return ME;
+}
+
+// LoadZero
+void euler_t::SetZero()
+{
+	z = y = x = 0.0;
+}
+
+// Set
+// quat
+void euler_t::Set( const quat_t& q )
+{
+	float test = q.x*q.y + q.z*q.w;
+	if (test > 0.499f)
+	{
+		heading() = 2.0f * atan2( q.x, q.w );
+		attitude() = PI/2.0f;
+		bank() = 0.0;
+		return;
+	}
+	if (test < -0.499f)
+	{
+		heading() = -2.0f * atan2( q.x, q.w );
+		attitude() = -PI/2.0f;
+		bank() = 0.0;
+		return;
+	}
+
+	float sqx = q.x*q.x;
+	float sqy = q.y*q.y;
+	float sqz = q.z*q.z;
+	heading() = atan2( 2.0f*q.y*q.w-2.0f*q.x*q.z, 1.0f-2.0f*sqy-2.0f*sqz );
+	attitude() = asin( 2.0f*test );
+	bank() = atan2( 2.0f*q.x*q.w-2.0f*q.y*q.z, 1.0f-2.0f*sqx-2.0f*sqz );
+}
+
+// Set
+// mat3
+void euler_t::Set( const mat3_t& m3 )
+{
+	float cx, sx;
+	float cy, sy;
+	float cz, sz;
+
+	sy = m3(0,2);
+	cy = Sqrt( 1.0f - sy*sy );
+	// normal case
+	if ( !IsZero( cy ) )
+	{
+		float factor = 1.0f/cy;
+		sx = -m3(1,2) * factor;
+		cx = m3(2,2) * factor;
+		sz = -m3(0,1) * factor;
+		cz = m3(0,0) * factor;
+	}
+	// x and z axes aligned
+	else
+	{
+		sz = 0.0f;
+		cz = 1.0f;
+		sx = m3(2,1);
+		cx = m3(1,1);
+	}
+
+	z = atan2f( sz, cz );
+	y = atan2f( sy, cy );
+	x = atan2f( sx, cx );
+}
+
+// Print
+void euler_t::Print() const
+{
+	for( int i=0; i<3; i++ )
+		cout << fixed << ME[i] << "(" << ME[i]/PI << " PI) Rad" << " / " << ToDegrees(ME[i]) << " Deg" << "\n";
+	cout << endl;
+}
+
+
+/*
+=======================================================================================================================================
+axisang_t                                                                                                                             =
+=======================================================================================================================================
+*/
+
+// Set
+// quat
+void axisang_t::Set( const quat_t& q )
+{
+	ang = 2.0f*acos( q.w );
+	float length = Sqrt( 1.0f - q.w*q.w );
+	if( IsZero(length) )
+		axis.SetZero();
+	else
+	{
+		length = 1.0f/length;
+		axis = vec3_t( q.x*length, q.y*length, q.z*length );
+	}
+}
+
+// Set
+// mat3
+void axisang_t::Set( const mat3_t& m3 )
+{
+	if( (fabs(m3(0,1)-m3(1,0))< EPSILON)  && (fabs(m3(0,2)-m3(2,0))< EPSILON)  && (fabs(m3(1,2)-m3(2,1))< EPSILON) )
+	{
+
+		if( (fabs(m3(0,1)+m3(1,0)) < 0.1 ) && (fabs(m3(0,2)+m3(2,0)) < 0.1) && (fabs(m3(1,2)+m3(2,1)) < 0.1) && (fabs(m3(0,0)+m3(1,1)+m3(2,2))-3) < 0.1 )
+		{
+			axis = vec3_t( 1.0f, 0.0f, 0.0f );
+			ang = 0.0f;
+			return;
+		}
+
+		ang = PI;
+		axis.x = (m3(0,0)+1)/2;
+		if( axis.x > 0.0f )
+			axis.x = Sqrt(axis.x);
+		else
+			axis.x = 0;
+		axis.y = (m3(1,1)+1)/2;
+		if( axis.y > 0 )
+			axis.y = Sqrt(axis.y);
+		else
+			axis.y = 0;
+		axis.z = (m3(2,2)+1)/2;
+		if( axis.z > 0 )
+			axis.z = Sqrt(axis.z);
+		else
+			axis.z = 0.0f;
+
+		bool xZero = ( fabs(axis.x)<EPSILON );
+		bool yZero = ( fabs(axis.y)<EPSILON );
+		bool zZero = ( fabs(axis.z)<EPSILON );
+		bool xyPositive = ( m3(0,1) > 0 );
+		bool xzPositive = ( m3(0,2) > 0 );
+		bool yzPositive = ( m3(1,2) > 0 );
+		if( xZero && !yZero && !zZero ){
+			if( !yzPositive ) axis.y = -axis.y;
+		}else if( yZero && !zZero ){
+			if( !xzPositive ) axis.z = -axis.z;
+		}else if (zZero){
+			if( !xyPositive ) axis.x = -axis.x;
+		}
+
+		return;
+	}
+
+	float s = Sqrt((m3(2,1) - m3(1,2))*(m3(2,1) - m3(1,2))+(m3(0,2) - m3(2,0))*(m3(0,2) - m3(2,0))+(m3(1,0) - m3(0,1))*(m3(1,0) - m3(0,1)));
+
+	if( fabs(s) < 0.001 ) s = 1;
+
+	ang = acos( ( m3(0,0) + m3(1,1) + m3(2,2) - 1)/2 );
+	axis.x= (m3(2,1) - m3(1,2))/s;
+	axis.y= (m3(0,2) - m3(2,0))/s;
+	axis.z= (m3(1,0) - m3(0,1))/s;
+}
+
+
+
+/*
+=======================================================================================================================================
+matrix 3x3                                                                                                                            =
+=======================================================================================================================================
+*/
+mat3_t mat3_t::ident( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 );
+mat3_t mat3_t::zero( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 );
+
+
+// constructor
+mat3_t::mat3_t( float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22 )
+{
+	ME(0,0) = m00;
+	ME(0,1) = m01;
+	ME(0,2) = m02;
+	ME(1,0) = m10;
+	ME(1,1) = m11;
+	ME(1,2) = m12;
+	ME(2,0) = m20;
+	ME(2,1) = m21;
+	ME(2,2) = m22;
+}
+
+
+// copy
+mat3_t& mat3_t::operator =( const mat3_t& b )
+{
+	ME[0] = b[0];
+	ME[1] = b[1];
+	ME[2] = b[2];
+	ME[3] = b[3];
+	ME[4] = b[4];
+	ME[5] = b[5];
+	ME[6] = b[6];
+	ME[7] = b[7];
+	ME[8] = b[8];
+	return ME;
+}
+
+// 3x3 + 3x3
+mat3_t mat3_t::operator +( const mat3_t& b ) const
+{
+	mat3_t c;
+	for( int i=0; i<9; i++ )
+		c[i] = ME[i] + b[i];
+	return c;
+}
+
+// 3x3 + 3x3 (self)
+mat3_t& mat3_t::operator +=( const mat3_t& b )
+{
+	for( int i=0; i<9; i++ )
+		ME[i] += b[i];
+	return ME;
+}
+
+// 3x3 - 3x3
+mat3_t mat3_t::operator -( const mat3_t& b ) const
+{
+	mat3_t c;
+	for( int i=0; i<9; i++ )
+		c[i] = ME[i] - b[i];
+	return c;
+}
+
+// 3x3 - 3x3 (self)
+mat3_t& mat3_t::operator -=( const mat3_t& b )
+{
+	for( int i=0; i<9; i++ )
+		ME[i] -= b[i];
+	return ME;
+}
+
+// 3x3 * 3x3
+mat3_t mat3_t::operator *( const mat3_t& b ) const
+{
+	mat3_t c;
+	c(0, 0) = ME(0, 0)*b(0, 0) + ME(0, 1)*b(1, 0) + ME(0, 2)*b(2, 0);
+	c(0, 1) = ME(0, 0)*b(0, 1) + ME(0, 1)*b(1, 1) + ME(0, 2)*b(2, 1);
+	c(0, 2) = ME(0, 0)*b(0, 2) + ME(0, 1)*b(1, 2) + ME(0, 2)*b(2, 2);
+	c(1, 0) = ME(1, 0)*b(0, 0) + ME(1, 1)*b(1, 0) + ME(1, 2)*b(2, 0);
+	c(1, 1) = ME(1, 0)*b(0, 1) + ME(1, 1)*b(1, 1) + ME(1, 2)*b(2, 1);
+	c(1, 2) = ME(1, 0)*b(0, 2) + ME(1, 1)*b(1, 2) + ME(1, 2)*b(2, 2);
+	c(2, 0) = ME(2, 0)*b(0, 0) + ME(2, 1)*b(1, 0) + ME(2, 2)*b(2, 0);
+	c(2, 1) = ME(2, 0)*b(0, 1) + ME(2, 1)*b(1, 1) + ME(2, 2)*b(2, 1);
+	c(2, 2) = ME(2, 0)*b(0, 2) + ME(2, 1)*b(1, 2) + ME(2, 2)*b(2, 2);
+	return c;
+}
+
+// 3x3 * 3x3 (self)
+mat3_t& mat3_t::operator *=( const mat3_t& b )
+{
+	ME = ME * b;
+	return ME;
+}
+
+// 3x3 * float
+mat3_t mat3_t::operator *( float f ) const
+{
+	mat3_t c;
+	for( uint i=0; i<9; i++ )
+		c[i] = ME[i] * f;
+	return c;
+}
+
+// 3x3 * float (self)
+mat3_t& mat3_t::operator *=( float f )
+{
+	for( uint i=0; i<9; i++ )
+		ME[i] *= f;
+	return ME;
+}
+
+// 3x3 * vec3 (cross products with rows)
+vec3_t mat3_t::operator *( const vec3_t& b ) const
+{
+	return vec3_t(
+		ME(0, 0)*b.x + ME(0, 1)*b.y + ME(0, 2)*b.z,
+		ME(1, 0)*b.x + ME(1, 1)*b.y + ME(1, 2)*b.z,
+		ME(2, 0)*b.x + ME(2, 1)*b.y + ME(2, 2)*b.z
+	);
+}
+
+// ==
+bool mat3_t::operator ==( const mat3_t& b ) const
+{
+	for( int i=0; i<9; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return false;
+	return true;
+}
+
+// !=
+bool mat3_t::operator !=( const mat3_t& b ) const
+{
+	for( int i=0; i<9; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return true;
+	return false;
+}
+
+// SetRows
+void mat3_t::SetRows( const vec3_t& a, const vec3_t& b, const vec3_t& c )
+{
+	ME(0,0) = a.x;
+	ME(0,1) = a.y;
+	ME(0,2) = a.z;
+	ME(1,0) = b.x;
+	ME(1,1) = b.y;
+	ME(1,2) = b.z;
+	ME(2,0) = c.x;
+	ME(2,1) = c.y;
+	ME(2,2) = c.z;
+}
+
+// SetColumns
+void mat3_t::SetColumns( const vec3_t& a, const vec3_t& b, const vec3_t& c )
+{
+	ME(0,0) = a.x;
+	ME(1,0) = a.y;
+	ME(2,0) = a.z;
+	ME(0,1) = b.x;
+	ME(1,1) = b.y;
+	ME(2,1) = b.z;
+	ME(0,2) = c.x;
+	ME(1,2) = c.y;
+	ME(2,2) = c.z;
+}
+
+// GetRows
+void mat3_t::GetRows( vec3_t& a, vec3_t& b, vec3_t& c ) const
+{
+	a.x = ME(0,0);
+	a.y = ME(0,1);
+	a.z = ME(0,2);
+	b.x = ME(1,0);
+	b.y = ME(1,1);
+	b.z = ME(1,2);
+	c.x = ME(2,0);
+	c.y = ME(2,1);
+	c.z = ME(2,2);
+}
+
+// GetColumns
+void mat3_t::GetColumns( vec3_t& a, vec3_t& b, vec3_t& c ) const
+{
+	a.x = ME(0,0);
+	a.y = ME(1,0);
+	a.z = ME(2,0);
+	b.x = ME(0,1);
+	b.y = ME(1,1);
+	b.z = ME(2,1);
+	c.x = ME(0,2);
+	c.y = ME(1,2);
+	c.z = ME(2,2);
+}
+
+// Set
+// quat
+void mat3_t::Set( const quat_t& q )
+{
+	DEBUG_ERR( !IsZero( 1.0f - q.Length()) ); // Not normalized quat
+
+	float xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
+
+	xs = q.x+q.x;
+	ys = q.y+q.y;
+	zs = q.z+q.z;
+	wx = q.w*xs;
+	wy = q.w*ys;
+	wz = q.w*zs;
+	xx = q.x*xs;
+	xy = q.x*ys;
+	xz = q.x*zs;
+	yy = q.y*ys;
+	yz = q.y*zs;
+	zz = q.z*zs;
+
+	ME(0,0) = 1.0f - (yy + zz);
+	ME(0,1) = xy - wz;
+	ME(0,2) = xz + wy;
+
+	ME(1,0) = xy + wz;
+	ME(1,1) = 1.0f - (xx + zz);
+	ME(1,2) = yz - wx;
+
+	ME(2,0) = xz - wy;
+	ME(2,1) = yz + wx;
+	ME(2,2) = 1.0f - (xx + yy);
+}
+
+// Set
+// euler
+void  mat3_t::Set( const euler_t& e )
+{
+	float ch, sh, ca, sa, cb, sb;
+  SinCos( e.heading(), sh, ch );
+  SinCos( e.attitude(), sa, ca );
+  SinCos( e.bank(), sb, cb );
+
+  ME(0, 0) = ch * ca;
+  ME(0, 1) = sh*sb - ch*sa*cb;
+  ME(0, 2) = ch*sa*sb + sh*cb;
+  ME(1, 0) = sa;
+  ME(1, 1) = ca*cb;
+  ME(1, 2) = -ca*sb;
+  ME(2, 0) = -sh*ca;
+  ME(2, 1) = sh*sa*cb + ch*sb;
+  ME(2, 2) = -sh*sa*sb + ch*cb;
+}
+
+// Set
+// axis angles
+void mat3_t::Set( const axisang_t& axisang )
+{
+	DEBUG_ERR( !IsZero( 1.0f-axisang.axis.Length() ) ); // Not normalized axis
+
+	float c, s;
+	SinCos( axisang.ang, s, c );
+	float t = 1.0f - c;
+
+	const vec3_t& axis = axisang.axis;
+	ME(0,0) = c + axis.x*axis.x*t;
+	ME(1,1) = c + axis.y*axis.y*t;
+	ME(2,2) = c + axis.z*axis.z*t;
+
+	float tmp1 = axis.x*axis.y*t;
+	float tmp2 = axis.z*s;
+	ME(1,0) = tmp1 + tmp2;
+	ME(0,1) = tmp1 - tmp2;
+	tmp1 = axis.x*axis.z*t;
+	tmp2 = axis.y*s;
+	ME(2,0) = tmp1 - tmp2;
+	ME(0,2) = tmp1 + tmp2;    tmp1 = axis.y*axis.z*t;
+	tmp2 = axis.x*s;
+	ME(2,1) = tmp1 + tmp2;
+	ME(1,2) = tmp1 - tmp2;
+
+}
+
+// SetRotationX
+void mat3_t::SetRotationX( float rad )
+{
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	ME(0,0) = 1.0f;
+	ME(0,1) = 0.0f;
+	ME(0,2) = 0.0f;
+	ME(1,0) = 0.0f;
+	ME(1,1) = costheta;
+	ME(1,2) = -sintheta;
+	ME(2,0) = 0.0f;
+	ME(2,1) = sintheta;
+	ME(2,2) = costheta;
+}
+
+// SetRotationY
+void mat3_t::SetRotationY( float rad )
+{
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	ME(0,0) = costheta;
+	ME(0,1) = 0.0f;
+	ME(0,2) = sintheta;
+	ME(1,0) = 0.0f;
+	ME(1,1) = 1.0f;
+	ME(1,2) = 0.0f;
+	ME(2,0) = -sintheta;
+	ME(2,1) = 0.0f;
+	ME(2,2) = costheta;
+}
+
+// LoadRotationZ
+void mat3_t::SetRotationZ( float rad )
+{
+	float sintheta, costheta;
+	SinCos( rad, sintheta, costheta );
+
+	ME(0,0) = costheta;
+	ME(0,1) = -sintheta;
+	ME(0,2) = 0.0f;
+	ME(1,0) = sintheta;
+	ME(1,1) = costheta;
+	ME(1,2) = 0.0f;
+	ME(2,0) = 0.0f;
+	ME(2,1) = 0.0f;
+	ME(2,2) = 1.0f;
+}
+
+// RotateXAxis
+/* the slow code is in comments and above the comments the optimized one
+If we analize the mat3 we can extract the 3 unit vectors rotated by the mat3. The 3 rotated vectors are in mat's colomns.
+This means that: mat3.colomn[0] == i*mat3. RotateXAxis() rotates rad angle not from i vector (aka x axis) but
+from the vector from colomn 0*/
+void mat3_t::RotateXAxis( float rad )
+{
+	float sina, cosa;
+	SinCos( rad, sina, cosa );
+
+	/*vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );*/
+
+	// z_axis = z_axis*cosa - y_axis*sina;
+	ME(0,2) = ME(0,2)*cosa - ME(0,1)*sina;
+	ME(1,2) = ME(1,2)*cosa - ME(1,1)*sina;
+	ME(2,2) = ME(2,2)*cosa - ME(2,1)*sina;
+
+	// z_axis.Normalize();
+	float len = InvSqrt( ME(0,2)*ME(0,2) + ME(1,2)*ME(1,2) + ME(2,2)*ME(2,2) );
+	ME(0,2) *= len;
+	ME(1,2) *= len;
+	ME(2,2) *= len;
+
+	// y_axis = z_axis * x_axis;
+	ME(0,1) = ME(1,2)*ME(2,0) - ME(2,2)*ME(1,0);
+	ME(1,1) = ME(2,2)*ME(0,0) - ME(0,2)*ME(2,0);
+	ME(2,1) = ME(0,2)*ME(1,0) - ME(1,2)*ME(0,0);
+
+	// y_axis.Normalize();
+	/*len = InvSqrt( ME(0,1)*ME(0,1) + ME(1,1)*ME(1,1) + ME(2,1)*ME(2,1) );
+	ME(0,1) *= len;
+	ME(1,1) *= len;
+	ME(2,1) *= len;*/
+
+	// SetColumns( x_axis, y_axis, z_axis );
+
+}
+
+// RotateYAxis
+void mat3_t::RotateYAxis( float rad )
+{
+	float sina, cosa;
+	SinCos( rad, sina, cosa );
+
+	/*vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );*/
+
+	// z_axis = z_axis*cosa + x_axis*sina;
+	ME(0,2) = ME(0,2)*cosa + ME(0,0)*sina;
+	ME(1,2) = ME(1,2)*cosa + ME(1,0)*sina;
+	ME(2,2) = ME(2,2)*cosa + ME(2,0)*sina;
+
+	// z_axis.Normalize();
+	float len = InvSqrt( ME(0,2)*ME(0,2) + ME(1,2)*ME(1,2) + ME(2,2)*ME(2,2) );
+	ME(0,2) *= len;
+	ME(1,2) *= len;
+	ME(2,2) *= len;
+
+	// x_axis = (z_axis*y_axis) * -1.0f;
+	ME(0,0) = ME(2,2)*ME(1,1) - ME(1,2)*ME(2,1);
+	ME(1,0) = ME(0,2)*ME(2,1) - ME(2,2)*ME(0,1);
+	ME(2,0) = ME(1,2)*ME(0,1) - ME(0,2)*ME(1,1);
+
+	// x_axis.Normalize();
+	/*len = InvSqrt( ME(0,0)*ME(0,0) + ME(1,0)*ME(1,0) + ME(2,0)*ME(2,0) );
+	ME(0,0) *= len;
+	ME(1,0) *= len;
+	ME(2,0) *= len;*/
+
+	// SetColumns( x_axis, y_axis, z_axis );
+}
+
+
+// RotateZAxis
+void mat3_t::RotateZAxis( float rad )
+{
+	float sina, cosa;
+	SinCos( rad, sina, cosa );
+
+	/*vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );*/
+
+	// x_axis = x_axis*cosa + y_axis*sina;
+	ME(0,0) = ME(0,0)*cosa + ME(0,1)*sina;
+	ME(1,0) = ME(1,0)*cosa + ME(1,1)*sina;
+	ME(2,0) = ME(2,0)*cosa + ME(2,1)*sina;
+
+	// x_axis.Normalize();
+	float len = InvSqrt( ME(0,0)*ME(0,0) + ME(1,0)*ME(1,0) + ME(2,0)*ME(2,0) );
+	ME(0,0) *= len;
+	ME(1,0) *= len;
+	ME(2,0) *= len;
+
+	// y_axis = z_axis*x_axis;
+	ME(0,1) = ME(1,2)*ME(2,0) - ME(2,2)*ME(1,0);
+	ME(1,1) = ME(2,2)*ME(0,0) - ME(0,2)*ME(2,0);
+	ME(2,1) = ME(0,2)*ME(1,0) - ME(1,2)*ME(0,0);
+
+	// y_axis.Normalize();
+	/*len = InvSqrt( ME(0,1)*ME(0,1) + ME(1,1)*ME(1,1) + ME(2,1)*ME(2,1) );
+	ME(0,1) *= len;
+	ME(1,1) *= len;
+	ME(2,1) *= len;*/
+
+	//SetColumns( x_axis, y_axis, z_axis );
+}
+
+// Transpose
+void mat3_t::Transpose()
+{
+	float temp = ME(0,1);
+	ME(0,1) = ME(1,0);
+	ME(1,0) = temp;
+	temp = ME(0,2);
+	ME(0,2) = ME(2,0);
+	ME(2,0) = temp;
+	temp = ME(1,2);
+	ME(1,2) = ME(2,1);
+	ME(2,1) = temp;
+}
+
+// Transposed
+mat3_t mat3_t::Transposed() const
+{
+	mat3_t m3;
+	m3[0] = ME[0];
+	m3[1] = ME[3];
+	m3[2] = ME[6];
+	m3[3] = ME[1];
+	m3[4] = ME[4];
+	m3[5] = ME[7];
+	m3[6] = ME[2];
+	m3[7] = ME[5];
+	m3[8] = ME[8];
+	return m3;
+}
+
+// Reorthogonalize
+void mat3_t::Reorthogonalize()
+{
+	// method 1: standard orthogonalization method
+	/*mat3_t correction_m3 =
+	(
+		(mat3_t::ident * 3.0f) -
+		(ME * ME.Transposed())
+	) * 0.5f;
+
+	ME = correction_m3 * ME;*/
+
+	// method 2: Gram-Schmidt method with a twist for z_axis
+	vec3_t x_axis, y_axis, z_axis;
+	GetColumns( x_axis, y_axis, z_axis );
+
+	x_axis.Normalize();
+
+	y_axis = y_axis - ( x_axis * x_axis.Dot(y_axis) );
+	y_axis.Normalize();
+
+	z_axis = x_axis.Cross(y_axis);
+
+	SetColumns( x_axis, y_axis, z_axis );
+}
+
+// SetIdent
+void mat3_t::SetIdent()
+{
+	ME = ident;
+}
+
+// SetZero
+void mat3_t::SetZero()
+{
+	ME[0] = ME[1] = ME[2] = ME[3] = ME[4] = ME[5] = ME[6] = ME[7] = ME[8] = 0.0f;
+}
+
+// Print
+void mat3_t::Print() const
+{
+	for( int i=0; i<3; i++ )
+	{
+		for( int j=0; j<3; j++ )
+			cout << fixed << ME(i, j) << " ";
+		cout << endl;
+	}
+	cout << endl;
+}
+
+// Determinant
+float mat3_t::Det() const
+{
+	/* accurate method:
+	return ME(0, 0)*ME(1, 1)*ME(2, 2) + ME(0, 1)*ME(1, 2)*ME(2, 0) + ME(0, 2)*ME(1, 0)*ME(2, 1)
+	- ME(0, 0)*ME(1, 2)*ME(2, 1) - ME(0, 1)*ME(1, 0)*ME(2, 2) - ME(0, 2)*ME(1, 1)*ME(2, 0);*/
+	return ME(0, 0)*( ME(1, 1)*ME(2, 2) - ME(1, 2)*ME(2, 1) ) -
+	ME(0, 1)*( ME(1, 0)*ME(2, 2) - ME(1, 2)*ME(2, 0) ) +
+	ME(0, 2)*( ME(0, 1)*ME(2, 1) - ME(1, 1)*ME(2, 0) );
+}
+
+
+// Invert
+// using Gramer's method ( Inv(A) = ( 1/Det(A) ) * Adj(A)  )
+mat3_t mat3_t::Inverted() const
+{
+	mat3_t result;
+
+	// compute determinant
+	float cofactor0 = ME(1,1)*ME(2,2) - ME(1,2)*ME(2,1);
+	float cofactor3 = ME(0,2)*ME(2,1) - ME(0,1)*ME(2,2);
+	float cofactor6 = ME(0,1)*ME(1,2) - ME(0,2)*ME(1,1);
+	float det = ME(0,0)*cofactor0 + ME(1,0)*cofactor3 + ME(2,0)*cofactor6;
+
+	DEBUG_ERR( IsZero( det ) ); // Cannot invert det == 0
+
+	// create adjoint matrix and multiply by 1/det to get inverse
+	float invDet = 1.0f/det;
+	result(0,0) = invDet*cofactor0;
+	result(0,1) = invDet*cofactor3;
+	result(0,2) = invDet*cofactor6;
+
+	result(1,0) = invDet*(ME(1,2)*ME(2,0) - ME(1,0)*ME(2,2));
+	result(1,1) = invDet*(ME(0,0)*ME(2,2) - ME(0,2)*ME(2,0));
+	result(1,2) = invDet*(ME(0,2)*ME(1,0) - ME(0,0)*ME(1,2));
+
+	result(2,0) = invDet*(ME(1,0)*ME(2,1) - ME(1,1)*ME(2,0));
+	result(2,1) = invDet*(ME(0,1)*ME(2,0) - ME(0,0)*ME(2,1));
+	result(2,2) = invDet*(ME(0,0)*ME(1,1) - ME(0,1)*ME(1,0));
+
+	return result;
+}
+
+// Invert
+// see above
+void mat3_t::Invert()
+{
+	ME = Inverted();
+}
+
+
+/*
+=======================================================================================================================================
+mat4_t                                                                                                                                =
+=======================================================================================================================================
+*/
+mat4_t mat4_t::ident( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 );
+mat4_t mat4_t::zero( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 );
+
+// constructor
+mat4_t::mat4_t( float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33 )
+{
+	ME(0,0) = m00;
+	ME(0,1) = m01;
+	ME(0,2) = m02;
+	ME(0,3) = m03;
+	ME(1,0) = m10;
+	ME(1,1) = m11;
+	ME(1,2) = m12;
+	ME(1,3) = m13;
+	ME(2,0) = m20;
+	ME(2,1) = m21;
+	ME(2,2) = m22;
+	ME(2,3) = m23;
+	ME(3,0) = m30;
+	ME(3,1) = m31;
+	ME(3,2) = m32;
+	ME(3,3) = m33;
+}
+
+// copy
+mat4_t& mat4_t::operator =( const mat4_t& b )
+{
+	ME[0] = b[0];
+	ME[1] = b[1];
+	ME[2] = b[2];
+	ME[3] = b[3];
+	ME[4] = b[4];
+	ME[5] = b[5];
+	ME[6] = b[6];
+	ME[7] = b[7];
+	ME[8] = b[8];
+	ME[9] = b[9];
+	ME[10] = b[10];
+	ME[11] = b[11];
+	ME[12] = b[12];
+	ME[13] = b[13];
+	ME[14] = b[14];
+	ME[15] = b[15];
+	return ME;
+}
+
+// 4x4 + 4x4
+mat4_t mat4_t::operator +( const mat4_t& b ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] + b[i];
+	return c;
+}
+
+// 4x4 + 4x4 (self)
+mat4_t& mat4_t::operator +=( const mat4_t& b )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] += b[i];
+	return ME;
+}
+
+// 4x4 - 4x4
+mat4_t mat4_t::operator -( const mat4_t& b ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] - b[i];
+	return c;
+}
+
+// 4x4 - 4x4 (self)
+mat4_t& mat4_t::operator -=( const mat4_t& b )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] -= b[i];
+	return ME;
+}
+
+// 4x4 * 4x4
+mat4_t mat4_t::operator *( const mat4_t& b ) const
+{
+	mat4_t c;
+	c(0,0) = ME(0,0)*b(0,0) + ME(0,1)*b(1,0) + ME(0,2)*b(2,0) + ME(0,3)*b(3,0);
+	c(0,1) = ME(0,0)*b(0,1) + ME(0,1)*b(1,1) + ME(0,2)*b(2,1) + ME(0,3)*b(3,1);
+	c(0,2) = ME(0,0)*b(0,2) + ME(0,1)*b(1,2) + ME(0,2)*b(2,2) + ME(0,3)*b(3,2);
+	c(0,3) = ME(0,0)*b(0,3) + ME(0,1)*b(1,3) + ME(0,2)*b(2,3) + ME(0,3)*b(3,3);
+	c(1,0) = ME(1,0)*b(0,0) + ME(1,1)*b(1,0) + ME(1,2)*b(2,0) + ME(1,3)*b(3,0);
+	c(1,1) = ME(1,0)*b(0,1) + ME(1,1)*b(1,1) + ME(1,2)*b(2,1) + ME(1,3)*b(3,1);
+	c(1,2) = ME(1,0)*b(0,2) + ME(1,1)*b(1,2) + ME(1,2)*b(2,2) + ME(1,3)*b(3,2);
+	c(1,3) = ME(1,0)*b(0,3) + ME(1,1)*b(1,3) + ME(1,2)*b(2,3) + ME(1,3)*b(3,3);
+	c(2,0) = ME(2,0)*b(0,0) + ME(2,1)*b(1,0) + ME(2,2)*b(2,0) + ME(2,3)*b(3,0);
+	c(2,1) = ME(2,0)*b(0,1) + ME(2,1)*b(1,1) + ME(2,2)*b(2,1) + ME(2,3)*b(3,1);
+	c(2,2) = ME(2,0)*b(0,2) + ME(2,1)*b(1,2) + ME(2,2)*b(2,2) + ME(2,3)*b(3,2);
+	c(2,3) = ME(2,0)*b(0,3) + ME(2,1)*b(1,3) + ME(2,2)*b(2,3) + ME(2,3)*b(3,3);
+	c(3,0) = ME(3,0)*b(0,0) + ME(3,1)*b(1,0) + ME(3,2)*b(2,0) + ME(3,3)*b(3,0);
+	c(3,1) = ME(3,0)*b(0,1) + ME(3,1)*b(1,1) + ME(3,2)*b(2,1) + ME(3,3)*b(3,1);
+	c(3,2) = ME(3,0)*b(0,2) + ME(3,1)*b(1,2) + ME(3,2)*b(2,2) + ME(3,3)*b(3,2);
+	c(3,3) = ME(3,0)*b(0,3) + ME(3,1)*b(1,3) + ME(3,2)*b(2,3) + ME(3,3)*b(3,3);
+	return c;
+}
+
+// 4x4 * 4x4 (self)
+mat4_t& mat4_t::operator *=( const mat4_t& b )
+{
+	ME = ME * b;
+	return ME;
+}
+
+// 4x4 * vec3
+vec3_t mat4_t::operator *( const vec3_t& b ) const
+{
+	return vec3_t(
+		ME(0,0)*b.x + ME(0,1)*b.y + ME(0,2)*b.z + ME(0,3),
+		ME(1,0)*b.x + ME(1,1)*b.y + ME(1,2)*b.z + ME(1,3),
+		ME(2,0)*b.x + ME(2,1)*b.y + ME(2,2)*b.z + ME(2,3)
+	);
+}
+
+// 4x4 * vec4
+vec4_t mat4_t::operator *( const vec4_t& b ) const
+{
+	return vec4_t(
+		ME(0,0)*b.x + ME(0,1)*b.y + ME(0,2)*b.z + ME(0,3)*b.w,
+		ME(1,0)*b.x + ME(1,1)*b.y + ME(1,2)*b.z + ME(1,3)*b.w,
+		ME(2,0)*b.x + ME(2,1)*b.y + ME(2,2)*b.z + ME(2,3)*b.w,
+		ME(3,0)*b.x + ME(3,1)*b.y + ME(3,2)*b.z + ME(3,3)*b.w
+	);
+}
+
+// 4x4 * scalar
+mat4_t mat4_t::operator *( float f ) const
+{
+	mat4_t c;
+	for( int i=0; i<16; i++ )
+		c[i] = ME[i] * f;
+	return c;
+}
+
+// 4x4 * scalar (self)
+mat4_t& mat4_t::operator *=( float f )
+{
+	for( int i=0; i<16; i++ )
+		ME[i] *= f;
+	return ME;
+}
+
+// ==
+bool mat4_t::operator ==( const mat4_t& b ) const
+{
+	for( int i=0; i<16; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return false;
+	return true;
+}
+
+// !=
+bool mat4_t::operator !=( const mat4_t& b ) const
+{
+	for( int i=0; i<16; i++ )
+		if( !IsZero( ME[i]-b[i] ) ) return true;
+	return false;
+}
+
+// SetRows
+void mat4_t::SetRows( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d )
+{
+	ME(0,0) = a.x;
+	ME(0,1) = a.y;
+	ME(0,2) = a.z;
+	ME(0,3) = a.w;
+	ME(1,0) = b.x;
+	ME(1,1) = b.y;
+	ME(1,2) = b.z;
+	ME(1,3) = b.w;
+	ME(2,0) = c.x;
+	ME(2,1) = c.y;
+	ME(2,2) = c.z;
+	ME(2,3) = c.w;
+	ME(3,0) = d.x;
+	ME(3,1) = d.y;
+	ME(3,2) = d.z;
+	ME(3,3) = d.w;
+}
+
+// SetRow
+void mat4_t::SetRow( uint i, const vec4_t& v )
+{
+	DEBUG_ERR( i > 3 );
+	ME(i,0) = v.x;
+	ME(i,1) = v.y;
+	ME(i,2) = v.z;
+	ME(i,3) = v.w;
+}
+
+// SetColumns
+void mat4_t::SetColumns( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d )
+{
+	ME(0,0) = a.x;
+	ME(1,0) = a.y;
+	ME(2,0) = a.z;
+	ME(3,0) = a.w;
+	ME(0,1) = b.x;
+	ME(1,1) = b.y;
+	ME(2,1) = b.z;
+	ME(3,1) = b.w;
+	ME(0,2) = c.x;
+	ME(1,2) = c.y;
+	ME(2,2) = c.z;
+	ME(3,2) = c.w;
+	ME(0,3) = d.x;
+	ME(1,3) = d.y;
+	ME(2,3) = d.z;
+	ME(3,3) = d.w;
+}
+
+// SetColumn
+void mat4_t::SetColumn( uint i, const vec4_t& v )
+{
+	DEBUG_ERR( i > 3 );
+	ME(0,i) = v.x;
+	ME(1,i) = v.y;
+	ME(2,i) = v.z;
+	ME(3,i) = v.w;
+}
+
+// Transpose
+void mat4_t::Transpose()
+{
+	float tmp = ME(0,1);
+	ME(0,1) = ME(1,0);
+	ME(1,0) = tmp;
+	tmp = ME(0,2);
+	ME(0,2) = ME(2,0);
+	ME(2,0) = tmp;
+	tmp = ME(0,3);
+	ME(0,3) = ME(3,0);
+	ME(3,0) = tmp;
+	tmp = ME(1,2);
+	ME(1,2) = ME(2,1);
+	ME(2,1) = tmp;
+	tmp = ME(1,3);
+	ME(1,3) = ME(3,1);
+	ME(3,1) = tmp;
+	tmp = ME(2,3);
+	ME(2,3) = ME(3,2);
+	ME(3,2) = tmp;
+}
+
+// Transposed
+// return the transposed
+mat4_t mat4_t::Transposed() const
+{
+	mat4_t m4;
+	m4[0] = ME[0];
+	m4[1] = ME[4];
+	m4[2] = ME[8];
+	m4[3] = ME[12];
+	m4[4] = ME[1];
+	m4[5] = ME[5];
+	m4[6] = ME[9];
+	m4[7] = ME[13];
+	m4[8] = ME[2];
+	m4[9] = ME[6];
+	m4[10] = ME[10];
+	m4[11] = ME[14];
+	m4[12] = ME[3];
+	m4[13] = ME[7];
+	m4[14] = ME[11];
+	m4[15] = ME[15];
+	return m4;
+}
+
+// SetIdent
+void mat4_t::SetIdent()
+{
+	ME = ident;
+}
+
+// SetZero
+void mat4_t::SetZero()
+{
+	ME[15] = ME[14] = ME[13] = ME[12] = ME[11] = ME[10] = ME[9] = ME[8] = ME[7] = ME[6] = ME[5] =
+	ME[4] = ME[3] = ME[2] = ME[1] = ME[0] = 0.0f;
+}
+
+// Set
+// vec3
+void mat4_t::Set( const vec3_t& v )
+{
+	SetIdent();
+	ME(0, 3) = v.x;
+	ME(1, 3) = v.y;
+	ME(2, 3) = v.z;
+}
+
+// Set
+// vec4
+void mat4_t::Set( const vec4_t& v )
+{
+	ME(0, 0) = 1.0;
+	ME(0, 1) = 0.0;
+	ME(0, 2) = 0.0;
+	ME(0, 3) = v.x;
+	ME(1, 0) = 0.0;
+	ME(1, 1) = 1.0;
+	ME(1, 2) = 0.0;
+	ME(1, 3) = v.y;
+	ME(2, 0) = 0.0;
+	ME(2, 1) = 0.0;
+	ME(2, 2) = 1.0;
+	ME(2, 3) = v.z;
+	ME(3, 0) = 0.0;
+	ME(3, 1) = 0.0;
+	ME(3, 2) = 0.0;
+	ME(3, 3) = v.w;
+}
+
+// 3x3 to 4x4
+void mat4_t::Set( const mat3_t& m3 )
+{
+	ME(0,0) = m3(0,0);
+	ME(0,1) = m3(0,1);
+	ME(0,2) = m3(0,2);
+	ME(1,0) = m3(1,0);
+	ME(1,1) = m3(1,1);
+	ME(1,2) = m3(1,2);
+	ME(2,0) = m3(2,0);
+	ME(2,1) = m3(2,1);
+	ME(2,2) = m3(2,2);
+	ME(3, 0) = ME(3, 1) = ME(3, 2) = ME(0, 3) = ME(1, 3) = ME(2, 3) = 0.0f;
+	ME(3, 3) = 1.0f;
+}
+
+// Set
+// from transformation and rotation
+void mat4_t::Set( const vec3_t& transl, const mat3_t& rot )
+{
+	SetRotationPart(rot);
+	SetTranslationPart(transl);
+	ME(3,0) = ME(3,1) = ME(3,2) = 0.0;
+	ME(3,3) = 1.0f;
+}
+
+// Set
+// from transformation, rotation and scale
+void mat4_t::Set( const vec3_t& translate, const mat3_t& rotate, float scale )
+{
+	if( !IsZero( scale-1.0 ) )
+		SetRotationPart( rotate*scale );
+	else
+		SetRotationPart( rotate );
+
+	SetTranslationPart( translate );
+
+	ME(3,0) = ME(3,1) = ME(3,2) = 0.0;
+	ME(3,3) = 1.0f;
+}
+
+// SetRotationPart
+void mat4_t::SetRotationPart( const mat3_t& m3 )
+{
+	ME(0,0) = m3(0,0);
+	ME(0,1) = m3(0,1);
+	ME(0,2) = m3(0,2);
+	ME(1,0) = m3(1,0);
+	ME(1,1) = m3(1,1);
+	ME(1,2) = m3(1,2);
+	ME(2,0) = m3(2,0);
+	ME(2,1) = m3(2,1);
+	ME(2,2) = m3(2,2);
+}
+
+// GetRotationPart
+mat3_t mat4_t::GetRotationPart() const
+{
+	mat3_t m3;
+	m3(0,0) = ME(0,0);
+	m3(0,1) = ME(0,1);
+	m3(0,2) = ME(0,2);
+	m3(1,0) = ME(1,0);
+	m3(1,1) = ME(1,1);
+	m3(1,2) = ME(1,2);
+	m3(2,0) = ME(2,0);
+	m3(2,1) = ME(2,1);
+	m3(2,2) = ME(2,2);
+	return m3;
+}
+
+// SetTranslationPart
+void mat4_t::SetTranslationPart( const vec4_t& v )
+{
+	ME(0, 3) = v.x;
+	ME(1, 3) = v.y;
+	ME(2, 3) = v.z;
+	ME(3, 3) = v.w;
+}
+
+// SetTranslationPart
+void mat4_t::SetTranslationPart( const vec3_t& v )
+{
+	ME(0, 3) = v.x;
+	ME(1, 3) = v.y;
+	ME(2, 3) = v.z;
+}
+
+// GetTranslationPart
+vec3_t mat4_t::GetTranslationPart() const
+{
+	return vec3_t( ME(0, 3), ME(1, 3), ME(2, 3) );
+}
+
+// Print
+void mat4_t::Print() const
+{
+	cout << fixed;
+	for( int i=0; i<4; i++ )
+	{
+		for( int j=0; j<4; j++ )
+		{
+			if( ME(i, j) < 0.0 )
+				cout << ME(i, j) << " ";
+			else
+				cout << " " << ME(i, j) << " ";
+		}
+		cout << endl;
+	}
+	cout << endl;
+}
+
+// Determinant
+float mat4_t::Det() const
+{
+	return
+	ME(0, 3)*ME(1, 2)*ME(2, 1)*ME(3, 0) - ME(0, 2)*ME(1, 3)*ME(2, 1)*ME(3, 0) -
+	ME(0, 3)*ME(1, 1)*ME(2, 2)*ME(3, 0) + ME(0, 1)*ME(1, 3)*ME(2, 2)*ME(3, 0) +
+	ME(0, 2)*ME(1, 1)*ME(2, 3)*ME(3, 0) - ME(0, 1)*ME(1, 2)*ME(2, 3)*ME(3, 0) -
+	ME(0, 3)*ME(1, 2)*ME(2, 0)*ME(3, 1) + ME(0, 2)*ME(1, 3)*ME(2, 0)*ME(3, 1) +
+	ME(0, 3)*ME(1, 0)*ME(2, 2)*ME(3, 1) - ME(0, 0)*ME(1, 3)*ME(2, 2)*ME(3, 1) -
+	ME(0, 2)*ME(1, 0)*ME(2, 3)*ME(3, 1) + ME(0, 0)*ME(1, 2)*ME(2, 3)*ME(3, 1) +
+	ME(0, 3)*ME(1, 1)*ME(2, 0)*ME(3, 2) - ME(0, 1)*ME(1, 3)*ME(2, 0)*ME(3, 2) -
+	ME(0, 3)*ME(1, 0)*ME(2, 1)*ME(3, 2) + ME(0, 0)*ME(1, 3)*ME(2, 1)*ME(3, 2) +
+	ME(0, 1)*ME(1, 0)*ME(2, 3)*ME(3, 2) - ME(0, 0)*ME(1, 1)*ME(2, 3)*ME(3, 2) -
+	ME(0, 2)*ME(1, 1)*ME(2, 0)*ME(3, 3) + ME(0, 1)*ME(1, 2)*ME(2, 0)*ME(3, 3) +
+	ME(0, 2)*ME(1, 0)*ME(2, 1)*ME(3, 3) - ME(0, 0)*ME(1, 2)*ME(2, 1)*ME(3, 3) -
+	ME(0, 1)*ME(1, 0)*ME(2, 2)*ME(3, 3) + ME(0, 0)*ME(1, 1)*ME(2, 2)*ME(3, 3);
+}
+
+// Invert
+void mat4_t::Invert()
+{
+	ME = Inverted();
+}
+
+// Inverted
+mat4_t mat4_t::Inverted() const
+{
+	float tmp[12];
+	float det;
+
+	mat4_t m4;
+
+	tmp[0] = ME(2,2) * ME(3,3);
+	tmp[1] = ME(3,2) * ME(2,3);
+	tmp[2] = ME(1,2) * ME(3,3);
+	tmp[3] = ME(3,2) * ME(1,3);
+	tmp[4] = ME(1,2) * ME(2,3);
+	tmp[5] = ME(2,2) * ME(1,3);
+	tmp[6] = ME(0,2) * ME(3,3);
+	tmp[7] = ME(3,2) * ME(0,3);
+	tmp[8] = ME(0,2) * ME(2,3);
+	tmp[9] = ME(2,2) * ME(0,3);
+	tmp[10] = ME(0,2) * ME(1,3);
+	tmp[11] = ME(1,2) * ME(0,3);
+
+	m4(0,0) =  tmp[0]*ME(1,1) + tmp[3]*ME(2,1) + tmp[4]*ME(3,1);
+	m4(0,0) -= tmp[1]*ME(1,1) + tmp[2]*ME(2,1) + tmp[5]*ME(3,1);
+	m4(0,1) =  tmp[1]*ME(0,1) + tmp[6]*ME(2,1) + tmp[9]*ME(3,1);
+	m4(0,1) -= tmp[0]*ME(0,1) + tmp[7]*ME(2,1) + tmp[8]*ME(3,1);
+	m4(0,2) =  tmp[2]*ME(0,1) + tmp[7]*ME(1,1) + tmp[10]*ME(3,1);
+	m4(0,2) -= tmp[3]*ME(0,1) + tmp[6]*ME(1,1) + tmp[11]*ME(3,1);
+	m4(0,3) =  tmp[5]*ME(0,1) + tmp[8]*ME(1,1) + tmp[11]*ME(2,1);
+	m4(0,3) -= tmp[4]*ME(0,1) + tmp[9]*ME(1,1) + tmp[10]*ME(2,1);
+	m4(1,0) =  tmp[1]*ME(1,0) + tmp[2]*ME(2,0) + tmp[5]*ME(3,0);
+	m4(1,0) -= tmp[0]*ME(1,0) + tmp[3]*ME(2,0) + tmp[4]*ME(3,0);
+	m4(1,1) =  tmp[0]*ME(0,0) + tmp[7]*ME(2,0) + tmp[8]*ME(3,0);
+	m4(1,1) -= tmp[1]*ME(0,0) + tmp[6]*ME(2,0) + tmp[9]*ME(3,0);
+	m4(1,2) =  tmp[3]*ME(0,0) + tmp[6]*ME(1,0) + tmp[11]*ME(3,0);
+	m4(1,2) -= tmp[2]*ME(0,0) + tmp[7]*ME(1,0) + tmp[10]*ME(3,0);
+	m4(1,3) =  tmp[4]*ME(0,0) + tmp[9]*ME(1,0) + tmp[10]*ME(2,0);
+	m4(1,3) -= tmp[5]*ME(0,0) + tmp[8]*ME(1,0) + tmp[11]*ME(2,0);
+
+	tmp[0] = ME(2,0)*ME(3,1);
+	tmp[1] = ME(3,0)*ME(2,1);
+	tmp[2] = ME(1,0)*ME(3,1);
+	tmp[3] = ME(3,0)*ME(1,1);
+	tmp[4] = ME(1,0)*ME(2,1);
+	tmp[5] = ME(2,0)*ME(1,1);
+	tmp[6] = ME(0,0)*ME(3,1);
+	tmp[7] = ME(3,0)*ME(0,1);
+	tmp[8] = ME(0,0)*ME(2,1);
+	tmp[9] = ME(2,0)*ME(0,1);
+	tmp[10] = ME(0,0)*ME(1,1);
+	tmp[11] = ME(1,0)*ME(0,1);
+
+	m4(2,0) = tmp[0]*ME(1,3) + tmp[3]*ME(2,3) + tmp[4]*ME(3,3);
+	m4(2,0)-= tmp[1]*ME(1,3) + tmp[2]*ME(2,3) + tmp[5]*ME(3,3);
+	m4(2,1) = tmp[1]*ME(0,3) + tmp[6]*ME(2,3) + tmp[9]*ME(3,3);
+	m4(2,1)-= tmp[0]*ME(0,3) + tmp[7]*ME(2,3) + tmp[8]*ME(3,3);
+	m4(2,2) = tmp[2]*ME(0,3) + tmp[7]*ME(1,3) + tmp[10]*ME(3,3);
+	m4(2,2)-= tmp[3]*ME(0,3) + tmp[6]*ME(1,3) + tmp[11]*ME(3,3);
+	m4(2,3) = tmp[5]*ME(0,3) + tmp[8]*ME(1,3) + tmp[11]*ME(2,3);
+	m4(2,3)-= tmp[4]*ME(0,3) + tmp[9]*ME(1,3) + tmp[10]*ME(2,3);
+	m4(3,0) = tmp[2]*ME(2,2) + tmp[5]*ME(3,2) + tmp[1]*ME(1,2);
+	m4(3,0)-= tmp[4]*ME(3,2) + tmp[0]*ME(1,2) + tmp[3]*ME(2,2);
+	m4(3,1) = tmp[8]*ME(3,2) + tmp[0]*ME(0,2) + tmp[7]*ME(2,2);
+	m4(3,1)-= tmp[6]*ME(2,2) + tmp[9]*ME(3,2) + tmp[1]*ME(0,2);
+	m4(3,2) = tmp[6]*ME(1,2) + tmp[11]*ME(3,2) + tmp[3]*ME(0,2);
+	m4(3,2)-= tmp[10]*ME(3,2) + tmp[2]*ME(0,2) + tmp[7]*ME(1,2);
+	m4(3,3) = tmp[10]*ME(2,2) + tmp[4]*ME(0,2) + tmp[9]*ME(1,2);
+	m4(3,3)-= tmp[8]*ME(1,2) + tmp[11]*ME(2,2) + tmp[5]*ME(0,2);
+
+	det = ME(0,0)*m4(0,0)+ME(1,0)*m4(0,1)+ME(2,0)*m4(0,2)+ME(3,0)*m4(0,3);
+	DEBUG_ERR( IsZero( det ) ); // Cannot invert, det == 0
+	det = 1/det;
+	m4 *= det;
+	return m4;
+}
+
+// Lerp
+mat4_t mat4_t::Lerp( const mat4_t& b, float t ) const
+{
+	return (ME*(1.0f-t))+(b*t);
+}
+
+// CombineTransformations
+mat4_t mat4_t::CombineTransformations( const mat4_t& m0, const mat4_t& m1 )
+{
+	/* the clean code is:
+	mat3_t rot = m0.GetRotationPart() * m1.GetRotationPart();  // combine the rotations
+	vec3_t tra = (m1.GetTranslationPart()).Transformed( m0.GetTranslationPart(), m0.GetRotationPart(), 1.0 );
+	return mat4_t( tra, rot );
+	and the optimized: */
+	DEBUG_ERR( !IsZero( m0(3,0)+m0(3,1)+m0(3,2)+m0(3,3)-1.0 ) ||
+	           !IsZero( m1(3,0)+m1(3,1)+m1(3,2)+m1(3,3)-1.0 ) ); // one of the 2 mat4 doesnt represent transformation
+
+	mat4_t m4;
+
+	m4(0, 0) = m0(0, 0)*m1(0, 0) + m0(0, 1)*m1(1, 0) + m0(0, 2)*m1(2, 0);
+	m4(0, 1) = m0(0, 0)*m1(0, 1) + m0(0, 1)*m1(1, 1) + m0(0, 2)*m1(2, 1);
+	m4(0, 2) = m0(0, 0)*m1(0, 2) + m0(0, 1)*m1(1, 2) + m0(0, 2)*m1(2, 2);
+	m4(1, 0) = m0(1, 0)*m1(0, 0) + m0(1, 1)*m1(1, 0) + m0(1, 2)*m1(2, 0);
+	m4(1, 1) = m0(1, 0)*m1(0, 1) + m0(1, 1)*m1(1, 1) + m0(1, 2)*m1(2, 1);
+	m4(1, 2) = m0(1, 0)*m1(0, 2) + m0(1, 1)*m1(1, 2) + m0(1, 2)*m1(2, 2);
+	m4(2, 0) = m0(2, 0)*m1(0, 0) + m0(2, 1)*m1(1, 0) + m0(2, 2)*m1(2, 0);
+	m4(2, 1) = m0(2, 0)*m1(0, 1) + m0(2, 1)*m1(1, 1) + m0(2, 2)*m1(2, 1);
+	m4(2, 2) = m0(2, 0)*m1(0, 2) + m0(2, 1)*m1(1, 2) + m0(2, 2)*m1(2, 2);
+
+	m4(0, 3) = m0(0, 0)*m1(0, 3) + m0(0, 1)*m1(1, 3) + m0(0, 2)*m1(2, 3) + m0(0, 3);
+	m4(1, 3) = m0(1, 0)*m1(0, 3) + m0(1, 1)*m1(1, 3) + m0(1, 2)*m1(2, 3) + m0(1, 3);
+	m4(2, 3) = m0(2, 0)*m1(0, 3) + m0(2, 1)*m1(1, 3) + m0(2, 2)*m1(2, 3) + m0(2, 3);
+
+	m4(3,0) = m4(3,1) = m4(3,2) = 0.0;
+	m4(3,3) = 1.0f;
+
+	return m4;
+}

+ 488 - 0
src/old_src/math.h

@@ -0,0 +1,488 @@
+#ifndef _MATH_H_
+#define _MATH_H_
+
+#include <stdio.h>
+#include <math.h>
+#include "common.h"
+
+#define PI 3.14159265358979323846f
+#define EPSILON 1.0e-6f
+
+
+class vec2_t;
+class vec4_t;
+class vec3_t;
+class quat_t;
+class euler_t;
+class axisang_t;
+class mat3_t;
+class mat4_t;
+
+
+
+/*
+=======================================================================================================================================
+vector 2                                                                                                                              =
+=======================================================================================================================================
+*/
+class vec2_t
+{
+	public:
+		// data members
+		float x, y;
+		static vec2_t zero;
+		// access to the data
+		inline float& operator []( uint i )  { return (&x)[i]; }
+		inline float  operator []( uint i ) const { return (&x)[i]; }
+		// constructors & distructors
+		inline vec2_t(): x(0.0), y(0.0) {}
+		inline vec2_t( float x_, float y_ ): x(x_), y(y_) {}
+		inline vec2_t( float f ): x(f), y(f) {}
+		inline vec2_t( const vec2_t& b ) { (*this) = b; }
+		       vec2_t( const vec3_t& v3 );
+		       vec2_t( const vec4_t& v4 );
+		// ops with same type
+		vec2_t& operator = ( const vec2_t& b );
+		vec2_t  operator + ( const vec2_t& b ) const;
+		vec2_t& operator +=( const vec2_t& b );
+		vec2_t  operator - ( const vec2_t& b ) const;
+		vec2_t& operator -=( const vec2_t& b );
+		vec2_t  operator * ( const vec2_t& b ) const;
+		vec2_t& operator *=( const vec2_t& b );
+		vec2_t  operator / ( const vec2_t& b ) const;
+		vec2_t& operator /=( const vec2_t& b );
+		vec2_t  operator - () const; // return the negative
+		// other types
+		vec2_t  operator * ( float f ) const;
+		vec2_t& operator *=( float f );
+		vec2_t  operator / ( float f ) const;
+		vec2_t& operator /=( float f );
+		// comparision
+		bool operator ==( const vec2_t& b ) const;
+		bool operator !=( const vec2_t& b ) const;
+		// other
+		float  Length() const;
+		void   SetZero();
+		void   Normalize();
+		vec2_t Normalized() const;
+		float  Dot( const vec2_t& b ) const;
+		void   Print() const;
+};
+
+
+/*
+=======================================================================================================================================
+vector 3                                                                                                                              =
+used as column matrix in mat*vec                                                                                                      =
+=======================================================================================================================================
+*/
+class vec3_t
+{
+	public:
+		// data members
+		float x, y, z;
+		static vec3_t zero;
+		static vec3_t one;
+		static vec3_t i, j, k; // unit vectors
+		// access to the data
+		inline float& operator []( uint i )  { return (&x)[i]; }
+		inline float  operator []( uint i ) const { return (&x)[i]; }
+		// constructors & distructors
+		inline vec3_t(): x(0.0), y(0.0), z(0.0) {}
+		inline vec3_t( float x_, float y_, float z_ ): x(x_), y(y_), z(z_) {}
+		inline vec3_t( float f ): x(f), y(f), z(f) {}
+		inline vec3_t( const vec3_t& b ) { (*this)=b; }
+		inline vec3_t( const vec2_t& v2, float z_ ): x(v2.x), y(v2.y), z(z_) {}
+		       vec3_t( const vec4_t& v4 );
+		       vec3_t( const quat_t& q );
+		// ops with same type
+		vec3_t& operator = ( const vec3_t& b );
+		vec3_t  operator + ( const vec3_t& b ) const;
+		vec3_t& operator +=( const vec3_t& b );
+		vec3_t  operator - ( const vec3_t& b ) const;
+		vec3_t& operator -=( const vec3_t& b );
+		vec3_t  operator * ( const vec3_t& b ) const;
+		vec3_t& operator *=( const vec3_t& b );
+		vec3_t  operator / ( const vec3_t& b ) const;
+		vec3_t& operator /=( const vec3_t& b );
+		vec3_t  operator - () const; // return the negative
+		// other types
+		vec3_t  operator * ( float f ) const;
+		vec3_t& operator *=( float f );
+		vec3_t  operator / ( float f ) const;
+		vec3_t& operator /=( float f );
+		vec3_t  operator * ( const mat3_t& m3 ) const;
+		// comparision
+		bool operator ==( const vec3_t& b ) const;
+		bool operator !=( const vec3_t& b ) const;
+		// other
+		float  Dot( const vec3_t& b ) const;
+		vec3_t Cross( const vec3_t& b ) const;
+		float  Length() const;
+		float  LengthSquared() const;
+		float  DistanceSquared( const vec3_t& b ) const { return ((*this)-b).LengthSquared(); }
+		void   Normalize();
+		vec3_t Normalized() const;
+		void   SetZero() { z=y=x=0.0; };
+		vec3_t Project( const vec3_t& to_this ) const;
+		vec3_t Rotated( const quat_t& q ) const; // returns q * this * q.Conjucated() aka rotates this. 21 muls, 12 adds
+		void   Rotate( const quat_t& q );
+		vec3_t Lerp( const vec3_t& v1, float t ) const; // return Lerp( this, v1, t )
+		void   Print() const;
+		// transformations. The faster way is by far the mat4 * vec3 or the Transformed( vec3_t, mat3_t )
+		vec3_t Transformed( const vec3_t& translate, const mat3_t& rotate, float scale ) const;
+		void   Transform( const vec3_t& translate, const mat3_t& rotate, float scale ) { (*this)=Transformed( translate, rotate, scale ); }
+		vec3_t Transformed( const vec3_t& translate, const mat3_t& rotate ) const;
+		void   Transform( const vec3_t& translate, const mat3_t& rotate ) { (*this)=Transformed( translate, rotate ); }
+		vec3_t Transformed( const vec3_t& translate, const quat_t& rotate, float scale ) const;
+		void   Transform( const vec3_t& translate, const quat_t& rotate, float scale ) { (*this)=Transformed( translate, rotate, scale ); }
+};
+
+
+/*
+=======================================================================================================================================
+vector 4                                                                                                                              =
+=======================================================================================================================================
+*/
+class vec4_t
+{
+	public:
+		// data members
+		float x, y, z, w;
+		static vec4_t zero, one, i, j, k, l;
+		// access to the data
+		inline float& operator []( uint i )  { return (&x)[i]; }
+		inline float operator []( uint i ) const { return (&x)[i]; }
+		// constructors & distructors
+		inline vec4_t(): x(0.0), y(0.0), z(0.0), w(0.0) {}
+		inline vec4_t( float x_, float y_, float z_, float w_ ): x(x_), y(y_), z(z_), w(w_) {}
+		inline vec4_t( float f ): x(f), y(f), z(f), w(f) {}
+		inline vec4_t( const vec4_t& b ) { (*this)=b; }
+		inline vec4_t( const vec4_t& v2, float z_, float w_ ): x(v2.x), y(v2.y), z(z_), w(w_) {}
+		inline vec4_t( const vec3_t& v3, float w_ ): x(v3.x), y(v3.y), z(v3.z), w(w_) {}
+		// ops with same
+		vec4_t& operator = ( const vec4_t& b );
+		vec4_t  operator + ( const vec4_t& b ) const;
+		vec4_t& operator +=( const vec4_t& b );
+		vec4_t  operator - ( const vec4_t& b ) const;
+		vec4_t& operator -=( const vec4_t& b );
+		vec4_t  operator - () const; // return the negative
+		vec4_t  operator * ( const vec4_t& b ) const; // for color operations
+		vec4_t& operator *=( const vec4_t& b );       //       >>
+		vec4_t  operator / ( const vec4_t& b ) const;
+		vec4_t& operator /=( const vec4_t& b );
+		// ops with other
+		vec4_t  operator * ( float f ) const;
+		vec4_t& operator *=( float f );
+		vec4_t  operator / ( float f ) const;
+		vec4_t& operator /=( float f );
+		vec4_t  operator * ( const mat4_t& m4 ) const;
+		// comparision
+		bool operator ==( const vec4_t& b ) const;
+		bool operator !=( const vec4_t& b ) const;
+		// other
+		void  SetZero();
+		float Length() const;
+		void  Normalize();
+		void  Print() const;
+		float Dot( const vec4_t& b ) const;
+};
+
+
+/*
+=======================================================================================================================================
+quaternion                                                                                                                            =
+=======================================================================================================================================
+*/
+class quat_t
+{
+	public:
+		// data members
+		float w, x, y, z;
+		static quat_t zero;
+		static quat_t ident;
+		// access to the data
+		inline float& operator []( uint i )  { return (&w)[i]; }
+		inline float operator []( uint i) const { return (&w)[i]; }
+		// constructors & distructors
+		inline quat_t() {}
+		inline quat_t( float w_, float x_, float y_, float z_ ): w(w_), x(x_), y(y_), z(z_) {}
+		inline quat_t( const quat_t& q ) { (*this)=q; }
+		inline quat_t( const mat3_t& m3 ) { Set(m3); }
+		inline quat_t( const euler_t& eu ) { Set(eu); }
+		inline quat_t( const axisang_t& axisang ) { Set( axisang ); }
+		inline quat_t( const vec3_t& v0, const vec3_t& v1 ) { CalcFromVecVec( v0, v1 ); }
+		inline quat_t( const vec3_t& v ) { Set(v); }
+		inline quat_t( const vec4_t& v ) { Set(v); }
+		// ops with same
+		quat_t& operator = ( const quat_t& b );
+		quat_t  operator + ( const quat_t& b ) const;
+		quat_t& operator +=( const quat_t& b );
+		quat_t  operator - ( const quat_t& b ) const;
+		quat_t& operator -=( const quat_t& b );
+		quat_t  operator * ( const quat_t& b ) const;
+		quat_t& operator *=( const quat_t& b );
+		// ops with other
+		quat_t  operator * ( float f ) const; // used to combine rotations. 16 muls and 12 adds
+		quat_t& operator *=( float f );
+		quat_t  operator / ( float f ) const;
+		quat_t& operator /=( float f );
+		// comparision
+		bool operator ==( const quat_t& b ) const;
+		bool operator !=( const quat_t& b ) const;
+		// other
+		void   Set( const mat3_t& m );
+		void   Set( const euler_t& e );
+		void   Set( const axisang_t& axisang );
+		void   CalcFromVecVec( const vec3_t& v0, const vec3_t& v1 ); // calculates the quat from v0 to v1
+		void   Set( const vec3_t& v ); // quat is: v.x*i + v.y*j + v.z*k + 0.0
+		void   Set( const vec4_t& v ); // quat is: v.x*i + v.y*j + v.z*k + v.w
+		void   SetIdent();
+		void   SetZero();
+		float  Length() const;
+		void   Invert();
+		void   Conjugate();
+		quat_t Conjugated() const;
+		void   Normalize();
+		void   Print() const;
+		float  Dot( const quat_t& b ) const;
+		quat_t Slerp( const quat_t& q1, float t ) const; // returns Slerp( this, q1, t )
+};
+
+
+/*
+=======================================================================================================================================
+euler angles in RAD                                                                                                                   =
+=======================================================================================================================================
+*/
+class euler_t
+{
+	public:
+		// data members
+		float x, y, z;
+		// access to the data
+		inline float& operator []( uint i )      { return (&x)[i]; }
+		inline float  operator []( uint i) const { return (&x)[i]; }
+		float& bank()           { return x; }
+		float  bank() const     { return x; }
+		float& heading()        { return y; }
+		float  heading() const  { return y; }
+		float& attitude()       { return z; }
+		float  attitude() const { return z; }
+		// constructors & distructors
+		inline euler_t() {}
+		inline euler_t( float x_, float y_, float z_  ) { x=x_; y=y_; z=z_; }
+		inline euler_t( const euler_t& b ) { (*this)=b; }
+		inline euler_t( const quat_t& q ) { Set(q); }
+		inline euler_t( const mat3_t& m3 ) { Set(m3); }
+		// ops with same
+		euler_t& operator = ( const euler_t& b );
+		// other
+		void SetZero();
+		void Set( const quat_t& q );
+		void Set( const mat3_t& m3 );
+		void Print() const;
+};
+
+
+/*
+=======================================================================================================================================
+axis orientation                                                                                                                      =
+=======================================================================================================================================
+*/
+class axisang_t
+{
+	public:
+		// data members
+		float ang;
+		vec3_t axis;
+		// constructors & distructors
+		inline axisang_t() {}
+		inline axisang_t( float rad, const vec3_t& axis_ ) { ang=rad; axis=axis_; }
+		inline axisang_t( const quat_t& q ) { Set(q); }
+		inline axisang_t( const mat3_t& m3 ) { Set(m3); }
+		// misc
+		void Set( const quat_t& q );
+		void Set( const mat3_t& m3 );
+};
+
+
+/*
+=======================================================================================================================================
+matrix 3x3                                                                                                                            =
+=======================================================================================================================================
+*/
+class mat3_t
+{
+	public:
+		// data members
+		float data_m3[9];
+		static mat3_t ident;
+		static mat3_t zero;
+		// accessors
+		inline float& operator ()( uint i, uint j ) { return data_m3[3*i+j]; }
+		inline float  operator ()( uint i, uint j ) const { return data_m3[3*i+j]; }
+		inline float& operator []( uint i) { return data_m3[i]; }    // used to access the array serial. It must be data_m3[i] cause its optimized
+		inline float  operator []( uint i) const { return data_m3[i]; }
+		// constructors & distructors
+		inline mat3_t() {}
+		       mat3_t( float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22 );
+		inline mat3_t( const mat3_t& b ) { (*this)=b; }
+		inline mat3_t( const quat_t& q ) { Set(q); }
+		inline mat3_t( const euler_t& eu ) { Set(eu); }
+		inline mat3_t( const axisang_t& axisang ) { Set(axisang); }
+		// ops with mat3
+		mat3_t& operator = ( const mat3_t& b );
+		mat3_t  operator + ( const mat3_t& b ) const;
+		mat3_t& operator +=( const mat3_t& b );
+		mat3_t  operator - ( const mat3_t& b ) const;
+		mat3_t& operator -=( const mat3_t& b );
+		mat3_t  operator * ( const mat3_t& b ) const; // 27 muls, 18 adds
+		mat3_t& operator *=( const mat3_t& b );
+		// ops with others
+		vec3_t  operator * ( const vec3_t& b ) const;  // 9 muls, 6 adds
+		mat3_t  operator * ( float f ) const;
+		mat3_t& operator *=( float f );
+		// comparision
+		bool operator ==( const mat3_t& b ) const;
+		bool operator !=( const mat3_t& b ) const;
+		// other
+		void   SetRows( const vec3_t& a, const vec3_t& b, const vec3_t& c );
+		void   SetRow( const uint i, const vec3_t& v ) { (*this)(i,0)=v.x; (*this)(i,1)=v.y; (*this)(i,2)=v.z; }
+		void   GetRows( vec3_t& a, vec3_t& b, vec3_t& c ) const;
+		vec3_t GetRow( const uint i ) const { return vec3_t( (*this)(i,0), (*this)(i,1), (*this)(i,2) ); }
+		void   SetColumns( const vec3_t& a, const vec3_t& b, const vec3_t& c );
+		void   SetColumn( const uint i, const vec3_t& v ) { (*this)(0,i)=v.x; (*this)(1,i)=v.y; (*this)(2,i)=v.z; }
+		void   GetColumns( vec3_t& a, vec3_t& b, vec3_t& c ) const;
+		vec3_t GetColumn( const uint i ) const { return vec3_t( (*this)(0,i), (*this)(1,i), (*this)(2,i) ); }
+		void   Set( const quat_t& q ); // 12 muls, 12 adds
+		void   Set( const euler_t& e );
+		void   Set( const axisang_t& axisang );
+		void   SetRotationX( float rad );
+		void   SetRotationY( float rad );
+		void   SetRotationZ( float rad );
+		void   RotateXAxis( float rad ); // it rotates "this" in the axis defined by the rotation AND not the world axis
+		void   RotateYAxis( float rad );
+		void   RotateZAxis( float rad );
+		void   Transpose();
+		mat3_t Transposed() const;
+		void   Reorthogonalize();
+		void   SetIdent();
+		void   SetZero();
+		void   Print() const;
+		float  Det() const;
+		void   Invert();
+		mat3_t Inverted() const;
+};
+
+
+/*
+=======================================================================================================================================
+matrix 4x4                                                                                                                            =
+=======================================================================================================================================
+*/
+class mat4_t
+{
+	public:
+		// data members
+		float data_m4[16];
+		static mat4_t ident;
+		static mat4_t zero;
+		// access to the data
+		inline float& operator ()( uint i, uint j )  { return data_m4[4*i+j]; }
+		inline float  operator ()( uint i, uint j ) const { return data_m4[4*i+j]; }
+		inline float& operator []( uint i) { return data_m4[i]; }
+		inline float  operator []( uint i) const { return data_m4[i]; }
+		// constructors & distructors
+		inline mat4_t()  {}
+		       mat4_t( float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33 );
+		inline mat4_t( const mat4_t& m4 )  { (*this)=m4; }
+		inline mat4_t( const mat3_t& m3 )  { Set(m3); }
+		inline mat4_t( const vec3_t& v ) { Set(v); }
+		inline mat4_t( const vec4_t& v ) { Set(v); }
+		inline mat4_t( const vec3_t& transl, const mat3_t& rot ) { Set(transl, rot); }
+		inline mat4_t( const vec3_t& transl, const mat3_t& rot, float scale ) { Set(transl, rot, scale); }
+		// with same
+		mat4_t& operator = ( const mat4_t& b );
+		mat4_t  operator + ( const mat4_t& b ) const;
+		mat4_t& operator +=( const mat4_t& b );
+		mat4_t  operator - ( const mat4_t& b ) const;
+		mat4_t& operator -=( const mat4_t& b );
+		mat4_t  operator * ( const mat4_t& b ) const;  // 64 muls, 48 adds. Use CombineTransformations instead
+		mat4_t& operator *=( const mat4_t& b );        //      >>
+		// with other types
+		vec3_t  operator * ( const vec3_t& v3 ) const; // 9 muls, 9 adds
+		vec4_t  operator * ( const vec4_t& v4 ) const; // 16 muls, 12 adds
+		mat4_t  operator * ( float f ) const;
+		mat4_t& operator *=( float f );
+		// comparision
+		bool operator ==( const mat4_t& b ) const;
+		bool operator !=( const mat4_t& b ) const;
+		// other
+		void   Set( const mat3_t& m3 ); // sets the rotation part equal to mat3 and the rest like the ident
+		void   Set( const vec3_t& v ); // sets the translation part equal to vec3 and the rest like the ident
+		void   Set( const vec4_t& v ); // sets the translation part equal to vec4 and the rest like the ident
+		void   Set( const vec3_t& transl, const mat3_t& rot ); // this = mat4_t(transl) * mat4_t(rot)
+		void   Set( const vec3_t& transl, const mat3_t& rot, float scale ); // this = mat4_t(transl) * mat4_t(rot) * mat4_t(scale). 9 muls
+		void   SetIdent();
+		void   SetZero();
+		void   SetRows( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d );
+		void   SetRow( uint i, const vec4_t& v );
+		void   SetColumns( const vec4_t& a, const vec4_t& b, const vec4_t& c, const vec4_t& d );
+		void   SetColumn( uint i, const vec4_t& v );
+		void   SetRotationPart( const mat3_t& m3 );
+		void   SetTranslationPart( const vec4_t& v4 );
+		mat3_t GetRotationPart() const;
+		void   SetTranslationPart( const vec3_t& v3 );
+		vec3_t GetTranslationPart() const;
+		void   Transpose();
+		mat4_t Transposed() const;
+		void   Print() const;
+		float  Det() const;
+		void   Invert();
+		mat4_t Inverted() const;
+		mat4_t Lerp( const mat4_t& b, float t ) const;
+		static mat4_t CombineTransformations( const mat4_t& m0, const mat4_t& m1 );  // 12 muls, 27 adds. Something like m4 = m0 * m1 ...
+		                                                                             // ...but without touching the 4rth row and allot faster
+};
+
+
+
+/*
+=======================================================================================================================================
+misc                                                                                                                                  =
+=======================================================================================================================================
+*/
+extern void  MathSanityChecks();
+extern void  SinCos( float rad, float& sin_, float& cos_ );
+extern float InvSqrt( float f );
+inline float Sqrt( float f ) { return 1/InvSqrt(f); }
+inline float ToRad( float degrees ) { return degrees*(PI/180.0); }
+inline float ToDegrees( float rad ) { return rad*(180.0/PI); }
+inline float Sin( float rad ) { return sin(rad); }
+inline float Cos( float rad ) { return cos(rad); }
+inline bool  IsZero( float f ) { return ( fabs(f) < EPSILON ); }
+inline float Max( float a, float b ) { return (a>b) ? a : b; }
+inline float Min( float a, float b ) { return (a<b) ? a : b; }
+
+
+//  CombineTransformations
+//  mat4(t0,r0,s0)*mat4(t1,r1,s1) == mat4(tf,rf,sf)
+inline void CombineTransformations( const vec3_t& t0, const mat3_t& r0, float s0,
+                                    const vec3_t& t1, const mat3_t& r1, float s1,
+                                    vec3_t& tf, mat3_t& rf, float& sf )
+{
+	tf = t1.Transformed( t0, r0, s0 );
+	rf = r0 * r1;
+	sf = s0 * s1;
+}
+
+//  CombineTransformations as the above but without scale
+inline void CombineTransformations( const vec3_t& t0, const mat3_t& r0, const vec3_t& t1, const mat3_t& r1, vec3_t& tf, mat3_t& rf)
+{
+	tf = t1.Transformed( t0, r0 );
+	rf = r0 * r1;
+}
+
+
+#endif

+ 670 - 0
src/old_src/model.cpp

@@ -0,0 +1,670 @@
+#include "model.h"
+
+
+/**
+=======================================================================================================================================
+model's data                                                                                                                          =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+skeleton_data_t::Load                                                                                                                 =
+=======================================================================================================================================
+*/
+bool skeleton_data_t::Load( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str[200];
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return false;
+	}
+
+	// bones num
+	int bones_num;
+	file >> str >> bones_num;
+	bones.Malloc( bones_num );
+
+	for( uint i=0; i<bones.Size(); i++ )
+	{
+		bone_data_t& bone = bones[i];
+		bone.id = i;
+		// name
+		file >> str >> str >> str >> str;
+		bone.SetName( str );
+
+		// head
+		file >> str;
+		for( int j=0; j<3; j++ )
+			file >> bone.head[j];
+
+		// tail
+		file >> str;
+		for( int j=0; j<3; j++ )
+			file >> bone.tail[j];
+
+		// matrix
+		mat4_t m4;
+		file >> str;
+		for( int j=0; j<4; j++ )
+			for( int k=0; k<4; k++ )
+				file >> m4(j,k);
+
+		// matrix for real
+		bone.rot_skel_space = m4.GetRotationPart();
+		bone.tsl_skel_space = m4.GetTranslationPart();
+		mat4_t MAi( m4.Inverted() );
+		bone.rot_skel_space_inv = MAi.GetRotationPart();
+		bone.tsl_skel_space_inv = MAi.GetTranslationPart();
+
+		// parent
+		int parent_id;
+		file >> str >> parent_id;
+		if( parent_id != -1 )
+			bone.parent = &bones[parent_id];
+		else
+			bone.parent = NULL;
+
+		// childs
+		int childs_num;
+		file >> str >> childs_num >> str;
+		DEBUG_ERR( childs_num>MAX_CHILDS_PER_BONE );
+		bone.childs_num = childs_num;
+		for( int j=0; j<bone.childs_num; j++ )
+		{
+			int child_id;
+			file >> child_id;
+			bone.childs[j] = &bones[child_id];
+		}
+
+	}
+
+	file.close();
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+model_data_t::LoadVWeights                                                                                                            =
+=======================================================================================================================================
+*/
+bool model_data_t::LoadVWeights( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str[200];
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return false;
+	}
+
+	uint verts_num;
+	file >> str >> verts_num;
+
+	// check if all verts have weights. This pressent time we treat
+	// as error if one or more verts dont have weigths.
+	if( verts_num != verts.Size() )
+	{
+		ERROR( "verts_num != verts.Size()" );
+		return false;
+	}
+
+	vert_weights.Malloc( verts_num );
+	for( size_t i=0; i<vert_weights.Size(); i++ )
+	{
+		int bones_num;
+		file >> str >> str >> str >> bones_num;
+
+		// we treat as error if one vert doesnt have a bone
+		if( bones_num < 1 )
+		{
+			ERROR( "Vert \"" << i << "\" doesnt have at least one bone" );
+			file.close();
+			return false;
+		}
+
+		// and here is another possible error
+		if( bones_num > MAX_BONES_PER_VERT )
+		{
+			ERROR( "Cannot have more than " << MAX_BONES_PER_VERT << " bones per vertex" );
+			file.close();
+			return false;
+		}
+
+		vert_weights[i].bones_num = bones_num;
+		for( int j=0; j<bones_num; j++ )
+		{
+			int bone_id;
+			float weight;
+			file >> str >> bone_id >> str >> weight;
+			vert_weights[i].bones[j] = &bones[ bone_id ];
+			vert_weights[i].weights[j] = weight;
+		}
+	}
+
+	file.close();
+	return true;
+}
+
+
+/*
+=======================================================================================================================================
+model_data_t::Load                                                                                                                    =
+=======================================================================================================================================
+*/
+bool model_data_t::Load( const char* path )
+{
+	char filename [200];
+
+	// get name
+	strcpy( filename, path );
+	filename[ strlen(path)-1 ] = '\0';
+	SetName( CutPath( filename ) );
+
+	// the mesh
+	strcpy( filename, path );
+	strcat( filename, "mesh.txt" );
+	if( !mesh_data_t::Load( filename ) ) return false;
+
+	// the skeleton
+	strcpy( filename, path );
+	strcat( filename, "skeleton.txt" );
+	if( !skeleton_data_t::Load( filename ) ) return false;
+
+
+	// vert weights
+	strcpy( filename, path );
+	strcat( filename, "vertweights.txt" );
+	if( !LoadVWeights( filename ) ) return false;
+
+	return true;
+}
+
+
+
+/**
+=======================================================================================================================================
+skeleton animation                                                                                                                    =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+Load                                                                                                                                  =
+=======================================================================================================================================
+*/
+bool skeleton_anim_t::Load( const char* filename )
+{
+	fstream file( filename, ios::in );
+	char str[200];
+	int tmpi;
+
+	if( !file.is_open() )
+	{
+		ERROR( "Cannot open \"" << filename << "\"" );
+		return false;
+	}
+
+	// read the name
+	file >> str >> str;
+	SetName(str);
+
+	// read the keyframes
+	file >> str >> tmpi >> str; // the keyframes num
+	keyframes.Malloc( tmpi );
+
+	for( uint i=0; i<keyframes.Size(); i++ )
+	{
+		file >> tmpi;
+		keyframes[i] = tmpi;
+	}
+
+	// frames_num
+	frames_num = keyframes[ keyframes.Size()-1 ];
+
+	// bones
+	file >> str >> tmpi;
+	bones.Malloc( tmpi );
+
+	for( uint i=0; i<bones.Size(); i++ )
+	{
+		file >> str >> str >> str >> str >> str >> tmpi;
+		if( tmpi ) // if has animation
+		{
+			bones[i].keyframes.Malloc( keyframes.Size() );
+
+			for( uint j=0; j<keyframes.Size(); j++ )
+			{
+				file >> str >> str >> str;
+				for( int k=0; k<4; k++ )
+					file >> bones[i].keyframes[j].rotation[k];
+
+				file >> str;
+				for( int k=0; k<3; k++ )
+					file >> bones[i].keyframes[j].translation[k];
+			}
+		}
+	}
+
+	file.close();
+	return true;
+}
+
+
+/**
+=======================================================================================================================================
+model                                                                                                                                 =
+=======================================================================================================================================
+*/
+
+
+/*
+=======================================================================================================================================
+model_t::Init                                                                                                                         =
+=======================================================================================================================================
+*/
+void model_t::Init( model_data_t* model_data_ )
+{
+	model_data = model_data_;
+	SetName( model_data->GetName() );
+
+	// init the bones
+	bones.Malloc( model_data->bones.Size() );
+
+	for( uint i=0; i<model_data->bones.Size(); i++ )
+	{
+		bone_data_t* bonedata = &model_data->bones[i];
+		bone_t* my_bone = &bones[i];
+
+		// set the parent
+		if( bonedata->parent != NULL )
+			my_bone->parent = &bones[ bonedata->parent->id ];
+
+		// set the childs
+		if( bonedata->childs_num != 0 )
+		{
+			my_bone->childs.Malloc( bonedata->childs_num );
+
+			for( uint j=0; j<bonedata->childs_num; j++ )
+				my_bone->childs[j] = &bones[ bonedata->childs[j]->id ];
+		}
+	}
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Interpolate                                                                                                                  =
+=======================================================================================================================================
+*/
+void model_t::Interpolate( skeleton_anim_t* anim, float frame )
+{
+	DEBUG_ERR( frame >= anim->frames_num );
+
+	// calculate the t (used in slerp and lerp) and
+	// calc the l_pose and r_pose witch indicate the pose ids in witch the frame lies between
+	const array_t<uint>& keyframes = anim->keyframes;
+	float t = 0.0;
+	uint l_pose = 0, r_pose = 0;
+	for( uint j=0; j<keyframes.Size(); j++ )
+	{
+		if( (float)keyframes[j] == frame )
+		{
+			l_pose = r_pose = j;
+			t = 0.0;
+			break;
+		}
+		else if( (float)keyframes[j] > frame )
+		{
+			l_pose = j-1;
+			r_pose = j;
+			t = ( frame - (float)keyframes[l_pose] ) / float( keyframes[r_pose] - keyframes[l_pose] );
+			break;
+		}
+	}
+
+
+	// now for all bones update bone's poses
+	for( uint bone_id=0; bone_id<bone_poses.Size(); bone_id++ )
+	{
+		const bone_anim_t& banim = anim->bones[bone_id];
+
+		quat_t& local_rot = bone_poses[bone_id].rotation;
+		vec3_t& local_transl = bone_poses[bone_id].translation;
+
+		// if the bone has animations then slerp and lerp to find the rotation and translation
+		if( banim.keyframes.Size() != 0 )
+		{
+			const bone_pose_t& l_bpose = banim.keyframes[l_pose];
+			const bone_pose_t& r_bpose = banim.keyframes[r_pose];
+
+			// rotation
+			const quat_t& q0 = l_bpose.rotation;
+			const quat_t& q1 = r_bpose.rotation;
+			local_rot = q0.Slerp(q1, t);
+
+			// translation
+			const vec3_t& v0 = l_bpose.translation;
+			const vec3_t& v1 = r_bpose.translation;
+			local_transl = v0.Lerp( v1, t );
+		}
+		// else put the idents
+		else
+		{
+			local_rot.SetIdent();
+			local_transl.SetZero();
+		}
+	}
+
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Interpolate                                                                                                                  =
+=======================================================================================================================================
+*/
+void model_t::Interpolate()
+{
+	DEBUG_ERR( !model_data );
+	DEBUG_ERR( bone_poses.Size() != 0 ); // the array must be empty
+
+	bone_poses.Malloc( model_data->bones.Size() );
+
+	for( ushort i=0; i<MAX_SIMULTANEOUS_ANIMS; i++ )
+	{
+		action_t* crnt = &crnt_actions[i];
+		action_t* next = &next_actions[i];
+
+		if( crnt->anim == NULL ) continue; // if the slot doesnt have anim dont bother
+
+		if( crnt->frame + crnt->step > crnt->anim->frames_num ) // if the crnt is finished then play the next or loop the crnt
+		{
+			if( next->anim == NULL ) // if there is no next anim then loop the crnt
+				crnt->frame = 0.0;
+			else // else play the next
+			{
+				crnt->anim = next->anim;
+				crnt->step = next->step;
+				crnt->frame = 0.0;
+				next->anim = NULL;
+			}
+		}
+
+		Interpolate( crnt->anim, crnt->frame );
+
+		crnt->frame += crnt->step; // inc the frame
+	}
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Play                                                                                                                         =
+=======================================================================================================================================
+*/
+void model_t::Play( skeleton_anim_t* anim, ushort slot, float step, ushort play_type, float smooth_transition_frames )
+{
+	DEBUG_ERR( !model_data );
+	DEBUG_ERR( anim->bones.Size() != model_data->bones.Size() );
+	DEBUG_ERR( slot >= MAX_SIMULTANEOUS_ANIMS );
+
+	switch( play_type )
+	{
+		case START_IMMEDIATELY:
+			crnt_actions[slot].anim = anim;
+			crnt_actions[slot].step = step;
+			crnt_actions[slot].frame = 0.0;
+			break;
+
+		case WAIT_CRNT_TO_FINISH:
+			next_actions[slot].anim = anim;
+			next_actions[slot].step = step;
+			next_actions[slot].frame = 0.0;
+			break;
+
+		case SMOOTH_TRANSITION:
+			DEBUG_ERR( true ); // unimplemented
+			break;
+
+		default:
+			DEBUG_ERR( true );
+	}
+}
+
+
+/*
+=======================================================================================================================================
+model_t::UpdateTransformations                                                                                                        =
+=======================================================================================================================================
+*/
+void model_t::UpdateTransformations()
+{
+	DEBUG_ERR( !model_data || bone_poses.Size()==0 || rotations.Size()!=0 || translations.Size()!=0 );
+
+	// allocate
+	rotations.Malloc( model_data->bones.Size() );
+	translations.Malloc( model_data->bones.Size() );
+
+
+	// using the in depth search algorithm animate the bones
+	// from father to child cause the child needs tha father's transformation matrix
+	ushort temp[200];
+	queue_t<ushort> queue( temp, 200 ); // the queue for the seatch. Takes bone ids
+
+	array_t<bone_data_t>& bones = model_data->bones;
+	// put the roots (AKA the bones without father) in the queue
+	for( uint i=0; i<bones.Size(); i++ )
+	{
+		if( bones[i].parent == NULL )
+			queue.Push( i );
+	}
+
+	// while queue is not empty
+	while( !queue.IsEmpty() )
+	{
+		// queue stuff
+		int bone_id = queue.Pop();
+		const bone_data_t& bone = bones[bone_id];
+
+		/// start the calculations
+
+		// m4 = MA * ANIM * MAi
+		// where  MA is bone matrix at armature space and ANIM the interpolated transformation.
+		CombineTransformations( bone_poses[bone_id].translation, bone_poses[bone_id].rotation,
+		                        bone.tsl_skel_space_inv, bone.rot_skel_space_inv,
+		                        translations[bone_id], rotations[bone_id] );
+
+		CombineTransformations( bone.tsl_skel_space, bone.rot_skel_space,
+		                        translations[bone_id], rotations[bone_id],
+		                        translations[bone_id], rotations[bone_id] );
+
+		// 1: Apply the parent's transformation
+		if( bone.parent )
+		{
+			// AKA transf_final = parent.transf * mine
+			CombineTransformations( translations[bone.parent->id], rotations[bone.parent->id],
+		                          translations[bone_id], rotations[bone_id],
+		                          translations[bone_id], rotations[bone_id] );
+		}
+
+		/// end of calculations
+
+		// queue stuff
+		for( int i=0; i<bone.childs_num; i++ )
+			queue.Push( bone.childs[i]->id );
+	}
+
+	// deallocate
+	bone_poses.Free();
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Deform                                                                                                                       =
+=======================================================================================================================================
+*/
+void model_t::Deform()
+{
+	DEBUG_ERR( !model_data || rotations.Size()==0 || translations.Size()==0 || verts.Size()!=0 );
+
+	// allocate
+	verts.Malloc( model_data->verts.Size() );
+
+	// deform the verts
+	for( uint i=0; i<model_data->verts.Size(); i++ ) // for all verts
+	{
+		const vertex_weight_t& vw = model_data->vert_weights[i];
+
+		// a small optimazation detour
+		if( vw.bones_num == 1 )
+		{
+			verts[i].coords = model_data->verts[i].coords.Transformed( translations[ vw.bones[0]->id ], rotations[ vw.bones[0]->id ] );
+			verts[i].normal = rotations[ vw.bones[0]->id ] * model_data->verts[i].normal;
+			continue;
+		}
+
+		// calc the matrix according the weights
+		mat3_t m3;
+		m3.SetZero();
+		vec3_t v3;
+		v3.SetZero();
+		// for all bones of this vert
+		for( int j=0; j< vw.bones_num; j++ )
+		{
+			m3 += rotations[ vw.bones[j]->id ] * vw.weights[j];
+			v3 += translations[ vw.bones[j]->id ] * vw.weights[j];
+		}
+
+		// apply the matrix to the verts
+		verts[i].coords = model_data->verts[i].coords.Transformed( v3, m3 );
+		verts[i].normal = m3 * model_data->verts[i].normal;
+	}
+
+	// deform the heads and tails
+	if( r::show_skeletons )
+	{
+		heads.Malloc( model_data->bones.Size() );
+		tails.Malloc( model_data->bones.Size() );
+
+		for( uint i=0; i<model_data->bones.Size(); i++ )
+		{
+			heads[i] = model_data->bones[i].head.Transformed( translations[i], rotations[i] );
+			tails[i] = model_data->bones[i].tail.Transformed( translations[i], rotations[i] );
+		}
+	}
+
+	// deallocate
+	rotations.Free();
+	translations.Free();
+}
+
+
+/*
+=======================================================================================================================================
+model_t::Render                                                                                                                       =
+=======================================================================================================================================
+*/
+void model_t::Render()
+{
+	DEBUG_ERR( !model_data || verts.Size()==0 );
+
+	// transform
+	glPushMatrix();
+	r::MultMatrix( world_transform );
+
+	// material
+	glEnable( GL_TEXTURE_2D );
+	glEnable( GL_LIGHTING );
+	glPolygonMode( GL_FRONT, GL_FILL );
+	glEnable( GL_DEPTH_TEST );
+	glDisable( GL_BLEND );
+
+	// draw
+	glEnableClientState( GL_VERTEX_ARRAY );
+	glEnableClientState( GL_NORMAL_ARRAY );
+	glEnableClientState( GL_TEXTURE_COORD_ARRAY );
+
+	glVertexPointer( 3, GL_FLOAT, sizeof(vertex_t), &verts[0].coords[0] );
+	glNormalPointer( GL_FLOAT, sizeof(vertex_t), &verts[0].normal[0] );
+	glTexCoordPointer( 2, GL_FLOAT, 0, &model_data->uvs[0] );
+
+	glDrawElements( GL_TRIANGLES, model_data->vert_list.Size(), GL_UNSIGNED_INT, &model_data->vert_list[0] );
+
+	glDisableClientState( GL_VERTEX_ARRAY );
+	glDisableClientState( GL_NORMAL_ARRAY );
+	glDisableClientState( GL_TEXTURE_COORD_ARRAY );
+
+	if( r::show_axis )
+	{
+		RenderAxis();
+	}
+
+
+	// reposition and draw the skeleton
+	if( r::show_skeletons )
+	{
+		DEBUG_ERR( heads.Size() != model_data->bones.Size() || tails.Size() != model_data->bones.Size() );
+
+		glDisable( GL_DEPTH_TEST );
+		for( uint i=0; i<model_data->bones.Size(); i++ )
+		{
+
+			glPointSize( 4.0f );
+			glColor3fv( &vec3_t( 1.0, 1.0, 1.0 )[0] );
+			glBegin( GL_POINTS );
+				glVertex3fv( &heads[i][0] );
+			glEnd();
+
+			glBegin( GL_LINES );
+				glVertex3fv( &heads[i][0] );
+				glColor3fv( &vec3_t( 1.0, 0.0, 0.0 )[0] );
+				glVertex3fv( &tails[i][0] );
+			glEnd();
+		}
+
+		heads.Free();
+		tails.Free();
+	}
+
+	// end
+	glPopMatrix();
+
+	// deallocate
+	verts.Free();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott