diff --git a/2dsg/2dsg.vcproj b/2dsg/2dsg.vcproj
index 9538733ec..3a61fee39 100644
--- a/2dsg/2dsg.vcproj
+++ b/2dsg/2dsg.vcproj
@@ -1,573 +1,573 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2dsg/Matrices.cpp b/2dsg/Matrices.cpp
index 870233299..1bfb3b726 100644
--- a/2dsg/Matrices.cpp
+++ b/2dsg/Matrices.cpp
@@ -1,635 +1,635 @@
-///////////////////////////////////////////////////////////////////////////////
-// Matrice.cpp
-// ===========
-// NxN Matrix Math classes
-//
-// The elements of the matrix are stored as column major order.
-// | 0 2 | | 0 3 6 | | 0 4 8 12 |
-// | 1 3 | | 1 4 7 | | 1 5 9 13 |
-// | 2 5 8 | | 2 6 10 14 |
-// | 3 7 11 15 |
-//
-// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
-// CREATED: 2005-06-24
-// UPDATED: 2014-09-21
-//
-// Copyright (C) 2005 Song Ho Ahn
-///////////////////////////////////////////////////////////////////////////////
-
-#include
-#include
-#include "Matrices.h"
-#include "glog.h"
-
-const float DEG2RAD = 3.141593f / 180;
-const float EPSILON = 0.00001f;
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// transpose 2x2 matrix
-///////////////////////////////////////////////////////////////////////////////
-Matrix2& Matrix2::transpose()
-{
- std::swap(m[1], m[2]);
- return *this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// return the determinant of 2x2 matrix
-///////////////////////////////////////////////////////////////////////////////
-float Matrix2::getDeterminant()
-{
- return m[0] * m[3] - m[1] * m[2];
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// inverse of 2x2 matrix
-// If cannot find inverse, set identity matrix
-///////////////////////////////////////////////////////////////////////////////
-Matrix2& Matrix2::invert()
-{
- float determinant = getDeterminant();
-/* if(fabs(determinant) ==0)
- determinant=EPSILON;*/
-
- float tmp = m[0]; // copy the first element
- float invDeterminant = 1.0f / determinant;
- m[0] = invDeterminant * m[3];
- m[1] = -invDeterminant * m[1];
- m[2] = -invDeterminant * m[2];
- m[3] = invDeterminant * tmp;
-
- return *this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// transpose 3x3 matrix
-///////////////////////////////////////////////////////////////////////////////
-Matrix3& Matrix3::transpose()
-{
- std::swap(m[1], m[3]);
- std::swap(m[2], m[6]);
- std::swap(m[5], m[7]);
-
- return *this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// return determinant of 3x3 matrix
-///////////////////////////////////////////////////////////////////////////////
-float Matrix3::getDeterminant()
-{
- return m[0] * (m[4] * m[8] - m[5] * m[7]) -
- m[1] * (m[3] * m[8] - m[5] * m[6]) +
- m[2] * (m[3] * m[7] - m[4] * m[6]);
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// inverse 3x3 matrix
-// If cannot find inverse, set identity matrix
-///////////////////////////////////////////////////////////////////////////////
-Matrix3& Matrix3::invert()
-{
- float determinant, invDeterminant;
- float tmp[9];
-
- tmp[0] = m[4] * m[8] - m[5] * m[7];
- tmp[1] = m[2] * m[7] - m[1] * m[8];
- tmp[2] = m[1] * m[5] - m[2] * m[4];
- tmp[3] = m[5] * m[6] - m[3] * m[8];
- tmp[4] = m[0] * m[8] - m[2] * m[6];
- tmp[5] = m[2] * m[3] - m[0] * m[5];
- tmp[6] = m[3] * m[7] - m[4] * m[6];
- tmp[7] = m[1] * m[6] - m[0] * m[7];
- tmp[8] = m[0] * m[4] - m[1] * m[3];
-
- // check determinant if it is 0
- determinant = m[0] * tmp[0] + m[1] * tmp[3] + m[2] * tmp[6];
-/* if(fabs(determinant) ==0)
- determinant=EPSILON;*/
-
- // divide by the determinant
- invDeterminant = 1.0f / determinant;
- m[0] = invDeterminant * tmp[0];
- m[1] = invDeterminant * tmp[1];
- m[2] = invDeterminant * tmp[2];
- m[3] = invDeterminant * tmp[3];
- m[4] = invDeterminant * tmp[4];
- m[5] = invDeterminant * tmp[5];
- m[6] = invDeterminant * tmp[6];
- m[7] = invDeterminant * tmp[7];
- m[8] = invDeterminant * tmp[8];
-
- return *this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// transpose 4x4 matrix
-///////////////////////////////////////////////////////////////////////////////
-Matrix4& Matrix4::transpose()
-{
- std::swap(m[1], m[4]);
- std::swap(m[2], m[8]);
- std::swap(m[3], m[12]);
- std::swap(m[6], m[9]);
- std::swap(m[7], m[13]);
- std::swap(m[11], m[14]);
-
- return *this;
-}
-
-
-void Matrix4::transformPoint(float x, float y, float* newx, float* newy) const
-{
- Vector4 src=Vector4(x,y,0,1);
- Vector4 dst=*this*src;
- *newx=dst.x;
- *newy=dst.y;
-/*
- glog_i("Matrix:\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n",
- m[0],m[4],m[8],m[12],
- m[1],m[5],m[9],m[13],
- m[2],m[6],m[10],m[14],
- m[3],m[7],m[11],m[15]
- );
- glog_i("XFORMP: (%f,%f)->(%f,%f)",x,y,*newx,*newy);
- */
-}
-
-void Matrix4::inverseTransformPoint(float x, float y, float* newx, float* newy) const
-{
- Vector4 src=Vector4(x,y,0,1);
- Matrix4 inv=inverse();
- Vector4 dst=inv*src;
- *newx=dst.x;
- *newy=dst.y;
-/* glog_i("Matrix:\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n",
- m[0],m[4],m[8],m[12],
- m[1],m[5],m[9],m[13],
- m[2],m[6],m[10],m[14],
- m[3],m[7],m[11],m[15]
- );
- glog_i("IMatrix:\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n",
- inv[0],inv[4],inv[8],inv[12],
- inv[1],inv[5],inv[9],inv[13],
- inv[2],inv[6],inv[10],inv[14],
- inv[3],inv[7],inv[11],inv[15]
- );
- glog_i("IXFORMP: (%f,%f)->(%f,%f)",x,y,*newx,*newy);
-*/
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// inverse 4x4 matrix
-///////////////////////////////////////////////////////////////////////////////
-Matrix4& Matrix4::invert()
-{
- // If the 4th row is [0,0,0,1] then it is affine matrix and
- // it has no projective transformation.
- if(m[3] == 0 && m[7] == 0 && m[11] == 0 && m[15] == 1)
- this->invertAffine();
- else
- {
- this->invertGeneral();
- /*@@ invertProjective() is not optimized (slower than generic one)
- if(fabs(m[0]*m[5] - m[1]*m[4]) > EPSILON)
- this->invertProjective(); // inverse using matrix partition
- else
- this->invertGeneral(); // generalized inverse
- */
- }
-
- return *this;
-}
-
-Matrix4 Matrix4::inverse() const
-{
- Matrix4 inv=*this;
- inv.invert();
- return inv;
-}
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// compute the inverse of 4x4 Euclidean transformation matrix
-//
-// Euclidean transformation is translation, rotation, and reflection.
-// With Euclidean transform, only the position and orientation of the object
-// will be changed. Euclidean transform does not change the shape of an object
-// (no scaling). Length and angle are reserved.
-//
-// Use inverseAffine() if the matrix has scale and shear transformation.
-//
-// M = [ R | T ]
-// [ --+-- ] (R denotes 3x3 rotation/reflection matrix)
-// [ 0 | 1 ] (T denotes 1x3 translation matrix)
-//
-// y = M*x -> y = R*x + T -> x = R^-1*(y - T) -> x = R^T*y - R^T*T
-// (R is orthogonal, R^-1 = R^T)
-//
-// [ R | T ]-1 [ R^T | -R^T * T ] (R denotes 3x3 rotation matrix)
-// [ --+-- ] = [ ----+--------- ] (T denotes 1x3 translation)
-// [ 0 | 1 ] [ 0 | 1 ] (R^T denotes R-transpose)
-///////////////////////////////////////////////////////////////////////////////
-Matrix4& Matrix4::invertEuclidean()
-{
- // transpose 3x3 rotation matrix part
- // | R^T | 0 |
- // | ----+-- |
- // | 0 | 1 |
- float tmp;
- tmp = m[1]; m[1] = m[4]; m[4] = tmp;
- tmp = m[2]; m[2] = m[8]; m[8] = tmp;
- tmp = m[6]; m[6] = m[9]; m[9] = tmp;
-
- // compute translation part -R^T * T
- // | 0 | -R^T x |
- // | --+------- |
- // | 0 | 0 |
- float x = m[12];
- float y = m[13];
- float z = m[14];
- m[12] = -(m[0] * x + m[4] * y + m[8] * z);
- m[13] = -(m[1] * x + m[5] * y + m[9] * z);
- m[14] = -(m[2] * x + m[6] * y + m[10]* z);
-
- // last row should be unchanged (0,0,0,1)
-
- return *this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// compute the inverse of a 4x4 affine transformation matrix
-//
-// Affine transformations are generalizations of Euclidean transformations.
-// Affine transformation includes translation, rotation, reflection, scaling,
-// and shearing. Length and angle are NOT preserved.
-// M = [ R | T ]
-// [ --+-- ] (R denotes 3x3 rotation/scale/shear matrix)
-// [ 0 | 1 ] (T denotes 1x3 translation matrix)
-//
-// y = M*x -> y = R*x + T -> x = R^-1*(y - T) -> x = R^-1*y - R^-1*T
-//
-// [ R | T ]-1 [ R^-1 | -R^-1 * T ]
-// [ --+-- ] = [ -----+---------- ]
-// [ 0 | 1 ] [ 0 + 1 ]
-///////////////////////////////////////////////////////////////////////////////
-Matrix4& Matrix4::invertAffine()
-{
- // R^-1
- Matrix3 r(m[0],m[1],m[2], m[4],m[5],m[6], m[8],m[9],m[10]);
- r.invert();
- m[0] = r[0]; m[1] = r[1]; m[2] = r[2];
- m[4] = r[3]; m[5] = r[4]; m[6] = r[5];
- m[8] = r[6]; m[9] = r[7]; m[10]= r[8];
-
- // -R^-1 * T
- float x = m[12];
- float y = m[13];
- float z = m[14];
- m[12] = -(r[0] * x + r[3] * y + r[6] * z);
- m[13] = -(r[1] * x + r[4] * y + r[7] * z);
- m[14] = -(r[2] * x + r[5] * y + r[8] * z);
-
- // last row should be unchanged (0,0,0,1)
- //m[3] = m[7] = m[11] = 0.0f;
- //m[15] = 1.0f;
- type=FULL;
-
- return * this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// inverse matrix using matrix partitioning (blockwise inverse)
-// It devides a 4x4 matrix into 4 of 2x2 matrices. It works in case of where
-// det(A) != 0. If not, use the generic inverse method
-// inverse formula.
-// M = [ A | B ] A, B, C, D are 2x2 matrix blocks
-// [ --+-- ] det(M) = |A| * |D - ((C * A^-1) * B)|
-// [ C | D ]
-//
-// M^-1 = [ A' | B' ] A' = A^-1 - (A^-1 * B) * C'
-// [ ---+--- ] B' = (A^-1 * B) * -D'
-// [ C' | D' ] C' = -D' * (C * A^-1)
-// D' = (D - ((C * A^-1) * B))^-1
-//
-// NOTE: I wrap with () if it it used more than once.
-// The matrix is invertable even if det(A)=0, so must check det(A) before
-// calling this function, and use invertGeneric() instead.
-///////////////////////////////////////////////////////////////////////////////
-Matrix4& Matrix4::invertProjective()
-{
- // partition
- Matrix2 a(m[0], m[1], m[4], m[5]);
- Matrix2 b(m[8], m[9], m[12], m[13]);
- Matrix2 c(m[2], m[3], m[6], m[7]);
- Matrix2 d(m[10], m[11], m[14], m[15]);
-
- // pre-compute repeated parts
- a.invert(); // A^-1
- Matrix2 ab = a * b; // A^-1 * B
- Matrix2 ca = c * a; // C * A^-1
- Matrix2 cab = ca * b; // C * A^-1 * B
- Matrix2 dcab = d - cab; // D - C * A^-1 * B
-
- // check determinant if |D - C * A^-1 * B| = 0
- //NOTE: this function assumes det(A) is already checked. if |A|=0 then,
- // cannot use this function.
- float determinant = dcab[0] * dcab[3] - dcab[1] * dcab[2];
- if(fabs(determinant) <= EPSILON)
- {
- return identity();
- }
-
- // compute D' and -D'
- Matrix2 d1 = dcab; // (D - C * A^-1 * B)
- d1.invert(); // (D - C * A^-1 * B)^-1
- Matrix2 d2 = -d1; // -(D - C * A^-1 * B)^-1
-
- // compute C'
- Matrix2 c1 = d2 * ca; // -D' * (C * A^-1)
-
- // compute B'
- Matrix2 b1 = ab * d2; // (A^-1 * B) * -D'
-
- // compute A'
- Matrix2 a1 = a - (ab * c1); // A^-1 - (A^-1 * B) * C'
-
- // assemble inverse matrix
- m[0] = a1[0]; m[4] = a1[2]; /*|*/ m[8] = b1[0]; m[12]= b1[2];
- m[1] = a1[1]; m[5] = a1[3]; /*|*/ m[9] = b1[1]; m[13]= b1[3];
- /*-----------------------------+-----------------------------*/
- m[2] = c1[0]; m[6] = c1[2]; /*|*/ m[10]= d1[0]; m[14]= d1[2];
- m[3] = c1[1]; m[7] = c1[3]; /*|*/ m[11]= d1[1]; m[15]= d1[3];
- type=FULL;
-
- return *this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// compute the inverse of a general 4x4 matrix using Cramer's Rule
-// If cannot find inverse, return indentity matrix
-// M^-1 = adj(M) / det(M)
-///////////////////////////////////////////////////////////////////////////////
-Matrix4& Matrix4::invertGeneral()
-{
- // get cofactors of minor matrices
- float cofactor0 = getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]);
- float cofactor1 = getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]);
- float cofactor2 = getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]);
- float cofactor3 = getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]);
-
- // get determinant
- float determinant = m[0] * cofactor0 - m[1] * cofactor1 + m[2] * cofactor2 - m[3] * cofactor3;
- if(fabs(determinant) <= EPSILON)
- {
- return identity();
- }
-
- // get rest of cofactors for adj(M)
- float cofactor4 = getCofactor(m[1],m[2],m[3], m[9],m[10],m[11], m[13],m[14],m[15]);
- float cofactor5 = getCofactor(m[0],m[2],m[3], m[8],m[10],m[11], m[12],m[14],m[15]);
- float cofactor6 = getCofactor(m[0],m[1],m[3], m[8],m[9], m[11], m[12],m[13],m[15]);
- float cofactor7 = getCofactor(m[0],m[1],m[2], m[8],m[9], m[10], m[12],m[13],m[14]);
-
- float cofactor8 = getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[13],m[14],m[15]);
- float cofactor9 = getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[12],m[14],m[15]);
- float cofactor10= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[12],m[13],m[15]);
- float cofactor11= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[12],m[13],m[14]);
-
- float cofactor12= getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[9], m[10],m[11]);
- float cofactor13= getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[8], m[10],m[11]);
- float cofactor14= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[8], m[9], m[11]);
- float cofactor15= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[8], m[9], m[10]);
-
- // build inverse matrix = adj(M) / det(M)
- // adjugate of M is the transpose of the cofactor matrix of M
- float invDeterminant = 1.0f / determinant;
- m[0] = invDeterminant * cofactor0;
- m[1] = -invDeterminant * cofactor4;
- m[2] = invDeterminant * cofactor8;
- m[3] = -invDeterminant * cofactor12;
-
- m[4] = -invDeterminant * cofactor1;
- m[5] = invDeterminant * cofactor5;
- m[6] = -invDeterminant * cofactor9;
- m[7] = invDeterminant * cofactor13;
-
- m[8] = invDeterminant * cofactor2;
- m[9] = -invDeterminant * cofactor6;
- m[10]= invDeterminant * cofactor10;
- m[11]= -invDeterminant * cofactor14;
-
- m[12]= -invDeterminant * cofactor3;
- m[13]= invDeterminant * cofactor7;
- m[14]= -invDeterminant * cofactor11;
- m[15]= invDeterminant * cofactor15;
- type=FULL;
-
- return *this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// return determinant of 4x4 matrix
-///////////////////////////////////////////////////////////////////////////////
-float Matrix4::getDeterminant()
-{
- return m[0] * getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]) -
- m[1] * getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]) +
- m[2] * getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]) -
- m[3] * getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]);
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// compute cofactor of 3x3 minor matrix without sign
-// input params are 9 elements of the minor matrix
-// NOTE: The caller must know its sign.
-///////////////////////////////////////////////////////////////////////////////
-float Matrix4::getCofactor(float m0, float m1, float m2,
- float m3, float m4, float m5,
- float m6, float m7, float m8)
-{
- return m0 * (m4 * m8 - m5 * m7) -
- m1 * (m3 * m8 - m5 * m6) +
- m2 * (m3 * m7 - m4 * m6);
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// translate this matrix by (x, y, z)
-///////////////////////////////////////////////////////////////////////////////
-Matrix4& Matrix4::translate(const Vector3& v)
-{
- return translate(v.x, v.y, v.z);
-}
-
-Matrix4& Matrix4::translate(float x, float y, float z)
-{
- m[0] += m[3] * x; m[4] += m[7] * x; m[8] += m[11]* x; m[12]+= m[15]* x;
- m[1] += m[3] * y; m[5] += m[7] * y; m[9] += m[11]* y; m[13]+= m[15]* y;
- m[2] += m[3] * z; m[6] += m[7] * z; m[10]+= m[11]* z; m[14]+= m[15]* z;
- if (type==TRANSLATE)
- type=M3D;
-
- return *this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// uniform scale
-///////////////////////////////////////////////////////////////////////////////
-Matrix4& Matrix4::scale(float s)
-{
- return scale(s, s, s);
-}
-
-Matrix4& Matrix4::scale(float x, float y, float z)
-{
- m[0] *= x; m[4] *= x; m[8] *= x; m[12] *= x;
- m[1] *= y; m[5] *= y; m[9] *= y; m[13] *= y;
- m[2] *= z; m[6] *= z; m[10]*= z; m[14] *= z;
- if (type==TRANSLATE)
- type=M3D;
- return *this;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// build a rotation matrix with given angle(degree) and rotation axis, then
-// multiply it with this object
-///////////////////////////////////////////////////////////////////////////////
-Matrix4& Matrix4::rotate(float angle, const Vector3& axis)
-{
- return rotate(angle, axis.x, axis.y, axis.z);
-}
-
-Matrix4& Matrix4::rotate(float angle, float x, float y, float z)
-{
- float c = cosf(angle * DEG2RAD); // cosine
- float s = sinf(angle * DEG2RAD); // sine
- float c1 = 1.0f - c; // 1 - c
- float m0 = m[0], m4 = m[4], m8 = m[8], m12= m[12],
- m1 = m[1], m5 = m[5], m9 = m[9], m13= m[13],
- m2 = m[2], m6 = m[6], m10= m[10], m14= m[14];
-
- // build rotation matrix
- float r0 = x * x * c1 + c;
- float r1 = x * y * c1 + z * s;
- float r2 = x * z * c1 - y * s;
- float r4 = x * y * c1 - z * s;
- float r5 = y * y * c1 + c;
- float r6 = y * z * c1 + x * s;
- float r8 = x * z * c1 + y * s;
- float r9 = y * z * c1 - x * s;
- float r10= z * z * c1 + c;
-
- // multiply rotation matrix
- m[0] = r0 * m0 + r4 * m1 + r8 * m2;
- m[1] = r1 * m0 + r5 * m1 + r9 * m2;
- m[2] = r2 * m0 + r6 * m1 + r10* m2;
- m[4] = r0 * m4 + r4 * m5 + r8 * m6;
- m[5] = r1 * m4 + r5 * m5 + r9 * m6;
- m[6] = r2 * m4 + r6 * m5 + r10* m6;
- m[8] = r0 * m8 + r4 * m9 + r8 * m10;
- m[9] = r1 * m8 + r5 * m9 + r9 * m10;
- m[10]= r2 * m8 + r6 * m9 + r10* m10;
- m[12]= r0 * m12+ r4 * m13+ r8 * m14;
- m[13]= r1 * m12+ r5 * m13+ r9 * m14;
- m[14]= r2 * m12+ r6 * m13+ r10* m14;
- type=FULL;
-
- return *this;
-}
-
-Matrix4& Matrix4::rotateX(float angle)
-{
- float c = cosf(angle * DEG2RAD);
- float s = sinf(angle * DEG2RAD);
- float m1 = m[1], m2 = m[2],
- m5 = m[5], m6 = m[6],
- m9 = m[9], m10= m[10],
- m13= m[13], m14= m[14];
-
- m[1] = m1 * c + m2 *-s;
- m[2] = m1 * s + m2 * c;
- m[5] = m5 * c + m6 *-s;
- m[6] = m5 * s + m6 * c;
- m[9] = m9 * c + m10*-s;
- m[10]= m9 * s + m10* c;
- m[13]= m13* c + m14*-s;
- m[14]= m13* s + m14* c;
- type=FULL;
-
- return *this;
-}
-
-Matrix4& Matrix4::rotateY(float angle)
-{
- float c = cosf(angle * DEG2RAD);
- float s = sinf(angle * DEG2RAD);
- float m0 = m[0], m2 = m[2],
- m4 = m[4], m6 = m[6],
- m8 = m[8], m10= m[10],
- m12= m[12], m14= m[14];
-
- m[0] = m0 * c + m2 * s;
- m[2] = m0 *-s + m2 * c;
- m[4] = m4 * c + m6 * s;
- m[6] = m4 *-s + m6 * c;
- m[8] = m8 * c + m10* s;
- m[10]= m8 *-s + m10* c;
- m[12]= m12* c + m14* s;
- m[14]= m12*-s + m14* c;
- type=FULL;
-
- return *this;
-}
-
-Matrix4& Matrix4::rotateZ(float angle)
-{
- float c = cosf(angle * DEG2RAD);
- float s = sinf(angle * DEG2RAD);
- float m0 = m[0], m1 = m[1],
- m4 = m[4], m5 = m[5],
- m8 = m[8], m9 = m[9],
- m12= m[12], m13= m[13];
-
- m[0] = m0 * c + m1 *-s;
- m[1] = m0 * s + m1 * c;
- m[4] = m4 * c + m5 *-s;
- m[5] = m4 * s + m5 * c;
- m[8] = m8 * c + m9 *-s;
- m[9] = m8 * s + m9 * c;
- m[12]= m12* c + m13*-s;
- m[13]= m12* s + m13* c;
- type=FULL;
- return *this;
-}
+///////////////////////////////////////////////////////////////////////////////
+// Matrice.cpp
+// ===========
+// NxN Matrix Math classes
+//
+// The elements of the matrix are stored as column major order.
+// | 0 2 | | 0 3 6 | | 0 4 8 12 |
+// | 1 3 | | 1 4 7 | | 1 5 9 13 |
+// | 2 5 8 | | 2 6 10 14 |
+// | 3 7 11 15 |
+//
+// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
+// CREATED: 2005-06-24
+// UPDATED: 2014-09-21
+//
+// Copyright (C) 2005 Song Ho Ahn
+///////////////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include "Matrices.h"
+#include "glog.h"
+
+const float DEG2RAD = 3.141593f / 180;
+const float EPSILON = 0.00001f;
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// transpose 2x2 matrix
+///////////////////////////////////////////////////////////////////////////////
+Matrix2& Matrix2::transpose()
+{
+ std::swap(m[1], m[2]);
+ return *this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// return the determinant of 2x2 matrix
+///////////////////////////////////////////////////////////////////////////////
+float Matrix2::getDeterminant()
+{
+ return m[0] * m[3] - m[1] * m[2];
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// inverse of 2x2 matrix
+// If cannot find inverse, set identity matrix
+///////////////////////////////////////////////////////////////////////////////
+Matrix2& Matrix2::invert()
+{
+ float determinant = getDeterminant();
+/* if(fabs(determinant) ==0)
+ determinant=EPSILON;*/
+
+ float tmp = m[0]; // copy the first element
+ float invDeterminant = 1.0f / determinant;
+ m[0] = invDeterminant * m[3];
+ m[1] = -invDeterminant * m[1];
+ m[2] = -invDeterminant * m[2];
+ m[3] = invDeterminant * tmp;
+
+ return *this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// transpose 3x3 matrix
+///////////////////////////////////////////////////////////////////////////////
+Matrix3& Matrix3::transpose()
+{
+ std::swap(m[1], m[3]);
+ std::swap(m[2], m[6]);
+ std::swap(m[5], m[7]);
+
+ return *this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// return determinant of 3x3 matrix
+///////////////////////////////////////////////////////////////////////////////
+float Matrix3::getDeterminant()
+{
+ return m[0] * (m[4] * m[8] - m[5] * m[7]) -
+ m[1] * (m[3] * m[8] - m[5] * m[6]) +
+ m[2] * (m[3] * m[7] - m[4] * m[6]);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// inverse 3x3 matrix
+// If cannot find inverse, set identity matrix
+///////////////////////////////////////////////////////////////////////////////
+Matrix3& Matrix3::invert()
+{
+ float determinant, invDeterminant;
+ float tmp[9];
+
+ tmp[0] = m[4] * m[8] - m[5] * m[7];
+ tmp[1] = m[2] * m[7] - m[1] * m[8];
+ tmp[2] = m[1] * m[5] - m[2] * m[4];
+ tmp[3] = m[5] * m[6] - m[3] * m[8];
+ tmp[4] = m[0] * m[8] - m[2] * m[6];
+ tmp[5] = m[2] * m[3] - m[0] * m[5];
+ tmp[6] = m[3] * m[7] - m[4] * m[6];
+ tmp[7] = m[1] * m[6] - m[0] * m[7];
+ tmp[8] = m[0] * m[4] - m[1] * m[3];
+
+ // check determinant if it is 0
+ determinant = m[0] * tmp[0] + m[1] * tmp[3] + m[2] * tmp[6];
+/* if(fabs(determinant) ==0)
+ determinant=EPSILON;*/
+
+ // divide by the determinant
+ invDeterminant = 1.0f / determinant;
+ m[0] = invDeterminant * tmp[0];
+ m[1] = invDeterminant * tmp[1];
+ m[2] = invDeterminant * tmp[2];
+ m[3] = invDeterminant * tmp[3];
+ m[4] = invDeterminant * tmp[4];
+ m[5] = invDeterminant * tmp[5];
+ m[6] = invDeterminant * tmp[6];
+ m[7] = invDeterminant * tmp[7];
+ m[8] = invDeterminant * tmp[8];
+
+ return *this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// transpose 4x4 matrix
+///////////////////////////////////////////////////////////////////////////////
+Matrix4& Matrix4::transpose()
+{
+ std::swap(m[1], m[4]);
+ std::swap(m[2], m[8]);
+ std::swap(m[3], m[12]);
+ std::swap(m[6], m[9]);
+ std::swap(m[7], m[13]);
+ std::swap(m[11], m[14]);
+
+ return *this;
+}
+
+
+void Matrix4::transformPoint(float x, float y, float* newx, float* newy) const
+{
+ Vector4 src=Vector4(x,y,0,1);
+ Vector4 dst=*this*src;
+ *newx=dst.x;
+ *newy=dst.y;
+/*
+ glog_i("Matrix:\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n",
+ m[0],m[4],m[8],m[12],
+ m[1],m[5],m[9],m[13],
+ m[2],m[6],m[10],m[14],
+ m[3],m[7],m[11],m[15]
+ );
+ glog_i("XFORMP: (%f,%f)->(%f,%f)",x,y,*newx,*newy);
+ */
+}
+
+void Matrix4::inverseTransformPoint(float x, float y, float* newx, float* newy) const
+{
+ Vector4 src=Vector4(x,y,0,1);
+ Matrix4 inv=inverse();
+ Vector4 dst=inv*src;
+ *newx=dst.x;
+ *newy=dst.y;
+/* glog_i("Matrix:\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n",
+ m[0],m[4],m[8],m[12],
+ m[1],m[5],m[9],m[13],
+ m[2],m[6],m[10],m[14],
+ m[3],m[7],m[11],m[15]
+ );
+ glog_i("IMatrix:\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n%f\t%f\t%f\t%f\n",
+ inv[0],inv[4],inv[8],inv[12],
+ inv[1],inv[5],inv[9],inv[13],
+ inv[2],inv[6],inv[10],inv[14],
+ inv[3],inv[7],inv[11],inv[15]
+ );
+ glog_i("IXFORMP: (%f,%f)->(%f,%f)",x,y,*newx,*newy);
+*/
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// inverse 4x4 matrix
+///////////////////////////////////////////////////////////////////////////////
+Matrix4& Matrix4::invert()
+{
+ // If the 4th row is [0,0,0,1] then it is affine matrix and
+ // it has no projective transformation.
+ if(m[3] == 0 && m[7] == 0 && m[11] == 0 && m[15] == 1)
+ this->invertAffine();
+ else
+ {
+ this->invertGeneral();
+ /*@@ invertProjective() is not optimized (slower than generic one)
+ if(fabs(m[0]*m[5] - m[1]*m[4]) > EPSILON)
+ this->invertProjective(); // inverse using matrix partition
+ else
+ this->invertGeneral(); // generalized inverse
+ */
+ }
+
+ return *this;
+}
+
+Matrix4 Matrix4::inverse() const
+{
+ Matrix4 inv=*this;
+ inv.invert();
+ return inv;
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// compute the inverse of 4x4 Euclidean transformation matrix
+//
+// Euclidean transformation is translation, rotation, and reflection.
+// With Euclidean transform, only the position and orientation of the object
+// will be changed. Euclidean transform does not change the shape of an object
+// (no scaling). Length and angle are reserved.
+//
+// Use inverseAffine() if the matrix has scale and shear transformation.
+//
+// M = [ R | T ]
+// [ --+-- ] (R denotes 3x3 rotation/reflection matrix)
+// [ 0 | 1 ] (T denotes 1x3 translation matrix)
+//
+// y = M*x -> y = R*x + T -> x = R^-1*(y - T) -> x = R^T*y - R^T*T
+// (R is orthogonal, R^-1 = R^T)
+//
+// [ R | T ]-1 [ R^T | -R^T * T ] (R denotes 3x3 rotation matrix)
+// [ --+-- ] = [ ----+--------- ] (T denotes 1x3 translation)
+// [ 0 | 1 ] [ 0 | 1 ] (R^T denotes R-transpose)
+///////////////////////////////////////////////////////////////////////////////
+Matrix4& Matrix4::invertEuclidean()
+{
+ // transpose 3x3 rotation matrix part
+ // | R^T | 0 |
+ // | ----+-- |
+ // | 0 | 1 |
+ float tmp;
+ tmp = m[1]; m[1] = m[4]; m[4] = tmp;
+ tmp = m[2]; m[2] = m[8]; m[8] = tmp;
+ tmp = m[6]; m[6] = m[9]; m[9] = tmp;
+
+ // compute translation part -R^T * T
+ // | 0 | -R^T x |
+ // | --+------- |
+ // | 0 | 0 |
+ float x = m[12];
+ float y = m[13];
+ float z = m[14];
+ m[12] = -(m[0] * x + m[4] * y + m[8] * z);
+ m[13] = -(m[1] * x + m[5] * y + m[9] * z);
+ m[14] = -(m[2] * x + m[6] * y + m[10]* z);
+
+ // last row should be unchanged (0,0,0,1)
+
+ return *this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// compute the inverse of a 4x4 affine transformation matrix
+//
+// Affine transformations are generalizations of Euclidean transformations.
+// Affine transformation includes translation, rotation, reflection, scaling,
+// and shearing. Length and angle are NOT preserved.
+// M = [ R | T ]
+// [ --+-- ] (R denotes 3x3 rotation/scale/shear matrix)
+// [ 0 | 1 ] (T denotes 1x3 translation matrix)
+//
+// y = M*x -> y = R*x + T -> x = R^-1*(y - T) -> x = R^-1*y - R^-1*T
+//
+// [ R | T ]-1 [ R^-1 | -R^-1 * T ]
+// [ --+-- ] = [ -----+---------- ]
+// [ 0 | 1 ] [ 0 + 1 ]
+///////////////////////////////////////////////////////////////////////////////
+Matrix4& Matrix4::invertAffine()
+{
+ // R^-1
+ Matrix3 r(m[0],m[1],m[2], m[4],m[5],m[6], m[8],m[9],m[10]);
+ r.invert();
+ m[0] = r[0]; m[1] = r[1]; m[2] = r[2];
+ m[4] = r[3]; m[5] = r[4]; m[6] = r[5];
+ m[8] = r[6]; m[9] = r[7]; m[10]= r[8];
+
+ // -R^-1 * T
+ float x = m[12];
+ float y = m[13];
+ float z = m[14];
+ m[12] = -(r[0] * x + r[3] * y + r[6] * z);
+ m[13] = -(r[1] * x + r[4] * y + r[7] * z);
+ m[14] = -(r[2] * x + r[5] * y + r[8] * z);
+
+ // last row should be unchanged (0,0,0,1)
+ //m[3] = m[7] = m[11] = 0.0f;
+ //m[15] = 1.0f;
+ type=FULL;
+
+ return * this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// inverse matrix using matrix partitioning (blockwise inverse)
+// It devides a 4x4 matrix into 4 of 2x2 matrices. It works in case of where
+// det(A) != 0. If not, use the generic inverse method
+// inverse formula.
+// M = [ A | B ] A, B, C, D are 2x2 matrix blocks
+// [ --+-- ] det(M) = |A| * |D - ((C * A^-1) * B)|
+// [ C | D ]
+//
+// M^-1 = [ A' | B' ] A' = A^-1 - (A^-1 * B) * C'
+// [ ---+--- ] B' = (A^-1 * B) * -D'
+// [ C' | D' ] C' = -D' * (C * A^-1)
+// D' = (D - ((C * A^-1) * B))^-1
+//
+// NOTE: I wrap with () if it it used more than once.
+// The matrix is invertable even if det(A)=0, so must check det(A) before
+// calling this function, and use invertGeneric() instead.
+///////////////////////////////////////////////////////////////////////////////
+Matrix4& Matrix4::invertProjective()
+{
+ // partition
+ Matrix2 a(m[0], m[1], m[4], m[5]);
+ Matrix2 b(m[8], m[9], m[12], m[13]);
+ Matrix2 c(m[2], m[3], m[6], m[7]);
+ Matrix2 d(m[10], m[11], m[14], m[15]);
+
+ // pre-compute repeated parts
+ a.invert(); // A^-1
+ Matrix2 ab = a * b; // A^-1 * B
+ Matrix2 ca = c * a; // C * A^-1
+ Matrix2 cab = ca * b; // C * A^-1 * B
+ Matrix2 dcab = d - cab; // D - C * A^-1 * B
+
+ // check determinant if |D - C * A^-1 * B| = 0
+ //NOTE: this function assumes det(A) is already checked. if |A|=0 then,
+ // cannot use this function.
+ float determinant = dcab[0] * dcab[3] - dcab[1] * dcab[2];
+ if(fabs(determinant) <= EPSILON)
+ {
+ return identity();
+ }
+
+ // compute D' and -D'
+ Matrix2 d1 = dcab; // (D - C * A^-1 * B)
+ d1.invert(); // (D - C * A^-1 * B)^-1
+ Matrix2 d2 = -d1; // -(D - C * A^-1 * B)^-1
+
+ // compute C'
+ Matrix2 c1 = d2 * ca; // -D' * (C * A^-1)
+
+ // compute B'
+ Matrix2 b1 = ab * d2; // (A^-1 * B) * -D'
+
+ // compute A'
+ Matrix2 a1 = a - (ab * c1); // A^-1 - (A^-1 * B) * C'
+
+ // assemble inverse matrix
+ m[0] = a1[0]; m[4] = a1[2]; /*|*/ m[8] = b1[0]; m[12]= b1[2];
+ m[1] = a1[1]; m[5] = a1[3]; /*|*/ m[9] = b1[1]; m[13]= b1[3];
+ /*-----------------------------+-----------------------------*/
+ m[2] = c1[0]; m[6] = c1[2]; /*|*/ m[10]= d1[0]; m[14]= d1[2];
+ m[3] = c1[1]; m[7] = c1[3]; /*|*/ m[11]= d1[1]; m[15]= d1[3];
+ type=FULL;
+
+ return *this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// compute the inverse of a general 4x4 matrix using Cramer's Rule
+// If cannot find inverse, return indentity matrix
+// M^-1 = adj(M) / det(M)
+///////////////////////////////////////////////////////////////////////////////
+Matrix4& Matrix4::invertGeneral()
+{
+ // get cofactors of minor matrices
+ float cofactor0 = getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]);
+ float cofactor1 = getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]);
+ float cofactor2 = getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]);
+ float cofactor3 = getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]);
+
+ // get determinant
+ float determinant = m[0] * cofactor0 - m[1] * cofactor1 + m[2] * cofactor2 - m[3] * cofactor3;
+ if(fabs(determinant) <= EPSILON)
+ {
+ return identity();
+ }
+
+ // get rest of cofactors for adj(M)
+ float cofactor4 = getCofactor(m[1],m[2],m[3], m[9],m[10],m[11], m[13],m[14],m[15]);
+ float cofactor5 = getCofactor(m[0],m[2],m[3], m[8],m[10],m[11], m[12],m[14],m[15]);
+ float cofactor6 = getCofactor(m[0],m[1],m[3], m[8],m[9], m[11], m[12],m[13],m[15]);
+ float cofactor7 = getCofactor(m[0],m[1],m[2], m[8],m[9], m[10], m[12],m[13],m[14]);
+
+ float cofactor8 = getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[13],m[14],m[15]);
+ float cofactor9 = getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[12],m[14],m[15]);
+ float cofactor10= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[12],m[13],m[15]);
+ float cofactor11= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[12],m[13],m[14]);
+
+ float cofactor12= getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[9], m[10],m[11]);
+ float cofactor13= getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[8], m[10],m[11]);
+ float cofactor14= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[8], m[9], m[11]);
+ float cofactor15= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[8], m[9], m[10]);
+
+ // build inverse matrix = adj(M) / det(M)
+ // adjugate of M is the transpose of the cofactor matrix of M
+ float invDeterminant = 1.0f / determinant;
+ m[0] = invDeterminant * cofactor0;
+ m[1] = -invDeterminant * cofactor4;
+ m[2] = invDeterminant * cofactor8;
+ m[3] = -invDeterminant * cofactor12;
+
+ m[4] = -invDeterminant * cofactor1;
+ m[5] = invDeterminant * cofactor5;
+ m[6] = -invDeterminant * cofactor9;
+ m[7] = invDeterminant * cofactor13;
+
+ m[8] = invDeterminant * cofactor2;
+ m[9] = -invDeterminant * cofactor6;
+ m[10]= invDeterminant * cofactor10;
+ m[11]= -invDeterminant * cofactor14;
+
+ m[12]= -invDeterminant * cofactor3;
+ m[13]= invDeterminant * cofactor7;
+ m[14]= -invDeterminant * cofactor11;
+ m[15]= invDeterminant * cofactor15;
+ type=FULL;
+
+ return *this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// return determinant of 4x4 matrix
+///////////////////////////////////////////////////////////////////////////////
+float Matrix4::getDeterminant()
+{
+ return m[0] * getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]) -
+ m[1] * getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]) +
+ m[2] * getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]) -
+ m[3] * getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// compute cofactor of 3x3 minor matrix without sign
+// input params are 9 elements of the minor matrix
+// NOTE: The caller must know its sign.
+///////////////////////////////////////////////////////////////////////////////
+float Matrix4::getCofactor(float m0, float m1, float m2,
+ float m3, float m4, float m5,
+ float m6, float m7, float m8)
+{
+ return m0 * (m4 * m8 - m5 * m7) -
+ m1 * (m3 * m8 - m5 * m6) +
+ m2 * (m3 * m7 - m4 * m6);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// translate this matrix by (x, y, z)
+///////////////////////////////////////////////////////////////////////////////
+Matrix4& Matrix4::translate(const Vector3& v)
+{
+ return translate(v.x, v.y, v.z);
+}
+
+Matrix4& Matrix4::translate(float x, float y, float z)
+{
+ m[0] += m[3] * x; m[4] += m[7] * x; m[8] += m[11]* x; m[12]+= m[15]* x;
+ m[1] += m[3] * y; m[5] += m[7] * y; m[9] += m[11]* y; m[13]+= m[15]* y;
+ m[2] += m[3] * z; m[6] += m[7] * z; m[10]+= m[11]* z; m[14]+= m[15]* z;
+ if (type==TRANSLATE)
+ type=M3D;
+
+ return *this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// uniform scale
+///////////////////////////////////////////////////////////////////////////////
+Matrix4& Matrix4::scale(float s)
+{
+ return scale(s, s, s);
+}
+
+Matrix4& Matrix4::scale(float x, float y, float z)
+{
+ m[0] *= x; m[4] *= x; m[8] *= x; m[12] *= x;
+ m[1] *= y; m[5] *= y; m[9] *= y; m[13] *= y;
+ m[2] *= z; m[6] *= z; m[10]*= z; m[14] *= z;
+ if (type==TRANSLATE)
+ type=M3D;
+ return *this;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// build a rotation matrix with given angle(degree) and rotation axis, then
+// multiply it with this object
+///////////////////////////////////////////////////////////////////////////////
+Matrix4& Matrix4::rotate(float angle, const Vector3& axis)
+{
+ return rotate(angle, axis.x, axis.y, axis.z);
+}
+
+Matrix4& Matrix4::rotate(float angle, float x, float y, float z)
+{
+ float c = cosf(angle * DEG2RAD); // cosine
+ float s = sinf(angle * DEG2RAD); // sine
+ float c1 = 1.0f - c; // 1 - c
+ float m0 = m[0], m4 = m[4], m8 = m[8], m12= m[12],
+ m1 = m[1], m5 = m[5], m9 = m[9], m13= m[13],
+ m2 = m[2], m6 = m[6], m10= m[10], m14= m[14];
+
+ // build rotation matrix
+ float r0 = x * x * c1 + c;
+ float r1 = x * y * c1 + z * s;
+ float r2 = x * z * c1 - y * s;
+ float r4 = x * y * c1 - z * s;
+ float r5 = y * y * c1 + c;
+ float r6 = y * z * c1 + x * s;
+ float r8 = x * z * c1 + y * s;
+ float r9 = y * z * c1 - x * s;
+ float r10= z * z * c1 + c;
+
+ // multiply rotation matrix
+ m[0] = r0 * m0 + r4 * m1 + r8 * m2;
+ m[1] = r1 * m0 + r5 * m1 + r9 * m2;
+ m[2] = r2 * m0 + r6 * m1 + r10* m2;
+ m[4] = r0 * m4 + r4 * m5 + r8 * m6;
+ m[5] = r1 * m4 + r5 * m5 + r9 * m6;
+ m[6] = r2 * m4 + r6 * m5 + r10* m6;
+ m[8] = r0 * m8 + r4 * m9 + r8 * m10;
+ m[9] = r1 * m8 + r5 * m9 + r9 * m10;
+ m[10]= r2 * m8 + r6 * m9 + r10* m10;
+ m[12]= r0 * m12+ r4 * m13+ r8 * m14;
+ m[13]= r1 * m12+ r5 * m13+ r9 * m14;
+ m[14]= r2 * m12+ r6 * m13+ r10* m14;
+ type=FULL;
+
+ return *this;
+}
+
+Matrix4& Matrix4::rotateX(float angle)
+{
+ float c = cosf(angle * DEG2RAD);
+ float s = sinf(angle * DEG2RAD);
+ float m1 = m[1], m2 = m[2],
+ m5 = m[5], m6 = m[6],
+ m9 = m[9], m10= m[10],
+ m13= m[13], m14= m[14];
+
+ m[1] = m1 * c + m2 *-s;
+ m[2] = m1 * s + m2 * c;
+ m[5] = m5 * c + m6 *-s;
+ m[6] = m5 * s + m6 * c;
+ m[9] = m9 * c + m10*-s;
+ m[10]= m9 * s + m10* c;
+ m[13]= m13* c + m14*-s;
+ m[14]= m13* s + m14* c;
+ type=FULL;
+
+ return *this;
+}
+
+Matrix4& Matrix4::rotateY(float angle)
+{
+ float c = cosf(angle * DEG2RAD);
+ float s = sinf(angle * DEG2RAD);
+ float m0 = m[0], m2 = m[2],
+ m4 = m[4], m6 = m[6],
+ m8 = m[8], m10= m[10],
+ m12= m[12], m14= m[14];
+
+ m[0] = m0 * c + m2 * s;
+ m[2] = m0 *-s + m2 * c;
+ m[4] = m4 * c + m6 * s;
+ m[6] = m4 *-s + m6 * c;
+ m[8] = m8 * c + m10* s;
+ m[10]= m8 *-s + m10* c;
+ m[12]= m12* c + m14* s;
+ m[14]= m12*-s + m14* c;
+ type=FULL;
+
+ return *this;
+}
+
+Matrix4& Matrix4::rotateZ(float angle)
+{
+ float c = cosf(angle * DEG2RAD);
+ float s = sinf(angle * DEG2RAD);
+ float m0 = m[0], m1 = m[1],
+ m4 = m[4], m5 = m[5],
+ m8 = m[8], m9 = m[9],
+ m12= m[12], m13= m[13];
+
+ m[0] = m0 * c + m1 *-s;
+ m[1] = m0 * s + m1 * c;
+ m[4] = m4 * c + m5 *-s;
+ m[5] = m4 * s + m5 * c;
+ m[8] = m8 * c + m9 *-s;
+ m[9] = m8 * s + m9 * c;
+ m[12]= m12* c + m13*-s;
+ m[13]= m12* s + m13* c;
+ type=FULL;
+ return *this;
+}
diff --git a/2dsg/Matrices.h b/2dsg/Matrices.h
index c0cb01b9c..80a4f36e9 100644
--- a/2dsg/Matrices.h
+++ b/2dsg/Matrices.h
@@ -1,1023 +1,1023 @@
-///////////////////////////////////////////////////////////////////////////////
-// Matrice.h
-// =========
-// NxN Matrix Math classes
-//
-// The elements of the matrix are stored as column major order.
-// | 0 2 | | 0 3 6 | | 0 4 8 12 |
-// | 1 3 | | 1 4 7 | | 1 5 9 13 |
-// | 2 5 8 | | 2 6 10 14 |
-// | 3 7 11 15 |
-//
-// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
-// CREATED: 2005-06-24
-// UPDATED: 2013-09-30
-//
-// Copyright (C) 2005 Song Ho Ahn
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef MATH_MATRICES_H
-#define MATH_MATRICES_H
-
-#include
-#include
-#include "Vectors.h"
-
-///////////////////////////////////////////////////////////////////////////
-// 2x2 matrix
-///////////////////////////////////////////////////////////////////////////
-class Matrix2
-{
-public:
- // constructors
- Matrix2(); // init with identity
- Matrix2(const float src[4]);
- Matrix2(float m0, float m1, float m2, float m3);
-
- void set(const float src[4]);
- void set(float m0, float m1, float m2, float m3);
- void setRow(int index, const float row[2]);
- void setRow(int index, const Vector2& v);
- void setColumn(int index, const float col[2]);
- void setColumn(int index, const Vector2& v);
-
- const float* get() const;
- float getDeterminant();
-
- Matrix2& identity();
- Matrix2& transpose(); // transpose itself and return reference
- Matrix2& invert();
-
- // operators
- Matrix2 operator+(const Matrix2& rhs) const; // add rhs
- Matrix2 operator-(const Matrix2& rhs) const; // subtract rhs
- Matrix2& operator+=(const Matrix2& rhs); // add rhs and update this object
- Matrix2& operator-=(const Matrix2& rhs); // subtract rhs and update this object
- Vector2 operator*(const Vector2& rhs) const; // multiplication: v' = M * v
- Matrix2 operator*(const Matrix2& rhs) const; // multiplication: M3 = M1 * M2
- Matrix2& operator*=(const Matrix2& rhs); // multiplication: M1' = M1 * M2
- bool operator==(const Matrix2& rhs) const; // exact compare, no epsilon
- bool operator!=(const Matrix2& rhs) const; // exact compare, no epsilon
- float operator[](int index) const; // subscript operator v[0], v[1]
- float& operator[](int index); // subscript operator v[0], v[1]
-
- friend Matrix2 operator-(const Matrix2& m); // unary operator (-)
- friend Matrix2 operator*(float scalar, const Matrix2& m); // pre-multiplication
- friend Vector2 operator*(const Vector2& vec, const Matrix2& m); // pre-multiplication
- friend std::ostream& operator<<(std::ostream& os, const Matrix2& m);
-
-protected:
-
-private:
- float m[4];
-
-};
-
-
-
-///////////////////////////////////////////////////////////////////////////
-// 3x3 matrix
-///////////////////////////////////////////////////////////////////////////
-class Matrix3
-{
-public:
- // constructors
- Matrix3(); // init with identity
- Matrix3(const float src[9]);
- Matrix3(float m0, float m1, float m2, // 1st column
- float m3, float m4, float m5, // 2nd column
- float m6, float m7, float m8); // 3rd column
-
- void set(const float src[9]);
- void set(float m0, float m1, float m2, // 1st column
- float m3, float m4, float m5, // 2nd column
- float m6, float m7, float m8); // 3rd column
- void setRow(int index, const float row[3]);
- void setRow(int index, const Vector3& v);
- void setColumn(int index, const float col[3]);
- void setColumn(int index, const Vector3& v);
-
- const float* get() const;
- float getDeterminant();
-
- Matrix3& identity();
- Matrix3& transpose(); // transpose itself and return reference
- Matrix3& invert();
-
- // operators
- Matrix3 operator+(const Matrix3& rhs) const; // add rhs
- Matrix3 operator-(const Matrix3& rhs) const; // subtract rhs
- Matrix3& operator+=(const Matrix3& rhs); // add rhs and update this object
- Matrix3& operator-=(const Matrix3& rhs); // subtract rhs and update this object
- Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v
- Matrix3 operator*(const Matrix3& rhs) const; // multiplication: M3 = M1 * M2
- Matrix3& operator*=(const Matrix3& rhs); // multiplication: M1' = M1 * M2
- bool operator==(const Matrix3& rhs) const; // exact compare, no epsilon
- bool operator!=(const Matrix3& rhs) const; // exact compare, no epsilon
- float operator[](int index) const; // subscript operator v[0], v[1]
- float& operator[](int index); // subscript operator v[0], v[1]
-
- friend Matrix3 operator-(const Matrix3& m); // unary operator (-)
- friend Matrix3 operator*(float scalar, const Matrix3& m); // pre-multiplication
- friend Vector3 operator*(const Vector3& vec, const Matrix3& m); // pre-multiplication
- friend std::ostream& operator<<(std::ostream& os, const Matrix3& m);
-
-protected:
-
-private:
- float m[9];
-
-};
-
-
-
-///////////////////////////////////////////////////////////////////////////
-// 4x4 matrix
-///////////////////////////////////////////////////////////////////////////
-class Matrix4
-{
-public:
- enum Type {
- TRANSLATE=0,
- M2D=1,
- M3D=2,
- FULL=3
- };
- // constructors
- Matrix4(); // init with identity
- Matrix4(const float src[16]);
- Matrix4(float m00, float m01, float m02, float m03, // 1st column
- float m04, float m05, float m06, float m07, // 2nd column
- float m08, float m09, float m10, float m11, // 3rd column
- float m12, float m13, float m14, float m15,Type t=FULL);// 4th column
-
- void set() { identity(); }
- void set(const float src[16]);
- void set(float m00, float m01, float m02, float m03, // 1st column
- float m04, float m05, float m06, float m07, // 2nd column
- float m08, float m09, float m10, float m11, // 3rd column
- float m12, float m13, float m14, float m15,Type t=FULL);// 4th column
- void setRow(int index, const float row[4]);
- void setRow(int index, const Vector4& v);
- void setRow(int index, const Vector3& v);
- void setColumn(int index, const float col[4]);
- void setColumn(int index, const Vector4& v);
- void setColumn(int index, const Vector3& v);
-
- const float* get() const;
- const float* data() const;
- float* raw();
- const float* getTranspose(); // return transposed matrix
- float getDeterminant();
-
- Matrix4& identity();
- Matrix4& transpose(); // transpose itself and return reference
- Matrix4& invert(); // check best inverse method before inverse
- Matrix4& invertEuclidean(); // inverse of Euclidean transform matrix
- Matrix4& invertAffine(); // inverse of affine transform matrix
- Matrix4& invertProjective(); // inverse of projective matrix using partitioning
- Matrix4& invertGeneral(); // inverse of generic matrix
- Matrix4 inverse() const;
-
- // transform matrix
- Matrix4& translate(float x, float y, float z); // translation by (x,y,z)
- Matrix4& translate(const Vector3& v); //
- Matrix4& rotate(float angle, const Vector3& axis); // rotate angle(degree) along the given axix
- Matrix4& rotate(float angle, float x, float y, float z);
- Matrix4& rotateX(float angle); // rotate on X-axis with degree
- Matrix4& rotateY(float angle); // rotate on Y-axis with degree
- Matrix4& rotateZ(float angle); // rotate on Z-axis with degree
- Matrix4& scale(float scale); // uniform scale
- Matrix4& scale(float sx, float sy, float sz); // scale by (sx, sy, sz) on each axis
-
- // operators
- Matrix4 operator+(const Matrix4& rhs) const; // add rhs
- Matrix4 operator-(const Matrix4& rhs) const; // subtract rhs
- Matrix4& operator+=(const Matrix4& rhs); // add rhs and update this object
- Matrix4& operator-=(const Matrix4& rhs); // subtract rhs and update this object
- Vector4 operator*(const Vector4& rhs) const; // multiplication: v' = M * v
- Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v
- Matrix4 operator*(const Matrix4& rhs) const; // multiplication: M3 = M1 * M2
- Matrix4& operator*=(const Matrix4& rhs); // multiplication: M1' = M1 * M2
- bool operator==(const Matrix4& rhs) const; // exact compare, no epsilon
- bool operator!=(const Matrix4& rhs) const; // exact compare, no epsilon
- float operator[](int index) const; // subscript operator v[0], v[1]
- float& operator[](int index); // subscript operator v[0], v[1]
-
- friend Matrix4 operator-(const Matrix4& m); // unary operator (-)
- friend Matrix4 operator*(float scalar, const Matrix4& m); // pre-multiplication
- friend Vector3 operator*(const Vector3& vec, const Matrix4& m); // pre-multiplication
- friend Vector4 operator*(const Vector4& vec, const Matrix4& m); // pre-multiplication
- friend std::ostream& operator<<(std::ostream& os, const Matrix4& m);
-
- void transformPoint(float x, float y, float* newx, float* newy) const;
- void inverseTransformPoint(float x, float y, float* newx, float* newy) const;
-
- enum Type type;
-protected:
-
-private:
- float getCofactor(float m0, float m1, float m2,
- float m3, float m4, float m5,
- float m6, float m7, float m8);
-
- float m[16];
- float tm[16]; // transpose m
-};
-
-
-
-///////////////////////////////////////////////////////////////////////////
-// inline functions for Matrix2
-///////////////////////////////////////////////////////////////////////////
-inline Matrix2::Matrix2()
-{
- // initially identity matrix
- identity();
-}
-
-
-
-inline Matrix2::Matrix2(const float src[4])
-{
- set(src);
-}
-
-
-
-inline Matrix2::Matrix2(float m0, float m1, float m2, float m3)
-{
- set(m0, m1, m2, m3);
-}
-
-
-
-inline void Matrix2::set(const float src[4])
-{
- m[0] = src[0]; m[1] = src[1]; m[2] = src[2]; m[3] = src[3];
-}
-
-
-
-inline void Matrix2::set(float m0, float m1, float m2, float m3)
-{
- m[0]= m0; m[1] = m1; m[2] = m2; m[3]= m3;
-}
-
-
-
-inline void Matrix2::setRow(int index, const float row[2])
-{
- m[index] = row[0]; m[index + 2] = row[1];
-}
-
-
-
-inline void Matrix2::setRow(int index, const Vector2& v)
-{
- m[index] = v.x; m[index + 2] = v.y;
-}
-
-
-
-inline void Matrix2::setColumn(int index, const float col[2])
-{
- m[index*2] = col[0]; m[index*2 + 1] = col[1];
-}
-
-
-
-inline void Matrix2::setColumn(int index, const Vector2& v)
-{
- m[index*2] = v.x; m[index*2 + 1] = v.y;
-}
-
-
-
-inline const float* Matrix2::get() const
-{
- return m;
-}
-
-
-inline Matrix2& Matrix2::identity()
-{
- m[0] = m[3] = 1.0f;
- m[1] = m[2] = 0.0f;
- return *this;
-}
-
-
-
-inline Matrix2 Matrix2::operator+(const Matrix2& rhs) const
-{
- return Matrix2(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2], m[3]+rhs[3]);
-}
-
-
-
-inline Matrix2 Matrix2::operator-(const Matrix2& rhs) const
-{
- return Matrix2(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2], m[3]-rhs[3]);
-}
-
-
-
-inline Matrix2& Matrix2::operator+=(const Matrix2& rhs)
-{
- m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2]; m[3] += rhs[3];
- return *this;
-}
-
-
-
-inline Matrix2& Matrix2::operator-=(const Matrix2& rhs)
-{
- m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2]; m[3] -= rhs[3];
- return *this;
-}
-
-
-
-inline Vector2 Matrix2::operator*(const Vector2& rhs) const
-{
- return Vector2(m[0]*rhs.x + m[2]*rhs.y, m[1]*rhs.x + m[3]*rhs.y);
-}
-
-
-
-inline Matrix2 Matrix2::operator*(const Matrix2& rhs) const
-{
- return Matrix2(m[0]*rhs[0] + m[2]*rhs[1], m[1]*rhs[0] + m[3]*rhs[1],
- m[0]*rhs[2] + m[2]*rhs[3], m[1]*rhs[2] + m[3]*rhs[3]);
-}
-
-
-
-inline Matrix2& Matrix2::operator*=(const Matrix2& rhs)
-{
- *this = *this * rhs;
- return *this;
-}
-
-
-
-inline bool Matrix2::operator==(const Matrix2& rhs) const
-{
- return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) && (m[3] == rhs[3]);
-}
-
-
-
-inline bool Matrix2::operator!=(const Matrix2& rhs) const
-{
- return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) || (m[3] != rhs[3]);
-}
-
-
-
-inline float Matrix2::operator[](int index) const
-{
- return m[index];
-}
-
-
-
-inline float& Matrix2::operator[](int index)
-{
- return m[index];
-}
-
-
-
-inline Matrix2 operator-(const Matrix2& rhs)
-{
- return Matrix2(-rhs[0], -rhs[1], -rhs[2], -rhs[3]);
-}
-
-
-
-inline Matrix2 operator*(float s, const Matrix2& rhs)
-{
- return Matrix2(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3]);
-}
-
-
-
-inline Vector2 operator*(const Vector2& v, const Matrix2& rhs)
-{
- return Vector2(v.x*rhs[0] + v.y*rhs[1], v.x*rhs[2] + v.y*rhs[3]);
-}
-
-
-
-inline std::ostream& operator<<(std::ostream& os, const Matrix2& m)
-{
- os << std::fixed << std::setprecision(5);
- os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[2] << "]\n"
- << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[3] << "]\n";
- os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
- return os;
-}
-// END OF MATRIX2 INLINE //////////////////////////////////////////////////////
-
-
-
-
-///////////////////////////////////////////////////////////////////////////
-// inline functions for Matrix3
-///////////////////////////////////////////////////////////////////////////
-inline Matrix3::Matrix3()
-{
- // initially identity matrix
- identity();
-}
-
-
-
-inline Matrix3::Matrix3(const float src[9])
-{
- set(src);
-}
-
-
-
-inline Matrix3::Matrix3(float m0, float m1, float m2,
- float m3, float m4, float m5,
- float m6, float m7, float m8)
-{
- set(m0, m1, m2, m3, m4, m5, m6, m7, m8);
-}
-
-
-
-inline void Matrix3::set(const float src[9])
-{
- m[0] = src[0]; m[1] = src[1]; m[2] = src[2];
- m[3] = src[3]; m[4] = src[4]; m[5] = src[5];
- m[6] = src[6]; m[7] = src[7]; m[8] = src[8];
-}
-
-
-
-inline void Matrix3::set(float m0, float m1, float m2,
- float m3, float m4, float m5,
- float m6, float m7, float m8)
-{
- m[0] = m0; m[1] = m1; m[2] = m2;
- m[3] = m3; m[4] = m4; m[5] = m5;
- m[6] = m6; m[7] = m7; m[8] = m8;
-}
-
-
-
-inline void Matrix3::setRow(int index, const float row[3])
-{
- m[index] = row[0]; m[index + 3] = row[1]; m[index + 6] = row[2];
-}
-
-
-
-inline void Matrix3::setRow(int index, const Vector3& v)
-{
- m[index] = v.x; m[index + 3] = v.y; m[index + 6] = v.z;
-}
-
-
-
-inline void Matrix3::setColumn(int index, const float col[3])
-{
- m[index*3] = col[0]; m[index*3 + 1] = col[1]; m[index*3 + 2] = col[2];
-}
-
-
-
-inline void Matrix3::setColumn(int index, const Vector3& v)
-{
- m[index*3] = v.x; m[index*3 + 1] = v.y; m[index*3 + 2] = v.z;
-}
-
-
-
-inline const float* Matrix3::get() const
-{
- return m;
-}
-
-
-
-inline Matrix3& Matrix3::identity()
-{
- m[0] = m[4] = m[8] = 1.0f;
- m[1] = m[2] = m[3] = m[5] = m[6] = m[7] = 0.0f;
- return *this;
-}
-
-
-
-inline Matrix3 Matrix3::operator+(const Matrix3& rhs) const
-{
- return Matrix3(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2],
- m[3]+rhs[3], m[4]+rhs[4], m[5]+rhs[5],
- m[6]+rhs[6], m[7]+rhs[7], m[8]+rhs[8]);
-}
-
-
-
-inline Matrix3 Matrix3::operator-(const Matrix3& rhs) const
-{
- return Matrix3(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2],
- m[3]-rhs[3], m[4]-rhs[4], m[5]-rhs[5],
- m[6]-rhs[6], m[7]-rhs[7], m[8]-rhs[8]);
-}
-
-
-
-inline Matrix3& Matrix3::operator+=(const Matrix3& rhs)
-{
- m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2];
- m[3] += rhs[3]; m[4] += rhs[4]; m[5] += rhs[5];
- m[6] += rhs[6]; m[7] += rhs[7]; m[8] += rhs[8];
- return *this;
-}
-
-
-
-inline Matrix3& Matrix3::operator-=(const Matrix3& rhs)
-{
- m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2];
- m[3] -= rhs[3]; m[4] -= rhs[4]; m[5] -= rhs[5];
- m[6] -= rhs[6]; m[7] -= rhs[7]; m[8] -= rhs[8];
- return *this;
-}
-
-
-
-inline Vector3 Matrix3::operator*(const Vector3& rhs) const
-{
- return Vector3(m[0]*rhs.x + m[3]*rhs.y + m[6]*rhs.z,
- m[1]*rhs.x + m[4]*rhs.y + m[7]*rhs.z,
- m[2]*rhs.x + m[5]*rhs.y + m[8]*rhs.z);
-}
-
-
-
-inline Matrix3 Matrix3::operator*(const Matrix3& rhs) const
-{
- return Matrix3(m[0]*rhs[0] + m[3]*rhs[1] + m[6]*rhs[2], m[1]*rhs[0] + m[4]*rhs[1] + m[7]*rhs[2], m[2]*rhs[0] + m[5]*rhs[1] + m[8]*rhs[2],
- m[0]*rhs[3] + m[3]*rhs[4] + m[6]*rhs[5], m[1]*rhs[3] + m[4]*rhs[4] + m[7]*rhs[5], m[2]*rhs[3] + m[5]*rhs[4] + m[8]*rhs[5],
- m[0]*rhs[6] + m[3]*rhs[7] + m[6]*rhs[8], m[1]*rhs[6] + m[4]*rhs[7] + m[7]*rhs[8], m[2]*rhs[6] + m[5]*rhs[7] + m[8]*rhs[8]);
-}
-
-
-
-inline Matrix3& Matrix3::operator*=(const Matrix3& rhs)
-{
- *this = *this * rhs;
- return *this;
-}
-
-
-
-inline bool Matrix3::operator==(const Matrix3& rhs) const
-{
- return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) &&
- (m[3] == rhs[3]) && (m[4] == rhs[4]) && (m[5] == rhs[5]) &&
- (m[6] == rhs[6]) && (m[7] == rhs[7]) && (m[8] == rhs[8]);
-}
-
-
-
-inline bool Matrix3::operator!=(const Matrix3& rhs) const
-{
- return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) ||
- (m[3] != rhs[3]) || (m[4] != rhs[4]) || (m[5] != rhs[5]) ||
- (m[6] != rhs[6]) || (m[7] != rhs[7]) || (m[8] != rhs[8]);
-}
-
-
-
-inline float Matrix3::operator[](int index) const
-{
- return m[index];
-}
-
-
-
-inline float& Matrix3::operator[](int index)
-{
- return m[index];
-}
-
-
-
-inline Matrix3 operator-(const Matrix3& rhs)
-{
- return Matrix3(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8]);
-}
-
-
-
-inline Matrix3 operator*(float s, const Matrix3& rhs)
-{
- return Matrix3(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3], s*rhs[4], s*rhs[5], s*rhs[6], s*rhs[7], s*rhs[8]);
-}
-
-
-
-inline Vector3 operator*(const Vector3& v, const Matrix3& m)
-{
- return Vector3(v.x*m[0] + v.y*m[1] + v.z*m[2], v.x*m[3] + v.y*m[4] + v.z*m[5], v.x*m[6] + v.y*m[7] + v.z*m[8]);
-}
-
-
-
-inline std::ostream& operator<<(std::ostream& os, const Matrix3& m)
-{
- os << std::fixed << std::setprecision(5);
- os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[3] << " " << std::setw(10) << m[6] << "]\n"
- << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[7] << "]\n"
- << "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[8] << "]\n";
- os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
- return os;
-}
-// END OF MATRIX3 INLINE //////////////////////////////////////////////////////
-
-
-
-
-///////////////////////////////////////////////////////////////////////////
-// inline functions for Matrix4
-///////////////////////////////////////////////////////////////////////////
-inline Matrix4::Matrix4()
-{
- // initially identity matrix
- identity();
-}
-
-
-
-inline Matrix4::Matrix4(const float src[16])
-{
- set(src);
-}
-
-
-
-inline Matrix4::Matrix4(float m00, float m01, float m02, float m03,
- float m04, float m05, float m06, float m07,
- float m08, float m09, float m10, float m11,
- float m12, float m13, float m14, float m15,Type t)
-{
- set(m00, m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12, m13, m14, m15,t);
-}
-
-
-
-inline void Matrix4::set(const float src[16])
-{
- m[0] = src[0]; m[1] = src[1]; m[2] = src[2]; m[3] = src[3];
- m[4] = src[4]; m[5] = src[5]; m[6] = src[6]; m[7] = src[7];
- m[8] = src[8]; m[9] = src[9]; m[10]= src[10]; m[11]= src[11];
- m[12]= src[12]; m[13]= src[13]; m[14]= src[14]; m[15]= src[15];
- type=FULL;
-}
-
-
-
-inline void Matrix4::set(float m00, float m01, float m02, float m03,
- float m04, float m05, float m06, float m07,
- float m08, float m09, float m10, float m11,
- float m12, float m13, float m14, float m15,Type t)
-{
- m[0] = m00; m[1] = m01; m[2] = m02; m[3] = m03;
- m[4] = m04; m[5] = m05; m[6] = m06; m[7] = m07;
- m[8] = m08; m[9] = m09; m[10]= m10; m[11]= m11;
- m[12]= m12; m[13]= m13; m[14]= m14; m[15]= m15;
- type=t;
-}
-
-
-
-inline void Matrix4::setRow(int index, const float row[4])
-{
- m[index] = row[0]; m[index + 4] = row[1]; m[index + 8] = row[2]; m[index + 12] = row[3];
- type=FULL;
-}
-
-
-
-inline void Matrix4::setRow(int index, const Vector4& v)
-{
- m[index] = v.x; m[index + 4] = v.y; m[index + 8] = v.z; m[index + 12] = v.w;
- type=FULL;
-}
-
-
-
-inline void Matrix4::setRow(int index, const Vector3& v)
-{
- m[index] = v.x; m[index + 4] = v.y; m[index + 8] = v.z;
- type=FULL;
-}
-
-
-
-inline void Matrix4::setColumn(int index, const float col[4])
-{
- m[index*4] = col[0]; m[index*4 + 1] = col[1]; m[index*4 + 2] = col[2]; m[index*4 + 3] = col[3];
- type=FULL;
-}
-
-
-
-inline void Matrix4::setColumn(int index, const Vector4& v)
-{
- m[index*4] = v.x; m[index*4 + 1] = v.y; m[index*4 + 2] = v.z; m[index*4 + 3] = v.w;
- type=FULL;
-}
-
-
-
-inline void Matrix4::setColumn(int index, const Vector3& v)
-{
- m[index*4] = v.x; m[index*4 + 1] = v.y; m[index*4 + 2] = v.z;
- type=FULL;
-}
-
-
-
-inline const float* Matrix4::get() const
-{
- return m;
-}
-
-inline const float* Matrix4::data() const
-{
- return m;
-}
-
-inline float* Matrix4::raw()
-{
- return m;
-}
-
-
-
-inline const float* Matrix4::getTranspose()
-{
- tm[0] = m[0]; tm[1] = m[4]; tm[2] = m[8]; tm[3] = m[12];
- tm[4] = m[1]; tm[5] = m[5]; tm[6] = m[9]; tm[7] = m[13];
- tm[8] = m[2]; tm[9] = m[6]; tm[10]= m[10]; tm[11]= m[14];
- tm[12]= m[3]; tm[13]= m[7]; tm[14]= m[11]; tm[15]= m[15];
- return tm;
-}
-
-
-
-inline Matrix4& Matrix4::identity()
-{
- m[0] = m[5] = m[10] = m[15] = 1.0f;
- m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f;
- type=TRANSLATE;
- return *this;
-}
-
-
-
-inline Matrix4 Matrix4::operator+(const Matrix4& rhs) const
-{
- return Matrix4(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2], m[3]+rhs[3],
- m[4]+rhs[4], m[5]+rhs[5], m[6]+rhs[6], m[7]+rhs[7],
- m[8]+rhs[8], m[9]+rhs[9], m[10]+rhs[10], m[11]+rhs[11],
- m[12]+rhs[12], m[13]+rhs[13], m[14]+rhs[14], m[15]+rhs[15]);
-}
-
-
-
-inline Matrix4 Matrix4::operator-(const Matrix4& rhs) const
-{
- return Matrix4(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2], m[3]-rhs[3],
- m[4]-rhs[4], m[5]-rhs[5], m[6]-rhs[6], m[7]-rhs[7],
- m[8]-rhs[8], m[9]-rhs[9], m[10]-rhs[10], m[11]-rhs[11],
- m[12]-rhs[12], m[13]-rhs[13], m[14]-rhs[14], m[15]-rhs[15]);
-}
-
-
-
-inline Matrix4& Matrix4::operator+=(const Matrix4& rhs)
-{
- m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2]; m[3] += rhs[3];
- m[4] += rhs[4]; m[5] += rhs[5]; m[6] += rhs[6]; m[7] += rhs[7];
- m[8] += rhs[8]; m[9] += rhs[9]; m[10]+= rhs[10]; m[11]+= rhs[11];
- m[12]+= rhs[12]; m[13]+= rhs[13]; m[14]+= rhs[14]; m[15]+= rhs[15];
- return *this;
-}
-
-
-
-inline Matrix4& Matrix4::operator-=(const Matrix4& rhs)
-{
- m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2]; m[3] -= rhs[3];
- m[4] -= rhs[4]; m[5] -= rhs[5]; m[6] -= rhs[6]; m[7] -= rhs[7];
- m[8] -= rhs[8]; m[9] -= rhs[9]; m[10]-= rhs[10]; m[11]-= rhs[11];
- m[12]-= rhs[12]; m[13]-= rhs[13]; m[14]-= rhs[14]; m[15]-= rhs[15];
- return *this;
-}
-
-
-
-inline Vector4 Matrix4::operator*(const Vector4& rhs) const
-{
- return Vector4(m[0]*rhs.x + m[4]*rhs.y + m[8]*rhs.z + m[12]*rhs.w,
- m[1]*rhs.x + m[5]*rhs.y + m[9]*rhs.z + m[13]*rhs.w,
- m[2]*rhs.x + m[6]*rhs.y + m[10]*rhs.z + m[14]*rhs.w,
- m[3]*rhs.x + m[7]*rhs.y + m[11]*rhs.z + m[15]*rhs.w);
-}
-
-
-
-inline Vector3 Matrix4::operator*(const Vector3& rhs) const
-{
- return Vector3(m[0]*rhs.x + m[4]*rhs.y + m[8]*rhs.z,
- m[1]*rhs.x + m[5]*rhs.y + m[9]*rhs.z,
- m[2]*rhs.x + m[6]*rhs.y + m[10]*rhs.z);
-}
-
-
-
-inline Matrix4 Matrix4::operator*(const Matrix4& n) const
-{
- //TRN: m0,m5,m10,m15=1 m12,m13,m14=x
- //M2D: m10,m15=1 m0,m1,m4,m5,m12,m13,m14=x
- //M3D: m15=1 m0,m1,m2,m4,m5,m6,m8,m9,m10,m12,m13,m14=x
- //FULL: no opt
- int mode=((type)<<2)|(n.type);
- switch (mode)
- {
- case 0: //TRNxTRN
- return Matrix4(1,0,0,0,
- 0,1,0,0,
- 0,0,1,0,
- n[12]+m[12],n[13]+m[13],n[14]+m[14],1,TRANSLATE);
- case 1: //TRNxM2D
- return Matrix4(n[0],n[1],0,0,
- n[4],n[5],0,0,
- 0,0,1,0,
- n[12] + m[12],n[13] + m[13],n[14] + m[14],1,M2D);
- case 2: //TRNxM3D
- return Matrix4(n[0],n[1],n[2],0,
- n[4],n[5],n[6],0,
- n[8],n[9],n[10],0,
- n[12] + m[12],n[13] + m[13],n[14] + m[14],1,M3D);
- case 3: //TRNxFULL
- return Matrix4(n[0],n[1],n[2],n[3],
- n[4],n[5],n[6],n[7],
- n[8],n[9],n[10],n[8],
- n[12] + m[12],n[13] + m[13],n[14] + m[14],n[15],FULL);
- case 4: //M2DxTRN
- return Matrix4(m[0],m[1],0,0,
- m[4],m[5],0,0,
- 0,0,1,0,
- m[0]*n[12] + m[4]*n[13] + m[12],
- m[1]*n[12] + m[5]*n[13] + m[13],
- n[14] + m[14],
- 1,M2D);
- case 5: //M2DxM2D
- return Matrix4(m[0]*n[0]+m[4]*n[1],m[1]*n[0]+m[5]*n[1],0,0,
- m[0]*n[4]+m[4]*n[5],m[1]*n[4]+m[5]*n[5],0,0,
- 0,0,1,0,
- m[0]*n[12] + m[4]*n[13] + m[12],
- m[1]*n[12] + m[5]*n[13] + m[13],
- n[14] + m[14],
- 1,M2D);
- case 8: //M3DxTRN
- return Matrix4(m[0],m[1],m[2],0,
- m[4],m[5],m[6],0,
- m[8],m[9],m[10],0,
- m[0]*n[12] + m[4]*n[13] + m[8]*n[14] + m[12],
- m[1]*n[12] + m[5]*n[13] + m[9]*n[14] + m[13],
- m[2]*n[12] + m[6]*n[13] + m[10]*n[14] + m[14],
- 1,M3D);
- case 12: //FULLxTRN
- return Matrix4(m[0],m[1],m[2],m[3],
- m[4],m[5],m[6],m[7],
- m[8],m[9],m[10],m[11],
- m[0]*n[12] + m[4]*n[13] + m[8]*n[14] + m[12],
- m[1]*n[12] + m[5]*n[13] + m[9]*n[14] + m[13],
- m[2]*n[12] + m[6]*n[13] + m[10]*n[14] + m[14],
- m[3]*n[12] + m[7]*n[13] + m[11]*n[14] + m[15],FULL);
- case 6: //M2DxM3D TODO
- case 7: //M2DxFULL TODO
- case 9: //M3DxM2D TODO
- case 10: //M3DxM3D TODO
- case 11: //M3DxFULL TODO
- case 13: //FULLxM2D TODO
- case 14: //FULLxM3D TODO
- default: //FULLxFULL
- return Matrix4(m[0]*n[0] + m[4]*n[1] + m[8]*n[2] + m[12]*n[3],
- m[1]*n[0] + m[5]*n[1] + m[9]*n[2] + m[13]*n[3],
- m[2]*n[0] + m[6]*n[1] + m[10]*n[2] + m[14]*n[3],
- m[3]*n[0] + m[7]*n[1] + m[11]*n[2] + m[15]*n[3],
-
- m[0]*n[4] + m[4]*n[5] + m[8]*n[6] + m[12]*n[7],
- m[1]*n[4] + m[5]*n[5] + m[9]*n[6] + m[13]*n[7],
- m[2]*n[4] + m[6]*n[5] + m[10]*n[6] + m[14]*n[7],
- m[3]*n[4] + m[7]*n[5] + m[11]*n[6] + m[15]*n[7],
-
- m[0]*n[8] + m[4]*n[9] + m[8]*n[10] + m[12]*n[11],
- m[1]*n[8] + m[5]*n[9] + m[9]*n[10] + m[13]*n[11],
- m[2]*n[8] + m[6]*n[9] + m[10]*n[10] + m[14]*n[11],
- m[3]*n[8] + m[7]*n[9] + m[11]*n[10] + m[15]*n[11],
-
- m[0]*n[12] + m[4]*n[13] + m[8]*n[14] + m[12]*n[15],
- m[1]*n[12] + m[5]*n[13] + m[9]*n[14] + m[13]*n[15],
- m[2]*n[12] + m[6]*n[13] + m[10]*n[14] + m[14]*n[15],
- m[3]*n[12] + m[7]*n[13] + m[11]*n[14] + m[15]*n[15],FULL);
- }
-}
-
-
-
-inline Matrix4& Matrix4::operator*=(const Matrix4& rhs)
-{
- *this = *this * rhs;
- return *this;
-}
-
-
-
-inline bool Matrix4::operator==(const Matrix4& n) const
-{
- return (m[0] == n[0]) && (m[1] == n[1]) && (m[2] == n[2]) && (m[3] == n[3]) &&
- (m[4] == n[4]) && (m[5] == n[5]) && (m[6] == n[6]) && (m[7] == n[7]) &&
- (m[8] == n[8]) && (m[9] == n[9]) && (m[10]== n[10]) && (m[11]== n[11]) &&
- (m[12]== n[12]) && (m[13]== n[13]) && (m[14]== n[14]) && (m[15]== n[15]);
-}
-
-
-
-inline bool Matrix4::operator!=(const Matrix4& n) const
-{
- return (m[0] != n[0]) || (m[1] != n[1]) || (m[2] != n[2]) || (m[3] != n[3]) ||
- (m[4] != n[4]) || (m[5] != n[5]) || (m[6] != n[6]) || (m[7] != n[7]) ||
- (m[8] != n[8]) || (m[9] != n[9]) || (m[10]!= n[10]) || (m[11]!= n[11]) ||
- (m[12]!= n[12]) || (m[13]!= n[13]) || (m[14]!= n[14]) || (m[15]!= n[15]);
-}
-
-
-
-inline float Matrix4::operator[](int index) const
-{
- return m[index];
-}
-
-
-
-inline float& Matrix4::operator[](int index)
-{
- return m[index];
-}
-
-
-
-inline Matrix4 operator-(const Matrix4& rhs)
-{
- return Matrix4(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8], -rhs[9], -rhs[10], -rhs[11], -rhs[12], -rhs[13], -rhs[14], -rhs[15]);
-}
-
-
-
-inline Matrix4 operator*(float s, const Matrix4& rhs)
-{
- return Matrix4(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3], s*rhs[4], s*rhs[5], s*rhs[6], s*rhs[7], s*rhs[8], s*rhs[9], s*rhs[10], s*rhs[11], s*rhs[12], s*rhs[13], s*rhs[14], s*rhs[15]);
-}
-
-
-
-inline Vector4 operator*(const Vector4& v, const Matrix4& m)
-{
- return Vector4(v.x*m[0] + v.y*m[1] + v.z*m[2] + v.w*m[3], v.x*m[4] + v.y*m[5] + v.z*m[6] + v.w*m[7], v.x*m[8] + v.y*m[9] + v.z*m[10] + v.w*m[11], v.x*m[12] + v.y*m[13] + v.z*m[14] + v.w*m[15]);
-}
-
-
-
-inline Vector3 operator*(const Vector3& v, const Matrix4& m)
-{
- return Vector3(v.x*m[0] + v.y*m[1] + v.z*m[2], v.x*m[4] + v.y*m[5] + v.z*m[6], v.x*m[8] + v.y*m[9] + v.z*m[10]);
-}
-
-
-
-inline std::ostream& operator<<(std::ostream& os, const Matrix4& m)
-{
- os << std::fixed << std::setprecision(5);
- os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[8] << " " << std::setw(10) << m[12] << "]\n"
- << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[9] << " " << std::setw(10) << m[13] << "]\n"
- << "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[6] << " " << std::setw(10) << m[10] << " " << std::setw(10) << m[14] << "]\n"
- << "[" << std::setw(10) << m[3] << " " << std::setw(10) << m[7] << " " << std::setw(10) << m[11] << " " << std::setw(10) << m[15] << "]\n";
- os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
- return os;
-}
-// END OF MATRIX4 INLINE //////////////////////////////////////////////////////
-#endif
+///////////////////////////////////////////////////////////////////////////////
+// Matrice.h
+// =========
+// NxN Matrix Math classes
+//
+// The elements of the matrix are stored as column major order.
+// | 0 2 | | 0 3 6 | | 0 4 8 12 |
+// | 1 3 | | 1 4 7 | | 1 5 9 13 |
+// | 2 5 8 | | 2 6 10 14 |
+// | 3 7 11 15 |
+//
+// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
+// CREATED: 2005-06-24
+// UPDATED: 2013-09-30
+//
+// Copyright (C) 2005 Song Ho Ahn
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef MATH_MATRICES_H
+#define MATH_MATRICES_H
+
+#include
+#include
+#include "Vectors.h"
+
+///////////////////////////////////////////////////////////////////////////
+// 2x2 matrix
+///////////////////////////////////////////////////////////////////////////
+class Matrix2
+{
+public:
+ // constructors
+ Matrix2(); // init with identity
+ Matrix2(const float src[4]);
+ Matrix2(float m0, float m1, float m2, float m3);
+
+ void set(const float src[4]);
+ void set(float m0, float m1, float m2, float m3);
+ void setRow(int index, const float row[2]);
+ void setRow(int index, const Vector2& v);
+ void setColumn(int index, const float col[2]);
+ void setColumn(int index, const Vector2& v);
+
+ const float* get() const;
+ float getDeterminant();
+
+ Matrix2& identity();
+ Matrix2& transpose(); // transpose itself and return reference
+ Matrix2& invert();
+
+ // operators
+ Matrix2 operator+(const Matrix2& rhs) const; // add rhs
+ Matrix2 operator-(const Matrix2& rhs) const; // subtract rhs
+ Matrix2& operator+=(const Matrix2& rhs); // add rhs and update this object
+ Matrix2& operator-=(const Matrix2& rhs); // subtract rhs and update this object
+ Vector2 operator*(const Vector2& rhs) const; // multiplication: v' = M * v
+ Matrix2 operator*(const Matrix2& rhs) const; // multiplication: M3 = M1 * M2
+ Matrix2& operator*=(const Matrix2& rhs); // multiplication: M1' = M1 * M2
+ bool operator==(const Matrix2& rhs) const; // exact compare, no epsilon
+ bool operator!=(const Matrix2& rhs) const; // exact compare, no epsilon
+ float operator[](int index) const; // subscript operator v[0], v[1]
+ float& operator[](int index); // subscript operator v[0], v[1]
+
+ friend Matrix2 operator-(const Matrix2& m); // unary operator (-)
+ friend Matrix2 operator*(float scalar, const Matrix2& m); // pre-multiplication
+ friend Vector2 operator*(const Vector2& vec, const Matrix2& m); // pre-multiplication
+ friend std::ostream& operator<<(std::ostream& os, const Matrix2& m);
+
+protected:
+
+private:
+ float m[4];
+
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////
+// 3x3 matrix
+///////////////////////////////////////////////////////////////////////////
+class Matrix3
+{
+public:
+ // constructors
+ Matrix3(); // init with identity
+ Matrix3(const float src[9]);
+ Matrix3(float m0, float m1, float m2, // 1st column
+ float m3, float m4, float m5, // 2nd column
+ float m6, float m7, float m8); // 3rd column
+
+ void set(const float src[9]);
+ void set(float m0, float m1, float m2, // 1st column
+ float m3, float m4, float m5, // 2nd column
+ float m6, float m7, float m8); // 3rd column
+ void setRow(int index, const float row[3]);
+ void setRow(int index, const Vector3& v);
+ void setColumn(int index, const float col[3]);
+ void setColumn(int index, const Vector3& v);
+
+ const float* get() const;
+ float getDeterminant();
+
+ Matrix3& identity();
+ Matrix3& transpose(); // transpose itself and return reference
+ Matrix3& invert();
+
+ // operators
+ Matrix3 operator+(const Matrix3& rhs) const; // add rhs
+ Matrix3 operator-(const Matrix3& rhs) const; // subtract rhs
+ Matrix3& operator+=(const Matrix3& rhs); // add rhs and update this object
+ Matrix3& operator-=(const Matrix3& rhs); // subtract rhs and update this object
+ Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v
+ Matrix3 operator*(const Matrix3& rhs) const; // multiplication: M3 = M1 * M2
+ Matrix3& operator*=(const Matrix3& rhs); // multiplication: M1' = M1 * M2
+ bool operator==(const Matrix3& rhs) const; // exact compare, no epsilon
+ bool operator!=(const Matrix3& rhs) const; // exact compare, no epsilon
+ float operator[](int index) const; // subscript operator v[0], v[1]
+ float& operator[](int index); // subscript operator v[0], v[1]
+
+ friend Matrix3 operator-(const Matrix3& m); // unary operator (-)
+ friend Matrix3 operator*(float scalar, const Matrix3& m); // pre-multiplication
+ friend Vector3 operator*(const Vector3& vec, const Matrix3& m); // pre-multiplication
+ friend std::ostream& operator<<(std::ostream& os, const Matrix3& m);
+
+protected:
+
+private:
+ float m[9];
+
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////
+// 4x4 matrix
+///////////////////////////////////////////////////////////////////////////
+class Matrix4
+{
+public:
+ enum Type {
+ TRANSLATE=0,
+ M2D=1,
+ M3D=2,
+ FULL=3
+ };
+ // constructors
+ Matrix4(); // init with identity
+ Matrix4(const float src[16]);
+ Matrix4(float m00, float m01, float m02, float m03, // 1st column
+ float m04, float m05, float m06, float m07, // 2nd column
+ float m08, float m09, float m10, float m11, // 3rd column
+ float m12, float m13, float m14, float m15,Type t=FULL);// 4th column
+
+ void set() { identity(); }
+ void set(const float src[16]);
+ void set(float m00, float m01, float m02, float m03, // 1st column
+ float m04, float m05, float m06, float m07, // 2nd column
+ float m08, float m09, float m10, float m11, // 3rd column
+ float m12, float m13, float m14, float m15,Type t=FULL);// 4th column
+ void setRow(int index, const float row[4]);
+ void setRow(int index, const Vector4& v);
+ void setRow(int index, const Vector3& v);
+ void setColumn(int index, const float col[4]);
+ void setColumn(int index, const Vector4& v);
+ void setColumn(int index, const Vector3& v);
+
+ const float* get() const;
+ const float* data() const;
+ float* raw();
+ const float* getTranspose(); // return transposed matrix
+ float getDeterminant();
+
+ Matrix4& identity();
+ Matrix4& transpose(); // transpose itself and return reference
+ Matrix4& invert(); // check best inverse method before inverse
+ Matrix4& invertEuclidean(); // inverse of Euclidean transform matrix
+ Matrix4& invertAffine(); // inverse of affine transform matrix
+ Matrix4& invertProjective(); // inverse of projective matrix using partitioning
+ Matrix4& invertGeneral(); // inverse of generic matrix
+ Matrix4 inverse() const;
+
+ // transform matrix
+ Matrix4& translate(float x, float y, float z); // translation by (x,y,z)
+ Matrix4& translate(const Vector3& v); //
+ Matrix4& rotate(float angle, const Vector3& axis); // rotate angle(degree) along the given axix
+ Matrix4& rotate(float angle, float x, float y, float z);
+ Matrix4& rotateX(float angle); // rotate on X-axis with degree
+ Matrix4& rotateY(float angle); // rotate on Y-axis with degree
+ Matrix4& rotateZ(float angle); // rotate on Z-axis with degree
+ Matrix4& scale(float scale); // uniform scale
+ Matrix4& scale(float sx, float sy, float sz); // scale by (sx, sy, sz) on each axis
+
+ // operators
+ Matrix4 operator+(const Matrix4& rhs) const; // add rhs
+ Matrix4 operator-(const Matrix4& rhs) const; // subtract rhs
+ Matrix4& operator+=(const Matrix4& rhs); // add rhs and update this object
+ Matrix4& operator-=(const Matrix4& rhs); // subtract rhs and update this object
+ Vector4 operator*(const Vector4& rhs) const; // multiplication: v' = M * v
+ Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v
+ Matrix4 operator*(const Matrix4& rhs) const; // multiplication: M3 = M1 * M2
+ Matrix4& operator*=(const Matrix4& rhs); // multiplication: M1' = M1 * M2
+ bool operator==(const Matrix4& rhs) const; // exact compare, no epsilon
+ bool operator!=(const Matrix4& rhs) const; // exact compare, no epsilon
+ float operator[](int index) const; // subscript operator v[0], v[1]
+ float& operator[](int index); // subscript operator v[0], v[1]
+
+ friend Matrix4 operator-(const Matrix4& m); // unary operator (-)
+ friend Matrix4 operator*(float scalar, const Matrix4& m); // pre-multiplication
+ friend Vector3 operator*(const Vector3& vec, const Matrix4& m); // pre-multiplication
+ friend Vector4 operator*(const Vector4& vec, const Matrix4& m); // pre-multiplication
+ friend std::ostream& operator<<(std::ostream& os, const Matrix4& m);
+
+ void transformPoint(float x, float y, float* newx, float* newy) const;
+ void inverseTransformPoint(float x, float y, float* newx, float* newy) const;
+
+ enum Type type;
+protected:
+
+private:
+ float getCofactor(float m0, float m1, float m2,
+ float m3, float m4, float m5,
+ float m6, float m7, float m8);
+
+ float m[16];
+ float tm[16]; // transpose m
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////
+// inline functions for Matrix2
+///////////////////////////////////////////////////////////////////////////
+inline Matrix2::Matrix2()
+{
+ // initially identity matrix
+ identity();
+}
+
+
+
+inline Matrix2::Matrix2(const float src[4])
+{
+ set(src);
+}
+
+
+
+inline Matrix2::Matrix2(float m0, float m1, float m2, float m3)
+{
+ set(m0, m1, m2, m3);
+}
+
+
+
+inline void Matrix2::set(const float src[4])
+{
+ m[0] = src[0]; m[1] = src[1]; m[2] = src[2]; m[3] = src[3];
+}
+
+
+
+inline void Matrix2::set(float m0, float m1, float m2, float m3)
+{
+ m[0]= m0; m[1] = m1; m[2] = m2; m[3]= m3;
+}
+
+
+
+inline void Matrix2::setRow(int index, const float row[2])
+{
+ m[index] = row[0]; m[index + 2] = row[1];
+}
+
+
+
+inline void Matrix2::setRow(int index, const Vector2& v)
+{
+ m[index] = v.x; m[index + 2] = v.y;
+}
+
+
+
+inline void Matrix2::setColumn(int index, const float col[2])
+{
+ m[index*2] = col[0]; m[index*2 + 1] = col[1];
+}
+
+
+
+inline void Matrix2::setColumn(int index, const Vector2& v)
+{
+ m[index*2] = v.x; m[index*2 + 1] = v.y;
+}
+
+
+
+inline const float* Matrix2::get() const
+{
+ return m;
+}
+
+
+inline Matrix2& Matrix2::identity()
+{
+ m[0] = m[3] = 1.0f;
+ m[1] = m[2] = 0.0f;
+ return *this;
+}
+
+
+
+inline Matrix2 Matrix2::operator+(const Matrix2& rhs) const
+{
+ return Matrix2(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2], m[3]+rhs[3]);
+}
+
+
+
+inline Matrix2 Matrix2::operator-(const Matrix2& rhs) const
+{
+ return Matrix2(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2], m[3]-rhs[3]);
+}
+
+
+
+inline Matrix2& Matrix2::operator+=(const Matrix2& rhs)
+{
+ m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2]; m[3] += rhs[3];
+ return *this;
+}
+
+
+
+inline Matrix2& Matrix2::operator-=(const Matrix2& rhs)
+{
+ m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2]; m[3] -= rhs[3];
+ return *this;
+}
+
+
+
+inline Vector2 Matrix2::operator*(const Vector2& rhs) const
+{
+ return Vector2(m[0]*rhs.x + m[2]*rhs.y, m[1]*rhs.x + m[3]*rhs.y);
+}
+
+
+
+inline Matrix2 Matrix2::operator*(const Matrix2& rhs) const
+{
+ return Matrix2(m[0]*rhs[0] + m[2]*rhs[1], m[1]*rhs[0] + m[3]*rhs[1],
+ m[0]*rhs[2] + m[2]*rhs[3], m[1]*rhs[2] + m[3]*rhs[3]);
+}
+
+
+
+inline Matrix2& Matrix2::operator*=(const Matrix2& rhs)
+{
+ *this = *this * rhs;
+ return *this;
+}
+
+
+
+inline bool Matrix2::operator==(const Matrix2& rhs) const
+{
+ return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) && (m[3] == rhs[3]);
+}
+
+
+
+inline bool Matrix2::operator!=(const Matrix2& rhs) const
+{
+ return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) || (m[3] != rhs[3]);
+}
+
+
+
+inline float Matrix2::operator[](int index) const
+{
+ return m[index];
+}
+
+
+
+inline float& Matrix2::operator[](int index)
+{
+ return m[index];
+}
+
+
+
+inline Matrix2 operator-(const Matrix2& rhs)
+{
+ return Matrix2(-rhs[0], -rhs[1], -rhs[2], -rhs[3]);
+}
+
+
+
+inline Matrix2 operator*(float s, const Matrix2& rhs)
+{
+ return Matrix2(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3]);
+}
+
+
+
+inline Vector2 operator*(const Vector2& v, const Matrix2& rhs)
+{
+ return Vector2(v.x*rhs[0] + v.y*rhs[1], v.x*rhs[2] + v.y*rhs[3]);
+}
+
+
+
+inline std::ostream& operator<<(std::ostream& os, const Matrix2& m)
+{
+ os << std::fixed << std::setprecision(5);
+ os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[2] << "]\n"
+ << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[3] << "]\n";
+ os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
+ return os;
+}
+// END OF MATRIX2 INLINE //////////////////////////////////////////////////////
+
+
+
+
+///////////////////////////////////////////////////////////////////////////
+// inline functions for Matrix3
+///////////////////////////////////////////////////////////////////////////
+inline Matrix3::Matrix3()
+{
+ // initially identity matrix
+ identity();
+}
+
+
+
+inline Matrix3::Matrix3(const float src[9])
+{
+ set(src);
+}
+
+
+
+inline Matrix3::Matrix3(float m0, float m1, float m2,
+ float m3, float m4, float m5,
+ float m6, float m7, float m8)
+{
+ set(m0, m1, m2, m3, m4, m5, m6, m7, m8);
+}
+
+
+
+inline void Matrix3::set(const float src[9])
+{
+ m[0] = src[0]; m[1] = src[1]; m[2] = src[2];
+ m[3] = src[3]; m[4] = src[4]; m[5] = src[5];
+ m[6] = src[6]; m[7] = src[7]; m[8] = src[8];
+}
+
+
+
+inline void Matrix3::set(float m0, float m1, float m2,
+ float m3, float m4, float m5,
+ float m6, float m7, float m8)
+{
+ m[0] = m0; m[1] = m1; m[2] = m2;
+ m[3] = m3; m[4] = m4; m[5] = m5;
+ m[6] = m6; m[7] = m7; m[8] = m8;
+}
+
+
+
+inline void Matrix3::setRow(int index, const float row[3])
+{
+ m[index] = row[0]; m[index + 3] = row[1]; m[index + 6] = row[2];
+}
+
+
+
+inline void Matrix3::setRow(int index, const Vector3& v)
+{
+ m[index] = v.x; m[index + 3] = v.y; m[index + 6] = v.z;
+}
+
+
+
+inline void Matrix3::setColumn(int index, const float col[3])
+{
+ m[index*3] = col[0]; m[index*3 + 1] = col[1]; m[index*3 + 2] = col[2];
+}
+
+
+
+inline void Matrix3::setColumn(int index, const Vector3& v)
+{
+ m[index*3] = v.x; m[index*3 + 1] = v.y; m[index*3 + 2] = v.z;
+}
+
+
+
+inline const float* Matrix3::get() const
+{
+ return m;
+}
+
+
+
+inline Matrix3& Matrix3::identity()
+{
+ m[0] = m[4] = m[8] = 1.0f;
+ m[1] = m[2] = m[3] = m[5] = m[6] = m[7] = 0.0f;
+ return *this;
+}
+
+
+
+inline Matrix3 Matrix3::operator+(const Matrix3& rhs) const
+{
+ return Matrix3(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2],
+ m[3]+rhs[3], m[4]+rhs[4], m[5]+rhs[5],
+ m[6]+rhs[6], m[7]+rhs[7], m[8]+rhs[8]);
+}
+
+
+
+inline Matrix3 Matrix3::operator-(const Matrix3& rhs) const
+{
+ return Matrix3(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2],
+ m[3]-rhs[3], m[4]-rhs[4], m[5]-rhs[5],
+ m[6]-rhs[6], m[7]-rhs[7], m[8]-rhs[8]);
+}
+
+
+
+inline Matrix3& Matrix3::operator+=(const Matrix3& rhs)
+{
+ m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2];
+ m[3] += rhs[3]; m[4] += rhs[4]; m[5] += rhs[5];
+ m[6] += rhs[6]; m[7] += rhs[7]; m[8] += rhs[8];
+ return *this;
+}
+
+
+
+inline Matrix3& Matrix3::operator-=(const Matrix3& rhs)
+{
+ m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2];
+ m[3] -= rhs[3]; m[4] -= rhs[4]; m[5] -= rhs[5];
+ m[6] -= rhs[6]; m[7] -= rhs[7]; m[8] -= rhs[8];
+ return *this;
+}
+
+
+
+inline Vector3 Matrix3::operator*(const Vector3& rhs) const
+{
+ return Vector3(m[0]*rhs.x + m[3]*rhs.y + m[6]*rhs.z,
+ m[1]*rhs.x + m[4]*rhs.y + m[7]*rhs.z,
+ m[2]*rhs.x + m[5]*rhs.y + m[8]*rhs.z);
+}
+
+
+
+inline Matrix3 Matrix3::operator*(const Matrix3& rhs) const
+{
+ return Matrix3(m[0]*rhs[0] + m[3]*rhs[1] + m[6]*rhs[2], m[1]*rhs[0] + m[4]*rhs[1] + m[7]*rhs[2], m[2]*rhs[0] + m[5]*rhs[1] + m[8]*rhs[2],
+ m[0]*rhs[3] + m[3]*rhs[4] + m[6]*rhs[5], m[1]*rhs[3] + m[4]*rhs[4] + m[7]*rhs[5], m[2]*rhs[3] + m[5]*rhs[4] + m[8]*rhs[5],
+ m[0]*rhs[6] + m[3]*rhs[7] + m[6]*rhs[8], m[1]*rhs[6] + m[4]*rhs[7] + m[7]*rhs[8], m[2]*rhs[6] + m[5]*rhs[7] + m[8]*rhs[8]);
+}
+
+
+
+inline Matrix3& Matrix3::operator*=(const Matrix3& rhs)
+{
+ *this = *this * rhs;
+ return *this;
+}
+
+
+
+inline bool Matrix3::operator==(const Matrix3& rhs) const
+{
+ return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) &&
+ (m[3] == rhs[3]) && (m[4] == rhs[4]) && (m[5] == rhs[5]) &&
+ (m[6] == rhs[6]) && (m[7] == rhs[7]) && (m[8] == rhs[8]);
+}
+
+
+
+inline bool Matrix3::operator!=(const Matrix3& rhs) const
+{
+ return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) ||
+ (m[3] != rhs[3]) || (m[4] != rhs[4]) || (m[5] != rhs[5]) ||
+ (m[6] != rhs[6]) || (m[7] != rhs[7]) || (m[8] != rhs[8]);
+}
+
+
+
+inline float Matrix3::operator[](int index) const
+{
+ return m[index];
+}
+
+
+
+inline float& Matrix3::operator[](int index)
+{
+ return m[index];
+}
+
+
+
+inline Matrix3 operator-(const Matrix3& rhs)
+{
+ return Matrix3(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8]);
+}
+
+
+
+inline Matrix3 operator*(float s, const Matrix3& rhs)
+{
+ return Matrix3(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3], s*rhs[4], s*rhs[5], s*rhs[6], s*rhs[7], s*rhs[8]);
+}
+
+
+
+inline Vector3 operator*(const Vector3& v, const Matrix3& m)
+{
+ return Vector3(v.x*m[0] + v.y*m[1] + v.z*m[2], v.x*m[3] + v.y*m[4] + v.z*m[5], v.x*m[6] + v.y*m[7] + v.z*m[8]);
+}
+
+
+
+inline std::ostream& operator<<(std::ostream& os, const Matrix3& m)
+{
+ os << std::fixed << std::setprecision(5);
+ os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[3] << " " << std::setw(10) << m[6] << "]\n"
+ << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[7] << "]\n"
+ << "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[8] << "]\n";
+ os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
+ return os;
+}
+// END OF MATRIX3 INLINE //////////////////////////////////////////////////////
+
+
+
+
+///////////////////////////////////////////////////////////////////////////
+// inline functions for Matrix4
+///////////////////////////////////////////////////////////////////////////
+inline Matrix4::Matrix4()
+{
+ // initially identity matrix
+ identity();
+}
+
+
+
+inline Matrix4::Matrix4(const float src[16])
+{
+ set(src);
+}
+
+
+
+inline Matrix4::Matrix4(float m00, float m01, float m02, float m03,
+ float m04, float m05, float m06, float m07,
+ float m08, float m09, float m10, float m11,
+ float m12, float m13, float m14, float m15,Type t)
+{
+ set(m00, m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12, m13, m14, m15,t);
+}
+
+
+
+inline void Matrix4::set(const float src[16])
+{
+ m[0] = src[0]; m[1] = src[1]; m[2] = src[2]; m[3] = src[3];
+ m[4] = src[4]; m[5] = src[5]; m[6] = src[6]; m[7] = src[7];
+ m[8] = src[8]; m[9] = src[9]; m[10]= src[10]; m[11]= src[11];
+ m[12]= src[12]; m[13]= src[13]; m[14]= src[14]; m[15]= src[15];
+ type=FULL;
+}
+
+
+
+inline void Matrix4::set(float m00, float m01, float m02, float m03,
+ float m04, float m05, float m06, float m07,
+ float m08, float m09, float m10, float m11,
+ float m12, float m13, float m14, float m15,Type t)
+{
+ m[0] = m00; m[1] = m01; m[2] = m02; m[3] = m03;
+ m[4] = m04; m[5] = m05; m[6] = m06; m[7] = m07;
+ m[8] = m08; m[9] = m09; m[10]= m10; m[11]= m11;
+ m[12]= m12; m[13]= m13; m[14]= m14; m[15]= m15;
+ type=t;
+}
+
+
+
+inline void Matrix4::setRow(int index, const float row[4])
+{
+ m[index] = row[0]; m[index + 4] = row[1]; m[index + 8] = row[2]; m[index + 12] = row[3];
+ type=FULL;
+}
+
+
+
+inline void Matrix4::setRow(int index, const Vector4& v)
+{
+ m[index] = v.x; m[index + 4] = v.y; m[index + 8] = v.z; m[index + 12] = v.w;
+ type=FULL;
+}
+
+
+
+inline void Matrix4::setRow(int index, const Vector3& v)
+{
+ m[index] = v.x; m[index + 4] = v.y; m[index + 8] = v.z;
+ type=FULL;
+}
+
+
+
+inline void Matrix4::setColumn(int index, const float col[4])
+{
+ m[index*4] = col[0]; m[index*4 + 1] = col[1]; m[index*4 + 2] = col[2]; m[index*4 + 3] = col[3];
+ type=FULL;
+}
+
+
+
+inline void Matrix4::setColumn(int index, const Vector4& v)
+{
+ m[index*4] = v.x; m[index*4 + 1] = v.y; m[index*4 + 2] = v.z; m[index*4 + 3] = v.w;
+ type=FULL;
+}
+
+
+
+inline void Matrix4::setColumn(int index, const Vector3& v)
+{
+ m[index*4] = v.x; m[index*4 + 1] = v.y; m[index*4 + 2] = v.z;
+ type=FULL;
+}
+
+
+
+inline const float* Matrix4::get() const
+{
+ return m;
+}
+
+inline const float* Matrix4::data() const
+{
+ return m;
+}
+
+inline float* Matrix4::raw()
+{
+ return m;
+}
+
+
+
+inline const float* Matrix4::getTranspose()
+{
+ tm[0] = m[0]; tm[1] = m[4]; tm[2] = m[8]; tm[3] = m[12];
+ tm[4] = m[1]; tm[5] = m[5]; tm[6] = m[9]; tm[7] = m[13];
+ tm[8] = m[2]; tm[9] = m[6]; tm[10]= m[10]; tm[11]= m[14];
+ tm[12]= m[3]; tm[13]= m[7]; tm[14]= m[11]; tm[15]= m[15];
+ return tm;
+}
+
+
+
+inline Matrix4& Matrix4::identity()
+{
+ m[0] = m[5] = m[10] = m[15] = 1.0f;
+ m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f;
+ type=TRANSLATE;
+ return *this;
+}
+
+
+
+inline Matrix4 Matrix4::operator+(const Matrix4& rhs) const
+{
+ return Matrix4(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2], m[3]+rhs[3],
+ m[4]+rhs[4], m[5]+rhs[5], m[6]+rhs[6], m[7]+rhs[7],
+ m[8]+rhs[8], m[9]+rhs[9], m[10]+rhs[10], m[11]+rhs[11],
+ m[12]+rhs[12], m[13]+rhs[13], m[14]+rhs[14], m[15]+rhs[15]);
+}
+
+
+
+inline Matrix4 Matrix4::operator-(const Matrix4& rhs) const
+{
+ return Matrix4(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2], m[3]-rhs[3],
+ m[4]-rhs[4], m[5]-rhs[5], m[6]-rhs[6], m[7]-rhs[7],
+ m[8]-rhs[8], m[9]-rhs[9], m[10]-rhs[10], m[11]-rhs[11],
+ m[12]-rhs[12], m[13]-rhs[13], m[14]-rhs[14], m[15]-rhs[15]);
+}
+
+
+
+inline Matrix4& Matrix4::operator+=(const Matrix4& rhs)
+{
+ m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2]; m[3] += rhs[3];
+ m[4] += rhs[4]; m[5] += rhs[5]; m[6] += rhs[6]; m[7] += rhs[7];
+ m[8] += rhs[8]; m[9] += rhs[9]; m[10]+= rhs[10]; m[11]+= rhs[11];
+ m[12]+= rhs[12]; m[13]+= rhs[13]; m[14]+= rhs[14]; m[15]+= rhs[15];
+ return *this;
+}
+
+
+
+inline Matrix4& Matrix4::operator-=(const Matrix4& rhs)
+{
+ m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2]; m[3] -= rhs[3];
+ m[4] -= rhs[4]; m[5] -= rhs[5]; m[6] -= rhs[6]; m[7] -= rhs[7];
+ m[8] -= rhs[8]; m[9] -= rhs[9]; m[10]-= rhs[10]; m[11]-= rhs[11];
+ m[12]-= rhs[12]; m[13]-= rhs[13]; m[14]-= rhs[14]; m[15]-= rhs[15];
+ return *this;
+}
+
+
+
+inline Vector4 Matrix4::operator*(const Vector4& rhs) const
+{
+ return Vector4(m[0]*rhs.x + m[4]*rhs.y + m[8]*rhs.z + m[12]*rhs.w,
+ m[1]*rhs.x + m[5]*rhs.y + m[9]*rhs.z + m[13]*rhs.w,
+ m[2]*rhs.x + m[6]*rhs.y + m[10]*rhs.z + m[14]*rhs.w,
+ m[3]*rhs.x + m[7]*rhs.y + m[11]*rhs.z + m[15]*rhs.w);
+}
+
+
+
+inline Vector3 Matrix4::operator*(const Vector3& rhs) const
+{
+ return Vector3(m[0]*rhs.x + m[4]*rhs.y + m[8]*rhs.z,
+ m[1]*rhs.x + m[5]*rhs.y + m[9]*rhs.z,
+ m[2]*rhs.x + m[6]*rhs.y + m[10]*rhs.z);
+}
+
+
+
+inline Matrix4 Matrix4::operator*(const Matrix4& n) const
+{
+ //TRN: m0,m5,m10,m15=1 m12,m13,m14=x
+ //M2D: m10,m15=1 m0,m1,m4,m5,m12,m13,m14=x
+ //M3D: m15=1 m0,m1,m2,m4,m5,m6,m8,m9,m10,m12,m13,m14=x
+ //FULL: no opt
+ int mode=((type)<<2)|(n.type);
+ switch (mode)
+ {
+ case 0: //TRNxTRN
+ return Matrix4(1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0,
+ n[12]+m[12],n[13]+m[13],n[14]+m[14],1,TRANSLATE);
+ case 1: //TRNxM2D
+ return Matrix4(n[0],n[1],0,0,
+ n[4],n[5],0,0,
+ 0,0,1,0,
+ n[12] + m[12],n[13] + m[13],n[14] + m[14],1,M2D);
+ case 2: //TRNxM3D
+ return Matrix4(n[0],n[1],n[2],0,
+ n[4],n[5],n[6],0,
+ n[8],n[9],n[10],0,
+ n[12] + m[12],n[13] + m[13],n[14] + m[14],1,M3D);
+ case 3: //TRNxFULL
+ return Matrix4(n[0],n[1],n[2],n[3],
+ n[4],n[5],n[6],n[7],
+ n[8],n[9],n[10],n[8],
+ n[12] + m[12],n[13] + m[13],n[14] + m[14],n[15],FULL);
+ case 4: //M2DxTRN
+ return Matrix4(m[0],m[1],0,0,
+ m[4],m[5],0,0,
+ 0,0,1,0,
+ m[0]*n[12] + m[4]*n[13] + m[12],
+ m[1]*n[12] + m[5]*n[13] + m[13],
+ n[14] + m[14],
+ 1,M2D);
+ case 5: //M2DxM2D
+ return Matrix4(m[0]*n[0]+m[4]*n[1],m[1]*n[0]+m[5]*n[1],0,0,
+ m[0]*n[4]+m[4]*n[5],m[1]*n[4]+m[5]*n[5],0,0,
+ 0,0,1,0,
+ m[0]*n[12] + m[4]*n[13] + m[12],
+ m[1]*n[12] + m[5]*n[13] + m[13],
+ n[14] + m[14],
+ 1,M2D);
+ case 8: //M3DxTRN
+ return Matrix4(m[0],m[1],m[2],0,
+ m[4],m[5],m[6],0,
+ m[8],m[9],m[10],0,
+ m[0]*n[12] + m[4]*n[13] + m[8]*n[14] + m[12],
+ m[1]*n[12] + m[5]*n[13] + m[9]*n[14] + m[13],
+ m[2]*n[12] + m[6]*n[13] + m[10]*n[14] + m[14],
+ 1,M3D);
+ case 12: //FULLxTRN
+ return Matrix4(m[0],m[1],m[2],m[3],
+ m[4],m[5],m[6],m[7],
+ m[8],m[9],m[10],m[11],
+ m[0]*n[12] + m[4]*n[13] + m[8]*n[14] + m[12],
+ m[1]*n[12] + m[5]*n[13] + m[9]*n[14] + m[13],
+ m[2]*n[12] + m[6]*n[13] + m[10]*n[14] + m[14],
+ m[3]*n[12] + m[7]*n[13] + m[11]*n[14] + m[15],FULL);
+ case 6: //M2DxM3D TODO
+ case 7: //M2DxFULL TODO
+ case 9: //M3DxM2D TODO
+ case 10: //M3DxM3D TODO
+ case 11: //M3DxFULL TODO
+ case 13: //FULLxM2D TODO
+ case 14: //FULLxM3D TODO
+ default: //FULLxFULL
+ return Matrix4(m[0]*n[0] + m[4]*n[1] + m[8]*n[2] + m[12]*n[3],
+ m[1]*n[0] + m[5]*n[1] + m[9]*n[2] + m[13]*n[3],
+ m[2]*n[0] + m[6]*n[1] + m[10]*n[2] + m[14]*n[3],
+ m[3]*n[0] + m[7]*n[1] + m[11]*n[2] + m[15]*n[3],
+
+ m[0]*n[4] + m[4]*n[5] + m[8]*n[6] + m[12]*n[7],
+ m[1]*n[4] + m[5]*n[5] + m[9]*n[6] + m[13]*n[7],
+ m[2]*n[4] + m[6]*n[5] + m[10]*n[6] + m[14]*n[7],
+ m[3]*n[4] + m[7]*n[5] + m[11]*n[6] + m[15]*n[7],
+
+ m[0]*n[8] + m[4]*n[9] + m[8]*n[10] + m[12]*n[11],
+ m[1]*n[8] + m[5]*n[9] + m[9]*n[10] + m[13]*n[11],
+ m[2]*n[8] + m[6]*n[9] + m[10]*n[10] + m[14]*n[11],
+ m[3]*n[8] + m[7]*n[9] + m[11]*n[10] + m[15]*n[11],
+
+ m[0]*n[12] + m[4]*n[13] + m[8]*n[14] + m[12]*n[15],
+ m[1]*n[12] + m[5]*n[13] + m[9]*n[14] + m[13]*n[15],
+ m[2]*n[12] + m[6]*n[13] + m[10]*n[14] + m[14]*n[15],
+ m[3]*n[12] + m[7]*n[13] + m[11]*n[14] + m[15]*n[15],FULL);
+ }
+}
+
+
+
+inline Matrix4& Matrix4::operator*=(const Matrix4& rhs)
+{
+ *this = *this * rhs;
+ return *this;
+}
+
+
+
+inline bool Matrix4::operator==(const Matrix4& n) const
+{
+ return (m[0] == n[0]) && (m[1] == n[1]) && (m[2] == n[2]) && (m[3] == n[3]) &&
+ (m[4] == n[4]) && (m[5] == n[5]) && (m[6] == n[6]) && (m[7] == n[7]) &&
+ (m[8] == n[8]) && (m[9] == n[9]) && (m[10]== n[10]) && (m[11]== n[11]) &&
+ (m[12]== n[12]) && (m[13]== n[13]) && (m[14]== n[14]) && (m[15]== n[15]);
+}
+
+
+
+inline bool Matrix4::operator!=(const Matrix4& n) const
+{
+ return (m[0] != n[0]) || (m[1] != n[1]) || (m[2] != n[2]) || (m[3] != n[3]) ||
+ (m[4] != n[4]) || (m[5] != n[5]) || (m[6] != n[6]) || (m[7] != n[7]) ||
+ (m[8] != n[8]) || (m[9] != n[9]) || (m[10]!= n[10]) || (m[11]!= n[11]) ||
+ (m[12]!= n[12]) || (m[13]!= n[13]) || (m[14]!= n[14]) || (m[15]!= n[15]);
+}
+
+
+
+inline float Matrix4::operator[](int index) const
+{
+ return m[index];
+}
+
+
+
+inline float& Matrix4::operator[](int index)
+{
+ return m[index];
+}
+
+
+
+inline Matrix4 operator-(const Matrix4& rhs)
+{
+ return Matrix4(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8], -rhs[9], -rhs[10], -rhs[11], -rhs[12], -rhs[13], -rhs[14], -rhs[15]);
+}
+
+
+
+inline Matrix4 operator*(float s, const Matrix4& rhs)
+{
+ return Matrix4(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3], s*rhs[4], s*rhs[5], s*rhs[6], s*rhs[7], s*rhs[8], s*rhs[9], s*rhs[10], s*rhs[11], s*rhs[12], s*rhs[13], s*rhs[14], s*rhs[15]);
+}
+
+
+
+inline Vector4 operator*(const Vector4& v, const Matrix4& m)
+{
+ return Vector4(v.x*m[0] + v.y*m[1] + v.z*m[2] + v.w*m[3], v.x*m[4] + v.y*m[5] + v.z*m[6] + v.w*m[7], v.x*m[8] + v.y*m[9] + v.z*m[10] + v.w*m[11], v.x*m[12] + v.y*m[13] + v.z*m[14] + v.w*m[15]);
+}
+
+
+
+inline Vector3 operator*(const Vector3& v, const Matrix4& m)
+{
+ return Vector3(v.x*m[0] + v.y*m[1] + v.z*m[2], v.x*m[4] + v.y*m[5] + v.z*m[6], v.x*m[8] + v.y*m[9] + v.z*m[10]);
+}
+
+
+
+inline std::ostream& operator<<(std::ostream& os, const Matrix4& m)
+{
+ os << std::fixed << std::setprecision(5);
+ os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[8] << " " << std::setw(10) << m[12] << "]\n"
+ << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[9] << " " << std::setw(10) << m[13] << "]\n"
+ << "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[6] << " " << std::setw(10) << m[10] << " " << std::setw(10) << m[14] << "]\n"
+ << "[" << std::setw(10) << m[3] << " " << std::setw(10) << m[7] << " " << std::setw(10) << m[11] << " " << std::setw(10) << m[15] << "]\n";
+ os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
+ return os;
+}
+// END OF MATRIX4 INLINE //////////////////////////////////////////////////////
+#endif
diff --git a/2dsg/MaxRectsBinPack.cpp b/2dsg/MaxRectsBinPack.cpp
index 757089a73..38dcc7d94 100644
--- a/2dsg/MaxRectsBinPack.cpp
+++ b/2dsg/MaxRectsBinPack.cpp
@@ -1,524 +1,524 @@
-/** @file MaxRectsBinPack.cpp
- @author Jukka Jylänki
-
- @brief Implements different bin packer algorithms that use the MAXRECTS data structure.
-
- This work is released to Public Domain, do whatever you want with it.
-*/
-#include
-#include
-
-#include
-
-#include "MaxRectsBinPack.h"
-
-#include
-#include
-#include
-#include
-
-#include
-
-using namespace std;
-
-MaxRectsBinPack::MaxRectsBinPack()
-:binWidth(0),
-binHeight(0)
-{
-}
-
-MaxRectsBinPack::MaxRectsBinPack(int width, int height)
-{
- Init(width, height);
-}
-
-void MaxRectsBinPack::Init(int width, int height)
-{
- binWidth = width;
- binHeight = height;
-
- Rect n;
- n.x = 0;
- n.y = 0;
- n.width = width;
- n.height = height;
-
- usedRectangles.clear();
-
- freeRectangles.clear();
- freeRectangles.push_back(n);
-}
-
-Rect MaxRectsBinPack::Insert(int width, int height, FreeRectChoiceHeuristic method)
-{
- Rect newNode;
- int score1; // Unused in this function. We don't need to know the score after finding the position.
- int score2;
- switch(method)
- {
- case RectBestShortSideFit: newNode = FindPositionForNewNodeBestShortSideFit(width, height, score1, score2); break;
- case RectBottomLeftRule: newNode = FindPositionForNewNodeBottomLeft(width, height, score1, score2); break;
- case RectContactPointRule: newNode = FindPositionForNewNodeContactPoint(width, height, score1); break;
- case RectBestLongSideFit: newNode = FindPositionForNewNodeBestLongSideFit(width, height, score2, score1); break;
- case RectBestAreaFit: newNode = FindPositionForNewNodeBestAreaFit(width, height, score1, score2); break;
- }
-
- if (newNode.height == 0)
- return newNode;
-
- size_t numRectanglesToProcess = freeRectangles.size();
- for(size_t i = 0; i < numRectanglesToProcess; ++i)
- {
- if (SplitFreeNode(freeRectangles[i], newNode))
- {
- freeRectangles.erase(freeRectangles.begin() + i);
- --i;
- --numRectanglesToProcess;
- }
- }
-
- PruneFreeList();
-
- usedRectangles.push_back(newNode);
- return newNode;
-}
-
-void MaxRectsBinPack::Insert(std::vector &rects, std::vector &dst, FreeRectChoiceHeuristic method)
-{
- dst.clear();
-
- while(rects.size() > 0)
- {
- int bestScore1 = std::numeric_limits::max();
- int bestScore2 = std::numeric_limits::max();
- int bestRectIndex = -1;
- Rect bestNode;
-
- for(size_t i = 0; i < rects.size(); ++i)
- {
- int score1;
- int score2;
- Rect newNode = ScoreRect(rects[i].width, rects[i].height, method, score1, score2);
-
- if (score1 < bestScore1 || (score1 == bestScore1 && score2 < bestScore2))
- {
- bestScore1 = score1;
- bestScore2 = score2;
- bestNode = newNode;
- bestRectIndex = i;
- }
- }
-
- if (bestRectIndex == -1)
- return;
-
- PlaceRect(bestNode);
- rects.erase(rects.begin() + bestRectIndex);
- }
-}
-
-void MaxRectsBinPack::PlaceRect(const Rect &node)
-{
- size_t numRectanglesToProcess = freeRectangles.size();
- for(size_t i = 0; i < numRectanglesToProcess; ++i)
- {
- if (SplitFreeNode(freeRectangles[i], node))
- {
- freeRectangles.erase(freeRectangles.begin() + i);
- --i;
- --numRectanglesToProcess;
- }
- }
-
- PruneFreeList();
-
- usedRectangles.push_back(node);
- // dst.push_back(bestNode); ///\todo Refactor so that this compiles.
-}
-
-Rect MaxRectsBinPack::ScoreRect(int width, int height, FreeRectChoiceHeuristic method, int &score1, int &score2) const
-{
- Rect newNode;
- score1 = std::numeric_limits::max();
- score2 = std::numeric_limits::max();
- switch(method)
- {
- case RectBestShortSideFit: newNode = FindPositionForNewNodeBestShortSideFit(width, height, score1, score2); break;
- case RectBottomLeftRule: newNode = FindPositionForNewNodeBottomLeft(width, height, score1, score2); break;
- case RectContactPointRule: newNode = FindPositionForNewNodeContactPoint(width, height, score1);
- score1 = -score1; // Reverse since we are minimizing, but for contact point score bigger is better.
- break;
- case RectBestLongSideFit: newNode = FindPositionForNewNodeBestLongSideFit(width, height, score2, score1); break;
- case RectBestAreaFit: newNode = FindPositionForNewNodeBestAreaFit(width, height, score1, score2); break;
- }
-
- // Cannot fit the current rectangle.
- if (newNode.height == 0)
- {
- score1 = std::numeric_limits::max();
- score2 = std::numeric_limits::max();
- }
-
- return newNode;
-}
-
-/// Computes the ratio of used surface area.
-float MaxRectsBinPack::Occupancy() const
-{
- unsigned long usedSurfaceArea = 0;
- for(size_t i = 0; i < usedRectangles.size(); ++i)
- usedSurfaceArea += usedRectangles[i].width * usedRectangles[i].height;
-
- return (float)usedSurfaceArea / (binWidth * binHeight);
-}
-
-Rect MaxRectsBinPack::FindPositionForNewNodeBottomLeft(int width, int height, int &bestY, int &bestX) const
-{
- Rect bestNode;
- memset(&bestNode, 0, sizeof(Rect));
-
- bestY = std::numeric_limits::max();
-
- for(size_t i = 0; i < freeRectangles.size(); ++i)
- {
- // Try to place the rectangle in upright (non-flipped) orientation.
- if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
- {
- int topSideY = freeRectangles[i].y + height;
- if (topSideY < bestY || (topSideY == bestY && freeRectangles[i].x < bestX))
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = width;
- bestNode.height = height;
- bestY = topSideY;
- bestX = freeRectangles[i].x;
- }
- }
-#if 0
- if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
- {
- int topSideY = freeRectangles[i].y + width;
- if (topSideY < bestY || (topSideY == bestY && freeRectangles[i].x < bestX))
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = height;
- bestNode.height = width;
- bestY = topSideY;
- bestX = freeRectangles[i].x;
- }
- }
-#endif
- }
- return bestNode;
-}
-
-Rect MaxRectsBinPack::FindPositionForNewNodeBestShortSideFit(int width, int height,
- int &bestShortSideFit, int &bestLongSideFit) const
-{
- Rect bestNode;
- memset(&bestNode, 0, sizeof(Rect));
-
- bestShortSideFit = std::numeric_limits::max();
-
- for(size_t i = 0; i < freeRectangles.size(); ++i)
- {
- // Try to place the rectangle in upright (non-flipped) orientation.
- if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
- {
- int leftoverHoriz = abs(freeRectangles[i].width - width);
- int leftoverVert = abs(freeRectangles[i].height - height);
- int shortSideFit = min(leftoverHoriz, leftoverVert);
- int longSideFit = max(leftoverHoriz, leftoverVert);
-
- if (shortSideFit < bestShortSideFit || (shortSideFit == bestShortSideFit && longSideFit < bestLongSideFit))
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = width;
- bestNode.height = height;
- bestShortSideFit = shortSideFit;
- bestLongSideFit = longSideFit;
- }
- }
-#if 0
- if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
- {
- int flippedLeftoverHoriz = abs(freeRectangles[i].width - height);
- int flippedLeftoverVert = abs(freeRectangles[i].height - width);
- int flippedShortSideFit = min(flippedLeftoverHoriz, flippedLeftoverVert);
- int flippedLongSideFit = max(flippedLeftoverHoriz, flippedLeftoverVert);
-
- if (flippedShortSideFit < bestShortSideFit || (flippedShortSideFit == bestShortSideFit && flippedLongSideFit < bestLongSideFit))
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = height;
- bestNode.height = width;
- bestShortSideFit = flippedShortSideFit;
- bestLongSideFit = flippedLongSideFit;
- }
- }
-#endif
- }
- return bestNode;
-}
-
-Rect MaxRectsBinPack::FindPositionForNewNodeBestLongSideFit(int width, int height,
- int &bestShortSideFit, int &bestLongSideFit) const
-{
- Rect bestNode;
- memset(&bestNode, 0, sizeof(Rect));
-
- bestLongSideFit = std::numeric_limits::max();
-
- for(size_t i = 0; i < freeRectangles.size(); ++i)
- {
- // Try to place the rectangle in upright (non-flipped) orientation.
- if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
- {
- int leftoverHoriz = abs(freeRectangles[i].width - width);
- int leftoverVert = abs(freeRectangles[i].height - height);
- int shortSideFit = min(leftoverHoriz, leftoverVert);
- int longSideFit = max(leftoverHoriz, leftoverVert);
-
- if (longSideFit < bestLongSideFit || (longSideFit == bestLongSideFit && shortSideFit < bestShortSideFit))
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = width;
- bestNode.height = height;
- bestShortSideFit = shortSideFit;
- bestLongSideFit = longSideFit;
- }
- }
-#if 0
- if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
- {
- int leftoverHoriz = abs(freeRectangles[i].width - height);
- int leftoverVert = abs(freeRectangles[i].height - width);
- int shortSideFit = min(leftoverHoriz, leftoverVert);
- int longSideFit = max(leftoverHoriz, leftoverVert);
-
- if (longSideFit < bestLongSideFit || (longSideFit == bestLongSideFit && shortSideFit < bestShortSideFit))
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = height;
- bestNode.height = width;
- bestShortSideFit = shortSideFit;
- bestLongSideFit = longSideFit;
- }
- }
-#endif
- }
- return bestNode;
-}
-
-Rect MaxRectsBinPack::FindPositionForNewNodeBestAreaFit(int width, int height,
- int &bestAreaFit, int &bestShortSideFit) const
-{
- Rect bestNode;
- memset(&bestNode, 0, sizeof(Rect));
-
- bestAreaFit = std::numeric_limits::max();
-
- for(size_t i = 0; i < freeRectangles.size(); ++i)
- {
- int areaFit = freeRectangles[i].width * freeRectangles[i].height - width * height;
-
- // Try to place the rectangle in upright (non-flipped) orientation.
- if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
- {
- int leftoverHoriz = abs(freeRectangles[i].width - width);
- int leftoverVert = abs(freeRectangles[i].height - height);
- int shortSideFit = min(leftoverHoriz, leftoverVert);
-
- if (areaFit < bestAreaFit || (areaFit == bestAreaFit && shortSideFit < bestShortSideFit))
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = width;
- bestNode.height = height;
- bestShortSideFit = shortSideFit;
- bestAreaFit = areaFit;
- }
- }
-#if 0
- if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
- {
- int leftoverHoriz = abs(freeRectangles[i].width - height);
- int leftoverVert = abs(freeRectangles[i].height - width);
- int shortSideFit = min(leftoverHoriz, leftoverVert);
-
- if (areaFit < bestAreaFit || (areaFit == bestAreaFit && shortSideFit < bestShortSideFit))
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = height;
- bestNode.height = width;
- bestShortSideFit = shortSideFit;
- bestAreaFit = areaFit;
- }
- }
-#endif
- }
- return bestNode;
-}
-
-/// Returns 0 if the two intervals i1 and i2 are disjoint, or the length of their overlap otherwise.
-int CommonIntervalLength(int i1start, int i1end, int i2start, int i2end)
-{
- if (i1end < i2start || i2end < i1start)
- return 0;
- return min(i1end, i2end) - max(i1start, i2start);
-}
-
-int MaxRectsBinPack::ContactPointScoreNode(int x, int y, int width, int height) const
-{
- int score = 0;
-
- if (x == 0 || x + width == binWidth)
- score += height;
- if (y == 0 || y + height == binHeight)
- score += width;
-
- for(size_t i = 0; i < usedRectangles.size(); ++i)
- {
- if (usedRectangles[i].x == x + width || usedRectangles[i].x + usedRectangles[i].width == x)
- score += CommonIntervalLength(usedRectangles[i].y, usedRectangles[i].y + usedRectangles[i].height, y, y + height);
- if (usedRectangles[i].y == y + height || usedRectangles[i].y + usedRectangles[i].height == y)
- score += CommonIntervalLength(usedRectangles[i].x, usedRectangles[i].x + usedRectangles[i].width, x, x + width);
- }
- return score;
-}
-
-Rect MaxRectsBinPack::FindPositionForNewNodeContactPoint(int width, int height, int &bestContactScore) const
-{
- Rect bestNode;
- memset(&bestNode, 0, sizeof(Rect));
-
- bestContactScore = -1;
-
- for(size_t i = 0; i < freeRectangles.size(); ++i)
- {
- // Try to place the rectangle in upright (non-flipped) orientation.
- if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
- {
- int score = ContactPointScoreNode(freeRectangles[i].x, freeRectangles[i].y, width, height);
- if (score > bestContactScore)
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = width;
- bestNode.height = height;
- bestContactScore = score;
- }
- }
-#if 0
- if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
- {
- int score = ContactPointScoreNode(freeRectangles[i].x, freeRectangles[i].y, width, height);
- if (score > bestContactScore)
- {
- bestNode.x = freeRectangles[i].x;
- bestNode.y = freeRectangles[i].y;
- bestNode.width = height;
- bestNode.height = width;
- bestContactScore = score;
- }
- }
-#endif
- }
- return bestNode;
-}
-
-bool MaxRectsBinPack::SplitFreeNode(Rect freeNode, const Rect &usedNode)
-{
- // Test with SAT if the rectangles even intersect.
- if (usedNode.x >= freeNode.x + freeNode.width || usedNode.x + usedNode.width <= freeNode.x ||
- usedNode.y >= freeNode.y + freeNode.height || usedNode.y + usedNode.height <= freeNode.y)
- return false;
-
- if (usedNode.x < freeNode.x + freeNode.width && usedNode.x + usedNode.width > freeNode.x)
- {
- // New node at the top side of the used node.
- if (usedNode.y > freeNode.y && usedNode.y < freeNode.y + freeNode.height)
- {
- Rect newNode = freeNode;
- newNode.height = usedNode.y - newNode.y;
- freeRectangles.push_back(newNode);
- }
-
- // New node at the bottom side of the used node.
- if (usedNode.y + usedNode.height < freeNode.y + freeNode.height)
- {
- Rect newNode = freeNode;
- newNode.y = usedNode.y + usedNode.height;
- newNode.height = freeNode.y + freeNode.height - (usedNode.y + usedNode.height);
- freeRectangles.push_back(newNode);
- }
- }
-
- if (usedNode.y < freeNode.y + freeNode.height && usedNode.y + usedNode.height > freeNode.y)
- {
- // New node at the left side of the used node.
- if (usedNode.x > freeNode.x && usedNode.x < freeNode.x + freeNode.width)
- {
- Rect newNode = freeNode;
- newNode.width = usedNode.x - newNode.x;
- freeRectangles.push_back(newNode);
- }
-
- // New node at the right side of the used node.
- if (usedNode.x + usedNode.width < freeNode.x + freeNode.width)
- {
- Rect newNode = freeNode;
- newNode.x = usedNode.x + usedNode.width;
- newNode.width = freeNode.x + freeNode.width - (usedNode.x + usedNode.width);
- freeRectangles.push_back(newNode);
- }
- }
-
- return true;
-}
-
-void MaxRectsBinPack::PruneFreeList()
-{
- /*
- /// Would be nice to do something like this, to avoid a Theta(n^2) loop through each pair.
- /// But unfortunately it doesn't quite cut it, since we also want to detect containment.
- /// Perhaps there's another way to do this faster than Theta(n^2).
-
- if (freeRectangles.size() > 0)
- clb::sort::QuickSort(&freeRectangles[0], freeRectangles.size(), NodeSortCmp);
-
- for(size_t i = 0; i < freeRectangles.size()-1; ++i)
- if (freeRectangles[i].x == freeRectangles[i+1].x &&
- freeRectangles[i].y == freeRectangles[i+1].y &&
- freeRectangles[i].width == freeRectangles[i+1].width &&
- freeRectangles[i].height == freeRectangles[i+1].height)
- {
- freeRectangles.erase(freeRectangles.begin() + i);
- --i;
- }
- */
-
- /// Go through each pair and remove any rectangle that is redundant.
- for(size_t i = 0; i < freeRectangles.size(); ++i)
- for(size_t j = i+1; j < freeRectangles.size(); ++j)
- {
- if (IsContainedIn(freeRectangles[i], freeRectangles[j]))
- {
- freeRectangles.erase(freeRectangles.begin()+i);
- --i;
- break;
- }
- if (IsContainedIn(freeRectangles[j], freeRectangles[i]))
- {
- freeRectangles.erase(freeRectangles.begin()+j);
- --j;
- }
- }
-}
+/** @file MaxRectsBinPack.cpp
+ @author Jukka Jylänki
+
+ @brief Implements different bin packer algorithms that use the MAXRECTS data structure.
+
+ This work is released to Public Domain, do whatever you want with it.
+*/
+#include
+#include
+
+#include
+
+#include "MaxRectsBinPack.h"
+
+#include
+#include
+#include
+#include
+
+#include
+
+using namespace std;
+
+MaxRectsBinPack::MaxRectsBinPack()
+:binWidth(0),
+binHeight(0)
+{
+}
+
+MaxRectsBinPack::MaxRectsBinPack(int width, int height)
+{
+ Init(width, height);
+}
+
+void MaxRectsBinPack::Init(int width, int height)
+{
+ binWidth = width;
+ binHeight = height;
+
+ Rect n;
+ n.x = 0;
+ n.y = 0;
+ n.width = width;
+ n.height = height;
+
+ usedRectangles.clear();
+
+ freeRectangles.clear();
+ freeRectangles.push_back(n);
+}
+
+Rect MaxRectsBinPack::Insert(int width, int height, FreeRectChoiceHeuristic method)
+{
+ Rect newNode;
+ int score1; // Unused in this function. We don't need to know the score after finding the position.
+ int score2;
+ switch(method)
+ {
+ case RectBestShortSideFit: newNode = FindPositionForNewNodeBestShortSideFit(width, height, score1, score2); break;
+ case RectBottomLeftRule: newNode = FindPositionForNewNodeBottomLeft(width, height, score1, score2); break;
+ case RectContactPointRule: newNode = FindPositionForNewNodeContactPoint(width, height, score1); break;
+ case RectBestLongSideFit: newNode = FindPositionForNewNodeBestLongSideFit(width, height, score2, score1); break;
+ case RectBestAreaFit: newNode = FindPositionForNewNodeBestAreaFit(width, height, score1, score2); break;
+ }
+
+ if (newNode.height == 0)
+ return newNode;
+
+ size_t numRectanglesToProcess = freeRectangles.size();
+ for(size_t i = 0; i < numRectanglesToProcess; ++i)
+ {
+ if (SplitFreeNode(freeRectangles[i], newNode))
+ {
+ freeRectangles.erase(freeRectangles.begin() + i);
+ --i;
+ --numRectanglesToProcess;
+ }
+ }
+
+ PruneFreeList();
+
+ usedRectangles.push_back(newNode);
+ return newNode;
+}
+
+void MaxRectsBinPack::Insert(std::vector &rects, std::vector &dst, FreeRectChoiceHeuristic method)
+{
+ dst.clear();
+
+ while(rects.size() > 0)
+ {
+ int bestScore1 = std::numeric_limits::max();
+ int bestScore2 = std::numeric_limits::max();
+ int bestRectIndex = -1;
+ Rect bestNode;
+
+ for(size_t i = 0; i < rects.size(); ++i)
+ {
+ int score1;
+ int score2;
+ Rect newNode = ScoreRect(rects[i].width, rects[i].height, method, score1, score2);
+
+ if (score1 < bestScore1 || (score1 == bestScore1 && score2 < bestScore2))
+ {
+ bestScore1 = score1;
+ bestScore2 = score2;
+ bestNode = newNode;
+ bestRectIndex = i;
+ }
+ }
+
+ if (bestRectIndex == -1)
+ return;
+
+ PlaceRect(bestNode);
+ rects.erase(rects.begin() + bestRectIndex);
+ }
+}
+
+void MaxRectsBinPack::PlaceRect(const Rect &node)
+{
+ size_t numRectanglesToProcess = freeRectangles.size();
+ for(size_t i = 0; i < numRectanglesToProcess; ++i)
+ {
+ if (SplitFreeNode(freeRectangles[i], node))
+ {
+ freeRectangles.erase(freeRectangles.begin() + i);
+ --i;
+ --numRectanglesToProcess;
+ }
+ }
+
+ PruneFreeList();
+
+ usedRectangles.push_back(node);
+ // dst.push_back(bestNode); ///\todo Refactor so that this compiles.
+}
+
+Rect MaxRectsBinPack::ScoreRect(int width, int height, FreeRectChoiceHeuristic method, int &score1, int &score2) const
+{
+ Rect newNode;
+ score1 = std::numeric_limits::max();
+ score2 = std::numeric_limits::max();
+ switch(method)
+ {
+ case RectBestShortSideFit: newNode = FindPositionForNewNodeBestShortSideFit(width, height, score1, score2); break;
+ case RectBottomLeftRule: newNode = FindPositionForNewNodeBottomLeft(width, height, score1, score2); break;
+ case RectContactPointRule: newNode = FindPositionForNewNodeContactPoint(width, height, score1);
+ score1 = -score1; // Reverse since we are minimizing, but for contact point score bigger is better.
+ break;
+ case RectBestLongSideFit: newNode = FindPositionForNewNodeBestLongSideFit(width, height, score2, score1); break;
+ case RectBestAreaFit: newNode = FindPositionForNewNodeBestAreaFit(width, height, score1, score2); break;
+ }
+
+ // Cannot fit the current rectangle.
+ if (newNode.height == 0)
+ {
+ score1 = std::numeric_limits::max();
+ score2 = std::numeric_limits::max();
+ }
+
+ return newNode;
+}
+
+/// Computes the ratio of used surface area.
+float MaxRectsBinPack::Occupancy() const
+{
+ unsigned long usedSurfaceArea = 0;
+ for(size_t i = 0; i < usedRectangles.size(); ++i)
+ usedSurfaceArea += usedRectangles[i].width * usedRectangles[i].height;
+
+ return (float)usedSurfaceArea / (binWidth * binHeight);
+}
+
+Rect MaxRectsBinPack::FindPositionForNewNodeBottomLeft(int width, int height, int &bestY, int &bestX) const
+{
+ Rect bestNode;
+ memset(&bestNode, 0, sizeof(Rect));
+
+ bestY = std::numeric_limits::max();
+
+ for(size_t i = 0; i < freeRectangles.size(); ++i)
+ {
+ // Try to place the rectangle in upright (non-flipped) orientation.
+ if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
+ {
+ int topSideY = freeRectangles[i].y + height;
+ if (topSideY < bestY || (topSideY == bestY && freeRectangles[i].x < bestX))
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = width;
+ bestNode.height = height;
+ bestY = topSideY;
+ bestX = freeRectangles[i].x;
+ }
+ }
+#if 0
+ if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
+ {
+ int topSideY = freeRectangles[i].y + width;
+ if (topSideY < bestY || (topSideY == bestY && freeRectangles[i].x < bestX))
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = height;
+ bestNode.height = width;
+ bestY = topSideY;
+ bestX = freeRectangles[i].x;
+ }
+ }
+#endif
+ }
+ return bestNode;
+}
+
+Rect MaxRectsBinPack::FindPositionForNewNodeBestShortSideFit(int width, int height,
+ int &bestShortSideFit, int &bestLongSideFit) const
+{
+ Rect bestNode;
+ memset(&bestNode, 0, sizeof(Rect));
+
+ bestShortSideFit = std::numeric_limits::max();
+
+ for(size_t i = 0; i < freeRectangles.size(); ++i)
+ {
+ // Try to place the rectangle in upright (non-flipped) orientation.
+ if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
+ {
+ int leftoverHoriz = abs(freeRectangles[i].width - width);
+ int leftoverVert = abs(freeRectangles[i].height - height);
+ int shortSideFit = min(leftoverHoriz, leftoverVert);
+ int longSideFit = max(leftoverHoriz, leftoverVert);
+
+ if (shortSideFit < bestShortSideFit || (shortSideFit == bestShortSideFit && longSideFit < bestLongSideFit))
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = width;
+ bestNode.height = height;
+ bestShortSideFit = shortSideFit;
+ bestLongSideFit = longSideFit;
+ }
+ }
+#if 0
+ if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
+ {
+ int flippedLeftoverHoriz = abs(freeRectangles[i].width - height);
+ int flippedLeftoverVert = abs(freeRectangles[i].height - width);
+ int flippedShortSideFit = min(flippedLeftoverHoriz, flippedLeftoverVert);
+ int flippedLongSideFit = max(flippedLeftoverHoriz, flippedLeftoverVert);
+
+ if (flippedShortSideFit < bestShortSideFit || (flippedShortSideFit == bestShortSideFit && flippedLongSideFit < bestLongSideFit))
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = height;
+ bestNode.height = width;
+ bestShortSideFit = flippedShortSideFit;
+ bestLongSideFit = flippedLongSideFit;
+ }
+ }
+#endif
+ }
+ return bestNode;
+}
+
+Rect MaxRectsBinPack::FindPositionForNewNodeBestLongSideFit(int width, int height,
+ int &bestShortSideFit, int &bestLongSideFit) const
+{
+ Rect bestNode;
+ memset(&bestNode, 0, sizeof(Rect));
+
+ bestLongSideFit = std::numeric_limits::max();
+
+ for(size_t i = 0; i < freeRectangles.size(); ++i)
+ {
+ // Try to place the rectangle in upright (non-flipped) orientation.
+ if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
+ {
+ int leftoverHoriz = abs(freeRectangles[i].width - width);
+ int leftoverVert = abs(freeRectangles[i].height - height);
+ int shortSideFit = min(leftoverHoriz, leftoverVert);
+ int longSideFit = max(leftoverHoriz, leftoverVert);
+
+ if (longSideFit < bestLongSideFit || (longSideFit == bestLongSideFit && shortSideFit < bestShortSideFit))
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = width;
+ bestNode.height = height;
+ bestShortSideFit = shortSideFit;
+ bestLongSideFit = longSideFit;
+ }
+ }
+#if 0
+ if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
+ {
+ int leftoverHoriz = abs(freeRectangles[i].width - height);
+ int leftoverVert = abs(freeRectangles[i].height - width);
+ int shortSideFit = min(leftoverHoriz, leftoverVert);
+ int longSideFit = max(leftoverHoriz, leftoverVert);
+
+ if (longSideFit < bestLongSideFit || (longSideFit == bestLongSideFit && shortSideFit < bestShortSideFit))
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = height;
+ bestNode.height = width;
+ bestShortSideFit = shortSideFit;
+ bestLongSideFit = longSideFit;
+ }
+ }
+#endif
+ }
+ return bestNode;
+}
+
+Rect MaxRectsBinPack::FindPositionForNewNodeBestAreaFit(int width, int height,
+ int &bestAreaFit, int &bestShortSideFit) const
+{
+ Rect bestNode;
+ memset(&bestNode, 0, sizeof(Rect));
+
+ bestAreaFit = std::numeric_limits::max();
+
+ for(size_t i = 0; i < freeRectangles.size(); ++i)
+ {
+ int areaFit = freeRectangles[i].width * freeRectangles[i].height - width * height;
+
+ // Try to place the rectangle in upright (non-flipped) orientation.
+ if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
+ {
+ int leftoverHoriz = abs(freeRectangles[i].width - width);
+ int leftoverVert = abs(freeRectangles[i].height - height);
+ int shortSideFit = min(leftoverHoriz, leftoverVert);
+
+ if (areaFit < bestAreaFit || (areaFit == bestAreaFit && shortSideFit < bestShortSideFit))
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = width;
+ bestNode.height = height;
+ bestShortSideFit = shortSideFit;
+ bestAreaFit = areaFit;
+ }
+ }
+#if 0
+ if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
+ {
+ int leftoverHoriz = abs(freeRectangles[i].width - height);
+ int leftoverVert = abs(freeRectangles[i].height - width);
+ int shortSideFit = min(leftoverHoriz, leftoverVert);
+
+ if (areaFit < bestAreaFit || (areaFit == bestAreaFit && shortSideFit < bestShortSideFit))
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = height;
+ bestNode.height = width;
+ bestShortSideFit = shortSideFit;
+ bestAreaFit = areaFit;
+ }
+ }
+#endif
+ }
+ return bestNode;
+}
+
+/// Returns 0 if the two intervals i1 and i2 are disjoint, or the length of their overlap otherwise.
+int CommonIntervalLength(int i1start, int i1end, int i2start, int i2end)
+{
+ if (i1end < i2start || i2end < i1start)
+ return 0;
+ return min(i1end, i2end) - max(i1start, i2start);
+}
+
+int MaxRectsBinPack::ContactPointScoreNode(int x, int y, int width, int height) const
+{
+ int score = 0;
+
+ if (x == 0 || x + width == binWidth)
+ score += height;
+ if (y == 0 || y + height == binHeight)
+ score += width;
+
+ for(size_t i = 0; i < usedRectangles.size(); ++i)
+ {
+ if (usedRectangles[i].x == x + width || usedRectangles[i].x + usedRectangles[i].width == x)
+ score += CommonIntervalLength(usedRectangles[i].y, usedRectangles[i].y + usedRectangles[i].height, y, y + height);
+ if (usedRectangles[i].y == y + height || usedRectangles[i].y + usedRectangles[i].height == y)
+ score += CommonIntervalLength(usedRectangles[i].x, usedRectangles[i].x + usedRectangles[i].width, x, x + width);
+ }
+ return score;
+}
+
+Rect MaxRectsBinPack::FindPositionForNewNodeContactPoint(int width, int height, int &bestContactScore) const
+{
+ Rect bestNode;
+ memset(&bestNode, 0, sizeof(Rect));
+
+ bestContactScore = -1;
+
+ for(size_t i = 0; i < freeRectangles.size(); ++i)
+ {
+ // Try to place the rectangle in upright (non-flipped) orientation.
+ if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
+ {
+ int score = ContactPointScoreNode(freeRectangles[i].x, freeRectangles[i].y, width, height);
+ if (score > bestContactScore)
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = width;
+ bestNode.height = height;
+ bestContactScore = score;
+ }
+ }
+#if 0
+ if (freeRectangles[i].width >= height && freeRectangles[i].height >= width)
+ {
+ int score = ContactPointScoreNode(freeRectangles[i].x, freeRectangles[i].y, width, height);
+ if (score > bestContactScore)
+ {
+ bestNode.x = freeRectangles[i].x;
+ bestNode.y = freeRectangles[i].y;
+ bestNode.width = height;
+ bestNode.height = width;
+ bestContactScore = score;
+ }
+ }
+#endif
+ }
+ return bestNode;
+}
+
+bool MaxRectsBinPack::SplitFreeNode(Rect freeNode, const Rect &usedNode)
+{
+ // Test with SAT if the rectangles even intersect.
+ if (usedNode.x >= freeNode.x + freeNode.width || usedNode.x + usedNode.width <= freeNode.x ||
+ usedNode.y >= freeNode.y + freeNode.height || usedNode.y + usedNode.height <= freeNode.y)
+ return false;
+
+ if (usedNode.x < freeNode.x + freeNode.width && usedNode.x + usedNode.width > freeNode.x)
+ {
+ // New node at the top side of the used node.
+ if (usedNode.y > freeNode.y && usedNode.y < freeNode.y + freeNode.height)
+ {
+ Rect newNode = freeNode;
+ newNode.height = usedNode.y - newNode.y;
+ freeRectangles.push_back(newNode);
+ }
+
+ // New node at the bottom side of the used node.
+ if (usedNode.y + usedNode.height < freeNode.y + freeNode.height)
+ {
+ Rect newNode = freeNode;
+ newNode.y = usedNode.y + usedNode.height;
+ newNode.height = freeNode.y + freeNode.height - (usedNode.y + usedNode.height);
+ freeRectangles.push_back(newNode);
+ }
+ }
+
+ if (usedNode.y < freeNode.y + freeNode.height && usedNode.y + usedNode.height > freeNode.y)
+ {
+ // New node at the left side of the used node.
+ if (usedNode.x > freeNode.x && usedNode.x < freeNode.x + freeNode.width)
+ {
+ Rect newNode = freeNode;
+ newNode.width = usedNode.x - newNode.x;
+ freeRectangles.push_back(newNode);
+ }
+
+ // New node at the right side of the used node.
+ if (usedNode.x + usedNode.width < freeNode.x + freeNode.width)
+ {
+ Rect newNode = freeNode;
+ newNode.x = usedNode.x + usedNode.width;
+ newNode.width = freeNode.x + freeNode.width - (usedNode.x + usedNode.width);
+ freeRectangles.push_back(newNode);
+ }
+ }
+
+ return true;
+}
+
+void MaxRectsBinPack::PruneFreeList()
+{
+ /*
+ /// Would be nice to do something like this, to avoid a Theta(n^2) loop through each pair.
+ /// But unfortunately it doesn't quite cut it, since we also want to detect containment.
+ /// Perhaps there's another way to do this faster than Theta(n^2).
+
+ if (freeRectangles.size() > 0)
+ clb::sort::QuickSort(&freeRectangles[0], freeRectangles.size(), NodeSortCmp);
+
+ for(size_t i = 0; i < freeRectangles.size()-1; ++i)
+ if (freeRectangles[i].x == freeRectangles[i+1].x &&
+ freeRectangles[i].y == freeRectangles[i+1].y &&
+ freeRectangles[i].width == freeRectangles[i+1].width &&
+ freeRectangles[i].height == freeRectangles[i+1].height)
+ {
+ freeRectangles.erase(freeRectangles.begin() + i);
+ --i;
+ }
+ */
+
+ /// Go through each pair and remove any rectangle that is redundant.
+ for(size_t i = 0; i < freeRectangles.size(); ++i)
+ for(size_t j = i+1; j < freeRectangles.size(); ++j)
+ {
+ if (IsContainedIn(freeRectangles[i], freeRectangles[j]))
+ {
+ freeRectangles.erase(freeRectangles.begin()+i);
+ --i;
+ break;
+ }
+ if (IsContainedIn(freeRectangles[j], freeRectangles[i]))
+ {
+ freeRectangles.erase(freeRectangles.begin()+j);
+ --j;
+ }
+ }
+}
diff --git a/2dsg/MaxRectsBinPack.h b/2dsg/MaxRectsBinPack.h
index ac0a07c9e..f4d6ac00c 100644
--- a/2dsg/MaxRectsBinPack.h
+++ b/2dsg/MaxRectsBinPack.h
@@ -1,81 +1,81 @@
-/** @file MaxRectsBinPack.h
- @author Jukka Jylänki
-
- @brief Implements different bin packer algorithms that use the MAXRECTS data structure.
-
- This work is released to Public Domain, do whatever you want with it.
-*/
-#pragma once
-
-#include
-
-#include "Rect.h"
-
-/** MaxRectsBinPack implements the MAXRECTS data structure and different bin packing algorithms that
- use this structure. */
-class MaxRectsBinPack
-{
-public:
- /// Instantiates a bin of size (0,0). Call Init to create a new bin.
- MaxRectsBinPack();
-
- /// Instantiates a bin of the given size.
- MaxRectsBinPack(int width, int height);
-
- /// (Re)initializes the packer to an empty bin of width x height units. Call whenever
- /// you need to restart with a new bin.
- void Init(int width, int height);
-
- /// Specifies the different heuristic rules that can be used when deciding where to place a new rectangle.
- enum FreeRectChoiceHeuristic
- {
- RectBestShortSideFit, ///< -BSSF: Positions the rectangle against the short side of a free rectangle into which it fits the best.
- RectBestLongSideFit, ///< -BLSF: Positions the rectangle against the long side of a free rectangle into which it fits the best.
- RectBestAreaFit, ///< -BAF: Positions the rectangle into the smallest free rect into which it fits.
- RectBottomLeftRule, ///< -BL: Does the Tetris placement.
- RectContactPointRule ///< -CP: Choosest the placement where the rectangle touches other rects as much as possible.
- };
-
- /// Inserts the given list of rectangles in an offline/batch mode, possibly rotated.
- /// @param rects The list of rectangles to insert. This vector will be destroyed in the process.
- /// @param dst [out] This list will contain the packed rectangles. The indices will not correspond to that of rects.
- /// @param method The rectangle placement rule to use when packing.
- void Insert(std::vector &rects, std::vector &dst, FreeRectChoiceHeuristic method);
-
- /// Inserts a single rectangle into the bin, possibly rotated.
- Rect Insert(int width, int height, FreeRectChoiceHeuristic method);
-
- /// Computes the ratio of used surface area to the total bin area.
- float Occupancy() const;
-
-private:
- int binWidth;
- int binHeight;
-
- std::vector usedRectangles;
- std::vector freeRectangles;
-
- /// Computes the placement score for placing the given rectangle with the given method.
- /// @param score1 [out] The primary placement score will be outputted here.
- /// @param score2 [out] The secondary placement score will be outputted here. This isu sed to break ties.
- /// @return This struct identifies where the rectangle would be placed if it were placed.
- Rect ScoreRect(int width, int height, FreeRectChoiceHeuristic method, int &score1, int &score2) const;
-
- /// Places the given rectangle into the bin.
- void PlaceRect(const Rect &node);
-
- /// Computes the placement score for the -CP variant.
- int ContactPointScoreNode(int x, int y, int width, int height) const;
-
- Rect FindPositionForNewNodeBottomLeft(int width, int height, int &bestY, int &bestX) const;
- Rect FindPositionForNewNodeBestShortSideFit(int width, int height, int &bestShortSideFit, int &bestLongSideFit) const;
- Rect FindPositionForNewNodeBestLongSideFit(int width, int height, int &bestShortSideFit, int &bestLongSideFit) const;
- Rect FindPositionForNewNodeBestAreaFit(int width, int height, int &bestAreaFit, int &bestShortSideFit) const;
- Rect FindPositionForNewNodeContactPoint(int width, int height, int &contactScore) const;
-
- /// @return True if the free node was split.
- bool SplitFreeNode(Rect freeNode, const Rect &usedNode);
-
- /// Goes through the free rectangle list and removes any redundant entries.
- void PruneFreeList();
-};
+/** @file MaxRectsBinPack.h
+ @author Jukka Jylänki
+
+ @brief Implements different bin packer algorithms that use the MAXRECTS data structure.
+
+ This work is released to Public Domain, do whatever you want with it.
+*/
+#pragma once
+
+#include
+
+#include "Rect.h"
+
+/** MaxRectsBinPack implements the MAXRECTS data structure and different bin packing algorithms that
+ use this structure. */
+class MaxRectsBinPack
+{
+public:
+ /// Instantiates a bin of size (0,0). Call Init to create a new bin.
+ MaxRectsBinPack();
+
+ /// Instantiates a bin of the given size.
+ MaxRectsBinPack(int width, int height);
+
+ /// (Re)initializes the packer to an empty bin of width x height units. Call whenever
+ /// you need to restart with a new bin.
+ void Init(int width, int height);
+
+ /// Specifies the different heuristic rules that can be used when deciding where to place a new rectangle.
+ enum FreeRectChoiceHeuristic
+ {
+ RectBestShortSideFit, ///< -BSSF: Positions the rectangle against the short side of a free rectangle into which it fits the best.
+ RectBestLongSideFit, ///< -BLSF: Positions the rectangle against the long side of a free rectangle into which it fits the best.
+ RectBestAreaFit, ///< -BAF: Positions the rectangle into the smallest free rect into which it fits.
+ RectBottomLeftRule, ///< -BL: Does the Tetris placement.
+ RectContactPointRule ///< -CP: Choosest the placement where the rectangle touches other rects as much as possible.
+ };
+
+ /// Inserts the given list of rectangles in an offline/batch mode, possibly rotated.
+ /// @param rects The list of rectangles to insert. This vector will be destroyed in the process.
+ /// @param dst [out] This list will contain the packed rectangles. The indices will not correspond to that of rects.
+ /// @param method The rectangle placement rule to use when packing.
+ void Insert(std::vector &rects, std::vector &dst, FreeRectChoiceHeuristic method);
+
+ /// Inserts a single rectangle into the bin, possibly rotated.
+ Rect Insert(int width, int height, FreeRectChoiceHeuristic method);
+
+ /// Computes the ratio of used surface area to the total bin area.
+ float Occupancy() const;
+
+private:
+ int binWidth;
+ int binHeight;
+
+ std::vector usedRectangles;
+ std::vector freeRectangles;
+
+ /// Computes the placement score for placing the given rectangle with the given method.
+ /// @param score1 [out] The primary placement score will be outputted here.
+ /// @param score2 [out] The secondary placement score will be outputted here. This isu sed to break ties.
+ /// @return This struct identifies where the rectangle would be placed if it were placed.
+ Rect ScoreRect(int width, int height, FreeRectChoiceHeuristic method, int &score1, int &score2) const;
+
+ /// Places the given rectangle into the bin.
+ void PlaceRect(const Rect &node);
+
+ /// Computes the placement score for the -CP variant.
+ int ContactPointScoreNode(int x, int y, int width, int height) const;
+
+ Rect FindPositionForNewNodeBottomLeft(int width, int height, int &bestY, int &bestX) const;
+ Rect FindPositionForNewNodeBestShortSideFit(int width, int height, int &bestShortSideFit, int &bestLongSideFit) const;
+ Rect FindPositionForNewNodeBestLongSideFit(int width, int height, int &bestShortSideFit, int &bestLongSideFit) const;
+ Rect FindPositionForNewNodeBestAreaFit(int width, int height, int &bestAreaFit, int &bestShortSideFit) const;
+ Rect FindPositionForNewNodeContactPoint(int width, int height, int &contactScore) const;
+
+ /// @return True if the free node was split.
+ bool SplitFreeNode(Rect freeNode, const Rect &usedNode);
+
+ /// Goes through the free rectangle list and removes any redundant entries.
+ void PruneFreeList();
+};
diff --git a/2dsg/Rect.h b/2dsg/Rect.h
index b5740a745..802f7f80b 100644
--- a/2dsg/Rect.h
+++ b/2dsg/Rect.h
@@ -1,88 +1,88 @@
-/** @file Rect.h
- @author Jukka Jylänki
-
- This work is released to Public Domain, do whatever you want with it.
-*/
-#ifndef __RECT_H_DEFINED__
-#define __RECT_H_DEFINED__
-
-#include
-#include
-
-struct RectSize
-{
- int width;
- int height;
-};
-
-struct Rect
-{
- int x;
- int y;
- int width;
- int height;
-};
-
-/// Performs a lexicographic compare on (rect short side, rect long side).
-/// @return -1 if the smaller side of a is shorter than the smaller side of b, 1 if the other way around.
-/// If they are equal, the larger side length is used as a tie-breaker.
-/// If the rectangles are of same size, returns 0.
-int CompareRectShortSide(const Rect &a, const Rect &b);
-
-/// Performs a lexicographic compare on (x, y, width, height).
-int NodeSortCmp(const Rect &a, const Rect &b);
-
-/// Returns true if a is contained in b.
-inline bool IsContainedIn(const Rect &a, const Rect &b)
-{
- return a.x >= b.x && a.y >= b.y
- && a.x+a.width <= b.x+b.width
- && a.y+a.height <= b.y+b.height;
-}
-
-class DisjointRectCollection
-{
-public:
- std::vector rects;
-
- bool Add(const Rect &r)
- {
- // Degenerate rectangles are ignored.
- if (r.width == 0 || r.height == 0)
- return true;
-
- if (!Disjoint(r))
- return false;
- rects.push_back(r);
- return true;
- }
-
- void Clear()
- {
- rects.clear();
- }
-
- bool Disjoint(const Rect &r) const
- {
- // Degenerate rectangles are ignored.
- if (r.width == 0 || r.height == 0)
- return true;
-
- for(size_t i = 0; i < rects.size(); ++i)
- if (!Disjoint(rects[i], r))
- return false;
- return true;
- }
-
- static bool Disjoint(const Rect &a, const Rect &b)
- {
- if (a.x + a.width <= b.x ||
- b.x + b.width <= a.x ||
- a.y + a.height <= b.y ||
- b.y + b.height <= a.y)
- return true;
- return false;
- }
-};
-
-#endif
+/** @file Rect.h
+ @author Jukka Jylänki
+
+ This work is released to Public Domain, do whatever you want with it.
+*/
+#ifndef __RECT_H_DEFINED__
+#define __RECT_H_DEFINED__
+
+#include
+#include
+
+struct RectSize
+{
+ int width;
+ int height;
+};
+
+struct Rect
+{
+ int x;
+ int y;
+ int width;
+ int height;
+};
+
+/// Performs a lexicographic compare on (rect short side, rect long side).
+/// @return -1 if the smaller side of a is shorter than the smaller side of b, 1 if the other way around.
+/// If they are equal, the larger side length is used as a tie-breaker.
+/// If the rectangles are of same size, returns 0.
+int CompareRectShortSide(const Rect &a, const Rect &b);
+
+/// Performs a lexicographic compare on (x, y, width, height).
+int NodeSortCmp(const Rect &a, const Rect &b);
+
+/// Returns true if a is contained in b.
+inline bool IsContainedIn(const Rect &a, const Rect &b)
+{
+ return a.x >= b.x && a.y >= b.y
+ && a.x+a.width <= b.x+b.width
+ && a.y+a.height <= b.y+b.height;
+}
+
+class DisjointRectCollection
+{
+public:
+ std::vector rects;
+
+ bool Add(const Rect &r)
+ {
+ // Degenerate rectangles are ignored.
+ if (r.width == 0 || r.height == 0)
+ return true;
+
+ if (!Disjoint(r))
+ return false;
+ rects.push_back(r);
+ return true;
+ }
+
+ void Clear()
+ {
+ rects.clear();
+ }
+
+ bool Disjoint(const Rect &r) const
+ {
+ // Degenerate rectangles are ignored.
+ if (r.width == 0 || r.height == 0)
+ return true;
+
+ for(size_t i = 0; i < rects.size(); ++i)
+ if (!Disjoint(rects[i], r))
+ return false;
+ return true;
+ }
+
+ static bool Disjoint(const Rect &a, const Rect &b)
+ {
+ if (a.x + a.width <= b.x ||
+ b.x + b.width <= a.x ||
+ a.y + a.height <= b.y ||
+ b.y + b.height <= a.y)
+ return true;
+ return false;
+ }
+};
+
+#endif
diff --git a/2dsg/Vectors.h b/2dsg/Vectors.h
index a1ef1927e..2e08103c4 100644
--- a/2dsg/Vectors.h
+++ b/2dsg/Vectors.h
@@ -1,530 +1,530 @@
-///////////////////////////////////////////////////////////////////////////////
-// Vectors.h
-// =========
-// 2D/3D/4D vectors
-//
-// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
-// CREATED: 2007-02-14
-// UPDATED: 2013-01-20
-//
-// Copyright (C) 2007-2013 Song Ho Ahn
-///////////////////////////////////////////////////////////////////////////////
-
-
-#ifndef VECTORS_H_DEF
-#define VECTORS_H_DEF
-
-#include
-#include
-
-///////////////////////////////////////////////////////////////////////////////
-// 2D vector
-///////////////////////////////////////////////////////////////////////////////
-struct Vector2
-{
- float x;
- float y;
-
- // ctors
- Vector2() : x(0), y(0) {};
- Vector2(float x, float y) : x(x), y(y) {};
-
- // utils functions
- void set(float x, float y);
- float length() const; //
- float distance(const Vector2& vec) const; // distance between two vectors
- Vector2& normalize(); //
- float dot(const Vector2& vec) const; // dot product
- bool equal(const Vector2& vec, float e) const; // compare with epsilon
-
- // operators
- Vector2 operator-() const; // unary operator (negate)
- Vector2 operator+(const Vector2& rhs) const; // add rhs
- Vector2 operator-(const Vector2& rhs) const; // subtract rhs
- Vector2& operator+=(const Vector2& rhs); // add rhs and update this object
- Vector2& operator-=(const Vector2& rhs); // subtract rhs and update this object
- Vector2 operator*(const float scale) const; // scale
- Vector2 operator*(const Vector2& rhs) const; // multiply each element
- Vector2& operator*=(const float scale); // scale and update this object
- Vector2& operator*=(const Vector2& rhs); // multiply each element and update this object
- Vector2 operator/(const float scale) const; // inverse scale
- Vector2& operator/=(const float scale); // scale and update this object
- bool operator==(const Vector2& rhs) const; // exact compare, no epsilon
- bool operator!=(const Vector2& rhs) const; // exact compare, no epsilon
- bool operator<(const Vector2& rhs) const; // comparison for sort
- float operator[](int index) const; // subscript operator v[0], v[1]
- float& operator[](int index); // subscript operator v[0], v[1]
-
- friend Vector2 operator*(const float a, const Vector2 vec);
- friend std::ostream& operator<<(std::ostream& os, const Vector2& vec);
-};
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// 3D vector
-///////////////////////////////////////////////////////////////////////////////
-struct Vector3
-{
- float x;
- float y;
- float z;
-
- // ctors
- Vector3() : x(0), y(0), z(0) {};
- Vector3(float x, float y, float z) : x(x), y(y), z(z) {};
-
- // utils functions
- void set(float x, float y, float z);
- float length() const; //
- float distance(const Vector3& vec) const; // distance between two vectors
- Vector3& normalize(); //
- float dot(const Vector3& vec) const; // dot product
- Vector3 cross(const Vector3& vec) const; // cross product
- bool equal(const Vector3& vec, float e) const; // compare with epsilon
-
- // operators
- Vector3 operator-() const; // unary operator (negate)
- Vector3 operator+(const Vector3& rhs) const; // add rhs
- Vector3 operator-(const Vector3& rhs) const; // subtract rhs
- Vector3& operator+=(const Vector3& rhs); // add rhs and update this object
- Vector3& operator-=(const Vector3& rhs); // subtract rhs and update this object
- Vector3 operator*(const float scale) const; // scale
- Vector3 operator*(const Vector3& rhs) const; // multiplay each element
- Vector3& operator*=(const float scale); // scale and update this object
- Vector3& operator*=(const Vector3& rhs); // product each element and update this object
- Vector3 operator/(const float scale) const; // inverse scale
- Vector3& operator/=(const float scale); // scale and update this object
- bool operator==(const Vector3& rhs) const; // exact compare, no epsilon
- bool operator!=(const Vector3& rhs) const; // exact compare, no epsilon
- bool operator<(const Vector3& rhs) const; // comparison for sort
- float operator[](int index) const; // subscript operator v[0], v[1]
- float& operator[](int index); // subscript operator v[0], v[1]
-
- friend Vector3 operator*(const float a, const Vector3 vec);
- friend std::ostream& operator<<(std::ostream& os, const Vector3& vec);
-};
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// 4D vector
-///////////////////////////////////////////////////////////////////////////////
-struct Vector4
-{
- float x;
- float y;
- float z;
- float w;
-
- // ctors
- Vector4() : x(0), y(0), z(0), w(0) {};
- Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {};
-
- // utils functions
- void set(float x, float y, float z, float w);
- float length() const; //
- float distance(const Vector4& vec) const; // distance between two vectors
- Vector4& normalize(); //
- float dot(const Vector4& vec) const; // dot product
- bool equal(const Vector4& vec, float e) const; // compare with epsilon
-
- // operators
- Vector4 operator-() const; // unary operator (negate)
- Vector4 operator+(const Vector4& rhs) const; // add rhs
- Vector4 operator-(const Vector4& rhs) const; // subtract rhs
- Vector4& operator+=(const Vector4& rhs); // add rhs and update this object
- Vector4& operator-=(const Vector4& rhs); // subtract rhs and update this object
- Vector4 operator*(const float scale) const; // scale
- Vector4 operator*(const Vector4& rhs) const; // multiply each element
- Vector4& operator*=(const float scale); // scale and update this object
- Vector4& operator*=(const Vector4& rhs); // multiply each element and update this object
- Vector4 operator/(const float scale) const; // inverse scale
- Vector4& operator/=(const float scale); // scale and update this object
- bool operator==(const Vector4& rhs) const; // exact compare, no epsilon
- bool operator!=(const Vector4& rhs) const; // exact compare, no epsilon
- bool operator<(const Vector4& rhs) const; // comparison for sort
- float operator[](int index) const; // subscript operator v[0], v[1]
- float& operator[](int index); // subscript operator v[0], v[1]
-
- friend Vector4 operator*(const float a, const Vector4 vec);
- friend std::ostream& operator<<(std::ostream& os, const Vector4& vec);
-};
-
-
-
-// fast math routines from Doom3 SDK
-inline float invSqrt(float x)
-{
- float xhalf = 0.5f * x;
- int i = *(int*)&x; // get bits for floating value
- i = 0x5f3759df - (i>>1); // gives initial guess
- x = *(float*)&i; // convert bits back to float
- x = x * (1.5f - xhalf*x*x); // Newton step
- return x;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// inline functions for Vector2
-///////////////////////////////////////////////////////////////////////////////
-inline Vector2 Vector2::operator-() const {
- return Vector2(-x, -y);
-}
-
-inline Vector2 Vector2::operator+(const Vector2& rhs) const {
- return Vector2(x+rhs.x, y+rhs.y);
-}
-
-inline Vector2 Vector2::operator-(const Vector2& rhs) const {
- return Vector2(x-rhs.x, y-rhs.y);
-}
-
-inline Vector2& Vector2::operator+=(const Vector2& rhs) {
- x += rhs.x; y += rhs.y; return *this;
-}
-
-inline Vector2& Vector2::operator-=(const Vector2& rhs) {
- x -= rhs.x; y -= rhs.y; return *this;
-}
-
-inline Vector2 Vector2::operator*(const float a) const {
- return Vector2(x*a, y*a);
-}
-
-inline Vector2 Vector2::operator*(const Vector2& rhs) const {
- return Vector2(x*rhs.x, y*rhs.y);
-}
-
-inline Vector2& Vector2::operator*=(const float a) {
- x *= a; y *= a; return *this;
-}
-
-inline Vector2& Vector2::operator*=(const Vector2& rhs) {
- x *= rhs.x; y *= rhs.y; return *this;
-}
-
-inline Vector2 Vector2::operator/(const float a) const {
- return Vector2(x/a, y/a);
-}
-
-inline Vector2& Vector2::operator/=(const float a) {
- x /= a; y /= a; return *this;
-}
-
-inline bool Vector2::operator==(const Vector2& rhs) const {
- return (x == rhs.x) && (y == rhs.y);
-}
-
-inline bool Vector2::operator!=(const Vector2& rhs) const {
- return (x != rhs.x) || (y != rhs.y);
-}
-
-inline bool Vector2::operator<(const Vector2& rhs) const {
- if(x < rhs.x) return true;
- if(x > rhs.x) return false;
- if(y < rhs.y) return true;
- if(y > rhs.y) return false;
- return false;
-}
-
-inline float Vector2::operator[](int index) const {
- return (&x)[index];
-}
-
-inline float& Vector2::operator[](int index) {
- return (&x)[index];
-}
-
-inline void Vector2::set(float x, float y) {
- this->x = x; this->y = y;
-}
-
-inline float Vector2::length() const {
- return sqrtf(x*x + y*y);
-}
-
-inline float Vector2::distance(const Vector2& vec) const {
- return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y));
-}
-
-inline Vector2& Vector2::normalize() {
- //@@const float EPSILON = 0.000001f;
- float xxyy = x*x + y*y;
- //@@if(xxyy < EPSILON)
- //@@ return *this;
-
- //float invLength = invSqrt(xxyy);
- float invLength = 1.0f / sqrtf(xxyy);
- x *= invLength;
- y *= invLength;
- return *this;
-}
-
-inline float Vector2::dot(const Vector2& rhs) const {
- return (x*rhs.x + y*rhs.y);
-}
-
-inline bool Vector2::equal(const Vector2& rhs, float epsilon) const {
- return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon;
-}
-
-inline Vector2 operator*(const float a, const Vector2 vec) {
- return Vector2(a*vec.x, a*vec.y);
-}
-
-inline std::ostream& operator<<(std::ostream& os, const Vector2& vec) {
- os << "(" << vec.x << ", " << vec.y << ")";
- return os;
-}
-// END OF VECTOR2 /////////////////////////////////////////////////////////////
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// inline functions for Vector3
-///////////////////////////////////////////////////////////////////////////////
-inline Vector3 Vector3::operator-() const {
- return Vector3(-x, -y, -z);
-}
-
-inline Vector3 Vector3::operator+(const Vector3& rhs) const {
- return Vector3(x+rhs.x, y+rhs.y, z+rhs.z);
-}
-
-inline Vector3 Vector3::operator-(const Vector3& rhs) const {
- return Vector3(x-rhs.x, y-rhs.y, z-rhs.z);
-}
-
-inline Vector3& Vector3::operator+=(const Vector3& rhs) {
- x += rhs.x; y += rhs.y; z += rhs.z; return *this;
-}
-
-inline Vector3& Vector3::operator-=(const Vector3& rhs) {
- x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this;
-}
-
-inline Vector3 Vector3::operator*(const float a) const {
- return Vector3(x*a, y*a, z*a);
-}
-
-inline Vector3 Vector3::operator*(const Vector3& rhs) const {
- return Vector3(x*rhs.x, y*rhs.y, z*rhs.z);
-}
-
-inline Vector3& Vector3::operator*=(const float a) {
- x *= a; y *= a; z *= a; return *this;
-}
-
-inline Vector3& Vector3::operator*=(const Vector3& rhs) {
- x *= rhs.x; y *= rhs.y; z *= rhs.z; return *this;
-}
-
-inline Vector3 Vector3::operator/(const float a) const {
- return Vector3(x/a, y/a, z/a);
-}
-
-inline Vector3& Vector3::operator/=(const float a) {
- x /= a; y /= a; z /= a; return *this;
-}
-
-inline bool Vector3::operator==(const Vector3& rhs) const {
- return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
-}
-
-inline bool Vector3::operator!=(const Vector3& rhs) const {
- return (x != rhs.x) || (y != rhs.y) || (z != rhs.z);
-}
-
-inline bool Vector3::operator<(const Vector3& rhs) const {
- if(x < rhs.x) return true;
- if(x > rhs.x) return false;
- if(y < rhs.y) return true;
- if(y > rhs.y) return false;
- if(z < rhs.z) return true;
- if(z > rhs.z) return false;
- return false;
-}
-
-inline float Vector3::operator[](int index) const {
- return (&x)[index];
-}
-
-inline float& Vector3::operator[](int index) {
- return (&x)[index];
-}
-
-inline void Vector3::set(float x, float y, float z) {
- this->x = x; this->y = y; this->z = z;
-}
-
-inline float Vector3::length() const {
- return sqrtf(x*x + y*y + z*z);
-}
-
-inline float Vector3::distance(const Vector3& vec) const {
- return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z));
-}
-
-inline Vector3& Vector3::normalize() {
- //@@const float EPSILON = 0.000001f;
- float xxyyzz = x*x + y*y + z*z;
- //@@if(xxyyzz < EPSILON)
- //@@ return *this; // do nothing if it is ~zero vector
-
- //float invLength = invSqrt(xxyyzz);
- float invLength = 1.0f / sqrtf(xxyyzz);
- x *= invLength;
- y *= invLength;
- z *= invLength;
- return *this;
-}
-
-inline float Vector3::dot(const Vector3& rhs) const {
- return (x*rhs.x + y*rhs.y + z*rhs.z);
-}
-
-inline Vector3 Vector3::cross(const Vector3& rhs) const {
- return Vector3(y*rhs.z - z*rhs.y, z*rhs.x - x*rhs.z, x*rhs.y - y*rhs.x);
-}
-
-inline bool Vector3::equal(const Vector3& rhs, float epsilon) const {
- return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon && fabs(z - rhs.z) < epsilon;
-}
-
-inline Vector3 operator*(const float a, const Vector3 vec) {
- return Vector3(a*vec.x, a*vec.y, a*vec.z);
-}
-
-inline std::ostream& operator<<(std::ostream& os, const Vector3& vec) {
- os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ")";
- return os;
-}
-// END OF VECTOR3 /////////////////////////////////////////////////////////////
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// inline functions for Vector4
-///////////////////////////////////////////////////////////////////////////////
-inline Vector4 Vector4::operator-() const {
- return Vector4(-x, -y, -z, -w);
-}
-
-inline Vector4 Vector4::operator+(const Vector4& rhs) const {
- return Vector4(x+rhs.x, y+rhs.y, z+rhs.z, w+rhs.w);
-}
-
-inline Vector4 Vector4::operator-(const Vector4& rhs) const {
- return Vector4(x-rhs.x, y-rhs.y, z-rhs.z, w-rhs.w);
-}
-
-inline Vector4& Vector4::operator+=(const Vector4& rhs) {
- x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; return *this;
-}
-
-inline Vector4& Vector4::operator-=(const Vector4& rhs) {
- x -= rhs.x; y -= rhs.y; z -= rhs.z; w -= rhs.w; return *this;
-}
-
-inline Vector4 Vector4::operator*(const float a) const {
- return Vector4(x*a, y*a, z*a, w*a);
-}
-
-inline Vector4 Vector4::operator*(const Vector4& rhs) const {
- return Vector4(x*rhs.x, y*rhs.y, z*rhs.z, w*rhs.w);
-}
-
-inline Vector4& Vector4::operator*=(const float a) {
- x *= a; y *= a; z *= a; w *= a; return *this;
-}
-
-inline Vector4& Vector4::operator*=(const Vector4& rhs) {
- x *= rhs.x; y *= rhs.y; z *= rhs.z; w *= rhs.w; return *this;
-}
-
-inline Vector4 Vector4::operator/(const float a) const {
- return Vector4(x/a, y/a, z/a, w/a);
-}
-
-inline Vector4& Vector4::operator/=(const float a) {
- x /= a; y /= a; z /= a; w /= a; return *this;
-}
-
-inline bool Vector4::operator==(const Vector4& rhs) const {
- return (x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w);
-}
-
-inline bool Vector4::operator!=(const Vector4& rhs) const {
- return (x != rhs.x) || (y != rhs.y) || (z != rhs.z) || (w != rhs.w);
-}
-
-inline bool Vector4::operator<(const Vector4& rhs) const {
- if(x < rhs.x) return true;
- if(x > rhs.x) return false;
- if(y < rhs.y) return true;
- if(y > rhs.y) return false;
- if(z < rhs.z) return true;
- if(z > rhs.z) return false;
- if(w < rhs.w) return true;
- if(w > rhs.w) return false;
- return false;
-}
-
-inline float Vector4::operator[](int index) const {
- return (&x)[index];
-}
-
-inline float& Vector4::operator[](int index) {
- return (&x)[index];
-}
-
-inline void Vector4::set(float x, float y, float z, float w) {
- this->x = x; this->y = y; this->z = z; this->w = w;
-}
-
-inline float Vector4::length() const {
- return sqrtf(x*x + y*y + z*z + w*w);
-}
-
-inline float Vector4::distance(const Vector4& vec) const {
- return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z) + (vec.w-w)*(vec.w-w));
-}
-
-inline Vector4& Vector4::normalize() {
- //NOTE: leave w-component untouched
- //@@const float EPSILON = 0.000001f;
- float xxyyzz = x*x + y*y + z*z;
- //@@if(xxyyzz < EPSILON)
- //@@ return *this; // do nothing if it is zero vector
-
- //float invLength = invSqrt(xxyyzz);
- float invLength = 1.0f / sqrtf(xxyyzz);
- x *= invLength;
- y *= invLength;
- z *= invLength;
- return *this;
-}
-
-inline float Vector4::dot(const Vector4& rhs) const {
- return (x*rhs.x + y*rhs.y + z*rhs.z + w*rhs.w);
-}
-
-inline bool Vector4::equal(const Vector4& rhs, float epsilon) const {
- return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon &&
- fabs(z - rhs.z) < epsilon && fabs(w - rhs.w) < epsilon;
-}
-
-inline Vector4 operator*(const float a, const Vector4 vec) {
- return Vector4(a*vec.x, a*vec.y, a*vec.z, a*vec.w);
-}
-
-inline std::ostream& operator<<(std::ostream& os, const Vector4& vec) {
- os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w << ")";
- return os;
-}
-// END OF VECTOR4 /////////////////////////////////////////////////////////////
-
-#endif
+///////////////////////////////////////////////////////////////////////////////
+// Vectors.h
+// =========
+// 2D/3D/4D vectors
+//
+// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
+// CREATED: 2007-02-14
+// UPDATED: 2013-01-20
+//
+// Copyright (C) 2007-2013 Song Ho Ahn
+///////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef VECTORS_H_DEF
+#define VECTORS_H_DEF
+
+#include
+#include
+
+///////////////////////////////////////////////////////////////////////////////
+// 2D vector
+///////////////////////////////////////////////////////////////////////////////
+struct Vector2
+{
+ float x;
+ float y;
+
+ // ctors
+ Vector2() : x(0), y(0) {};
+ Vector2(float x, float y) : x(x), y(y) {};
+
+ // utils functions
+ void set(float x, float y);
+ float length() const; //
+ float distance(const Vector2& vec) const; // distance between two vectors
+ Vector2& normalize(); //
+ float dot(const Vector2& vec) const; // dot product
+ bool equal(const Vector2& vec, float e) const; // compare with epsilon
+
+ // operators
+ Vector2 operator-() const; // unary operator (negate)
+ Vector2 operator+(const Vector2& rhs) const; // add rhs
+ Vector2 operator-(const Vector2& rhs) const; // subtract rhs
+ Vector2& operator+=(const Vector2& rhs); // add rhs and update this object
+ Vector2& operator-=(const Vector2& rhs); // subtract rhs and update this object
+ Vector2 operator*(const float scale) const; // scale
+ Vector2 operator*(const Vector2& rhs) const; // multiply each element
+ Vector2& operator*=(const float scale); // scale and update this object
+ Vector2& operator*=(const Vector2& rhs); // multiply each element and update this object
+ Vector2 operator/(const float scale) const; // inverse scale
+ Vector2& operator/=(const float scale); // scale and update this object
+ bool operator==(const Vector2& rhs) const; // exact compare, no epsilon
+ bool operator!=(const Vector2& rhs) const; // exact compare, no epsilon
+ bool operator<(const Vector2& rhs) const; // comparison for sort
+ float operator[](int index) const; // subscript operator v[0], v[1]
+ float& operator[](int index); // subscript operator v[0], v[1]
+
+ friend Vector2 operator*(const float a, const Vector2 vec);
+ friend std::ostream& operator<<(std::ostream& os, const Vector2& vec);
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// 3D vector
+///////////////////////////////////////////////////////////////////////////////
+struct Vector3
+{
+ float x;
+ float y;
+ float z;
+
+ // ctors
+ Vector3() : x(0), y(0), z(0) {};
+ Vector3(float x, float y, float z) : x(x), y(y), z(z) {};
+
+ // utils functions
+ void set(float x, float y, float z);
+ float length() const; //
+ float distance(const Vector3& vec) const; // distance between two vectors
+ Vector3& normalize(); //
+ float dot(const Vector3& vec) const; // dot product
+ Vector3 cross(const Vector3& vec) const; // cross product
+ bool equal(const Vector3& vec, float e) const; // compare with epsilon
+
+ // operators
+ Vector3 operator-() const; // unary operator (negate)
+ Vector3 operator+(const Vector3& rhs) const; // add rhs
+ Vector3 operator-(const Vector3& rhs) const; // subtract rhs
+ Vector3& operator+=(const Vector3& rhs); // add rhs and update this object
+ Vector3& operator-=(const Vector3& rhs); // subtract rhs and update this object
+ Vector3 operator*(const float scale) const; // scale
+ Vector3 operator*(const Vector3& rhs) const; // multiplay each element
+ Vector3& operator*=(const float scale); // scale and update this object
+ Vector3& operator*=(const Vector3& rhs); // product each element and update this object
+ Vector3 operator/(const float scale) const; // inverse scale
+ Vector3& operator/=(const float scale); // scale and update this object
+ bool operator==(const Vector3& rhs) const; // exact compare, no epsilon
+ bool operator!=(const Vector3& rhs) const; // exact compare, no epsilon
+ bool operator<(const Vector3& rhs) const; // comparison for sort
+ float operator[](int index) const; // subscript operator v[0], v[1]
+ float& operator[](int index); // subscript operator v[0], v[1]
+
+ friend Vector3 operator*(const float a, const Vector3 vec);
+ friend std::ostream& operator<<(std::ostream& os, const Vector3& vec);
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// 4D vector
+///////////////////////////////////////////////////////////////////////////////
+struct Vector4
+{
+ float x;
+ float y;
+ float z;
+ float w;
+
+ // ctors
+ Vector4() : x(0), y(0), z(0), w(0) {};
+ Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {};
+
+ // utils functions
+ void set(float x, float y, float z, float w);
+ float length() const; //
+ float distance(const Vector4& vec) const; // distance between two vectors
+ Vector4& normalize(); //
+ float dot(const Vector4& vec) const; // dot product
+ bool equal(const Vector4& vec, float e) const; // compare with epsilon
+
+ // operators
+ Vector4 operator-() const; // unary operator (negate)
+ Vector4 operator+(const Vector4& rhs) const; // add rhs
+ Vector4 operator-(const Vector4& rhs) const; // subtract rhs
+ Vector4& operator+=(const Vector4& rhs); // add rhs and update this object
+ Vector4& operator-=(const Vector4& rhs); // subtract rhs and update this object
+ Vector4 operator*(const float scale) const; // scale
+ Vector4 operator*(const Vector4& rhs) const; // multiply each element
+ Vector4& operator*=(const float scale); // scale and update this object
+ Vector4& operator*=(const Vector4& rhs); // multiply each element and update this object
+ Vector4 operator/(const float scale) const; // inverse scale
+ Vector4& operator/=(const float scale); // scale and update this object
+ bool operator==(const Vector4& rhs) const; // exact compare, no epsilon
+ bool operator!=(const Vector4& rhs) const; // exact compare, no epsilon
+ bool operator<(const Vector4& rhs) const; // comparison for sort
+ float operator[](int index) const; // subscript operator v[0], v[1]
+ float& operator[](int index); // subscript operator v[0], v[1]
+
+ friend Vector4 operator*(const float a, const Vector4 vec);
+ friend std::ostream& operator<<(std::ostream& os, const Vector4& vec);
+};
+
+
+
+// fast math routines from Doom3 SDK
+inline float invSqrt(float x)
+{
+ float xhalf = 0.5f * x;
+ int i = *(int*)&x; // get bits for floating value
+ i = 0x5f3759df - (i>>1); // gives initial guess
+ x = *(float*)&i; // convert bits back to float
+ x = x * (1.5f - xhalf*x*x); // Newton step
+ return x;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// inline functions for Vector2
+///////////////////////////////////////////////////////////////////////////////
+inline Vector2 Vector2::operator-() const {
+ return Vector2(-x, -y);
+}
+
+inline Vector2 Vector2::operator+(const Vector2& rhs) const {
+ return Vector2(x+rhs.x, y+rhs.y);
+}
+
+inline Vector2 Vector2::operator-(const Vector2& rhs) const {
+ return Vector2(x-rhs.x, y-rhs.y);
+}
+
+inline Vector2& Vector2::operator+=(const Vector2& rhs) {
+ x += rhs.x; y += rhs.y; return *this;
+}
+
+inline Vector2& Vector2::operator-=(const Vector2& rhs) {
+ x -= rhs.x; y -= rhs.y; return *this;
+}
+
+inline Vector2 Vector2::operator*(const float a) const {
+ return Vector2(x*a, y*a);
+}
+
+inline Vector2 Vector2::operator*(const Vector2& rhs) const {
+ return Vector2(x*rhs.x, y*rhs.y);
+}
+
+inline Vector2& Vector2::operator*=(const float a) {
+ x *= a; y *= a; return *this;
+}
+
+inline Vector2& Vector2::operator*=(const Vector2& rhs) {
+ x *= rhs.x; y *= rhs.y; return *this;
+}
+
+inline Vector2 Vector2::operator/(const float a) const {
+ return Vector2(x/a, y/a);
+}
+
+inline Vector2& Vector2::operator/=(const float a) {
+ x /= a; y /= a; return *this;
+}
+
+inline bool Vector2::operator==(const Vector2& rhs) const {
+ return (x == rhs.x) && (y == rhs.y);
+}
+
+inline bool Vector2::operator!=(const Vector2& rhs) const {
+ return (x != rhs.x) || (y != rhs.y);
+}
+
+inline bool Vector2::operator<(const Vector2& rhs) const {
+ if(x < rhs.x) return true;
+ if(x > rhs.x) return false;
+ if(y < rhs.y) return true;
+ if(y > rhs.y) return false;
+ return false;
+}
+
+inline float Vector2::operator[](int index) const {
+ return (&x)[index];
+}
+
+inline float& Vector2::operator[](int index) {
+ return (&x)[index];
+}
+
+inline void Vector2::set(float x, float y) {
+ this->x = x; this->y = y;
+}
+
+inline float Vector2::length() const {
+ return sqrtf(x*x + y*y);
+}
+
+inline float Vector2::distance(const Vector2& vec) const {
+ return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y));
+}
+
+inline Vector2& Vector2::normalize() {
+ //@@const float EPSILON = 0.000001f;
+ float xxyy = x*x + y*y;
+ //@@if(xxyy < EPSILON)
+ //@@ return *this;
+
+ //float invLength = invSqrt(xxyy);
+ float invLength = 1.0f / sqrtf(xxyy);
+ x *= invLength;
+ y *= invLength;
+ return *this;
+}
+
+inline float Vector2::dot(const Vector2& rhs) const {
+ return (x*rhs.x + y*rhs.y);
+}
+
+inline bool Vector2::equal(const Vector2& rhs, float epsilon) const {
+ return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon;
+}
+
+inline Vector2 operator*(const float a, const Vector2 vec) {
+ return Vector2(a*vec.x, a*vec.y);
+}
+
+inline std::ostream& operator<<(std::ostream& os, const Vector2& vec) {
+ os << "(" << vec.x << ", " << vec.y << ")";
+ return os;
+}
+// END OF VECTOR2 /////////////////////////////////////////////////////////////
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// inline functions for Vector3
+///////////////////////////////////////////////////////////////////////////////
+inline Vector3 Vector3::operator-() const {
+ return Vector3(-x, -y, -z);
+}
+
+inline Vector3 Vector3::operator+(const Vector3& rhs) const {
+ return Vector3(x+rhs.x, y+rhs.y, z+rhs.z);
+}
+
+inline Vector3 Vector3::operator-(const Vector3& rhs) const {
+ return Vector3(x-rhs.x, y-rhs.y, z-rhs.z);
+}
+
+inline Vector3& Vector3::operator+=(const Vector3& rhs) {
+ x += rhs.x; y += rhs.y; z += rhs.z; return *this;
+}
+
+inline Vector3& Vector3::operator-=(const Vector3& rhs) {
+ x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this;
+}
+
+inline Vector3 Vector3::operator*(const float a) const {
+ return Vector3(x*a, y*a, z*a);
+}
+
+inline Vector3 Vector3::operator*(const Vector3& rhs) const {
+ return Vector3(x*rhs.x, y*rhs.y, z*rhs.z);
+}
+
+inline Vector3& Vector3::operator*=(const float a) {
+ x *= a; y *= a; z *= a; return *this;
+}
+
+inline Vector3& Vector3::operator*=(const Vector3& rhs) {
+ x *= rhs.x; y *= rhs.y; z *= rhs.z; return *this;
+}
+
+inline Vector3 Vector3::operator/(const float a) const {
+ return Vector3(x/a, y/a, z/a);
+}
+
+inline Vector3& Vector3::operator/=(const float a) {
+ x /= a; y /= a; z /= a; return *this;
+}
+
+inline bool Vector3::operator==(const Vector3& rhs) const {
+ return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
+}
+
+inline bool Vector3::operator!=(const Vector3& rhs) const {
+ return (x != rhs.x) || (y != rhs.y) || (z != rhs.z);
+}
+
+inline bool Vector3::operator<(const Vector3& rhs) const {
+ if(x < rhs.x) return true;
+ if(x > rhs.x) return false;
+ if(y < rhs.y) return true;
+ if(y > rhs.y) return false;
+ if(z < rhs.z) return true;
+ if(z > rhs.z) return false;
+ return false;
+}
+
+inline float Vector3::operator[](int index) const {
+ return (&x)[index];
+}
+
+inline float& Vector3::operator[](int index) {
+ return (&x)[index];
+}
+
+inline void Vector3::set(float x, float y, float z) {
+ this->x = x; this->y = y; this->z = z;
+}
+
+inline float Vector3::length() const {
+ return sqrtf(x*x + y*y + z*z);
+}
+
+inline float Vector3::distance(const Vector3& vec) const {
+ return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z));
+}
+
+inline Vector3& Vector3::normalize() {
+ //@@const float EPSILON = 0.000001f;
+ float xxyyzz = x*x + y*y + z*z;
+ //@@if(xxyyzz < EPSILON)
+ //@@ return *this; // do nothing if it is ~zero vector
+
+ //float invLength = invSqrt(xxyyzz);
+ float invLength = 1.0f / sqrtf(xxyyzz);
+ x *= invLength;
+ y *= invLength;
+ z *= invLength;
+ return *this;
+}
+
+inline float Vector3::dot(const Vector3& rhs) const {
+ return (x*rhs.x + y*rhs.y + z*rhs.z);
+}
+
+inline Vector3 Vector3::cross(const Vector3& rhs) const {
+ return Vector3(y*rhs.z - z*rhs.y, z*rhs.x - x*rhs.z, x*rhs.y - y*rhs.x);
+}
+
+inline bool Vector3::equal(const Vector3& rhs, float epsilon) const {
+ return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon && fabs(z - rhs.z) < epsilon;
+}
+
+inline Vector3 operator*(const float a, const Vector3 vec) {
+ return Vector3(a*vec.x, a*vec.y, a*vec.z);
+}
+
+inline std::ostream& operator<<(std::ostream& os, const Vector3& vec) {
+ os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ")";
+ return os;
+}
+// END OF VECTOR3 /////////////////////////////////////////////////////////////
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// inline functions for Vector4
+///////////////////////////////////////////////////////////////////////////////
+inline Vector4 Vector4::operator-() const {
+ return Vector4(-x, -y, -z, -w);
+}
+
+inline Vector4 Vector4::operator+(const Vector4& rhs) const {
+ return Vector4(x+rhs.x, y+rhs.y, z+rhs.z, w+rhs.w);
+}
+
+inline Vector4 Vector4::operator-(const Vector4& rhs) const {
+ return Vector4(x-rhs.x, y-rhs.y, z-rhs.z, w-rhs.w);
+}
+
+inline Vector4& Vector4::operator+=(const Vector4& rhs) {
+ x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; return *this;
+}
+
+inline Vector4& Vector4::operator-=(const Vector4& rhs) {
+ x -= rhs.x; y -= rhs.y; z -= rhs.z; w -= rhs.w; return *this;
+}
+
+inline Vector4 Vector4::operator*(const float a) const {
+ return Vector4(x*a, y*a, z*a, w*a);
+}
+
+inline Vector4 Vector4::operator*(const Vector4& rhs) const {
+ return Vector4(x*rhs.x, y*rhs.y, z*rhs.z, w*rhs.w);
+}
+
+inline Vector4& Vector4::operator*=(const float a) {
+ x *= a; y *= a; z *= a; w *= a; return *this;
+}
+
+inline Vector4& Vector4::operator*=(const Vector4& rhs) {
+ x *= rhs.x; y *= rhs.y; z *= rhs.z; w *= rhs.w; return *this;
+}
+
+inline Vector4 Vector4::operator/(const float a) const {
+ return Vector4(x/a, y/a, z/a, w/a);
+}
+
+inline Vector4& Vector4::operator/=(const float a) {
+ x /= a; y /= a; z /= a; w /= a; return *this;
+}
+
+inline bool Vector4::operator==(const Vector4& rhs) const {
+ return (x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w);
+}
+
+inline bool Vector4::operator!=(const Vector4& rhs) const {
+ return (x != rhs.x) || (y != rhs.y) || (z != rhs.z) || (w != rhs.w);
+}
+
+inline bool Vector4::operator<(const Vector4& rhs) const {
+ if(x < rhs.x) return true;
+ if(x > rhs.x) return false;
+ if(y < rhs.y) return true;
+ if(y > rhs.y) return false;
+ if(z < rhs.z) return true;
+ if(z > rhs.z) return false;
+ if(w < rhs.w) return true;
+ if(w > rhs.w) return false;
+ return false;
+}
+
+inline float Vector4::operator[](int index) const {
+ return (&x)[index];
+}
+
+inline float& Vector4::operator[](int index) {
+ return (&x)[index];
+}
+
+inline void Vector4::set(float x, float y, float z, float w) {
+ this->x = x; this->y = y; this->z = z; this->w = w;
+}
+
+inline float Vector4::length() const {
+ return sqrtf(x*x + y*y + z*z + w*w);
+}
+
+inline float Vector4::distance(const Vector4& vec) const {
+ return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z) + (vec.w-w)*(vec.w-w));
+}
+
+inline Vector4& Vector4::normalize() {
+ //NOTE: leave w-component untouched
+ //@@const float EPSILON = 0.000001f;
+ float xxyyzz = x*x + y*y + z*z;
+ //@@if(xxyyzz < EPSILON)
+ //@@ return *this; // do nothing if it is zero vector
+
+ //float invLength = invSqrt(xxyyzz);
+ float invLength = 1.0f / sqrtf(xxyyzz);
+ x *= invLength;
+ y *= invLength;
+ z *= invLength;
+ return *this;
+}
+
+inline float Vector4::dot(const Vector4& rhs) const {
+ return (x*rhs.x + y*rhs.y + z*rhs.z + w*rhs.w);
+}
+
+inline bool Vector4::equal(const Vector4& rhs, float epsilon) const {
+ return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon &&
+ fabs(z - rhs.z) < epsilon && fabs(w - rhs.w) < epsilon;
+}
+
+inline Vector4 operator*(const float a, const Vector4 vec) {
+ return Vector4(a*vec.x, a*vec.y, a*vec.z, a*vec.w);
+}
+
+inline std::ostream& operator<<(std::ostream& os, const Vector4& vec) {
+ os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w << ")";
+ return os;
+}
+// END OF VECTOR4 /////////////////////////////////////////////////////////////
+
+#endif
diff --git a/2dsg/bitmapdata.cpp b/2dsg/bitmapdata.cpp
index fc87c9d24..b1ded96d0 100644
--- a/2dsg/bitmapdata.cpp
+++ b/2dsg/bitmapdata.cpp
@@ -1,97 +1,97 @@
-#include "bitmapdata.h"
-#include
-
-BitmapData::BitmapData(TextureBase* texture)
-{
- //printf("TextureRegion()\n");
- texture_ = texture;
- texture_->ref();
-
- x = 0;
- y = 0;
- width = texture->data->baseWidth;
- height = texture->data->baseHeight;
- dx1 = 0;
- dy1 = 0;
- dx2 = 0;
- dy2 = 0;
-
- initUV();
-}
-
-BitmapData::BitmapData(TextureBase* texture, int x, int y, int width, int height, int dx1/* = 0*/, int dy1/* = 0*/, int dx2/* = 0*/, int dy2/* = 0*/) :
- x(x), y(y),
- width(width), height(height),
- dx1(dx1), dy1(dy1),
- dx2(dx2), dy2(dy2)
-{
- //printf("TextureRegion()\n");
- texture_ = texture;
- texture_->ref();
-
- initUV();
-}
-
-BitmapData::~BitmapData()
-{
- //printf("~TextureRegion()\n");
- texture_->unref();
-}
-
-void BitmapData::initUV()
-{
- u0 = (float)x / (float)texture_->data->exwidth;
- v0 = (float)y / (float)texture_->data->exheight;
- u1 = (float)(x + width) / (float)texture_->data->exwidth;
- v1 = (float)(y + height) / (float)texture_->data->exheight;
-
- // uv scale
- {
- float scalex = texture_->uvscalex;
- float scaley = texture_->uvscaley;
-
- u0 *= scalex;
- v0 *= scaley;
- u1 *= scalex;
- v1 *= scaley;
- }
-}
-
-BitmapData* BitmapData::clone()
-{
- return new BitmapData(texture_, x, y, width, height, dx1, dy1, dx2, dy2);
-}
-
-void BitmapData::setRegion(int x, int y, int width, int height, int dx1, int dy1, int dx2, int dy2)
-{
- this->x = x;
- this->y = y;
- this->width = width;
- this->height = height;
- this->dx1 = dx1;
- this->dy1 = dy1;
- this->dx2 = dx2;
- this->dy2 = dy2;
-
- initUV();
-}
-
-void BitmapData::getRegion(int *x, int *y, int *width, int *height, int *dx1, int *dy1, int *dx2, int *dy2)
-{
- if (x)
- *x = this->x;
- if (y)
- *y = this->y;
- if (width)
- *width = this->width;
- if (height)
- *height = this->height;
- if (dx1)
- *dx1 = this->dx1;
- if (dy1)
- *dy1 = this->dy1;
- if (dx2)
- *dx2 = this->dx2;
- if (dy2)
- *dy2 = this->dy2;
-}
+#include "bitmapdata.h"
+#include
+
+BitmapData::BitmapData(TextureBase* texture)
+{
+ //printf("TextureRegion()\n");
+ texture_ = texture;
+ texture_->ref();
+
+ x = 0;
+ y = 0;
+ width = texture->data->baseWidth;
+ height = texture->data->baseHeight;
+ dx1 = 0;
+ dy1 = 0;
+ dx2 = 0;
+ dy2 = 0;
+
+ initUV();
+}
+
+BitmapData::BitmapData(TextureBase* texture, int x, int y, int width, int height, int dx1/* = 0*/, int dy1/* = 0*/, int dx2/* = 0*/, int dy2/* = 0*/) :
+ x(x), y(y),
+ width(width), height(height),
+ dx1(dx1), dy1(dy1),
+ dx2(dx2), dy2(dy2)
+{
+ //printf("TextureRegion()\n");
+ texture_ = texture;
+ texture_->ref();
+
+ initUV();
+}
+
+BitmapData::~BitmapData()
+{
+ //printf("~TextureRegion()\n");
+ texture_->unref();
+}
+
+void BitmapData::initUV()
+{
+ u0 = (float)x / (float)texture_->data->exwidth;
+ v0 = (float)y / (float)texture_->data->exheight;
+ u1 = (float)(x + width) / (float)texture_->data->exwidth;
+ v1 = (float)(y + height) / (float)texture_->data->exheight;
+
+ // uv scale
+ {
+ float scalex = texture_->uvscalex;
+ float scaley = texture_->uvscaley;
+
+ u0 *= scalex;
+ v0 *= scaley;
+ u1 *= scalex;
+ v1 *= scaley;
+ }
+}
+
+BitmapData* BitmapData::clone()
+{
+ return new BitmapData(texture_, x, y, width, height, dx1, dy1, dx2, dy2);
+}
+
+void BitmapData::setRegion(int x, int y, int width, int height, int dx1, int dy1, int dx2, int dy2)
+{
+ this->x = x;
+ this->y = y;
+ this->width = width;
+ this->height = height;
+ this->dx1 = dx1;
+ this->dy1 = dy1;
+ this->dx2 = dx2;
+ this->dy2 = dy2;
+
+ initUV();
+}
+
+void BitmapData::getRegion(int *x, int *y, int *width, int *height, int *dx1, int *dy1, int *dx2, int *dy2)
+{
+ if (x)
+ *x = this->x;
+ if (y)
+ *y = this->y;
+ if (width)
+ *width = this->width;
+ if (height)
+ *height = this->height;
+ if (dx1)
+ *dx1 = this->dx1;
+ if (dy1)
+ *dy1 = this->dy1;
+ if (dx2)
+ *dx2 = this->dx2;
+ if (dy2)
+ *dy2 = this->dy2;
+}
diff --git a/2dsg/bitmapdata.h b/2dsg/bitmapdata.h
index 113d02373..c05b8d05b 100644
--- a/2dsg/bitmapdata.h
+++ b/2dsg/bitmapdata.h
@@ -1,44 +1,44 @@
-#ifndef BITMAPDATA_H
-#define BITMAPDATA_H
-
-#include "refptr.h"
-#include "texturebase.h"
-
-class BitmapData : public GReferenced
-{
-public:
- BitmapData(TextureBase* texture);
- BitmapData(TextureBase* texture, int x, int y, int width, int height, int dx1 = 0, int dy1 = 0, int dx2 = 0, int dy2 = 0);
-
- virtual ~BitmapData();
-
- TextureBase* texture() const
- {
- return texture_;
- }
-
- BitmapData* clone();
-
- void setRegion(int x, int y, int width, int height, int dx1, int dy1, int dx2, int dy2);
- void getRegion(int *x, int *y, int *width, int *height, int *dx1, int *dy1, int *dx2, int *dy2);
-
-private:
- friend class Bitmap;
- friend class TexturePack;
-
- TextureBase* texture_;
- int x, y;
- int width, height;
- int dx1, dy1;
- int dx2, dy2;
- float u0, v0, u1, v1;
-
-private:
- void initUV();
-};
-
-
-typedef BitmapData TextureRegion;
-
-
-#endif
+#ifndef BITMAPDATA_H
+#define BITMAPDATA_H
+
+#include "refptr.h"
+#include "texturebase.h"
+
+class BitmapData : public GReferenced
+{
+public:
+ BitmapData(TextureBase* texture);
+ BitmapData(TextureBase* texture, int x, int y, int width, int height, int dx1 = 0, int dy1 = 0, int dx2 = 0, int dy2 = 0);
+
+ virtual ~BitmapData();
+
+ TextureBase* texture() const
+ {
+ return texture_;
+ }
+
+ BitmapData* clone();
+
+ void setRegion(int x, int y, int width, int height, int dx1, int dy1, int dx2, int dy2);
+ void getRegion(int *x, int *y, int *width, int *height, int *dx1, int *dy1, int *dx2, int *dy2);
+
+private:
+ friend class Bitmap;
+ friend class TexturePack;
+
+ TextureBase* texture_;
+ int x, y;
+ int width, height;
+ int dx1, dy1;
+ int dx2, dy2;
+ float u0, v0, u1, v1;
+
+private:
+ void initUV();
+};
+
+
+typedef BitmapData TextureRegion;
+
+
+#endif
diff --git a/2dsg/blendfunc.cpp b/2dsg/blendfunc.cpp
index b36dca813..5b54c22ea 100644
--- a/2dsg/blendfunc.cpp
+++ b/2dsg/blendfunc.cpp
@@ -1,50 +1,50 @@
-#include "blendfunc.h"
-#include
-
-struct BlendFunc
-{
- BlendFunc() {}
-
- BlendFunc(ShaderEngine::BlendFactor sfactor, ShaderEngine::BlendFactor dfactor) :
- sfactor(sfactor),
- dfactor(dfactor)
- {
-
- }
-
- ShaderEngine::BlendFactor sfactor;
- ShaderEngine::BlendFactor dfactor;
-};
-
-static std::stack blendFuncStack;
-
-#ifndef PREMULTIPLIED_ALPHA
-#error PREMULTIPLIED_ALPHA is not defined
-#endif
-
-#if PREMULTIPLIED_ALPHA
-static BlendFunc currentBlendFunc(ShaderEngine::ONE, ShaderEngine::ONE_MINUS_SRC_ALPHA);
-#else
-static BlendFunc currentBlendFunc(ShaderEngine::SRC_ALPHA, ShaderEngine::ONE_MINUS_SRC_ALPHA);
-#endif
-
-void glPushBlendFunc()
-{
- blendFuncStack.push(currentBlendFunc);
-}
-
-void glPopBlendFunc()
-{
- currentBlendFunc = blendFuncStack.top();
- blendFuncStack.pop();
-
- ShaderEngine::Engine->setBlendFunc(currentBlendFunc.sfactor, currentBlendFunc.dfactor);
-}
-
-void glSetBlendFunc(ShaderEngine::BlendFactor sfactor, ShaderEngine::BlendFactor dfactor)
-{
- currentBlendFunc.sfactor = sfactor;
- currentBlendFunc.dfactor = dfactor;
-
- ShaderEngine::Engine->setBlendFunc(currentBlendFunc.sfactor, currentBlendFunc.dfactor);
-}
+#include "blendfunc.h"
+#include
+
+struct BlendFunc
+{
+ BlendFunc() {}
+
+ BlendFunc(ShaderEngine::BlendFactor sfactor, ShaderEngine::BlendFactor dfactor) :
+ sfactor(sfactor),
+ dfactor(dfactor)
+ {
+
+ }
+
+ ShaderEngine::BlendFactor sfactor;
+ ShaderEngine::BlendFactor dfactor;
+};
+
+static std::stack blendFuncStack;
+
+#ifndef PREMULTIPLIED_ALPHA
+#error PREMULTIPLIED_ALPHA is not defined
+#endif
+
+#if PREMULTIPLIED_ALPHA
+static BlendFunc currentBlendFunc(ShaderEngine::ONE, ShaderEngine::ONE_MINUS_SRC_ALPHA);
+#else
+static BlendFunc currentBlendFunc(ShaderEngine::SRC_ALPHA, ShaderEngine::ONE_MINUS_SRC_ALPHA);
+#endif
+
+void glPushBlendFunc()
+{
+ blendFuncStack.push(currentBlendFunc);
+}
+
+void glPopBlendFunc()
+{
+ currentBlendFunc = blendFuncStack.top();
+ blendFuncStack.pop();
+
+ ShaderEngine::Engine->setBlendFunc(currentBlendFunc.sfactor, currentBlendFunc.dfactor);
+}
+
+void glSetBlendFunc(ShaderEngine::BlendFactor sfactor, ShaderEngine::BlendFactor dfactor)
+{
+ currentBlendFunc.sfactor = sfactor;
+ currentBlendFunc.dfactor = dfactor;
+
+ ShaderEngine::Engine->setBlendFunc(currentBlendFunc.sfactor, currentBlendFunc.dfactor);
+}
diff --git a/2dsg/blendfunc.h b/2dsg/blendfunc.h
index ec6da7b72..c08fe8ca6 100644
--- a/2dsg/blendfunc.h
+++ b/2dsg/blendfunc.h
@@ -1,10 +1,10 @@
-#ifndef BLENDFUNC_H
-#define BLENDFUNC_H
-
-#include "ogl.h"
-
-void glPushBlendFunc();
-void glPopBlendFunc();
-void glSetBlendFunc(ShaderEngine::BlendFactor sfactor, ShaderEngine::BlendFactor dfactor);
-
-#endif
+#ifndef BLENDFUNC_H
+#define BLENDFUNC_H
+
+#include "ogl.h"
+
+void glPushBlendFunc();
+void glPopBlendFunc();
+void glSetBlendFunc(ShaderEngine::BlendFactor sfactor, ShaderEngine::BlendFactor dfactor);
+
+#endif
diff --git a/2dsg/color.cpp b/2dsg/color.cpp
index a61156182..22ee7912c 100644
--- a/2dsg/color.cpp
+++ b/2dsg/color.cpp
@@ -1,74 +1,74 @@
-#include "color.h"
-#include
-#include "ogl.h"
-
-struct Color
-{
- Color() {}
- Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {}
-
- float r, g, b, a;
-};
-
-static std::stack colorStack;
-static Color currentColor(1, 1, 1, 1);
-
-static inline void setColor(float r, float g, float b, float a)
-{
- if (!ShaderEngine::Engine) return;
-#ifndef PREMULTIPLIED_ALPHA
-#error PREMULTIPLIED_ALPHA is not defined
-#endif
-
-#if PREMULTIPLIED_ALPHA
- ShaderEngine::Engine->setColor(r * a, g * a, b * a, a);
-#else
- ShaderEngine::Engine->setColor(r, g, b, a);
-#endif
-}
-
-void glPushColor()
-{
- colorStack.push(currentColor);
-}
-
-void glPopColor()
-{
- currentColor = colorStack.top();
- colorStack.pop();
-
- setColor(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
-}
-
-void glMultColor(float r, float g, float b, float a)
-{
- currentColor.r *= r;
- currentColor.g *= g;
- currentColor.b *= b;
- currentColor.a *= a;
-
- setColor(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
-}
-
-void glSetColor(float r, float g, float b, float a)
-{
- currentColor.r = r;
- currentColor.g = g;
- currentColor.b = b;
- currentColor.a = a;
-
- setColor(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
-}
-
-void glGetColor(float *r, float *g, float *b, float *a)
-{
- *r = currentColor.r;
- *g = currentColor.g;
- *b = currentColor.b;
- *a = currentColor.a;
-}
-
-int colorStackSize()
-{
- return (int)colorStack.size();
-}
+#include "color.h"
+#include
+#include "ogl.h"
+
+struct Color
+{
+ Color() {}
+ Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {}
+
+ float r, g, b, a;
+};
+
+static std::stack colorStack;
+static Color currentColor(1, 1, 1, 1);
+
+static inline void setColor(float r, float g, float b, float a)
+{
+ if (!ShaderEngine::Engine) return;
+#ifndef PREMULTIPLIED_ALPHA
+#error PREMULTIPLIED_ALPHA is not defined
+#endif
+
+#if PREMULTIPLIED_ALPHA
+ ShaderEngine::Engine->setColor(r * a, g * a, b * a, a);
+#else
+ ShaderEngine::Engine->setColor(r, g, b, a);
+#endif
+}
+
+void glPushColor()
+{
+ colorStack.push(currentColor);
+}
+
+void glPopColor()
+{
+ currentColor = colorStack.top();
+ colorStack.pop();
+
+ setColor(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
+}
+
+void glMultColor(float r, float g, float b, float a)
+{
+ currentColor.r *= r;
+ currentColor.g *= g;
+ currentColor.b *= b;
+ currentColor.a *= a;
+
+ setColor(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
+}
+
+void glSetColor(float r, float g, float b, float a)
+{
+ currentColor.r = r;
+ currentColor.g = g;
+ currentColor.b = b;
+ currentColor.a = a;
+
+ setColor(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
+}
+
+void glGetColor(float *r, float *g, float *b, float *a)
+{
+ *r = currentColor.r;
+ *g = currentColor.g;
+ *b = currentColor.b;
+ *a = currentColor.a;
+}
+
+int colorStackSize()
+{
+ return (int)colorStack.size();
+}
diff --git a/2dsg/color.h b/2dsg/color.h
index 353d117cb..7ca1860d0 100644
--- a/2dsg/color.h
+++ b/2dsg/color.h
@@ -1,11 +1,11 @@
-#ifndef COLOR_H
-#define COLOR_H
-
-void glPushColor();
-void glPopColor();
-void glMultColor(float r, float g, float b, float a);
-void glSetColor(float r, float g, float b, float a);
-void glGetColor(float *r, float *g, float *b, float *a);
-int colorStackSize();
-
-#endif
+#ifndef COLOR_H
+#define COLOR_H
+
+void glPushColor();
+void glPopColor();
+void glMultColor(float r, float g, float b, float a);
+void glSetColor(float r, float g, float b, float a);
+void glGetColor(float *r, float *g, float *b, float *a);
+int colorStackSize();
+
+#endif
diff --git a/2dsg/colortransform.cpp b/2dsg/colortransform.cpp
index 35e38b0b7..2cfefcdf9 100644
--- a/2dsg/colortransform.cpp
+++ b/2dsg/colortransform.cpp
@@ -1,22 +1,22 @@
-#include "colortransform.h"
-
-ColorTransform::ColorTransform( float redMultiplier,
- float greenMultiplier,
- float blueMultiplier,
- float alphaMultiplier,
- float redOffset,
- float greenOffset,
- float blueOffset,
- float alphaOffset) :
- redMultiplier_(redMultiplier),
- greenMultiplier_(greenMultiplier),
- blueMultiplier_(blueMultiplier),
- alphaMultiplier_(alphaMultiplier),
- redOffset_(redOffset),
- greenOffset_(greenOffset),
- blueOffset_(blueOffset),
- alphaOffset_(alphaOffset)
-{
-
-}
-
+#include "colortransform.h"
+
+ColorTransform::ColorTransform( float redMultiplier,
+ float greenMultiplier,
+ float blueMultiplier,
+ float alphaMultiplier,
+ float redOffset,
+ float greenOffset,
+ float blueOffset,
+ float alphaOffset) :
+ redMultiplier_(redMultiplier),
+ greenMultiplier_(greenMultiplier),
+ blueMultiplier_(blueMultiplier),
+ alphaMultiplier_(alphaMultiplier),
+ redOffset_(redOffset),
+ greenOffset_(greenOffset),
+ blueOffset_(blueOffset),
+ alphaOffset_(alphaOffset)
+{
+
+}
+
diff --git a/2dsg/colortransform.h b/2dsg/colortransform.h
index 6a8e6ac7a..ce0c3a479 100644
--- a/2dsg/colortransform.h
+++ b/2dsg/colortransform.h
@@ -1,87 +1,87 @@
-#ifndef COLORTRANSFORM_H
-#define COLORTRANSFORM_H
-
-class ColorTransform
-{
-public:
- ColorTransform( float redMultiplier = 1,
- float greenMultiplier = 1,
- float blueMultiplier = 1,
- float alphaMultiplier = 1,
- float redOffset = 0,
- float greenOffset = 0,
- float blueOffset = 0,
- float alphaOffset = 0);
-
- float redMultiplier() const
- {
- return redMultiplier_;
- }
-
- float greenMultiplier() const
- {
- return greenMultiplier_;
- }
-
- float blueMultiplier() const
- {
- return blueMultiplier_;
- }
-
- float alphaMultiplier() const
- {
- return alphaMultiplier_;
- }
-
- float redOffset() const
- {
- return redOffset_;
- }
-
- float greenOffset() const
- {
- return greenOffset_;
- }
-
- float blueOffset() const
- {
- return blueOffset_;
- }
-
- float alphaOffset() const
- {
- return alphaOffset_;
- }
-
- void setRedMultiplier(float redMultiplier)
- {
- redMultiplier_ = redMultiplier;
- }
-
- void setGreenMultiplier(float greenMultiplier)
- {
- greenMultiplier_ = greenMultiplier;
- }
-
- void setBlueMultiplier(float blueMultiplier)
- {
- blueMultiplier_ = blueMultiplier;
- }
-
- void setAlphaMultiplier(float alphaMultiplier)
- {
- alphaMultiplier_ = alphaMultiplier;
- }
-
-private:
- float redMultiplier_;
- float greenMultiplier_;
- float blueMultiplier_;
- float alphaMultiplier_;
- float redOffset_;
- float greenOffset_;
- float blueOffset_;
- float alphaOffset_;
-};
-
-#endif
+#ifndef COLORTRANSFORM_H
+#define COLORTRANSFORM_H
+
+class ColorTransform
+{
+public:
+ ColorTransform( float redMultiplier = 1,
+ float greenMultiplier = 1,
+ float blueMultiplier = 1,
+ float alphaMultiplier = 1,
+ float redOffset = 0,
+ float greenOffset = 0,
+ float blueOffset = 0,
+ float alphaOffset = 0);
+
+ float redMultiplier() const
+ {
+ return redMultiplier_;
+ }
+
+ float greenMultiplier() const
+ {
+ return greenMultiplier_;
+ }
+
+ float blueMultiplier() const
+ {
+ return blueMultiplier_;
+ }
+
+ float alphaMultiplier() const
+ {
+ return alphaMultiplier_;
+ }
+
+ float redOffset() const
+ {
+ return redOffset_;
+ }
+
+ float greenOffset() const
+ {
+ return greenOffset_;
+ }
+
+ float blueOffset() const
+ {
+ return blueOffset_;
+ }
+
+ float alphaOffset() const
+ {
+ return alphaOffset_;
+ }
+
+ void setRedMultiplier(float redMultiplier)
+ {
+ redMultiplier_ = redMultiplier;
+ }
+
+ void setGreenMultiplier(float greenMultiplier)
+ {
+ greenMultiplier_ = greenMultiplier;
+ }
+
+ void setBlueMultiplier(float blueMultiplier)
+ {
+ blueMultiplier_ = blueMultiplier;
+ }
+
+ void setAlphaMultiplier(float alphaMultiplier)
+ {
+ alphaMultiplier_ = alphaMultiplier;
+ }
+
+private:
+ float redMultiplier_;
+ float greenMultiplier_;
+ float blueMultiplier_;
+ float alphaMultiplier_;
+ float redOffset_;
+ float greenOffset_;
+ float blueOffset_;
+ float alphaOffset_;
+};
+
+#endif
diff --git a/2dsg/completeevent.cpp b/2dsg/completeevent.cpp
index 61f515461..d7c652b8c 100644
--- a/2dsg/completeevent.cpp
+++ b/2dsg/completeevent.cpp
@@ -1,9 +1,9 @@
-#include "completeevent.h"
-#include "eventvisitor.h"
-
-CompleteEvent::Type CompleteEvent::COMPLETE("complete");
-
-void CompleteEvent::apply(EventVisitor* v)
-{
- v->visit(this);
-}
+#include "completeevent.h"
+#include "eventvisitor.h"
+
+CompleteEvent::Type CompleteEvent::COMPLETE("complete");
+
+void CompleteEvent::apply(EventVisitor* v)
+{
+ v->visit(this);
+}
diff --git a/2dsg/completeevent.h b/2dsg/completeevent.h
index 346d53784..6abe701b6 100644
--- a/2dsg/completeevent.h
+++ b/2dsg/completeevent.h
@@ -1,21 +1,21 @@
-#ifndef COMPLETEEVENT_H
-#define COMPLETEEVENT_H
-
-#include "event.h"
-
-class CompleteEvent : public Event
-{
-public:
- typedef EventType Type;
-
- CompleteEvent(const Type& type) : Event(type.type())
- {
-
- }
-
- static Type COMPLETE;
-
- virtual void apply(EventVisitor* v);
-};
-
-#endif
+#ifndef COMPLETEEVENT_H
+#define COMPLETEEVENT_H
+
+#include "event.h"
+
+class CompleteEvent : public Event
+{
+public:
+ typedef EventType Type;
+
+ CompleteEvent(const Type& type) : Event(type.type())
+ {
+
+ }
+
+ static Type COMPLETE;
+
+ virtual void apply(EventVisitor* v);
+};
+
+#endif
diff --git a/2dsg/dib.cpp b/2dsg/dib.cpp
index 68700e101..6c0acc085 100644
--- a/2dsg/dib.cpp
+++ b/2dsg/dib.cpp
@@ -1,337 +1,337 @@
-#include "platform.h"
-#include "dib.h"
-#include "refptr.h"
-#include
-#include "application.h"
-#include
-#include "giderosexception.h"
-#include
-#include
-
-static unsigned int nextpow2(unsigned int v)
-{
- v--;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- v++;
-
- return v;
-}
-
-Dib::Dib(Application* application,
- int width, int height,
- bool pow2)
-{
- originalWidth_ = width;
- originalHeight_ = height;
-
- if (pow2)
- {
- width_ = nextpow2(originalWidth_);
- height_ = nextpow2(originalHeight_);
- }
- else
- {
- width_ = originalWidth_;
- height_ = originalHeight_;
- }
-
- baseOriginalWidth_ = originalWidth_;
- baseOriginalHeight_ = originalHeight_;
-
- data_.resize(width_ * height_ * 4, 0);
-}
-
-static void check(int result, const char* file)
-{
- switch (result)
- {
- case GIMAGE_NO_ERROR:
- break;
- case GIMAGE_CANNOT_OPEN_FILE:
- throw GiderosException(GStatus(6000, file));
- break;
- case GIMAGE_UNRECOGNIZED_FORMAT:
- throw GiderosException(GStatus(6005, file));
- break;
- case GIMAGE_ERROR_WHILE_READING:
- throw GiderosException(GStatus(6013, file));
- break;
- case GIMAGE_UNSUPPORTED_COLOR_SPACE:
- throw GiderosException(GStatus(6014, file));
- break;
- }
-}
-
-Dib::Dib(Application* application,
- const char* file,
- bool withsuffix,
- bool pow2,
- bool maketransparent,
- unsigned int transparentcolor)
-{
- int width1, height1;
- int width2, height2;
- int comp;
-
- std::string filename;
-
- if (withsuffix)
- {
- const char *ext = strrchr(file, '.');
- if (ext == NULL)
- ext = file + strlen(file);
-
- float scale;
- const char *suffix = application->getImageSuffix(file, &scale);
-
- filename = std::string(file, ext - file) + (suffix ? suffix : "") + ext;
-
- check(gimage_parseImage(filename.c_str(), &width2, &height2, &comp), filename.c_str());
-
- G_FILE *fis = g_fopen(file, "rb");
- if (fis)
- {
- g_fclose(fis);
- check(gimage_parseImage(file, &width1, &height1, NULL), file);
- }
- else
- {
- width1 = width2 / scale;
- height1 = height2 / scale;
- }
- }
- else
- {
- check(gimage_parseImage(file, &width1, &height1, &comp), file);
- filename = file;
- width2 = width1;
- height2 = height1;
- }
-
- originalWidth_ = width2;
- originalHeight_ = height2;
- baseOriginalWidth_ = width1;
- baseOriginalHeight_ = height1;
-
- if (pow2)
- {
- width_ = nextpow2(originalWidth_);
- height_ = nextpow2(originalHeight_);
- }
- else
- {
- width_ = originalWidth_;
- height_ = originalHeight_;
- }
-
- std::vector buf(originalWidth_ * originalHeight_ * comp);
-
- check(gimage_loadImage(filename.c_str(), &buf[0]), filename.c_str());
-
- data_.resize(width_ * height_ * 4);
-
- for (int y = 0; y < originalHeight_; ++y)
- for (int x = 0; x < originalWidth_; ++x)
- {
- unsigned char rgba[4] = {255, 255, 255, 255};
-
- int srcindex = (x + y * originalWidth_) * comp;
-
- switch (comp)
- {
- case 1:
- rgba[0] = rgba[1] = rgba[2] = buf[srcindex + 0];
- break;
- case 2:
- rgba[0] = rgba[1] = rgba[2] = buf[srcindex + 0];
- rgba[3] = buf[srcindex + 1];
- break;
- case 3:
- rgba[0] = buf[srcindex + 0];
- rgba[1] = buf[srcindex + 1];
- rgba[2] = buf[srcindex + 2];
- break;
- case 4:
- rgba[0] = buf[srcindex + 0];
- rgba[1] = buf[srcindex + 1];
- rgba[2] = buf[srcindex + 2];
- rgba[3] = buf[srcindex + 3];
- break;
- }
-
- int dstindex = (x + y * width_) * 4;
-
- data_[dstindex + 0] = rgba[0];
- data_[dstindex + 1] = rgba[1];
- data_[dstindex + 2] = rgba[2];
- data_[dstindex + 3] = rgba[3];
- }
-
-
- if (maketransparent)
- {
- unsigned int r = (transparentcolor >> 16) & 0xff;
- unsigned int g = (transparentcolor >> 8) & 0xff;
- unsigned int b = transparentcolor & 0xff;
-
- for (int y = 0; y < originalHeight_; ++y)
- for (int x = 0; x < originalWidth_; ++x)
- {
- int index = (x + y * width_) * 4;
-
- if (data_[index + 0] == r &&
- data_[index + 1] == g &&
- data_[index + 2] == b)
- {
- data_[index + 3] = 0;
- }
- }
- }
-
- intelligentFill();
-}
-
-void Dib::intelligentFill()
-{
- int midx = (originalWidth_ + width_) / 2;
- int midy = (originalHeight_ + height_) / 2;
-
- midx = midy = 0x7fffffff; // currently clamp mode, if this is comment out then repeat mode
-
- for (int y = 0; y < originalHeight_; ++y)
- {
- for (int x = originalWidth_; x < width_; ++x)
- {
- int indexsrc = (x < midx) ? ((originalWidth_ - 1) + y * width_) * 4 : (y * width_) * 4;
- int indexdst = (x + y * width_) * 4;
-
- data_[indexdst + 0] = data_[indexsrc + 0];
- data_[indexdst + 1] = data_[indexsrc + 1];
- data_[indexdst + 2] = data_[indexsrc + 2];
- data_[indexdst + 3] = data_[indexsrc + 3]; //0;
- }
- }
-
- for (int x = 0; x < originalWidth_; ++x)
- {
- for (int y = originalHeight_; y < height_; ++y)
- {
- int indexsrc = (y < midy) ? (x + (originalHeight_ - 1) * width_) * 4 : (x) * 4;
- int indexdst = (x + y * width_) * 4;
-
- data_[indexdst + 0] = data_[indexsrc + 0];
- data_[indexdst + 1] = data_[indexsrc + 1];
- data_[indexdst + 2] = data_[indexsrc + 2];
- data_[indexdst + 3] = data_[indexsrc + 3]; //0;
- }
- }
-
- for (int y = originalHeight_; y < height_; ++y)
- for (int x = originalWidth_; x < width_; ++x)
- {
- int indexsrc = 0;
- indexsrc += (x < midx) ? (originalWidth_ - 1) * 4 : 0;
- indexsrc += (y < midy) ? (originalHeight_ - 1) * width_ * 4 : 0;
- int indexdst = (x + y * width_) * 4;
-
- data_[indexdst + 0] = data_[indexsrc + 0];
- data_[indexdst + 1] = data_[indexsrc + 1];
- data_[indexdst + 2] = data_[indexsrc + 2];
- data_[indexdst + 3] = data_[indexsrc + 3]; //0;
- }
-}
-
-void Dib::premultiplyAlpha()
-{
- gimage_premultiplyAlpha(width_, height_, &data_[0]);
-}
-
-void Dib::convertGrayscale()
-{
- unsigned int* iptr = (unsigned int*)&data_[0];
-
- for (int i = 0; i < width_ * height_; ++i)
- iptr[i] = ((iptr[i] ^ 0x00ff0000) << 8) | 0x00ffffff;
-}
-
-std::vector Dib::to565() const
-{
- std::vector result(width_ * height_);
-
- for (int y = 0; y < height_; ++y)
- for (int x = 0; x < width_; ++x)
- {
- int index = x + y * width_;
- unsigned short r = data_[index * 4 + 0];
- unsigned short g = data_[index * 4 + 1];
- unsigned short b = data_[index * 4 + 2];
- result[index] = ((r >> 3) << 11) |
- ((g >> 2) << 5) |
- ((b >> 3) << 0);
- }
-
- return result;
-}
-
-std::vector Dib::to888() const
-{
- std::vector result(width_ * height_ * 3);
-
- for (int y = 0; y < height_; ++y)
- for (int x = 0; x < width_; ++x)
- {
- int index = x + y * width_;
- result[index * 3 + 0] = data_[index * 4 + 0];
- result[index * 3 + 1] = data_[index * 4 + 1];
- result[index * 3 + 2] = data_[index * 4 + 2];
- }
-
- return result;
-}
-
-std::vector Dib::to4444() const
-{
- std::vector result(width_ * height_);
-
- for (int y = 0; y < height_; ++y)
- for (int x = 0; x < width_; ++x)
- {
- int index = x + y * width_;
- unsigned short r = data_[index * 4 + 0];
- unsigned short g = data_[index * 4 + 1];
- unsigned short b = data_[index * 4 + 2];
- unsigned short a = data_[index * 4 + 3];
- result[index] = ((r >> 4) << 12) |
- ((g >> 4) << 8) |
- ((b >> 4) << 4) |
- ((a >> 4) << 0);
- }
-
- return result;
-}
-
-
-std::vector Dib::to5551() const
-{
- std::vector result(width_ * height_);
-
- for (int y = 0; y < height_; ++y)
- for (int x = 0; x < width_; ++x)
- {
- int index = x + y * width_;
- unsigned short r = data_[index * 4 + 0];
- unsigned short g = data_[index * 4 + 1];
- unsigned short b = data_[index * 4 + 2];
- unsigned short a = data_[index * 4 + 3];
- result[index] = ((r >> 3) << 11) |
- ((g >> 3) << 6) |
- ((b >> 3) << 1) |
- ((a >> 7) << 0);
- }
-
- return result;
-}
+#include "platform.h"
+#include "dib.h"
+#include "refptr.h"
+#include
+#include "application.h"
+#include
+#include "giderosexception.h"
+#include
+#include
+
+static unsigned int nextpow2(unsigned int v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v++;
+
+ return v;
+}
+
+Dib::Dib(Application* application,
+ int width, int height,
+ bool pow2)
+{
+ originalWidth_ = width;
+ originalHeight_ = height;
+
+ if (pow2)
+ {
+ width_ = nextpow2(originalWidth_);
+ height_ = nextpow2(originalHeight_);
+ }
+ else
+ {
+ width_ = originalWidth_;
+ height_ = originalHeight_;
+ }
+
+ baseOriginalWidth_ = originalWidth_;
+ baseOriginalHeight_ = originalHeight_;
+
+ data_.resize(width_ * height_ * 4, 0);
+}
+
+static void check(int result, const char* file)
+{
+ switch (result)
+ {
+ case GIMAGE_NO_ERROR:
+ break;
+ case GIMAGE_CANNOT_OPEN_FILE:
+ throw GiderosException(GStatus(6000, file));
+ break;
+ case GIMAGE_UNRECOGNIZED_FORMAT:
+ throw GiderosException(GStatus(6005, file));
+ break;
+ case GIMAGE_ERROR_WHILE_READING:
+ throw GiderosException(GStatus(6013, file));
+ break;
+ case GIMAGE_UNSUPPORTED_COLOR_SPACE:
+ throw GiderosException(GStatus(6014, file));
+ break;
+ }
+}
+
+Dib::Dib(Application* application,
+ const char* file,
+ bool withsuffix,
+ bool pow2,
+ bool maketransparent,
+ unsigned int transparentcolor)
+{
+ int width1, height1;
+ int width2, height2;
+ int comp;
+
+ std::string filename;
+
+ if (withsuffix)
+ {
+ const char *ext = strrchr(file, '.');
+ if (ext == NULL)
+ ext = file + strlen(file);
+
+ float scale;
+ const char *suffix = application->getImageSuffix(file, &scale);
+
+ filename = std::string(file, ext - file) + (suffix ? suffix : "") + ext;
+
+ check(gimage_parseImage(filename.c_str(), &width2, &height2, &comp), filename.c_str());
+
+ G_FILE *fis = g_fopen(file, "rb");
+ if (fis)
+ {
+ g_fclose(fis);
+ check(gimage_parseImage(file, &width1, &height1, NULL), file);
+ }
+ else
+ {
+ width1 = width2 / scale;
+ height1 = height2 / scale;
+ }
+ }
+ else
+ {
+ check(gimage_parseImage(file, &width1, &height1, &comp), file);
+ filename = file;
+ width2 = width1;
+ height2 = height1;
+ }
+
+ originalWidth_ = width2;
+ originalHeight_ = height2;
+ baseOriginalWidth_ = width1;
+ baseOriginalHeight_ = height1;
+
+ if (pow2)
+ {
+ width_ = nextpow2(originalWidth_);
+ height_ = nextpow2(originalHeight_);
+ }
+ else
+ {
+ width_ = originalWidth_;
+ height_ = originalHeight_;
+ }
+
+ std::vector buf(originalWidth_ * originalHeight_ * comp);
+
+ check(gimage_loadImage(filename.c_str(), &buf[0]), filename.c_str());
+
+ data_.resize(width_ * height_ * 4);
+
+ for (int y = 0; y < originalHeight_; ++y)
+ for (int x = 0; x < originalWidth_; ++x)
+ {
+ unsigned char rgba[4] = {255, 255, 255, 255};
+
+ int srcindex = (x + y * originalWidth_) * comp;
+
+ switch (comp)
+ {
+ case 1:
+ rgba[0] = rgba[1] = rgba[2] = buf[srcindex + 0];
+ break;
+ case 2:
+ rgba[0] = rgba[1] = rgba[2] = buf[srcindex + 0];
+ rgba[3] = buf[srcindex + 1];
+ break;
+ case 3:
+ rgba[0] = buf[srcindex + 0];
+ rgba[1] = buf[srcindex + 1];
+ rgba[2] = buf[srcindex + 2];
+ break;
+ case 4:
+ rgba[0] = buf[srcindex + 0];
+ rgba[1] = buf[srcindex + 1];
+ rgba[2] = buf[srcindex + 2];
+ rgba[3] = buf[srcindex + 3];
+ break;
+ }
+
+ int dstindex = (x + y * width_) * 4;
+
+ data_[dstindex + 0] = rgba[0];
+ data_[dstindex + 1] = rgba[1];
+ data_[dstindex + 2] = rgba[2];
+ data_[dstindex + 3] = rgba[3];
+ }
+
+
+ if (maketransparent)
+ {
+ unsigned int r = (transparentcolor >> 16) & 0xff;
+ unsigned int g = (transparentcolor >> 8) & 0xff;
+ unsigned int b = transparentcolor & 0xff;
+
+ for (int y = 0; y < originalHeight_; ++y)
+ for (int x = 0; x < originalWidth_; ++x)
+ {
+ int index = (x + y * width_) * 4;
+
+ if (data_[index + 0] == r &&
+ data_[index + 1] == g &&
+ data_[index + 2] == b)
+ {
+ data_[index + 3] = 0;
+ }
+ }
+ }
+
+ intelligentFill();
+}
+
+void Dib::intelligentFill()
+{
+ int midx = (originalWidth_ + width_) / 2;
+ int midy = (originalHeight_ + height_) / 2;
+
+ midx = midy = 0x7fffffff; // currently clamp mode, if this is comment out then repeat mode
+
+ for (int y = 0; y < originalHeight_; ++y)
+ {
+ for (int x = originalWidth_; x < width_; ++x)
+ {
+ int indexsrc = (x < midx) ? ((originalWidth_ - 1) + y * width_) * 4 : (y * width_) * 4;
+ int indexdst = (x + y * width_) * 4;
+
+ data_[indexdst + 0] = data_[indexsrc + 0];
+ data_[indexdst + 1] = data_[indexsrc + 1];
+ data_[indexdst + 2] = data_[indexsrc + 2];
+ data_[indexdst + 3] = data_[indexsrc + 3]; //0;
+ }
+ }
+
+ for (int x = 0; x < originalWidth_; ++x)
+ {
+ for (int y = originalHeight_; y < height_; ++y)
+ {
+ int indexsrc = (y < midy) ? (x + (originalHeight_ - 1) * width_) * 4 : (x) * 4;
+ int indexdst = (x + y * width_) * 4;
+
+ data_[indexdst + 0] = data_[indexsrc + 0];
+ data_[indexdst + 1] = data_[indexsrc + 1];
+ data_[indexdst + 2] = data_[indexsrc + 2];
+ data_[indexdst + 3] = data_[indexsrc + 3]; //0;
+ }
+ }
+
+ for (int y = originalHeight_; y < height_; ++y)
+ for (int x = originalWidth_; x < width_; ++x)
+ {
+ int indexsrc = 0;
+ indexsrc += (x < midx) ? (originalWidth_ - 1) * 4 : 0;
+ indexsrc += (y < midy) ? (originalHeight_ - 1) * width_ * 4 : 0;
+ int indexdst = (x + y * width_) * 4;
+
+ data_[indexdst + 0] = data_[indexsrc + 0];
+ data_[indexdst + 1] = data_[indexsrc + 1];
+ data_[indexdst + 2] = data_[indexsrc + 2];
+ data_[indexdst + 3] = data_[indexsrc + 3]; //0;
+ }
+}
+
+void Dib::premultiplyAlpha()
+{
+ gimage_premultiplyAlpha(width_, height_, &data_[0]);
+}
+
+void Dib::convertGrayscale()
+{
+ unsigned int* iptr = (unsigned int*)&data_[0];
+
+ for (int i = 0; i < width_ * height_; ++i)
+ iptr[i] = ((iptr[i] ^ 0x00ff0000) << 8) | 0x00ffffff;
+}
+
+std::vector Dib::to565() const
+{
+ std::vector result(width_ * height_);
+
+ for (int y = 0; y < height_; ++y)
+ for (int x = 0; x < width_; ++x)
+ {
+ int index = x + y * width_;
+ unsigned short r = data_[index * 4 + 0];
+ unsigned short g = data_[index * 4 + 1];
+ unsigned short b = data_[index * 4 + 2];
+ result[index] = ((r >> 3) << 11) |
+ ((g >> 2) << 5) |
+ ((b >> 3) << 0);
+ }
+
+ return result;
+}
+
+std::vector Dib::to888() const
+{
+ std::vector result(width_ * height_ * 3);
+
+ for (int y = 0; y < height_; ++y)
+ for (int x = 0; x < width_; ++x)
+ {
+ int index = x + y * width_;
+ result[index * 3 + 0] = data_[index * 4 + 0];
+ result[index * 3 + 1] = data_[index * 4 + 1];
+ result[index * 3 + 2] = data_[index * 4 + 2];
+ }
+
+ return result;
+}
+
+std::vector Dib::to4444() const
+{
+ std::vector result(width_ * height_);
+
+ for (int y = 0; y < height_; ++y)
+ for (int x = 0; x < width_; ++x)
+ {
+ int index = x + y * width_;
+ unsigned short r = data_[index * 4 + 0];
+ unsigned short g = data_[index * 4 + 1];
+ unsigned short b = data_[index * 4 + 2];
+ unsigned short a = data_[index * 4 + 3];
+ result[index] = ((r >> 4) << 12) |
+ ((g >> 4) << 8) |
+ ((b >> 4) << 4) |
+ ((a >> 4) << 0);
+ }
+
+ return result;
+}
+
+
+std::vector Dib::to5551() const
+{
+ std::vector result(width_ * height_);
+
+ for (int y = 0; y < height_; ++y)
+ for (int x = 0; x < width_; ++x)
+ {
+ int index = x + y * width_;
+ unsigned short r = data_[index * 4 + 0];
+ unsigned short g = data_[index * 4 + 1];
+ unsigned short b = data_[index * 4 + 2];
+ unsigned short a = data_[index * 4 + 3];
+ result[index] = ((r >> 3) << 11) |
+ ((g >> 3) << 6) |
+ ((b >> 3) << 1) |
+ ((a >> 7) << 0);
+ }
+
+ return result;
+}
diff --git a/2dsg/enterframeevent.cpp b/2dsg/enterframeevent.cpp
index 06d9a5b9f..108110fed 100644
--- a/2dsg/enterframeevent.cpp
+++ b/2dsg/enterframeevent.cpp
@@ -1,9 +1,9 @@
-#include "enterframeevent.h"
-#include "eventvisitor.h"
-
-EnterFrameEvent::Type EnterFrameEvent::ENTER_FRAME("enterFrame");
-
-void EnterFrameEvent::apply(EventVisitor* v)
-{
- v->visit(this);
-}
+#include "enterframeevent.h"
+#include "eventvisitor.h"
+
+EnterFrameEvent::Type EnterFrameEvent::ENTER_FRAME("enterFrame");
+
+void EnterFrameEvent::apply(EventVisitor* v)
+{
+ v->visit(this);
+}
diff --git a/2dsg/enterframeevent.h b/2dsg/enterframeevent.h
index 74948401a..f7a808436 100644
--- a/2dsg/enterframeevent.h
+++ b/2dsg/enterframeevent.h
@@ -1,61 +1,61 @@
-#ifndef ENTERFRAMEEVENT_H
-#define ENTERFRAMEEVENT_H
-
-#include "event.h"
-
-class EnterFrameEvent : public Event
-{
-public:
- typedef EventType Type;
-
- EnterFrameEvent( const Type& type,
- int frameCount, int deltaFrameCount,
- double time, double deltaTime, double lastFrameRenderTime) : Event(type.type()),
- frameCount_(frameCount),
- deltaFrameCount_(deltaFrameCount),
- time_(time),
- deltaTime_(deltaTime),
- lastFrameRenderTime_(lastFrameRenderTime)
- {
-
- }
-
- int frameCount() const
- {
- return frameCount_;
- }
-
- int deltaFrameCount() const
- {
- return deltaFrameCount_;
- }
-
- double time() const
- {
- return time_;
- }
-
- double deltaTime() const
- {
- return deltaTime_;
- }
-
- double lastFrameRenderTime() const
- {
- return lastFrameRenderTime_;
- }
-
-
- virtual void apply(EventVisitor* v);
-
- static Type ENTER_FRAME;
-
-private:
- int frameCount_;
- int deltaFrameCount_;
- double time_;
- double deltaTime_;
- double lastFrameRenderTime_;
-};
-
-#endif
+#ifndef ENTERFRAMEEVENT_H
+#define ENTERFRAMEEVENT_H
+
+#include "event.h"
+
+class EnterFrameEvent : public Event
+{
+public:
+ typedef EventType Type;
+
+ EnterFrameEvent( const Type& type,
+ int frameCount, int deltaFrameCount,
+ double time, double deltaTime, double lastFrameRenderTime) : Event(type.type()),
+ frameCount_(frameCount),
+ deltaFrameCount_(deltaFrameCount),
+ time_(time),
+ deltaTime_(deltaTime),
+ lastFrameRenderTime_(lastFrameRenderTime)
+ {
+
+ }
+
+ int frameCount() const
+ {
+ return frameCount_;
+ }
+
+ int deltaFrameCount() const
+ {
+ return deltaFrameCount_;
+ }
+
+ double time() const
+ {
+ return time_;
+ }
+
+ double deltaTime() const
+ {
+ return deltaTime_;
+ }
+
+ double lastFrameRenderTime() const
+ {
+ return lastFrameRenderTime_;
+ }
+
+
+ virtual void apply(EventVisitor* v);
+
+ static Type ENTER_FRAME;
+
+private:
+ int frameCount_;
+ int deltaFrameCount_;
+ double time_;
+ double deltaTime_;
+ double lastFrameRenderTime_;
+};
+
+#endif
diff --git a/2dsg/errorevent.cpp b/2dsg/errorevent.cpp
index 433b7d9ff..5f1a4abf3 100644
--- a/2dsg/errorevent.cpp
+++ b/2dsg/errorevent.cpp
@@ -1,9 +1,9 @@
-#include "errorevent.h"
-#include "eventvisitor.h"
-
-ErrorEvent::Type ErrorEvent::ERROR("error");
-
-void ErrorEvent::apply(EventVisitor* v)
-{
- v->visit(this);
-}
+#include "errorevent.h"
+#include "eventvisitor.h"
+
+ErrorEvent::Type ErrorEvent::ERROR("error");
+
+void ErrorEvent::apply(EventVisitor* v)
+{
+ v->visit(this);
+}
diff --git a/2dsg/errorevent.h b/2dsg/errorevent.h
index a43999fc5..f2bbcde3b 100644
--- a/2dsg/errorevent.h
+++ b/2dsg/errorevent.h
@@ -1,21 +1,21 @@
-#ifndef ERROREVENT_H
-#define ERROREVENT_H
-
-#include "event.h"
-
-class ErrorEvent : public Event
-{
-public:
- typedef EventType Type;
-
- ErrorEvent(const Type& type) : Event(type.type())
- {
-
- }
-
- static Type ERROR;
-
- virtual void apply(EventVisitor* v);
-};
-
-#endif
+#ifndef ERROREVENT_H
+#define ERROREVENT_H
+
+#include "event.h"
+
+class ErrorEvent : public Event
+{
+public:
+ typedef EventType Type;
+
+ ErrorEvent(const Type& type) : Event(type.type())
+ {
+
+ }
+
+ static Type ERROR;
+
+ virtual void apply(EventVisitor* v);
+};
+
+#endif
diff --git a/2dsg/font.h b/2dsg/font.h
index 30dd89203..f77b3b26c 100644
--- a/2dsg/font.h
+++ b/2dsg/font.h
@@ -1,69 +1,69 @@
-#ifndef FONT_H
-#define FONT_H
-
-#include "fontbase.h"
-#include