1 module meld.camera;
2 
3 import meld.maths;
4 import std.math;
5 import std.stdio;
6 import std.conv;
7 
8 class Camera
9 {
10 private:
11 	vec2 m_rot = vec2(0.0f, 0.0f);
12 	vec3 m_pos = vec3(0.0f, 2.0f, 0.0f), m_fwd = vec3(0.0f, 0.0f, 1.0f);
13 	mat4 m_viewProj, m_proj;
14 	bool m_dirty = true;
15 
16 public:
17 	@property mat4 viewProj()
18 	{
19 		//Only recalculate view*proj if it changed.
20 		if (m_dirty)
21 		{
22 			mat4 view = 
23 				mat4.translate(-m_pos) *
24 				mat4.axisangle(vec3(0.0f, 1.0f, 0.0f), -m_rot.y) *
25 				mat4.axisangle(vec3(1.0f, 0.0f, 0.0f), -m_rot.x); 
26 				
27 			m_fwd = cast(vec3)(view * vec4(0.0f, 0.0f, 1.0f, 1.0f));
28 			m_viewProj = view * mat4.proj(deg2rad(45.0f), 640.0f/480.0f, 0.1f, 5000.0f);
29 			m_dirty = false;
30 		}
31 
32 		return m_viewProj;
33 	}
34 
35 	@property vec3 pos() { return m_pos; }
36 	@property void pos(vec3 pos) { m_pos = pos; m_dirty = true; }
37 
38 	this(int width, int height)
39 	{
40 		Resize(width, height);
41 	}
42 
43 	void Move(float side, float forward)
44 	{
45 		if (side != 0.0f || forward != 0.0f)
46 		{
47 			m_pos = m_pos + (m_fwd * forward);
48 			vec3 sideV = vec3.cross(m_fwd, vec3(0.0f, 1.0f, 0.0f));
49 			m_pos = m_pos + (sideV * side);
50 
51 			m_dirty = true;
52 		}
53 	}
54 
55 	void Look(float side, float up)
56 	{
57 		if (side != 0.0f || up != 0.0f)
58 		{
59 			m_rot.y += side;
60 			m_rot.x += up;
61 
62 			m_dirty = true;
63 		}
64 	}
65 	
66 	void Resize(int width, int height)
67 	{
68 		float aspect = cast(float)width / cast(float)height;
69 		m_proj = mat4.proj(45.0f, aspect, 0.1f, 5000.0f);
70 		m_dirty = true;
71 	}
72 }