Line data Source code
1 : #include "catch.hpp"
2 : #include "Matrix.h"
3 :
4 3 : void validate_identity_matrix(Matrix &m) {
5 51 : for (int i = 0; i < NUM_CELLS; ++i) {
6 48 : int expected = i % 5 == 0;
7 48 : REQUIRE(m.data[i] == expected);
8 48 : }
9 3 : }
10 :
11 4 : void populate_matrix(Matrix &m) {
12 68 : for (int i = 0; i < NUM_CELLS; ++i) {
13 64 : m.data[i] = i;
14 64 : }
15 4 : }
16 :
17 10 : SCENARIO( "Manipulating a matrix", "[matrix]" ) {
18 11 : GIVEN( "A populated matrix" ) {
19 2 : Matrix m;
20 :
21 : // Matrix is defaulted to the identity matrix
22 2 : validate_identity_matrix(m);
23 :
24 2 : populate_matrix(m);
25 :
26 3 : WHEN( "the matrix is zeroed" ) {
27 1 : m.loadZero();
28 :
29 2 : THEN( "all cells contain 0" ) {
30 17 : for (int i = 0; i < NUM_CELLS; ++i) {
31 16 : REQUIRE(m.data[i] == 0);
32 16 : }
33 1 : }
34 1 : }
35 :
36 3 : WHEN( "the identity matrix is loaded" ) {
37 1 : m.loadIdentity();
38 :
39 2 : THEN( "the matrix contains the identify matrix" ) {
40 1 : validate_identity_matrix(m);
41 1 : }
42 1 : }
43 2 : }
44 :
45 11 : GIVEN( "Copy and assignment" ) {
46 2 : Matrix a;
47 2 : populate_matrix(a);
48 2 : Matrix b(a);
49 :
50 3 : THEN( "copy constructor duplicates data" ) {
51 17 : for (int i = 0; i < NUM_CELLS; ++i) {
52 16 : REQUIRE(b.data[i] == a.data[i]);
53 16 : }
54 1 : }
55 :
56 2 : Matrix c;
57 2 : c = a;
58 3 : THEN( "assignment duplicates data" ) {
59 17 : for (int i = 0; i < NUM_CELLS; ++i) {
60 16 : REQUIRE(c.data[i] == a.data[i]);
61 16 : }
62 1 : }
63 2 : }
64 :
65 10 : GIVEN( "Identity times translation" ) {
66 1 : Matrix i;
67 1 : Matrix t;
68 1 : t.setTranslation(5.0f, -2.0f, 7.0f);
69 1 : Matrix r = i * t;
70 :
71 2 : THEN( "product is the translation matrix" ) {
72 1 : REQUIRE(r.data[12] == Approx(5.0f));
73 1 : REQUIRE(r.data[13] == Approx(-2.0f));
74 1 : REQUIRE(r.data[14] == Approx(7.0f));
75 1 : REQUIRE(r.data[0] == Approx(1.0f));
76 1 : REQUIRE(r.data[15] == Approx(1.0f));
77 1 : }
78 1 : }
79 :
80 10 : GIVEN( "Translation transforms a vertex with perspective divide" ) {
81 1 : Matrix t;
82 1 : t.setTranslation(1.0f, 2.0f, 3.0f);
83 1 : float v[3] = { 0.0f, 0.0f, 0.0f };
84 : float out[3];
85 1 : t.transformVertex(v, out);
86 :
87 2 : THEN( "origin maps to translation" ) {
88 1 : REQUIRE(out[0] == Approx(1.0f));
89 1 : REQUIRE(out[1] == Approx(2.0f));
90 1 : REQUIRE(out[2] == Approx(3.0f));
91 1 : }
92 1 : }
93 :
94 : // 16-arg ctor: four columns (c11..c41), (c12..c42), … OpenGL column-major data[].
95 10 : GIVEN( "Explicit 16-element constructor (four columns: c1x,c2x,c3x,c4x each)" ) {
96 : // Matches Matrix(c11,c21,c31,c41, c12,..., c44) -> OpenGL column-major data[].
97 1 : Matrix m(
98 1 : 1.0f, 0.0f, 0.0f, 0.0f,
99 1 : 0.0f, 2.0f, 0.0f, 0.0f,
100 1 : 0.0f, 0.0f, 3.0f, 0.0f,
101 1 : 4.0f, 5.0f, 6.0f, 1.0f
102 : );
103 :
104 2 : THEN( "diagonal and last-column translation match constructor" ) {
105 1 : REQUIRE(m.data[0] == Approx(1.0f));
106 1 : REQUIRE(m.data[5] == Approx(2.0f));
107 1 : REQUIRE(m.data[10] == Approx(3.0f));
108 1 : REQUIRE(m.data[3] == Approx(4.0f));
109 1 : REQUIRE(m.data[7] == Approx(5.0f));
110 1 : REQUIRE(m.data[11] == Approx(6.0f));
111 1 : REQUIRE(m.data[15] == Approx(1.0f));
112 1 : }
113 1 : }
114 :
115 10 : GIVEN( "Uniform scale matrix" ) {
116 1 : Matrix s;
117 1 : s.setScale(2.0f, 3.0f, 4.0f);
118 :
119 2 : THEN( "diagonal holds scale factors" ) {
120 1 : REQUIRE(s.data[0] == Approx(2.0f));
121 1 : REQUIRE(s.data[5] == Approx(3.0f));
122 1 : REQUIRE(s.data[10] == Approx(4.0f));
123 1 : REQUIRE(s.data[15] == Approx(1.0f));
124 1 : }
125 1 : }
126 :
127 10 : GIVEN( "Scale times translation multiply order" ) {
128 1 : Matrix s;
129 1 : s.setScale(2.0f, 1.0f, 1.0f);
130 1 : Matrix t;
131 1 : t.setTranslation(1.0f, 0.0f, 0.0f);
132 1 : Matrix a = s * t;
133 1 : float v[3] = { 1.0f, 0.0f, 0.0f };
134 : float out[3];
135 1 : a.transformVertex(v, out);
136 :
137 2 : THEN( "with A = S*T as implemented, vertex is translated then scaled on X" ) {
138 1 : REQUIRE(out[0] == Approx(4.0f));
139 1 : REQUIRE(out[1] == Approx(0.0f));
140 1 : REQUIRE(out[2] == Approx(0.0f));
141 1 : }
142 1 : }
143 9 : }
|