#pragma once #include "constants.h" #include #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& 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& translation) { m[12] = translation.x; m[13] = translation.y; m[14] = translation.z; } vec3 getTranslation() const { return vec3(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 vec3 rotate(const vec3& b) const { vec3 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 vec3 operator*(const vec3& b) const { vec3 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 vec4 operator*(const vec4& b) const { vec4 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; } };