1 module armos.graphics.matrixstack;
2 
3 import std.array;
4 import armos.app;
5 import armos.types;
6 import armos.math;
7 
8 private alias M4 = Matrix4f;
9 
10 /++
11 RendererでのMatrixを管理するclassです.
12 Deprecated: 現在使用されていません.
13 +/
14 
15 /++
16 +/
17 class MatrixStack {
18     public{
19         M4 matrix()const{
20             return _matrices[$-1];
21         }
22         
23         void push(){
24             _matrices ~= _matrices[$-1];
25         }
26         
27         void pop(){
28             _matrices.popBack;
29         }
30         
31         void load(in M4 matrix){
32             _matrices[$-1] = matrix;
33         }
34         
35         void mult(in M4 matrix){
36             _matrices[$-1] = _matrices[$-1] * matrix;
37         }
38     }//public
39 
40     private{
41         M4[] _matrices = [M4.identity];
42     }//private
43 }//class MatrixStack
44 
45 unittest{
46     immutable m1 = M4(
47             [1, 0, 0, 10], 
48             [0, 1, 0, 0], 
49             [0, 0, 1, 0], 
50             [0, 0, 0, 1], 
51     );
52         
53     immutable m2 = M4(
54             [1, 0, 0, 0], 
55             [0, 1, 0, 20], 
56             [0, 0, 1, 0], 
57             [0, 0, 0, 1], 
58     );
59     
60     immutable m3 = M4(
61             [1, 0, 0, 0], 
62             [0, 1, 0, 0], 
63             [0, 0, 1, 30], 
64             [0, 0, 0, 1], 
65     );
66     
67     auto matrixStack = new MatrixStack;
68     
69     matrixStack.push;
70     matrixStack.mult(m1);
71     assert(matrixStack.matrix == m1);
72     matrixStack.mult(m2);
73     assert(matrixStack.matrix== m1*m2);
74     matrixStack.push;
75     matrixStack.mult(m2);
76     assert(matrixStack.matrix == m1*m2*m2);
77     matrixStack.pop;
78     
79     assert(matrixStack.matrix == m1*m2);
80     
81     matrixStack.mult(m3);
82     assert(matrixStack.matrix == m1*m2*m3);
83     matrixStack.push();
84     assert(matrixStack.matrix == m1*m2*m3);
85     matrixStack.pop();
86     assert(matrixStack.matrix == m1*m2*m3);
87 }
88 
89 unittest{
90     immutable m1 = M4(
91             [1, 0, 0, 10], 
92             [0, 1, 0, 0], 
93             [0, 0, 1, 0], 
94             [0, 0, 0, 1], 
95     );
96         
97     immutable m2 = M4(
98             [1, 0, 0, 0], 
99             [0, 1, 0, 20], 
100             [0, 0, 1, 0], 
101             [0, 0, 0, 1], 
102     );
103     
104     auto matrixStack = new MatrixStack;
105     
106     matrixStack.push;
107     matrixStack.push;
108     
109     matrixStack.mult(m1);
110     assert(matrixStack.matrix == m1);
111     
112     matrixStack.mult(m2);
113     assert(matrixStack.matrix == m1*m2);
114     
115     // assert(matrixStack.modelViewProjectionMatrix == m2*m1);
116     //
117     // matrixStack.popProjectionMatrix;
118     // assert(matrixStack.modelViewProjectionMatrix == m1);
119     //
120     // matrixStack.popModelViewMatrix;
121     // assert(matrixStack.modelViewProjectionMatrix == M4.identity);
122 }
123 
124 package mixin template MatrixStackFunction(string Name){
125     public{
126         import std.string;
127         /// Matrix4f nameMatrix()
128         mixin("
129         Matrix4f " ~ Name.toLower ~ "Matrix(){
130           return currentRenderer." ~ Name.toLower ~ "Matrix;
131         }
132         ");
133         
134         /// void pushNameMatrix(in Matrix4f newMatrix = Matrix4f.identity)
135         mixin("
136         void push" ~ Name ~ "Matrix(){
137             currentRenderer.push" ~ Name ~ "Matrix();
138         }
139         ");
140 
141         /// Matrix4f popNameMatrix()
142         mixin( "
143         void pop" ~ Name ~ "Matrix(){
144             currentRenderer.pop" ~ Name ~ "Matrix;
145         }
146         ");
147 
148         /// void multNameMatrix(in Matrix4f matrix)
149         mixin("
150         void mult" ~ Name ~ "Matrix(in Matrix4f matrix){
151             currentRenderer.mult" ~ Name ~ "Matrix(matrix);
152         }
153         ");
154 
155         /// void loadNameMatrix(in Matrix4f matrix)
156         mixin( "
157         void load" ~ Name ~ "Matrix(in Matrix4f matrix){
158             currentRenderer.load" ~ Name ~ "Matrix(matrix);
159         }
160         ");
161 
162     }
163 }
164 
165 package mixin template MatrixStackManipulator(string Name){
166     public{
167         import std.string;
168         mixin("
169         Matrix4f " ~ Name.toLower ~ "Matrix()const{
170           return _" ~ Name.toLower ~ "MatrixStack.matrix;
171         }
172         ");
173         
174         ///
175         mixin("
176         void push" ~ Name ~ "Matrix(){
177             _" ~ Name.toLower ~ "MatrixStack.push();
178         }
179         ");
180 
181         ///
182         mixin( "
183         void pop" ~ Name ~ "Matrix(){
184             _" ~ Name.toLower ~ "MatrixStack.pop;
185         }
186         ");
187 
188         ///
189         mixin("
190         void mult" ~ Name ~ "Matrix(in Matrix4f matrix){
191           _" ~ Name.toLower ~ "MatrixStack.mult(matrix);
192         }
193         ");
194 
195         ///
196         mixin( "
197         void load" ~ Name ~ "Matrix(in Matrix4f matrix){
198             _" ~ Name.toLower ~ "MatrixStack.load(matrix);
199         }
200         ");
201     }
202     
203     private{
204         mixin("MatrixStack _" ~ Name.toLower ~ "MatrixStack = new MatrixStack();");
205     }
206 }