diff options
author | Rat <none@none> | 2010-06-07 19:35:24 +0200 |
---|---|---|
committer | Rat <none@none> | 2010-06-07 19:35:24 +0200 |
commit | e4e13c2bb8c691486ac717b206f166f33c8c531a (patch) | |
tree | a0ab601406c1396d41527a49392725c8179a6d8a /dep/src/g3dlite/Matrix4.cpp | |
parent | 32546e22828e793e3881e1055acb72b6a044e331 (diff) |
removed 'dep' folder, no more needed
--HG--
branch : trunk
Diffstat (limited to 'dep/src/g3dlite/Matrix4.cpp')
-rw-r--r-- | dep/src/g3dlite/Matrix4.cpp | 523 |
1 files changed, 0 insertions, 523 deletions
diff --git a/dep/src/g3dlite/Matrix4.cpp b/dep/src/g3dlite/Matrix4.cpp deleted file mode 100644 index cd38a1a3602..00000000000 --- a/dep/src/g3dlite/Matrix4.cpp +++ /dev/null @@ -1,523 +0,0 @@ -/** - @file Matrix4.cpp - - - @maintainer Morgan McGuire, http://graphics.cs.williams.edu - - @created 2003-10-02 - @edited 2010-01-29 - */ - -#include "G3D/platform.h" -#include "G3D/Matrix4.h" -#include "G3D/Matrix3.h" -#include "G3D/Vector4.h" -#include "G3D/Vector3.h" -#include "G3D/BinaryInput.h" -#include "G3D/BinaryOutput.h" -#include "G3D/CoordinateFrame.h" -#include "G3D/Rect2D.h" -#include "G3D/Any.h" -#include "G3D/stringutils.h" - -namespace G3D { - - -Matrix4::Matrix4(const Any& any) { - any.verifyName("Matrix4"); - any.verifyType(Any::ARRAY); - - const std::string& name = toLower(any.name()); - if (name == "matrix4") { - any.verifySize(16); - - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - elt[r][c] = any[r * 4 + c]; - } - } - } else if (name == "matrix4::scale") { - if (any.size() == 1) { - *this = scale(any[0].number()); - } else if (any.size() == 3) { - *this = scale(any[0], any[1], any[2]); - } else { - any.verify(false, "Matrix4::scale() takes either 1 or 3 arguments"); - } - } else { - any.verify(false, "Expected Matrix4 constructor"); - } -} - - -Matrix4::operator Any() const { - Any any(Any::ARRAY, "Matrix4"); - any.resize(16); - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - any[r * 4 + c] = elt[r][c]; - } - } - - return any; -} - -const Matrix4& Matrix4::identity() { - static Matrix4 m( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - return m; -} - - -const Matrix4& Matrix4::zero() { - static Matrix4 m( - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0); - return m; -} - - -Matrix4::Matrix4(const class CoordinateFrame& cframe) { - for (int r = 0; r < 3; ++r) { - for (int c = 0; c < 3; ++c) { - elt[r][c] = cframe.rotation[r][c]; - } - elt[r][3] = cframe.translation[r]; - } - elt[3][0] = 0.0f; - elt[3][1] = 0.0f; - elt[3][2] = 0.0f; - elt[3][3] = 1.0f; -} - -Matrix4::Matrix4(const Matrix3& upper3x3, const Vector3& lastCol) { - for (int r = 0; r < 3; ++r) { - for (int c = 0; c < 3; ++c) { - elt[r][c] = upper3x3[r][c]; - } - elt[r][3] = lastCol[r]; - } - elt[3][0] = 0.0f; - elt[3][1] = 0.0f; - elt[3][2] = 0.0f; - elt[3][3] = 1.0f; -} - - -Matrix3 Matrix4::upper3x3() const { - return Matrix3(elt[0][0], elt[0][1], elt[0][2], - elt[1][0], elt[1][1], elt[1][2], - elt[2][0], elt[2][1], elt[2][2]); -} - - -Matrix4 Matrix4::orthogonalProjection( - const class Rect2D& rect, - float nearval, - float farval, - float upDirection) { - return Matrix4::orthogonalProjection(rect.x0(), rect.x1(), rect.y1(), rect.y0(), nearval, farval, upDirection); -} - - -Matrix4 Matrix4::orthogonalProjection( - float left, - float right, - float bottom, - float top, - float nearval, - float farval, - float upDirection) { - - // Adapted from Mesa. Note that Microsoft (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/glfunc03_8qnj.asp) - // and Linux (http://www.xfree86.org/current/glOrtho.3.html) have different matrices shown in their documentation. - - float x, y, z; - float tx, ty, tz; - - x = 2.0f / (right-left); - y = 2.0f / (top-bottom); - z = -2.0f / (farval-nearval); - tx = -(right+left) / (right-left); - ty = -(top+bottom) / (top-bottom); - tz = -(farval+nearval) / (farval-nearval); - - y *= upDirection; - ty *= upDirection; - - return - Matrix4( x , 0.0f, 0.0f, tx, - 0.0f, y , 0.0f, ty, - 0.0f, 0.0f, z , tz, - 0.0f, 0.0f, 0.0f, 1.0f); -} - - -Matrix4 Matrix4::perspectiveProjection( - float left, - float right, - float bottom, - float top, - float nearval, - float farval, - float upDirection) { - - float x, y, a, b, c, d; - - x = (2.0f*nearval) / (right-left); - y = (2.0f*nearval) / (top-bottom); - a = (right+left) / (right-left); - b = (top+bottom) / (top-bottom); - - if (farval >= finf()) { - // Infinite view frustum - c = -1.0f; - d = -2.0f * nearval; - } else { - c = -(farval+nearval) / (farval-nearval); - d = -(2.0f*farval*nearval) / (farval-nearval); - } - - debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1"); - y *= upDirection; - b *= upDirection; - - return Matrix4( - x, 0, a, 0, - 0, y, b, 0, - 0, 0, c, d, - 0, 0, -1, 0); -} - - -void Matrix4::getPerspectiveProjectionParameters( - float& left, - float& right, - float& bottom, - float& top, - float& nearval, - float& farval, - float upDirection) const { - - debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1"); - - float x = elt[0][0]; - float y = elt[1][1] * upDirection; - float a = elt[0][2]; - float b = elt[1][2] * upDirection; - float c = elt[2][2]; - float d = elt[2][3]; - - // Verify that this really is a projection matrix - debugAssertM(elt[3][2] == -1, "Not a projection matrix"); - debugAssertM(elt[0][1] == 0, "Not a projection matrix"); - debugAssertM(elt[0][3] == 0, "Not a projection matrix"); - debugAssertM(elt[1][3] == 0, "Not a projection matrix"); - debugAssertM(elt[3][3] == 0, "Not a projection matrix"); - debugAssertM(elt[1][0] == 0, "Not a projection matrix"); - debugAssertM(elt[2][0] == 0, "Not a projection matrix"); - debugAssertM(elt[2][1] == 0, "Not a projection matrix"); - debugAssertM(elt[3][0] == 0, "Not a projection matrix"); - debugAssertM(elt[3][1] == 0, "Not a projection matrix"); - - if (c == -1) { - farval = finf(); - nearval = -d / 2.0f; - } else { - nearval = d * ((c - 1.0f) / (c + 1.0f) - 1.0f) / (-2.0f * (c - 1.0f) / (c + 1.0f)); - farval = nearval * ((c - 1.0f) / (c + 1.0f)); - } - - - left = (a - 1.0f) * nearval / x; - right = 2.0f * nearval / x + left; - - bottom = (b - 1.0f) * nearval / y; - top = 2.0f * nearval / y + bottom; -} - - -Matrix4::Matrix4( - float r1c1, float r1c2, float r1c3, float r1c4, - float r2c1, float r2c2, float r2c3, float r2c4, - float r3c1, float r3c2, float r3c3, float r3c4, - float r4c1, float r4c2, float r4c3, float r4c4) { - elt[0][0] = r1c1; elt[0][1] = r1c2; elt[0][2] = r1c3; elt[0][3] = r1c4; - elt[1][0] = r2c1; elt[1][1] = r2c2; elt[1][2] = r2c3; elt[1][3] = r2c4; - elt[2][0] = r3c1; elt[2][1] = r3c2; elt[2][2] = r3c3; elt[2][3] = r3c4; - elt[3][0] = r4c1; elt[3][1] = r4c2; elt[3][2] = r4c3; elt[3][3] = r4c4; -} - -/** - init should be <B>row major</B>. - */ -Matrix4::Matrix4(const float* init) { - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - elt[r][c] = init[r * 4 + c]; - } - } -} - - -Matrix4::Matrix4(const double* init) { - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - elt[r][c] = (float)init[r * 4 + c]; - } - } -} - - -Matrix4::Matrix4() { - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - elt[r][c] = 0; - } - } -} - - -void Matrix4::setRow(int r, const Vector4& v) { - for (int c = 0; c < 4; ++c) { - elt[r][c] = v[c]; - } -} - - -void Matrix4::setColumn(int c, const Vector4& v) { - for (int r = 0; r < 4; ++r) { - elt[r][c] = v[r]; - } -} - - -const Vector4& Matrix4::row(int r) const { - return reinterpret_cast<const Vector4*>(elt[r])[0]; -} - - -Vector4 Matrix4::column(int c) const { - Vector4 v; - for (int r = 0; r < 4; ++r) { - v[r] = elt[r][c]; - } - return v; -} - - -Matrix4 Matrix4::operator*(const Matrix4& other) const { - Matrix4 result; - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - for (int i = 0; i < 4; ++i) { - result.elt[r][c] += elt[r][i] * other.elt[i][c]; - } - } - } - - return result; -} - - -Matrix4 Matrix4::operator*(const float s) const { - Matrix4 result; - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - result.elt[r][c] = elt[r][c] * s; - } - } - - return result; -} - - -Vector3 Matrix4::homoMul(const class Vector3& v, float w) const { - Vector4 r = (*this) * Vector4(v, w); - return r.xyz() * (1.0f / r.w); -} - - -Vector4 Matrix4::operator*(const Vector4& vector) const { - Vector4 result(0,0,0,0); - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - result[r] += elt[r][c] * vector[c]; - } - } - - return result; -} - - -Matrix4 Matrix4::transpose() const { - Matrix4 result; - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - result.elt[c][r] = elt[r][c]; - } - } - - return result; -} - - -bool Matrix4::operator!=(const Matrix4& other) const { - return ! (*this == other); -} - - -bool Matrix4::operator==(const Matrix4& other) const { - - // If the bit patterns are identical, they must be - // the same matrix. If not, they *might* still have - // equal elements due to floating point weirdness. - if (memcmp(this, &other, sizeof(Matrix4) == 0)) { - return true; - } - - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - if (elt[r][c] != other.elt[r][c]) { - return false; - } - } - } - - return true; -} - - -float Matrix4::determinant() const { - // Determinant is the dot product of the first row and the first row - // of cofactors (i.e. the first col of the adjoint matrix) - return cofactor().row(0).dot(row(0)); -} - - -Matrix4 Matrix4::adjoint() const { - return cofactor().transpose(); -} - - -Matrix4 Matrix4::inverse() const { - // Inverse = adjoint / determinant - - Matrix4 A = adjoint(); - - // Determinant is the dot product of the first row and the first row - // of cofactors (i.e. the first col of the adjoint matrix) - float det = A.column(0).dot(row(0)); - - return A * (1.0f / det); -} - - -Matrix4 Matrix4::cofactor() const { - Matrix4 out; - - // We'll use i to incrementally compute -1 ^ (r+c) - int i = 1; - - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - // Compute the determinant of the 3x3 submatrix - float det = subDeterminant(r, c); - out.elt[r][c] = i * det; - i = -i; - } - i = -i; - } - - return out; -} - - -float Matrix4::subDeterminant(int excludeRow, int excludeCol) const { - // Compute non-excluded row and column indices - int row[3]; - int col[3]; - - for (int i = 0; i < 3; ++i) { - row[i] = i; - col[i] = i; - - if (i >= excludeRow) { - ++row[i]; - } - if (i >= excludeCol) { - ++col[i]; - } - } - - // Compute the first row of cofactors - float cofactor00 = - elt[row[1]][col[1]] * elt[row[2]][col[2]] - - elt[row[1]][col[2]] * elt[row[2]][col[1]]; - - float cofactor10 = - elt[row[1]][col[2]] * elt[row[2]][col[0]] - - elt[row[1]][col[0]] * elt[row[2]][col[2]]; - - float cofactor20 = - elt[row[1]][col[0]] * elt[row[2]][col[1]] - - elt[row[1]][col[1]] * elt[row[2]][col[0]]; - - // Product of the first row and the cofactors along the first row - return - elt[row[0]][col[0]] * cofactor00 + - elt[row[0]][col[1]] * cofactor10 + - elt[row[0]][col[2]] * cofactor20; -} - - -CoordinateFrame Matrix4::approxCoordinateFrame() const { - CoordinateFrame cframe; - - for (int r = 0; r < 3; ++r) { - for (int c = 0; c < 3; ++c) { - cframe.rotation[r][c] = elt[r][c]; - } - cframe.translation[r] = elt[r][3]; - } - - // Ensure that the rotation matrix is orthonormal - cframe.rotation.orthonormalize(); - - return cframe; -} - - -void Matrix4::serialize(class BinaryOutput& b) const { - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - b.writeFloat32(elt[r][c]); - } - } -} - - -void Matrix4::deserialize(class BinaryInput& b) { - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - elt[r][c] = b.readFloat32(); - } - } -} - -std::string Matrix4::toString() const { - return G3D::format("[%g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g]", - elt[0][0], elt[0][1], elt[0][2], elt[0][3], - elt[1][0], elt[1][1], elt[1][2], elt[1][3], - elt[2][0], elt[2][1], elt[2][2], elt[2][3], - elt[3][0], elt[3][1], elt[3][2], elt[3][3]); -} - -} // namespace - - |