1 module camera; 2 3 import std.math; 4 5 import des.space; 6 import des.app; 7 8 class MCamera : SimpleCamera 9 { 10 protected: 11 vec3 orb; 12 vec2 rot; 13 14 float rotate_coef = 80.0f; 15 float offset_coef = 50.0f; 16 float y_angle_limit = PI_2 - 0.01; 17 18 public: 19 this() 20 { 21 super(); 22 orb = vec3( 5, 1, 3 ); 23 look_tr.target = vec3(0,0,0); 24 look_tr.up = vec3(0,0,1); 25 near = 0.001; 26 updatePos(); 27 } 28 29 void mouseReaction( in MouseEvent ev ) 30 { 31 if( ev.type == MouseEvent.Type.WHEEL ) 32 moveFront( -ev.whe.y * 0.1 ); 33 34 if( ev.type == ev.Type.MOTION ) 35 { 36 if( ev.isPressed( ev.Button.LEFT ) ) 37 { 38 auto frel = vec2( ev.rel ) * vec2(-1,1); 39 auto angle = frel / rotate_coef; 40 addRotate( angle ); 41 } 42 if( ev.isPressed( ev.Button.MIDDLE ) ) 43 { 44 auto frel = vec2( ev.rel ) * vec2(-1,1); 45 auto offset = frel / offset_coef * sqrt( orb.len ); 46 moveCenter( offset ); 47 } 48 } 49 } 50 51 protected: 52 void moveFront( float dist ) 53 { 54 orb += orb * dist; 55 if( orb.len2 < 1 ) orb = orb.e; 56 updatePos(); 57 } 58 59 void addRotate( in vec2 angle ) 60 { 61 rot = normRotate( rot + angle ); 62 orb = vec3( cos(rot.x) * cos(rot.y), 63 sin(rot.x) * cos(rot.y), 64 sin(rot.y) ) * orb.len; 65 updatePos(); 66 } 67 68 void moveCenter( in vec2 offset ) 69 { 70 auto lo = (look_tr.matrix * vec4(offset,0,0)).xyz; 71 look_tr.target += lo; 72 updatePos(); 73 } 74 75 void updatePos() { pos = orb + look_tr.target; } 76 77 vec2 normRotate( in vec2 r ) 78 { 79 vec2 ret = r; 80 if( ret.y > y_angle_limit ) ret.y = y_angle_limit; 81 if( ret.y < -y_angle_limit ) ret.y = -y_angle_limit; 82 return ret; 83 } 84 }