1 module des.space.camera;
2 
3 public import des.space.node;
4 public import des.space.resolver;
5 
6 ///
7 interface Camera : SpaceNode
8 {
9     mixin template CameraHelper()
10     {
11         mixin SpaceNodeHelper!false;
12 
13         protected Resolver resolver;
14         protected Transform projection, transform;
15 
16         const
17         {
18             mat4 resolve( const(SpaceNode) obj )
19             {
20                 assert( resolver !is null, "resolver not created (null)" );
21                 return resolver( obj, this );
22             }
23 
24             @property
25             {
26                 mat4 matrix() { return getMatrix( transform ); }
27                 mat4 projectMatrix() { return getMatrix( projection ); }
28                 vec3 offset() { return vec3( matrix.col(3).data[0..3] ); }
29             }
30         }
31     }
32 
33     const
34     {
35         /// get transform matrix from obj local coord system to camera coord system
36         mat4 resolve( const(SpaceNode) obj );
37 
38         /// `projectMatrix * resolve`
39         final mat4 view( const(SpaceNode) obj )
40         { return projectMatrix * resolve( obj ); }
41 
42         @property
43         {
44             /// transform from local to parent
45             mat4 matrix();
46             ///
47             mat4 projectMatrix();
48             ///
49             vec3 offset();
50         }
51     }
52 }
53 
54 /++ simple lookAt perspective/ortho camera +/
55 class SimpleCamera : Camera
56 {
57     mixin CameraHelper;
58 
59 protected:
60 
61     ///
62     LookAtTransform look_tr;
63     ///
64     PerspectiveTransform perspective;
65     ///
66     OrthoTransform ortho;
67 
68 public:
69 
70     ///
71     this( SpaceNode p=null )
72     {
73         spaceParent = p;
74         resolver = new Resolver;
75 
76         look_tr = new LookAtTransform;
77         look_tr.up = vec3(0,0,1);
78         transform = look_tr;
79         perspective = new PerspectiveTransform;
80         ortho = new OrthoTransform;
81         projection = perspective;
82     }
83 
84     ///
85     void setPerspective() { projection = perspective; }
86     ///
87     void setOrtho() { projection = ortho; }
88 
89     @property
90     {
91         ///
92         bool isPerspective() const { return projection == perspective; }
93         ///
94         bool isOrtho() const { return projection == ortho; }
95 
96         /// for perspective
97         void fov( float val ) { perspective.fov = val; }
98         /// ditto
99         float fov() const { return perspective.fov; }
100 
101         /// for ortho
102         void scale( float val ) { ortho.scale = val; }
103         /// ditto
104         float scale() const { return ortho.scale; }
105 
106         ///
107         void ratio( float val )
108         {
109             perspective.ratio = val;
110             ortho.ratio = val;
111         }
112         ///
113         float ratio() const { return perspective.ratio; }
114 
115         ///
116         void near( float val )
117         {
118             perspective.near = val;
119             ortho.near = val;
120         }
121         ///
122         float near() const { return perspective.near; }
123 
124         ///
125         void far( float val )
126         {
127             perspective.far = val;
128             ortho.far = val;
129         }
130         ///
131         float far() const { return perspective.far; }
132 
133         ///
134         void pos( in vec3 val ) { look_tr.pos = val; }
135         ///
136         vec3 pos() const { return look_tr.pos; }
137 
138         ///
139         void up( in vec3 val ) { look_tr.up = val; }
140         ///
141         vec3 up() const { return look_tr.up; }
142 
143         ///
144         void target( in vec3 val ) { look_tr.target = val; }
145         ///
146         vec3 target() const { return look_tr.target; }
147     }
148 }