Files
starruler-linux/source/util/include/matrix.h
T
2018-07-17 14:15:37 +02:00

143 lines
3.6 KiB
C++

#pragma once
#include "constants.h"
#include <memory.h>
#include "vec3.h"
#include "vec4.h"
const double _identityMatrixData[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
//A 4x4 Matrix
struct Matrix {
double m[16];
void setScale(vec3<double>& scale) {
m[0] = scale.x;
m[5] = scale.y;
m[10] = scale.z;
}
void scaleUniformly(double scale) {
m[0] *= scale; m[4] *= scale; m[8] *= scale;
m[1] *= scale; m[5] *= scale; m[9] *= scale;
m[2] *= scale; m[6] *= scale; m[10] *= scale;
}
void setTranslation(vec3<double>& translation) {
m[12] = translation.x;
m[13] = translation.y;
m[14] = translation.z;
}
vec3<double> getTranslation() const {
return vec3<double>(m[12],m[13],m[14]);
}
double& operator[](unsigned i) {
return m[i];
}
const double& operator[](unsigned i) const {
return m[i];
}
void operator=(const Matrix& b) {
memcpy(m, b.m, sizeof(m));
}
template<class T>
vec3<T> rotate(const vec3<T>& b) const {
vec3<T> r;
r.x= (m[0]*b.x) + (m[4]*b.y) + (m[8]*b.z);
r.y= (m[1]*b.x) + (m[5]*b.y) + (m[9]*b.z);
r.z= (m[2]*b.x) + (m[6]*b.y) + (m[10]*b.z);
return r;
}
template<class T>
vec3<T> operator*(const vec3<T>& b) const {
vec3<T> r;
r.x= (m[0]*b.x) + (m[4]*b.y) + (m[8]*b.z) + m[12];
r.y= (m[1]*b.x) + (m[5]*b.y) + (m[9]*b.z) + m[13];
r.z= (m[2]*b.x) + (m[6]*b.y) + (m[10]*b.z) + m[14];
return r;
}
template<class T>
vec4<T> operator*(const vec4<T>& b) const {
vec4<T> r;
r.x= (m[0]*b.x) + (m[4]*b.y) + (m[8]*b.z) + (m[12]*b.w);
r.y= (m[1]*b.x) + (m[5]*b.y) + (m[9]*b.z) + (m[13]*b.w);
r.z= (m[2]*b.x) + (m[6]*b.y) + (m[10]*b.z) + (m[14]*b.w);
r.w= (m[2]*b.x) + (m[6]*b.y) + (m[10]*b.z) + (m[15]*b.w);
return r;
}
Matrix operator*(const Matrix& b) const {
Matrix r;
r[0]= (m[0]*b[0]) + (m[4]*b[1]) + (m[8]*b[2]) + (m[12]*b[3]);
r[1]= (m[1]*b[0]) + (m[5]*b[1]) + (m[9]*b[2]) + (m[13]*b[3]);
r[2]= (m[2]*b[0]) + (m[6]*b[1]) + (m[10]*b[2]) + (m[14]*b[3]);
r[3]= (m[3]*b[0]) + (m[7]*b[1]) + (m[11]*b[2]) + (m[15]*b[3]);
r[4]= (m[0]*b[4]) + (m[4]*b[5]) + (m[8]*b[6]) + (m[12]*b[7]);
r[5]= (m[1]*b[4]) + (m[5]*b[5]) + (m[9]*b[6]) + (m[13]*b[7]);
r[6]= (m[2]*b[4]) + (m[6]*b[5]) + (m[10]*b[6]) + (m[14]*b[7]);
r[7]= (m[3]*b[4]) + (m[7]*b[5]) + (m[11]*b[6]) + (m[15]*b[7]);
r[8]= (m[0]*b[8]) + (m[4]*b[9]) + (m[8]*b[10]) + (m[12]*b[11]);
r[9]= (m[1]*b[8]) + (m[5]*b[9]) + (m[9]*b[10]) + (m[13]*b[11]);
r[10]= (m[2]*b[8]) + (m[6]*b[9]) + (m[10]*b[10]) + (m[14]*b[11]);
r[11]= (m[3]*b[8]) + (m[7]*b[9]) + (m[11]*b[10]) + (m[15]*b[11]);
r[12]= (m[0]*b[12]) + (m[4]*b[13]) + (m[8]*b[14]) + (m[12]*b[15]);
r[13]= (m[1]*b[12]) + (m[5]*b[13]) + (m[9]*b[14]) + (m[13]*b[15]);
r[14]= (m[2]*b[12]) + (m[6]*b[13]) + (m[10]*b[14]) + (m[14]*b[15]);
r[15]= (m[3]*b[12]) + (m[7]*b[13]) + (m[11]*b[14]) + (m[15]*b[15]);
return r;
}
Matrix& operator*=(const Matrix& b) {
*this = *this * b;
return *this;
}
Matrix() {
memcpy(m, _identityMatrixData, sizeof(_identityMatrixData));
}
Matrix(const Matrix& b) {
memcpy(m, b.m, sizeof(m));
}
static Matrix projection(double fov, double aspect, double znear, double zfar) {
double ymax = znear * tan(fov * pi / 360.0);
double xmax = ymax * aspect;
double w = xmax + xmax;
double h = ymax + ymax;
Matrix m;
m[0] = (2.0 * znear) / w;
//m[1] = 0;
//m[2] = 0;
//m[3] = 0;
//m[4] = 0;
m[5] = (2.0 * znear) / h;
//m[6] = 0;
//m[7] = 0;
//m[8] = 0;
//m[9] = 0;
m[10] = (-zfar - znear) / (zfar - znear);
m[11] = -1.0;
//m[12] = 0;
//m[13] = 0;
m[14] = (-2.0 * znear * zfar) / (zfar - znear);
m[15] = 0;
return m;
}
};