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 }