📄 mtxlib.cpp
字号:
col[0] -= m[0]; col[1] -= m[1]; col[2] -= m[2]; col[3] -= m[3]; return *this;}// Multiply the matrix44 by another matrix44matrix44 &matrix44::operator *= (const matrix44 &m) { matrix44 t; for (unsigned int r = 0; r < 4; r++) { for (unsigned int c = 0; c < 4; c++) { float f = 0; f += col[0][r] * m[c][0]; f += col[1][r] * m[c][1]; f += col[2][r] * m[c][2]; f += col[3][r] * m[c][3]; t[c][r] = f; } } *this = t; return *this;}// Multiply the matrix44 by a floatmatrix44 &matrix44::operator *= (float f) { col[0] *= f; col[1] *= f; col[2] *= f; col[3] *= f; return *this;}// Are these two matrix44's equal?bool operator == (const matrix44 &a, const matrix44 &b) { return ((a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]));}// Are these two matrix44's not equal?bool operator != (const matrix44 &a, const matrix44 &b) { return ((a[0] != b[0]) || (a[1] != b[1]) || (a[2] != b[2]) || (a[3] != b[3]));}// Add two matrix44'smatrix44 operator + (const matrix44 &a, const matrix44 &b) { matrix44 ret(a); ret += b; return ret;}// Subtract one matrix44 from anothermatrix44 operator - (const matrix44 &a, const matrix44 &b) { matrix44 ret(a); ret -= b; return ret;}// Multiply matrix44 by another matrix44matrix44 operator * (const matrix44 &a, const matrix44 &b) { matrix44 ret(a); ret *= b; return ret;}// Multiply a vector3 by this matrix44vector3 operator * (const matrix44 &m, const vector3 &v) { vector4 ret(v); ret = m * ret; return vector3(ret.x, ret.y, ret.z);}// Multiply a vector3 by this matrix44vector3 operator * (const vector3 &v, const matrix44 &m) { vector4 ret(v); ret = ret * m; return vector3(ret.x, ret.y, ret.z);}// Multiply a vector4 by this matrix44vector4 operator * (const matrix44 &m, const vector4 &v) { vector4 ret; ret.x = v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]; ret.y = v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]; ret.z = v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]; ret.w = v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]; return ret;}// Multiply a vector4 by this matrix44vector4 operator * (const vector4 &v, const matrix44 &m) { vector4 ret; ret.x = DotProduct(m[0], v); ret.y = DotProduct(m[1], v); ret.z = DotProduct(m[2], v); ret.w = DotProduct(m[3], v); return ret;}// Multiply matrix44 by a floatmatrix44 operator * (float f, const matrix44 &m) { matrix44 ret(m); ret *= f; return ret;}// Set matrix44 to the identity matrixmatrix44 &matrix44::identity() { for (unsigned int c = 0; c < 4; c++) { for (unsigned int r = 0; r < 4; r++) { if (c == r) col[c][r] = 1.0F; else col[c][r] = 0.0F; } } return *this;}// Transpose the matrix44matrix44 &matrix44::transpose() { float t; for (unsigned int c = 0; c < 4; c++) { for (unsigned int r = c + 1; r < 4; r++) { t = col[c][r]; col[c][r] = col[r][c]; col[r][c] = t; } } return *this;}// Invert the matrix44matrix44 &matrix44::invert() { matrix44 a(*this); matrix44 b(IdentityMatrix44()); unsigned int r, c; unsigned int cc; unsigned int rowMax; // Points to max abs value row in this column unsigned int row; float tmp; // Go through columns for (c=0; c<4; c++) { // Find the row with max value in this column rowMax = c; for (r=c+1; r<4; r++) { if (fabs(a[c][r]) > fabs(a[c][rowMax])) { rowMax = r; } } // If the max value here is 0, we can't invert. Return identity. if (a[rowMax][c] == 0.0F) return (identity()); // Swap row "rowMax" with row "c" for (cc=0; cc<4; cc++) { tmp = a[cc][c]; a[cc][c] = a[cc][rowMax]; a[cc][rowMax] = tmp; tmp = b[cc][c]; b[cc][c] = b[cc][rowMax]; b[cc][rowMax] = tmp; } // Now everything we do is on row "c". // Set the max cell to 1 by dividing the entire row by that value tmp = a[c][c]; for (cc=0; cc<4; cc++) { a[cc][c] /= tmp; b[cc][c] /= tmp; } // Now do the other rows, so that this column only has a 1 and 0's for (row = 0; row < 4; row++) { if (row != c) { tmp = a[c][row]; for (cc=0; cc<4; cc++) { a[cc][row] -= a[cc][c] * tmp; b[cc][row] -= b[cc][c] * tmp; } } } } *this = b; return *this;}// Return a matrix44 set to the identity matrixmatrix44 IdentityMatrix44() { matrix44 ret; return ret.identity();}// Return the transpose of the matrix44matrix44 TransposeMatrix44(const matrix44 &m) { matrix44 ret(m); return ret.transpose();}// Return the inverted matrix44matrix44 InvertMatrix44(const matrix44 &m) { matrix44 ret(m); return ret.invert();}// Return a 3D axis-rotation matrix44// Pass in 'x', 'y', or 'z' for the axis.matrix44 RotateRadMatrix44(char axis, float rad) { matrix44 ret; float sinA, cosA; sinA = (float)sin(rad); cosA = (float)cos(rad); switch(axis) { case 'x': case 'X': ret[0][0] = 1.0F; ret[1][0] = 0.0F; ret[2][0] = 0.0F; ret[0][1] = 0.0F; ret[1][1] = cosA; ret[2][1] = -sinA; ret[0][2] = 0.0F; ret[1][2] = sinA; ret[2][2] = cosA; break; case 'y': case 'Y': ret[0][0] = cosA; ret[1][0] = 0.0F; ret[2][0] = sinA; ret[0][1] = 0.0F; ret[1][1] = 1.0F; ret[2][1] = 0.0F; ret[0][2] = -sinA; ret[1][2] = 0.0F; ret[2][2] = cosA; break; case 'z': case 'Z': ret[0][0] = cosA; ret[1][0] = -sinA; ret[2][0] = 0.0F; ret[0][1] = sinA; ret[1][1] = cosA; ret[2][1] = 0.0F; ret[0][2] = 0.0F; ret[1][2] = 0.0F; ret[2][2] = 1.0F; break; } ret[0][3] = 0.0F; ret[1][3] = 0.0F; ret[2][3] = 0.0F; ret[3][0] = 0.0F; ret[3][1] = 0.0F; ret[3][2] = 0.0F; ret[3][3] = 1.0F; return ret;}// Return a 3D axis-rotation matrix44// Pass in an arbitrary vector3 axis.matrix44 RotateRadMatrix44(const vector3 &axis, float rad) { matrix44 ret; float sinA, cosA; float invCosA; vector3 nrm = axis; float x, y, z; float xSq, ySq, zSq; nrm.normalize(); sinA = (float)sin(rad); cosA = (float)cos(rad); invCosA = 1.0F - cosA; x = nrm.x; y = nrm.y; z = nrm.z; xSq = x * x; ySq = y * y; zSq = z * z; ret[0][0] = (invCosA * xSq) + (cosA); ret[1][0] = (invCosA * x * y) - (sinA * z ); ret[2][0] = (invCosA * x * z) + (sinA * y ); ret[3][0] = 0.0F; ret[0][1] = (invCosA * x * y) + (sinA * z); ret[1][1] = (invCosA * ySq) + (cosA); ret[2][1] = (invCosA * y * z) - (sinA * x); ret[3][1] = 0.0F; ret[0][2] = (invCosA * x * z) - (sinA * y); ret[1][2] = (invCosA * y * z) + (sinA * x); ret[2][2] = (invCosA * zSq) + (cosA); ret[3][2] = 0.0F; ret[0][3] = 0.0F; ret[1][3] = 0.0F; ret[2][3] = 0.0F; ret[3][3] = 1.0F; return ret;}// Return a 3D translation matrix44matrix44 TranslateMatrix44(float x, float y, float z) { matrix44 ret; ret.identity(); ret[3][0] = x; ret[3][1] = y; ret[3][2] = z; return ret;}// Return a 3D/4D scale matrix44matrix44 ScaleMatrix44(float x, float y, float z, float w) { matrix44 ret; ret.identity(); ret[0][0] = x; ret[1][1] = y; ret[2][2] = z; ret[3][3] = w; return ret;}// Return a "lookat" matrix44 given the current camera position (vector3),// camera-up vector3, and camera-target vector3.matrix44 LookAtMatrix44(const vector3 &camPos, const vector3 &camUp, const vector3 &target ) { matrix44 rot; matrix44 tran; vector3 look = (camPos - target); look.normalize(); vector3 right = CrossProduct(camUp, look); right.normalize(); vector3 up = CrossProduct(look, right); up.normalize(); rot[0][0] = right.x; rot[1][0] = right.y; rot[2][0] = right.z; rot[3][0] = 0.0; rot[0][1] = up.x; rot[1][1] = up.y; rot[2][1] = up.z; rot[3][1] = 0.0; rot[0][2] = look.x; rot[1][2] = look.y; rot[2][2] = look.z; rot[3][2] = 0.0; rot[0][3] = 0.0F; rot[1][3] = 0.0F; rot[2][3] = 0.0F; rot[3][3] = 1.0F; tran = TranslateMatrix44(-camPos.x, -camPos.y, -camPos.z); return (rot * tran);}// Return a frustum matrix44 given the left, right, bottom, top,// near, and far values for the frustum boundaries.matrix44 FrustumMatrix44(float l, float r, float b, float t, float n, float f) { matrix44 ret; float width = r-l; float height = t-b; float depth = f-n; ret[0][0] = (2*n) / width; ret[0][1] = 0.0F; ret[0][2] = 0.0F; ret[0][3] = 0.0F; ret[1][0] = 0.0F; ret[1][1] = (2*n) / height; ret[1][2] = 0.0F; ret[1][3] = 0.0F; ret[2][0] = (r + l) / width; ret[2][1] = (t + b) / height; ret[2][2] = -(f + n) / depth; ret[2][3] = -1.0F; ret[3][0] = 0.0F; ret[3][1] = 0.0F; ret[3][2] = -(2*f*n) / depth; ret[3][3] = 0.0F; return ret;}// Return a perspective matrix44 given the field-of-view in the Y// direction in degrees, the aspect ratio of Y/X, and near and// far plane distances.matrix44 PerspectiveMatrix44(float fovY, float aspect, float n, float f) { matrix44 ret; float angle; float cot; angle = fovY / 2.0F; angle = DegToRad( angle ); cot = (float) cos(angle) / (float) sin(angle); ret[0][0] = cot / aspect; ret[0][1] = 0.0F; ret[0][2] = 0.0F; ret[0][3] = 0.0F; ret[1][0] = 0.0F; ret[1][1] = cot; ret[1][2] = 0.0F; ret[1][3] = 0.0F; ret[2][0] = 0.0F; ret[2][1] = 0.0F; ret[2][2] = -(f + n) / (f - n); ret[2][3] = -1.0F; ret[3][0] = 0.0F; ret[3][1] = 0.0F; ret[3][2] = -(2*f*n) / (f - n); ret[3][3] = 0.0F; return ret;}// Return an orthographic matrix44 given the left, right, bottom, top,// near, and far values for the frustum boundaries.matrix44 OrthoMatrix44(float l, float r, float b, float t, float n, float f) { matrix44 ret; float width = r-l; float height = t-b; float depth = f-n; ret[0][0] = 2.0F / width; ret[0][1] = 0.0F; ret[0][2] = 0.0F; ret[0][3] = 0.0F; ret[1][0] = 0.0F; ret[1][1] = 2.0F / height; ret[1][2] = 0.0F; ret[1][3] = 0.0F; ret[2][0] = 0.0F; ret[2][1] = 0.0F; ret[2][2] = -(2.0F) / depth; ret[2][3] = 0.0F; ret[3][0] = -(r + l) / width; ret[1][3] = -(t + b) / height; ret[3][2] = -(f + n) / depth; ret[3][3] = 1.0F; return ret;}// Return an orientation matrix using 3 basis normalized vectorsmatrix44 OrthoNormalMatrix44(const vector3 &xdir, const vector3 &ydir, const vector3 &zdir){ matrix44 ret; ret[0] = (vector4)xdir; ret[1] = (vector4)ydir; ret[2] = (vector4)zdir; ret[3][3] = 1.0F; return ret;}////////////////////////////////////////////////////////////// Debug functions//// Print a vector2 to a filevoid vector2::fprint(FILE* file, char* str) const { fprintf(file, "%svector2: <%f, %f>\n", str, x, y);}// Print a vector3 to a filevoid vector3::fprint(FILE* file, char* str) const { fprintf(file, "%svector3: <%f, %f, %f>\n", str, x, y, z);}// Print a vector4 to a filevoid vector4::fprint(FILE* file, char* str) const { fprintf(file, "%svector4: <%f, %f, %f, %f>\n", str, x, y, z, w);}// Print a matrix33 to a filevoid matrix33::fprint(FILE* file, char * str) const { fprintf(file, "%smatrix33:\n", str); vector3 row0(col[0][0], col[1][0], col[2][0]); row0.fprint(file, "\t"); vector3 row1(col[0][1], col[1][1], col[2][1]); row1.fprint(file, "\t"); vector3 row2(col[0][2], col[1][2], col[2][2]); row2.fprint(file, "\t");}// Print a matrix44 to a filevoid matrix44::fprint(FILE* file, char* str) const { fprintf(file, "%smatrix44:\n", str); vector4 row0(col[0][0], col[1][0], col[2][0], col[3][0]); row0.fprint(file, "\t"); vector4 row1(col[0][1], col[1][1], col[2][1], col[3][1]); row1.fprint(file, "\t"); vector4 row2(col[0][2], col[1][2], col[2][2], col[3][2]); row2.fprint(file, "\t"); vector4 row3(col[0][3], col[1][3], col[2][3], col[3][3]); row3.fprint(file, "\t");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -