• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "MatrixStack.hpp"
16 
17 #include "Common/Math.hpp"
18 
19 namespace sw
20 {
MatrixStack(int size)21 	MatrixStack::MatrixStack(int size)
22 	{
23 		stack = new Matrix[size];
24 		stack[0] = 1;
25 
26 		top = 0;
27 		this->size = size;
28 	}
29 
~MatrixStack()30 	MatrixStack::~MatrixStack()
31 	{
32 		delete[] stack;
33 		stack = 0;
34 	}
35 
identity()36 	void MatrixStack::identity()
37 	{
38 		stack[top] = 1;
39 	}
40 
load(const Matrix & M)41 	void MatrixStack::load(const Matrix &M)
42 	{
43 		stack[top] = M;
44 	}
45 
load(const float * M)46 	void MatrixStack::load(const float *M)
47 	{
48 		stack[top] = Matrix(M[0], M[4], M[8],  M[12],
49 		                    M[1], M[5], M[9],  M[13],
50 		                    M[2], M[6], M[10], M[14],
51 		                    M[3], M[7], M[11], M[15]);
52 	}
53 
load(const double * M)54 	void MatrixStack::load(const double *M)
55 	{
56 		stack[top] = Matrix((float)M[0], (float)M[4], (float)M[8],  (float)M[12],
57 		                    (float)M[1], (float)M[5], (float)M[9],  (float)M[13],
58 		                    (float)M[2], (float)M[6], (float)M[10], (float)M[14],
59 		                    (float)M[3], (float)M[7], (float)M[11], (float)M[15]);
60 	}
61 
translate(float x,float y,float z)62 	void MatrixStack::translate(float x, float y, float z)
63 	{
64 		stack[top] *= Matrix::translate(x, y, z);
65 	}
66 
translate(double x,double y,double z)67 	void MatrixStack::translate(double x, double y, double z)
68 	{
69 		translate((float)x, (float)y, (float)z);
70 	}
71 
rotate(float angle,float x,float y,float z)72 	void MatrixStack::rotate(float angle, float x, float y, float z)
73 	{
74 		float n = 1.0f / sqrt(x*x + y*y + z*z);
75 
76 		x *= n;
77 		y *= n;
78 		z *= n;
79 
80 		float theta = angle * 0.0174532925f;   // In radians
81 		float c = cos(theta);
82 		float _c = 1 - c;
83 		float s = sin(theta);
84 
85 		// Rodrigues' rotation formula
86 		sw::Matrix rotate(c+x*x*_c,   x*y*_c-z*s, x*z*_c+y*s,
87 		                  x*y*_c+z*s, c+y*y*_c,   y*z*_c-x*s,
88 		                  x*z*_c-y*s, y*z*_c+x*s, c+z*z*_c);
89 
90 		stack[top] *= rotate;
91 	}
92 
rotate(double angle,double x,double y,double z)93 	void MatrixStack::rotate(double angle, double x, double y, double z)
94 	{
95 		rotate((float)angle, (float)x, (float)y, (float)z);
96 	}
97 
scale(float x,float y,float z)98 	void MatrixStack::scale(float x, float y, float z)
99 	{
100 		stack[top] *= Matrix::scale(x, y, z);
101 	}
102 
scale(double x,double y,double z)103 	void MatrixStack::scale(double x, double y, double z)
104 	{
105 		scale((float)x, (float)y, (float)z);
106 	}
107 
multiply(const float * M)108 	void MatrixStack::multiply(const float *M)
109 	{
110 		stack[top] *= Matrix(M[0], M[4], M[8],  M[12],
111 		                     M[1], M[5], M[9],  M[13],
112 		                     M[2], M[6], M[10], M[14],
113 		                     M[3], M[7], M[11], M[15]);
114 	}
115 
multiply(const double * M)116 	void MatrixStack::multiply(const double *M)
117 	{
118 		stack[top] *= Matrix((float)M[0], (float)M[4], (float)M[8],  (float)M[12],
119 		                     (float)M[1], (float)M[5], (float)M[9],  (float)M[13],
120 		                     (float)M[2], (float)M[6], (float)M[10], (float)M[14],
121 		                     (float)M[3], (float)M[7], (float)M[11], (float)M[15]);
122 	}
123 
frustum(float left,float right,float bottom,float top,float zNear,float zFar)124 	void MatrixStack::frustum(float left, float right, float bottom, float top, float zNear, float zFar)
125 	{
126 		float l = (float)left;
127 		float r = (float)right;
128 		float b = (float)bottom;
129 		float t = (float)top;
130 		float n = (float)zNear;
131 		float f = (float)zFar;
132 
133 		float A = (r + l) / (r - l);
134 		float B = (t + b) / (t - b);
135 		float C = -(f + n) / (f - n);
136 		float D = -2 * f * n / (f - n);
137 
138 		Matrix frustum(2 * n / (r - l), 0,               A,  0,
139 		               0,               2 * n / (t - b), B,  0,
140 	                   0,               0,               C,  D,
141 	                   0,               0,               -1, 0);
142 
143 		stack[this->top] *= frustum;
144 	}
145 
ortho(double left,double right,double bottom,double top,double zNear,double zFar)146 	void MatrixStack::ortho(double left, double right, double bottom, double top, double zNear, double zFar)
147 	{
148 		float l = (float)left;
149 		float r = (float)right;
150 		float b = (float)bottom;
151 		float t = (float)top;
152 		float n = (float)zNear;
153 		float f = (float)zFar;
154 
155 		float tx = -(r + l) / (r - l);
156 		float ty = -(t + b) / (t - b);
157 		float tz = -(f + n) / (f - n);
158 
159 		Matrix ortho(2 / (r - l), 0,           0,            tx,
160 		             0,           2 / (t - b), 0,            ty,
161 		             0,           0,           -2 / (f - n), tz,
162 		             0,           0,           0,            1);
163 
164 		stack[this->top] *= ortho;
165 	}
166 
push()167 	bool MatrixStack::push()
168 	{
169 		if(top >= size - 1) return false;
170 
171 		stack[top + 1] = stack[top];
172 		top++;
173 
174 		return true;
175 	}
176 
pop()177 	bool MatrixStack::pop()
178 	{
179 		if(top <= 0) return false;
180 
181 		top--;
182 
183 		return true;
184 	}
185 
current()186 	const Matrix &MatrixStack::current()
187 	{
188 		return stack[top];
189 	}
190 
isIdentity() const191 	bool MatrixStack::isIdentity() const
192 	{
193 		const Matrix &m = stack[top];
194 
195 		if(m.m[0][0] != 1.0f) return false;
196 		if(m.m[0][1] != 0.0f) return false;
197 		if(m.m[0][2] != 0.0f) return false;
198 		if(m.m[0][3] != 0.0f) return false;
199 
200 		if(m.m[1][0] != 0.0f) return false;
201 		if(m.m[1][1] != 1.0f) return false;
202 		if(m.m[1][2] != 0.0f) return false;
203 		if(m.m[1][3] != 0.0f) return false;
204 
205 		if(m.m[2][0] != 0.0f) return false;
206 		if(m.m[2][1] != 0.0f) return false;
207 		if(m.m[2][2] != 1.0f) return false;
208 		if(m.m[2][3] != 0.0f) return false;
209 
210 		if(m.m[3][0] != 0.0f) return false;
211 		if(m.m[3][1] != 0.0f) return false;
212 		if(m.m[3][2] != 0.0f) return false;
213 		if(m.m[3][3] != 1.0f) return false;
214 
215 		return true;
216 	}
217 }
218