/* * draw() * - this draws the sprite texture at its current frame of its current animation * - it positions the sprite based on the transformation formula: * v' = RotationMatrix*(v-center) + position * where position is the bottom left corner of the sprite * and v is each corner of the sprite rectangle, v' is the transformed corner * and RotationMatrix is defined by the sprite's theta value (counter clockwise) */ void TextureSprite::draw(Vector2D camera) { if (!visible) return; glEnable(GL_TEXTURE_2D); // turn on texturing /* draw the sprite */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glPushMatrix(); /* create the drawing tranformation matrix */ Matrix2x2 matrix(1, 0, 0, 1); // identity matrix if (flipped) matrix *= Matrix2x2(-1, 0, 0, 1); // if the image is flipped, multiply by a horizontal reflection matrix matrix *= Matrix2x2(cos(theta), sin(theta), -sin(theta), cos(theta)); // multiply by a rotation matrix /* find pixel location */ Vector2D screenPos = position + center - getScrollMatrix() * camera; // scrollMatrix is used for parallax scrolling /* find the corner points of the image */ Vector2D p00 = (matrix * Vector2D(-center.x, -center.y)) + screenPos; Vector2D p01 = (matrix * Vector2D(-center.x, sz.height - center.y)) + screenPos; Vector2D p10 = (matrix * Vector2D(sz.width - center.x, sz.height - center.y)) + screenPos; Vector2D p11 = (matrix * Vector2D(sz.width - center.x, -center.y)) + screenPos; /* get the texture coordinate from the sprite so we know which frame to draw */ SpriteAnimation *anim = animations[currentAnimation]; int currentFrame = anim->currentFrame; float u,v; u = anim->coords[currentFrame]->u; v = anim->coords[currentFrame]->v; glColor3f(1,1,1); /* bind the appropriate texture frame */ glBindTexture(GL_TEXTURE_2D,sheet.textureID); /* Make texture scaling pixelly */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /* draw the image as a quad the size of the first loaded image */ glBegin(GL_QUADS); glTexCoord2f(u,v); glVertex3f(p00.x,p00.y,0); glTexCoord2f(u,v+sz.normalizedHeight); glVertex3f(p01.x,p01.y,0); glTexCoord2f(u+sz.normalizedWidth,v+sz.normalizedHeight); glVertex3f(p10.x,p10.y,0); glTexCoord2f(u+sz.normalizedWidth,v); glVertex3f(p11.x,p11.y,0); glEnd(); glPopMatrix(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); }
a2de::Matrix3x3 Matrix3x3::Inverse(const Matrix3x3& mat) { //Minors, Cofactors, Adjugates method. //See http://www.mathsisfun.com/algebra/matrix-inverse-minors-cofactors-adjugate.html //[00 01 02] [0 1 2] //[10 11 12] [3 4 5] //[20 21 22] [6 7 8] //Calculate minors double m00 = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[4], mat._indicies[5], mat._indicies[7], mat._indicies[8])); double m01 = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[3], mat._indicies[5], mat._indicies[6], mat._indicies[7])); double m02 = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[3], mat._indicies[4], mat._indicies[6], mat._indicies[7])); double m10 = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[1], mat._indicies[2], mat._indicies[7], mat._indicies[8])); double m11 = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[0], mat._indicies[2], mat._indicies[6], mat._indicies[7])); double m12 = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[0], mat._indicies[1], mat._indicies[6], mat._indicies[7])); double m20 = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[1], mat._indicies[2], mat._indicies[4], mat._indicies[5])); double m21 = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[0], mat._indicies[2], mat._indicies[3], mat._indicies[5])); double m22 = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[0], mat._indicies[1], mat._indicies[3], mat._indicies[4])); Matrix3x3 cofactors(m00, -m01, m02, -m10, m11, -m12, m20, -m21, m22); Matrix3x3 adjugate(Matrix3x3::Transpose(cofactors)); double det_mat = mat.CalculateDeterminant(); double inv_det = 1.0 / det_mat; return inv_det * adjugate; }
double Matrix3x3::CalculateDeterminant(const Matrix3x3& mat) { //a b //c d //ad - bc double a = mat._indicies[0]; double det_not_a = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[4], mat._indicies[5], mat._indicies[7], mat._indicies[8])); double b = mat._indicies[1]; double det_not_b = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[3], mat._indicies[5], mat._indicies[6], mat._indicies[8])); double c = mat._indicies[2]; double det_not_c = Matrix2x2::CalculateDeterminant(Matrix2x2(mat._indicies[3], mat._indicies[4], mat._indicies[6], mat._indicies[7])); return (a * det_not_a) - (b * det_not_b) + (c * det_not_c); }
const Matrix2x2 transpose(const Matrix2x2& m) { return Matrix2x2( m.m00, m.m10, m.m01, m.m11 ); }
const Matrix2x2 Matrix2x2::rotation(const float rotation) { const float c = Math::cos(rotation); const float s = Math::sin(rotation); return Matrix2x2(c, s, -s, c); }
Matrix2x2 Matrix2x2::Add(Matrix2x2 matrix) { return Matrix2x2( (this->M00 + matrix.M00), (this->M10 + matrix.M10), (this->M01 + matrix.M01), (this->M11 + matrix.M11) ); }
Matrix2x2 Matrix2x2::Substract(Matrix2x2 matrix) { return Matrix2x2( (this->M00 - matrix.M00), (this->M10 - matrix.M10), (this->M01 - matrix.M01), (this->M11 - matrix.M11) ); }
const Matrix2x2 operator *(const float k, const Matrix2x2& m) { return Matrix2x2( k * m.m00, k * m.m01, k * m.m10, k * m.m11 ); }
const Matrix2x2 operator -(const Matrix2x2& a, const Matrix2x2& b) { return Matrix2x2( a.m00 - b.m00, a.m01 - b.m01, a.m10 - b.m10, a.m11 - b.m11 ); }
const Matrix2x2 operator -(const Matrix2x2& m) { return Matrix2x2( -m.m00, -m.m01, -m.m10, -m.m11 ); }
const Matrix2x2 operator +(const Matrix2x2& a, const Matrix2x2& b) { return Matrix2x2( a.m00 + b.m00, a.m01 + b.m01, a.m10 + b.m10, a.m11 + b.m11 ); }
const Matrix2x2 Matrix2x2::identity() { return Matrix2x2( 1.0f, 0.0f, 0.0f, 1.0f ); }
Matrix2x2 Matrix2x2::Adjugate() { return Matrix2x2( M11, -M10, -M01, M00 ); }
Matrix2x2 operator*(const Matrix2x2 &lhs, const Matrix2x2 &rhs) { Matrix2x2 matrix = Matrix2x2(); matrix.set(0, 0, lhs.get(0, 0) * rhs.get(0, 0) + lhs.get(0, 1) * rhs.get(1, 0)); matrix.set(0, 1, lhs.get(0, 0) * rhs.get(0, 1) + lhs.get(0, 1) * rhs.get(1, 1)); matrix.set(1, 0, lhs.get(1, 0) * rhs.get(0, 0) + lhs.get(1, 1) * rhs.get(1, 0)); matrix.set(1, 1, lhs.get(1, 0) * rhs.get(0, 1) + lhs.get(1, 1) * rhs.get(1, 1)); return matrix; }
Matrix2x2 Matrix2x2::inverse() const { double d = det(); if (d == 0) throw std::invalid_argument("Determinant is 0, so no inverse exists."); double factor = 1 / d; return Matrix2x2(get(1, 1) * factor, -get(0, 1) * factor, -get(1, 0) * factor, get(0, 0) * factor); }
Matrix2x2 Matrix2x2::inverse() { double det = 1 / determinant(); double i11 = det * m22; double i12 = det * -m12; double i21 = det * -m21; double i22 = det * m11; return Matrix2x2(i11, i12, i21, i22); }
const Matrix2x2 timesTranspose(const Matrix2x2& a, const Matrix2x2& b) { return Matrix2x2( a.m00 * b.m00 + a.m01 * b.m01, a.m00 * b.m10 + a.m01 * b.m11, a.m10 * b.m00 + a.m11 * b.m01, a.m10 * b.m10 + a.m11 * b.m11 ); }
const Matrix2x2 operator *(const Matrix2x2& a, const Matrix2x2& b) { return Matrix2x2( a.m00 * b.m00 + a.m01 * b.m10, a.m00 * b.m01 + a.m01 * b.m11, a.m10 * b.m00 + a.m11 * b.m10, a.m10 * b.m01 + a.m11 * b.m11 ); }
const Matrix2x2 operator /(const Matrix2x2& m, const float k) { // TODO: use tolerances instead of exact values? GEOMETRY_RUNTIME_ASSERT(k != 0.0f); return Matrix2x2( m.m00 / k, m.m01 / k, m.m10 / k, m.m11 / k ); }
const Matrix2x2 transposeTimes(const Matrix2x2& a, const Matrix2x2& b) { return Matrix2x2( a.m00 * b.m00 + a.m10 * b.m10, a.m00 * b.m01 + a.m10 * b.m11, a.m01 * b.m00 + a.m11 * b.m10, a.m01 * b.m01 + a.m11 * b.m11 ); }
Ougi::Matrix2x2 Ougi::Matrix2x2::operator*(const Ougi::Matrix2x2& multiplier) const { return Matrix2x2( (matrix[0][0] * multiplier[0][0]) + (matrix[0][1] * multiplier[1][0]), (matrix[0][0] * multiplier[0][1]) + (matrix[0][1] * multiplier[1][1]), (matrix[1][0] * multiplier[0][0]) + (matrix[1][1] * multiplier[1][0]), (matrix[1][0] * multiplier[0][1]) + (matrix[1][1] * multiplier[1][1]) ); }
Matrix2x2 Matrix2x2::Multiply(Matrix2x2 matrix) { Vector2 m1r0 = Vector2(this->M00, this->M10); Vector2 m1r1 = Vector2(this->M01, this->M11); Vector2 m2r0 = Vector2(matrix.M00, matrix.M01); Vector2 m2r1 = Vector2(matrix.M10, matrix.M11); return Matrix2x2( Vector2::Dot(m1r0,m2r0), Vector2::Dot(m1r0,m2r1), Vector2::Dot(m1r1,m1r1), Vector2::Dot(m1r1,m2r1) ); }
const Matrix2x2 orthogonalize(const Matrix2x2& m) { // TODO: In the worst case scenario, this could construct a matrix where // one or both rows are incorrectly set to Vector2(1.0f, 0.0f) because of // how normalize(const Vector2&) is implemented. Should this function check // for division by zero instead of relying on the default behavior of // vector normalization? const Vector2 x = normalize(m.row(0)); Vector2 y = m.row(1); // extract the part that is parallel to x and normalize y -= x * dot(y, x); y = normalize(y); return Matrix2x2(x, y); }
#include "Core/Matrix2x2.h" #pragma region Vars Matrix2x2 Matrix2x2::Identity = Matrix2x2( 1, 0, 0, 1 ); #pragma endregion #pragma region Init Matrix2x2::Matrix2x2(void) { } Matrix2x2::Matrix2x2( float m00, float m10, float m01, float m11 ) : M00(m00), M10(m10), M01(m01), M11(m11) { } Matrix2x2::Matrix2x2(Vector2 v1, Vector2 v2) : M00(v1.X), M10(v2.X), M01(v1.Y), M11(v2.Y) { } Matrix2x2::~Matrix2x2(void) {
//! Subtraction of 2x2 matrices __device__ Matrix2x2 operator-( const Matrix2x2& b ) const { return (Matrix2x2( *this ) -= b ); }