1 module radeonrays.math.matrix;
2 
3 /**********************************************************************
4 Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 ********************************************************************/
24 
25 import radeonrays.math.float3;
26 
27 extern(C++,"RadeonRays")
28 {
29 	struct matrix
30 	{
31 	public:
32 		//@disable this();
33 
34 		/*matrix(float mm00 = 1.f, float mm01 = 0.f, float mm02 = 0.f, float mm03 = 0.f,
35 			float mm10 = 0.f, float mm11 = 1.f, float mm12 = 0.f, float mm13 = 0.f,
36 			float mm20 = 0.f, float mm21 = 0.f, float mm22 = 1.f, float mm23 = 0.f,
37 			float mm30 = 0.f, float mm31 = 0.f, float mm32 = 0.f, float mm33 = 1.f)
38 			: m00(mm00), m01(mm01), m02(mm02), m03(mm03)
39 				, m10(mm10), m11(mm11), m12(mm12), m13(mm13)
40 				, m20(mm20), m21(mm21), m22(mm22), m23(mm23)
41 				, m30(mm30), m31(mm31), m32(mm32), m33(mm33)
42 		{
43 		}
44 		
45 		matrix(matrix const& o)
46 			: m00(o.m00), m01(o.m01), m02(o.m02), m03(o.m03)
47 				, m10(o.m10), m11(o.m11), m12(o.m12), m13(o.m13)
48 				, m20(o.m20), m21(o.m21), m22(o.m22), m23(o.m23)
49 				, m30(o.m30), m31(o.m31), m32(o.m32), m33(o.m33)
50 		{
51 		}
52 		
53 		matrix& operator = (matrix const& o)
54 		{
55 			for (int i = 0; i < 4; ++i)
56 				for (int j = 0; j < 4; ++j)
57 					m[i][j] = o.m[i][j];
58 			return *this;
59 		}
60 		
61 		matrix operator-() const;
62 		matrix transpose() const;
63 		float  trace() const { return m00 + m11 + m22 + m33; }
64 		
65 		matrix& operator += (matrix const& o);
66 		matrix& operator -= (matrix const& o);
67 		matrix& operator *= (matrix const& o);
68 		matrix& operator *= (float c);*/
69 		
70 		union
71 		{
72 			float[4][4] m;// = [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];
73 			struct 
74 			{
75 				float m00 = 1, m01 = 0, m02 = 0, m03 = 0;
76 				float m10 = 0, m11 = 1, m12 = 0, m13 = 0;
77 				float m20 = 0, m21 = 0, m22 = 1, m23 = 0;
78 				float m30 = 0, m31 = 0, m32 = 0, m33 = 1;
79 			}
80 		}
81 	};
82 	
83 	
84 	/*inline matrix matrix::operator -() const
85 	{
86 		matrix res = *this;
87 		for(int i=0;i<4;++i)
88 			for (int j=0;j<4;++j)
89 				res.m[i][j] = -m[i][j]; 
90 		return res;
91 	}
92 	
93 	inline matrix matrix::transpose() const
94 	{
95 		matrix res;
96 		for (int i=0;i<4;++i)
97 			for (int j=0;j<4;++j)
98 				res.m[j][i] = m[i][j];
99 		return res;
100 	}
101 	
102 	inline matrix& matrix::operator += (matrix const& o)
103 	{
104 		for(int i=0;i<4;++i)
105 			for (int j=0;j<4;++j)
106 				m[i][j] += o.m[i][j]; 
107 		return *this;
108 	}
109 	
110 	inline matrix& matrix::operator -= (matrix const& o)
111 	{
112 		for(int i=0;i<4;++i)
113 			for (int j=0;j<4;++j)
114 				m[i][j] -= o.m[i][j]; 
115 		return *this;
116 	}
117 	
118 	inline matrix& matrix::operator *= (matrix const& o)
119 	{
120 		matrix temp;
121 		for (int i=0;i<4;++i)
122 		{
123 			for (int j=0;j<4;++j)
124 			{
125 				temp.m[i][j] = 0.f;
126 				for (int k=0;k<4;++k)
127 					temp.m[i][j] += m[i][k] * o.m[k][j];
128 			}
129 		}
130 		*this = temp;
131 		return *this;
132 	}
133 	
134 	inline matrix& matrix::operator *= (float c)
135 	{
136 		for(int i=0;i<4;++i)
137 			for (int j=0;j<4;++j)
138 				m[i][j] *= c; 
139 		return *this;
140 	}
141 	
142 	inline matrix operator+(matrix const& m1, matrix const& m2)
143 	{
144 		matrix res = m1;
145 		return res+=m2;
146 	}
147 	
148 	inline matrix operator-(matrix const& m1, matrix const& m2)
149 	{
150 		matrix res = m1;
151 		return res-=m2;
152 	}
153 	
154 	inline matrix operator*(matrix const& m1, matrix const& m2)
155 	{
156 		matrix res;
157 		for (int i=0;i<4;++i)
158 		{
159 			for (int j=0;j<4;++j)
160 			{
161 				res.m[i][j] = 0.f;
162 				for (int k=0;k<4;++k)
163 					res.m[i][j] += m1.m[i][k]*m2.m[k][j];
164 			}
165 		}
166 		return res;
167 	}
168 	
169 	inline matrix operator*(matrix const& m, float c)
170 	{
171 		matrix res = m;
172 		return res*=c;
173 	}
174 	
175 	inline matrix operator*(float c, matrix const& m)
176 	{
177 		matrix res = m;
178 		return res*=c;
179 	}
180 	
181 	inline float4 operator * (matrix const& m, float4 const& v)
182 	{
183 		float4 res(0, 0, 0, 0);
184 		
185 		for (int i = 0; i < 4; ++i) {
186 			//res[i] = 0.f;
187 			for (int j = 0; j < 4; ++j)
188 				res[i] += m.m[i][j] * v[j];
189 		}
190 		
191 		return res;
192 	}
193 	
194 	inline matrix inverse(matrix const& m)
195 	{
196 		int indxc[4], indxr[4];
197 		int ipiv[4] = { 0, 0, 0, 0 };
198 		float minv[4][4];
199 		matrix temp = m;  
200 		memcpy(minv,  &temp.m[0][0], 4*4*sizeof(float));
201 		for (int i = 0; i < 4; i++) {
202 			int irow = -1, icol = -1;
203 			float big = 0.;
204 			// Choose pivot
205 			for (int j = 0; j < 4; j++) {
206 				if (ipiv[j] != 1) {
207 					for (int k = 0; k < 4; k++) {
208 						if (ipiv[k] == 0) {
209 							if (fabsf(minv[j][k]) >= big) {
210 								big = float(fabsf(minv[j][k]));
211 								irow = j;
212 								icol = k;
213 							}
214 						}
215 						else if (ipiv[k] > 1)
216 							return matrix();
217 					}
218 				}
219 			}
220 			++ipiv[icol];
221 			// Swap rows _irow_ and _icol_ for pivot
222 			if (irow != icol) {
223 				for (int k = 0; k < 4; ++k)
224 					std::swap(minv[irow][k], minv[icol][k]);
225 			}
226 			indxr[i] = irow;
227 			indxc[i] = icol;
228 			if (minv[icol][icol] == 0.)
229 				return matrix();
230 			
231 			// Set $m[icol][icol]$ to one by scaling row _icol_ appropriately
232 			float pivinv = 1.f / minv[icol][icol];
233 			minv[icol][icol] = 1.f;
234 			for (int j = 0; j < 4; j++)
235 				minv[icol][j] *= pivinv;
236 			
237 			// Subtract this row from others to zero out their columns
238 			for (int j = 0; j < 4; j++) {
239 				if (j != icol) {
240 					float save = minv[j][icol];
241 					minv[j][icol] = 0;
242 					for (int k = 0; k < 4; k++)
243 						minv[j][k] -= minv[icol][k]*save;
244 				}
245 			}
246 		}
247 		// Swap columns to reflect permutation
248 		for (int j = 3; j >= 0; j--) {
249 			if (indxr[j] != indxc[j]) {
250 				for (int k = 0; k < 4; k++)
251 					std::swap(minv[k][indxr[j]], minv[k][indxc[j]]);
252 			}
253 		}
254 		
255 		matrix result;
256 	std::memcpy(&result.m[0][0], minv, 4*4*sizeof(float));
257 		return result;
258 	}*/
259 }