volmetrics

diff src/matrix.cc @ 0:88d390af583f

Image loader
author Eleni Maria Stea <eleni@mutantstargoat.com>
date Sat, 11 Jan 2014 17:22:36 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/matrix.cc	Sat Jan 11 17:22:36 2014 +0200
     1.3 @@ -0,0 +1,393 @@
     1.4 +#include <math.h>
     1.5 +#include <stdio.h>
     1.6 +#include <string.h>
     1.7 +#include "matrix.h"
     1.8 +
     1.9 +Matrix4x4 Matrix4x4::identity = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
    1.10 +
    1.11 +Matrix4x4::Matrix4x4()
    1.12 +{
    1.13 +	*this = identity;
    1.14 +}
    1.15 +
    1.16 +Matrix4x4::Matrix4x4(	float m11, float m12, float m13, float m14,
    1.17 +						float m21, float m22, float m23, float m24,
    1.18 +						float m31, float m32, float m33, float m34,
    1.19 +						float m41, float m42, float m43, float m44)
    1.20 +{
    1.21 +	m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14;
    1.22 +	m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24;
    1.23 +	m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34;
    1.24 +	m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44;
    1.25 +}
    1.26 +
    1.27 +Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2)
    1.28 +{
    1.29 +	Matrix4x4 res;
    1.30 +	const float *op1 = m1.m[0], *op2 = m2.m[0];
    1.31 +	float *dest = res.m[0];
    1.32 +
    1.33 +	for(int i=0; i<16; i++) {
    1.34 +		*dest++ = *op1++ + *op2++;
    1.35 +	}
    1.36 +	return res;
    1.37 +}
    1.38 +
    1.39 +Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2)
    1.40 +{
    1.41 +	Matrix4x4 res;
    1.42 +	const float *op1 = m1.m[0], *op2 = m2.m[0];
    1.43 +	float *dest = res.m[0];
    1.44 +
    1.45 +	for(int i=0; i<16; i++) {
    1.46 +		*dest++ = *op1++ - *op2++;
    1.47 +	}
    1.48 +	return res;
    1.49 +}
    1.50 +
    1.51 +Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2) {
    1.52 +	Matrix4x4 res;
    1.53 +
    1.54 +	for(int i=0; i<4; i++) {
    1.55 +		for(int j=0; j<4; j++) {
    1.56 +			res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j];
    1.57 +		}
    1.58 +	}
    1.59 +
    1.60 +	return res;
    1.61 +}
    1.62 +
    1.63 +void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2)
    1.64 +{
    1.65 +	float *op1 = m1.m[0];
    1.66 +	const float *op2 = m2.m[0];
    1.67 +
    1.68 +	for(int i=0; i<16; i++) {
    1.69 +		*op1++ += *op2++;
    1.70 +	}
    1.71 +}
    1.72 +
    1.73 +void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2)
    1.74 +{
    1.75 +	float *op1 = m1.m[0];
    1.76 +	const float *op2 = m2.m[0];
    1.77 +
    1.78 +	for(int i=0; i<16; i++) {
    1.79 +		*op1++ -= *op2++;
    1.80 +	}
    1.81 +}
    1.82 +
    1.83 +void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2)
    1.84 +{
    1.85 +	Matrix4x4 res;
    1.86 +	for(int i=0; i<4; i++) {
    1.87 +		for(int j=0; j<4; j++) {
    1.88 +			res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j];
    1.89 +		}
    1.90 +	}
    1.91 +	memcpy(m1.m, res.m, 16 * sizeof(float));
    1.92 +}
    1.93 +
    1.94 +Matrix4x4 operator *(const Matrix4x4 &mat, float scalar)
    1.95 +{
    1.96 +	Matrix4x4 res;
    1.97 +	const float *mptr = mat.m[0];
    1.98 +	float *dptr = res.m[0];
    1.99 +
   1.100 +	for(int i=0; i<16; i++) {
   1.101 +		*dptr++ = *mptr++ * scalar;
   1.102 +	}
   1.103 +	return res;
   1.104 +}
   1.105 +
   1.106 +Matrix4x4 operator *(float scalar, const Matrix4x4 &mat)
   1.107 +{
   1.108 +	Matrix4x4 res;
   1.109 +	const float *mptr = mat.m[0];
   1.110 +	float *dptr = res.m[0];
   1.111 +
   1.112 +	for(int i=0; i<16; i++) {
   1.113 +		*dptr++ = *mptr++ * scalar;
   1.114 +	}
   1.115 +	return res;
   1.116 +}
   1.117 +
   1.118 +void operator *=(Matrix4x4 &mat, float scalar)
   1.119 +{
   1.120 +	float *mptr = mat.m[0];
   1.121 +
   1.122 +	for(int i=0; i<16; i++) {
   1.123 +		*mptr++ *= scalar;
   1.124 +	}
   1.125 +}
   1.126 +
   1.127 +void Matrix4x4::translate(const Vector3 &trans)
   1.128 +{
   1.129 +	Matrix4x4 tmat(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1);
   1.130 +	*this *= tmat;
   1.131 +}
   1.132 +
   1.133 +void Matrix4x4::set_translation(const Vector3 &trans)
   1.134 +{
   1.135 +	*this = Matrix4x4(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1);
   1.136 +}
   1.137 +
   1.138 +void Matrix4x4::rotate(const Vector3 &euler)
   1.139 +{
   1.140 +	float sinx = sin(euler.x);
   1.141 +	float cosx = cos(euler.x);
   1.142 +	float siny = sin(euler.y);
   1.143 +	float cosy = cos(euler.y);
   1.144 +	float sinz = sin(euler.z);
   1.145 +	float cosz = cos(euler.z);
   1.146 +
   1.147 +	Matrix4x4 xrot = Matrix4x4(
   1.148 +			1, 0, 0, 0,
   1.149 +			0, cosx, sinx, 0,
   1.150 +			0, -sinx, cosx, 0,
   1.151 +			0, 0, 0, 1);
   1.152 +
   1.153 +	Matrix4x4 yrot = Matrix4x4(
   1.154 +			cosy, 0, -siny, 0,
   1.155 +			0, 1, 0, 0,
   1.156 +			siny, 0, cosy, 0,
   1.157 +			0, 0, 0, 1);
   1.158 +
   1.159 +	Matrix4x4 zrot = Matrix4x4(
   1.160 +			cosz, sinz, 0, 0,
   1.161 +			-sinz, cosz, 0, 0,
   1.162 +			0, 0, 1, 0,
   1.163 +			0, 0, 0, 1);
   1.164 +
   1.165 +	*this *= (xrot * yrot * zrot);
   1.166 +}
   1.167 +
   1.168 +void Matrix4x4::rotate(const Vector3 &axis, float angle)
   1.169 +{
   1.170 +	float sina = (float)sin(angle);
   1.171 +	float cosa = (float)cos(angle);
   1.172 +	float invcosa = 1-cosa;
   1.173 +	float nxsq = axis.x * axis.x;
   1.174 +	float nysq = axis.y * axis.y;
   1.175 +	float nzsq = axis.z * axis.z;
   1.176 +
   1.177 +	Matrix4x4 xform;
   1.178 +	xform[0][0] = nxsq + (1-nxsq) * cosa;
   1.179 +	xform[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
   1.180 +	xform[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
   1.181 +	xform[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
   1.182 +	xform[1][1] = nysq + (1-nysq) * cosa;
   1.183 +	xform[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
   1.184 +	xform[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
   1.185 +	xform[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
   1.186 +	xform[2][2] = nzsq + (1-nzsq) * cosa;
   1.187 +
   1.188 +	*this *= Matrix4x4(xform);
   1.189 +}
   1.190 +
   1.191 +void Matrix4x4::set_rotation(const Vector3 &axis, float angle)
   1.192 +{
   1.193 +	float sina = (float)sin(angle);
   1.194 +	float cosa = (float)cos(angle);
   1.195 +	float invcosa = 1-cosa;
   1.196 +	float nxsq = axis.x * axis.x;
   1.197 +	float nysq = axis.y * axis.y;
   1.198 +	float nzsq = axis.z * axis.z;
   1.199 +
   1.200 +	reset_identity();
   1.201 +	m[0][0] = nxsq + (1-nxsq) * cosa;
   1.202 +	m[0][1] = axis.x * axis.y * invcosa - axis.z * sina;
   1.203 +	m[0][2] = axis.x * axis.z * invcosa + axis.y * sina;
   1.204 +	m[1][0] = axis.x * axis.y * invcosa + axis.z * sina;
   1.205 +	m[1][1] = nysq + (1-nysq) * cosa;
   1.206 +	m[1][2] = axis.y * axis.z * invcosa - axis.x * sina;
   1.207 +	m[2][0] = axis.x * axis.z * invcosa - axis.y * sina;
   1.208 +	m[2][1] = axis.y * axis.z * invcosa + axis.x * sina;
   1.209 +	m[2][2] = nzsq + (1-nzsq) * cosa;
   1.210 +}
   1.211 +
   1.212 +void Matrix4x4::scale(const Vector3 &scale_vec)
   1.213 +{
   1.214 +	Matrix4x4 smat(	scale_vec.x, 0, 0, 0,
   1.215 +					0, scale_vec.y, 0, 0,
   1.216 +					0, 0, scale_vec.z, 0,
   1.217 +					0, 0, 0, 1.0);
   1.218 +	*this *= smat;
   1.219 +}
   1.220 +
   1.221 +void Matrix4x4::set_scaling(const Vector3 &scale_vec)
   1.222 +{
   1.223 +	*this = Matrix4x4(	scale_vec.x, 0, 0, 0,
   1.224 +						0, scale_vec.y, 0, 0,
   1.225 +						0, 0, scale_vec.z, 0,
   1.226 +						0, 0, 0, 1);
   1.227 +}
   1.228 +
   1.229 +void Matrix4x4::set_column_vector(const Vector3 &vec, unsigned int col_index)
   1.230 +{
   1.231 +	m[0][col_index] = vec.x;
   1.232 +	m[1][col_index] = vec.y;
   1.233 +	m[2][col_index] = vec.z;
   1.234 +	m[3][col_index] = 1;
   1.235 +}
   1.236 +
   1.237 +void Matrix4x4::set_row_vector(const Vector3 &vec, unsigned int row_index)
   1.238 +{
   1.239 +	m[row_index][0] = vec.x;
   1.240 +	m[row_index][1] = vec.y;
   1.241 +	m[row_index][2] = vec.z;
   1.242 +	m[row_index][3] = 1;
   1.243 +}
   1.244 +
   1.245 +Vector3 Matrix4x4::get_column_vector(unsigned int col_index) const
   1.246 +{
   1.247 +	return Vector3(m[0][col_index], m[1][col_index], m[2][col_index]);
   1.248 +}
   1.249 +
   1.250 +Vector3 Matrix4x4::get_row_vector(unsigned int row_index) const
   1.251 +{
   1.252 +	return Vector3(m[row_index][0], m[row_index][1], m[row_index][2]);
   1.253 +}
   1.254 +
   1.255 +void Matrix4x4::transpose()
   1.256 +{
   1.257 +	Matrix4x4 tmp = *this;
   1.258 +	for(int i=0; i<4; i++) {
   1.259 +		for(int j=0; j<4; j++) {
   1.260 +			m[i][j] = tmp[j][i];
   1.261 +		}
   1.262 +	}
   1.263 +}
   1.264 +
   1.265 +Matrix4x4 Matrix4x4::transposed() const
   1.266 +{
   1.267 +	Matrix4x4 res;
   1.268 +	for(int i=0; i<4; i++) {
   1.269 +		for(int j=0; j<4; j++) {
   1.270 +			res[i][j] = m[j][i];
   1.271 +		}
   1.272 +	}
   1.273 +	return res;
   1.274 +}
   1.275 +
   1.276 +float Matrix4x4::determinant() const
   1.277 +{
   1.278 +	float det11 =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   1.279 +						(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
   1.280 +						(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
   1.281 +
   1.282 +	float det12 =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   1.283 +						(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   1.284 +						(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
   1.285 +
   1.286 +	float det13 =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
   1.287 +						(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   1.288 +						(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   1.289 +
   1.290 +	float det14 =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
   1.291 +						(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
   1.292 +						(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   1.293 +
   1.294 +	return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14;
   1.295 +}
   1.296 +
   1.297 +
   1.298 +Matrix4x4 Matrix4x4::adjoint() const
   1.299 +{
   1.300 +	Matrix4x4 coef;
   1.301 +
   1.302 +	coef.m[0][0] =	(m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   1.303 +					(m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
   1.304 +					(m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
   1.305 +	coef.m[0][1] =	(m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   1.306 +					(m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   1.307 +					(m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
   1.308 +	coef.m[0][2] =	(m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
   1.309 +					(m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   1.310 +					(m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   1.311 +	coef.m[0][3] =	(m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
   1.312 +					(m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
   1.313 +					(m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   1.314 +
   1.315 +	coef.m[1][0] =	(m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   1.316 +					(m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) +
   1.317 +					(m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2]));
   1.318 +	coef.m[1][1] =	(m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) -
   1.319 +					(m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   1.320 +					(m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2]));
   1.321 +	coef.m[1][2] =	(m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) -
   1.322 +					(m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) +
   1.323 +					(m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   1.324 +	coef.m[1][3] =	(m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) -
   1.325 +					(m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) +
   1.326 +					(m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1]));
   1.327 +
   1.328 +	coef.m[2][0] =	(m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
   1.329 +					(m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) +
   1.330 +					(m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2]));
   1.331 +	coef.m[2][1] =	(m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) -
   1.332 +					(m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
   1.333 +					(m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2]));
   1.334 +	coef.m[2][2] =	(m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) -
   1.335 +					(m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) +
   1.336 +					(m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
   1.337 +	coef.m[2][3] =	(m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) -
   1.338 +					(m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) +
   1.339 +					(m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1]));
   1.340 +
   1.341 +	coef.m[3][0] =	(m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
   1.342 +					(m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) +
   1.343 +					(m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]));
   1.344 +	coef.m[3][1] =	(m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) -
   1.345 +					(m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
   1.346 +					(m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2]));
   1.347 +	coef.m[3][2] =	(m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) -
   1.348 +					(m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) +
   1.349 +					(m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
   1.350 +	coef.m[3][3] =	(m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) -
   1.351 +					(m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) +
   1.352 +					(m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1]));
   1.353 +
   1.354 +	coef.transpose();
   1.355 +
   1.356 +	for(int i=0; i<4; i++) {
   1.357 +		for(int j=0; j<4; j++) {
   1.358 +			coef.m[i][j] = j%2 ? -coef.m[i][j] : coef.m[i][j];
   1.359 +			if(i%2) coef.m[i][j] = -coef.m[i][j];
   1.360 +		}
   1.361 +	}
   1.362 +
   1.363 +	return coef;
   1.364 +}
   1.365 +
   1.366 +Matrix4x4 Matrix4x4::inverse() const
   1.367 +{
   1.368 +	Matrix4x4 adj = adjoint();
   1.369 +
   1.370 +	return adj * (1.0f / determinant());
   1.371 +}
   1.372 +
   1.373 +inline float *Matrix4x4::operator [](int index)
   1.374 +{
   1.375 +	return m[index];
   1.376 +}
   1.377 +
   1.378 +inline const float *Matrix4x4::operator [](int index) const
   1.379 +{
   1.380 +	return m[index];
   1.381 +}
   1.382 +
   1.383 +inline void Matrix4x4::reset_identity()
   1.384 +{
   1.385 +	*this = identity;
   1.386 +}
   1.387 +
   1.388 +std::ostream &operator <<(std::ostream &out, const Matrix4x4 &mat)
   1.389 +{
   1.390 +	for(int i=0; i<4; i++) {
   1.391 +		char str[100];
   1.392 +		sprintf(str, "[ %12.5f %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2], (float)mat.m[i][3]);
   1.393 +		out << str;
   1.394 +	}
   1.395 +	return out;
   1.396 +}