123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 |
- // Copyright (C) 2008-2012 Colin MacDonald
- // No rights reserved: this software is in the public domain.
- #include "testUtils.h"
- using namespace irr;
- using namespace core;
- using namespace scene;
- using namespace video;
- using namespace io;
- using namespace gui;
- namespace
- {
- // Basic tests for identity matrix
- bool identity(void)
- {
- bool result = true;
- matrix4 m;
- // Check default init
- result &= (m==core::IdentityMatrix);
- result &= (core::IdentityMatrix==m);
- assert_log(result);
- // Since the last test can be made with isDefinitelyIdentityMatrix we set it to false here
- m.setDefinitelyIdentityMatrix(false);
- result &= (m==core::IdentityMatrix);
- result &= (core::IdentityMatrix==m);
- assert_log(result);
- // also equals should see this
- result &= m.equals(core::IdentityMatrix);
- result &= core::IdentityMatrix.equals(m);
- assert_log(result);
- // Check inequality
- m[12]=5.f;
- result &= (m!=core::IdentityMatrix);
- result &= (core::IdentityMatrix!=m);
- result &= !m.equals(core::IdentityMatrix);
- result &= !core::IdentityMatrix.equals(m);
- assert_log(result);
- // Test multiplication
- result &= (m==(core::IdentityMatrix*m));
- result &= m.equals(core::IdentityMatrix*m);
- result &= (m==(m*core::IdentityMatrix));
- result &= m.equals(m*core::IdentityMatrix);
- assert_log(result);
- return result;
- }
- // Test rotations
- bool transformations(void)
- {
- bool result = true;
- matrix4 m, s;
- m.setRotationDegrees(core::vector3df(30,40,50));
- s.setScale(core::vector3df(2,3,4));
- m *= s;
- m.setTranslation(core::vector3df(5,6,7));
- result &= (core::vector3df(5,6,7).equals(m.getTranslation()));
- assert_log(result);
- result &= (core::vector3df(2,3,4).equals(m.getScale()));
- assert_log(result);
- core::vector3df newRotation = m.getRotationDegrees();
- result &= (core::vector3df(30,40,50).equals(newRotation, 0.000004f));
- assert_log(result);
- m.setRotationDegrees(vector3df(90.0001f, 270.85f, 180.0f));
- s.setRotationDegrees(vector3df(0,0, 0.860866f));
- m *= s;
- newRotation = m.getRotationDegrees();
- result &= (core::vector3df(0,270,270).equals(newRotation, 0.0001f));
- assert_log(result);
- m.setRotationDegrees(vector3df(270.0f, 89.8264f, 0.000100879f));
- s.setRotationDegrees(vector3df(0,0, 0.189398f));
- m *= s;
- newRotation = m.getRotationDegrees();
- result &= (core::vector3df(0,90,90).equals(newRotation, 0.0001f));
- assert_log(result);
- m.setRotationDegrees(vector3df(270.0f, 89.0602f, 359.999f));
- s.setRotationDegrees(vector3df(0,0, 0.949104f));
- m *= s;
- newRotation = m.getRotationDegrees();
- result &= (core::vector3df(0,90,89.999f).equals(newRotation));
- assert_log(result);
- return result;
- }
- // Test rotations
- bool rotations(void)
- {
- bool result = true;
- matrix4 rot1,rot2,rot3,rot4,rot5;
- core::vector3df vec1(1,2,3),vec12(1,2,3);
- core::vector3df vec2(-5,0,0),vec22(-5,0,0);
- core::vector3df vec3(20,0,-20), vec32(20,0,-20);
- // Make sure the matrix multiplication and rotation application give same results
- rot1.setRotationDegrees(core::vector3df(90,0,0));
- rot2.setRotationDegrees(core::vector3df(0,90,0));
- rot3.setRotationDegrees(core::vector3df(0,0,90));
- rot4.setRotationDegrees(core::vector3df(90,90,90));
- rot5 = rot3*rot2*rot1;
- result &= (rot4.equals(rot5, ROUNDING_ERROR_f32));
- assert_log(result);
- rot4.transformVect(vec1);rot5.transformVect(vec12);
- rot4.transformVect(vec2);rot5.transformVect(vec22);
- rot4.transformVect(vec3);rot5.transformVect(vec32);
- result &= (vec1.equals(vec12));
- result &= (vec2.equals(vec22));
- result &= (vec3.equals(vec32));
- assert_log(result);
- vec1.set(1,2,3);vec12.set(1,2,3);
- vec2.set(-5,0,0);vec22.set(-5,0,0);
- vec3.set(20,0,-20);vec32.set(20,0,-20);
- rot1.setRotationDegrees(core::vector3df(45,0,0));
- rot2.setRotationDegrees(core::vector3df(0,45,0));
- rot3.setRotationDegrees(core::vector3df(0,0,45));
- rot4.setRotationDegrees(core::vector3df(45,45,45));
- rot5 = rot3*rot2*rot1;
- result &= (rot4.equals(rot5, ROUNDING_ERROR_f32));
- assert_log(result);
- rot4.transformVect(vec1);rot5.transformVect(vec12);
- rot4.transformVect(vec2);rot5.transformVect(vec22);
- rot4.transformVect(vec3);rot5.transformVect(vec32);
- result &= (vec1.equals(vec12));
- result &= (vec2.equals(vec22));
- result &= (vec3.equals(vec32, 2*ROUNDING_ERROR_f32));
- assert_log(result);
- vec1.set(1,2,3);vec12.set(1,2,3);
- vec2.set(-5,0,0);vec22.set(-5,0,0);
- vec3.set(20,0,-20);vec32.set(20,0,-20);
- rot1.setRotationDegrees(core::vector3df(-60,0,0));
- rot2.setRotationDegrees(core::vector3df(0,-60,0));
- rot3.setRotationDegrees(core::vector3df(0,0,-60));
- rot4.setRotationDegrees(core::vector3df(-60,-60,-60));
- rot5 = rot3*rot2*rot1;
- result &= (rot4.equals(rot5, ROUNDING_ERROR_f32));
- assert_log(result);
- rot4.transformVect(vec1);rot5.transformVect(vec12);
- rot4.transformVect(vec2);rot5.transformVect(vec22);
- rot4.transformVect(vec3);rot5.transformVect(vec32);
- result &= (vec1.equals(vec12));
- result &= (vec2.equals(vec22));
- // this one needs higher tolerance due to rounding issues
- result &= (vec3.equals(vec32, 0.000002f));
- assert_log(result);
- vec1.set(1,2,3);vec12.set(1,2,3);
- vec2.set(-5,0,0);vec22.set(-5,0,0);
- vec3.set(20,0,-20);vec32.set(20,0,-20);
- rot1.setRotationDegrees(core::vector3df(113,0,0));
- rot2.setRotationDegrees(core::vector3df(0,-27,0));
- rot3.setRotationDegrees(core::vector3df(0,0,193));
- rot4.setRotationDegrees(core::vector3df(113,-27,193));
- rot5 = rot3*rot2*rot1;
- result &= (rot4.equals(rot5, ROUNDING_ERROR_f32));
- assert_log(result);
- rot4.transformVect(vec1);rot5.transformVect(vec12);
- rot4.transformVect(vec2);rot5.transformVect(vec22);
- rot4.transformVect(vec3);rot5.transformVect(vec32);
- // these ones need higher tolerance due to rounding issues
- result &= (vec1.equals(vec12, 0.000002f));
- assert_log(result);
- result &= (vec2.equals(vec22));
- assert_log(result);
- result &= (vec3.equals(vec32, 0.000002f));
- assert_log(result);
- rot1.setRotationDegrees(core::vector3df(0,0,34));
- rot2.setRotationDegrees(core::vector3df(0,43,0));
- vec1=(rot2*rot1).getRotationDegrees();
- result &= (vec1.equals(core::vector3df(27.5400505f, 34.4302292f, 42.6845398f), 0.000002f));
- assert_log(result);
- // corner cases
- rot1.setRotationDegrees(irr::core::vector3df(180.0f, 0.f, 0.f));
- vec1=rot1.getRotationDegrees();
- result &= (vec1.equals(core::vector3df(180.0f, 0.f, 0.f), 0.000002f));
- assert_log(result);
- rot1.setRotationDegrees(irr::core::vector3df(0.f, 180.0f, 0.f));
- vec1=rot1.getRotationDegrees();
- result &= (vec1.equals(core::vector3df(180.0f, 360, 180.0f), 0.000002f));
- assert_log(result);
- rot1.setRotationDegrees(irr::core::vector3df(0.f, 0.f, 180.0f));
- vec1=rot1.getRotationDegrees();
- result &= (vec1.equals(core::vector3df(0.f, 0.f, 180.0f), 0.000002f));
- assert_log(result);
- rot1.makeIdentity();
- rot1.setRotationDegrees(core::vector3df(270.f,0,0));
- rot2.makeIdentity();
- rot2.setRotationDegrees(core::vector3df(-90.f,0,0));
- vec1=(rot1*rot2).getRotationDegrees();
- result &= (vec1.equals(core::vector3df(180.f, 0.f, 0.0f)));
- assert_log(result);
- return result;
- }
- // Test isOrthogonal
- bool isOrthogonal(void)
- {
- matrix4 rotationMatrix;
- if (!rotationMatrix.isOrthogonal())
- {
- logTestString("irr::core::matrix4::isOrthogonal() failed with Identity.\n");
- return false;
- }
- rotationMatrix.setRotationDegrees(vector3df(90, 0, 0));
- if (!rotationMatrix.isOrthogonal())
- {
- logTestString("irr::core::matrix4::isOrthogonal() failed with rotation.\n");
- return false;
- }
- matrix4 translationMatrix;
- translationMatrix.setTranslation(vector3df(0, 3, 0));
- if (translationMatrix.isOrthogonal())
- {
- logTestString("irr::core::matrix4::isOrthogonal() failed with translation.\n");
- return false;
- }
- matrix4 scaleMatrix;
- scaleMatrix.setScale(vector3df(1, 2, 3));
- if (!scaleMatrix.isOrthogonal())
- {
- logTestString("irr::core::matrix4::isOrthogonal() failed with scale.\n");
- return false;
- }
- return true;
- }
- bool checkMatrixRotation(irr::core::matrix4& m, const vector3df& vector, const vector3df& expectedResult)
- {
- vector3df v(vector);
- m.rotateVect(v);
- if ( expectedResult.equals(v) )
- return true;
- logTestString("checkMatrixRotation failed for vector %f %f %f. Expected %f %f %f, got %f %f %f \n"
- , vector.X, vector.Y, vector.Z, expectedResult.X, expectedResult.Y, expectedResult.Z, v.X, v.Y, v.Z);
- logTestString("matrix: ");
- for ( int i=0; i<16; ++i )
- logTestString("%.2f ", m[i]);
- logTestString("\n");
- return false;
- }
- bool setRotationAxis()
- {
- matrix4 m;
- vector3df v;
-
- // y up, x right, z depth (as usual)
- // y rotated around x-axis
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(1,0,0)), vector3df(0,1,0), vector3df(0, 0, 1)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
- if ( !checkMatrixRotation( m.setRotationAxisRadians(180.f*DEGTORAD, vector3df(1,0,0)), vector3df(0,1,0), vector3df(0, -1, 0)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
-
- // y rotated around negative x-axis
- m.makeIdentity();
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(-1,0,0)), vector3df(0,1,0), vector3df(0, 0, -1)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
-
- // x rotated around x-axis
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(1,0,0)), vector3df(1,0,0), vector3df(1, 0, 0)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
- // x rotated around y-axis
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,1,0)), vector3df(1,0,0), vector3df(0, 0, -1)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
- if ( !checkMatrixRotation( m.setRotationAxisRadians(180.f*DEGTORAD, vector3df(0,1,0)), vector3df(1,0,0), vector3df(-1, 0, 0)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
-
- // x rotated around negative y-axis
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,-1,0)), vector3df(1,0,0), vector3df(0, 0, 1)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
-
- // y rotated around y-axis
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,1,0)), vector3df(0,1,0), vector3df(0, 1, 0)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
- // x rotated around z-axis
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,0,1)), vector3df(1,0,0), vector3df(0, 1, 0)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
- if ( !checkMatrixRotation( m.setRotationAxisRadians(180.f*DEGTORAD, vector3df(0,0,1)), vector3df(1,0,0), vector3df(-1, 0, 0)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
- // x rotated around negative z-axis
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,0,-1)), vector3df(1,0,0), vector3df(0, -1, 0)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
-
- // y rotated around z-axis
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,0,1)), vector3df(0,1,0), vector3df(-1, 0, 0)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
- if ( !checkMatrixRotation( m.setRotationAxisRadians(180.f*DEGTORAD, vector3df(0,0,1)), vector3df(0,1,0), vector3df(0, -1, 0)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
-
- // z rotated around z-axis
- if ( !checkMatrixRotation( m.setRotationAxisRadians(90.f*DEGTORAD, vector3df(0,0,1)), vector3df(0,0,1), vector3df(0, 0, 1)) )
- {
- logTestString("%s:%d", __FILE__, __LINE__);
- return false;
- }
-
- return true;
- }
- // just calling each function once to find compile problems
- void calltest()
- {
- matrix4 mat;
- matrix4 mat2(mat);
- f32& f1 = mat(0,0);
- const f32& f2 = mat(0,0);
- f32& f3 = mat[0];
- const f32& f4 = mat[0];
- mat = mat;
- mat = 1.f;
- const f32 * pf1 = mat.pointer();
- f32 * pf2 = mat.pointer();
- bool b = mat == mat2;
- b = mat != mat2;
- mat = mat + mat2;
- mat += mat2;
- mat = mat - mat2;
- mat -= mat2;
- mat.setbyproduct(mat, mat2);
- mat.setbyproduct_nocheck(mat, mat2);
- mat = mat * mat2;
- mat *= mat2;
- mat = mat * 10.f;
- mat *= 10.f;
- mat.makeIdentity();
- b = mat.isIdentity();
- b = mat.isOrthogonal();
- b = mat.isIdentity_integer_base ();
- mat.setTranslation(vector3df(1.f, 1.f, 1.f) );
- vector3df v1 = mat.getTranslation();
- mat.setInverseTranslation(vector3df(1.f, 1.f, 1.f) );
- mat.setRotationRadians(vector3df(1.f, 1.f, 1.f) );
- mat.setRotationDegrees(vector3df(1.f, 1.f, 1.f) );
- vector3df v2 = mat.getRotationDegrees();
- mat.setInverseRotationRadians(vector3df(1.f, 1.f, 1.f) );
- mat.setInverseRotationDegrees(vector3df(1.f, 1.f, 1.f) );
- mat.setRotationAxisRadians(1.f, vector3df(1.f, 1.f, 1.f) );
- mat.setScale(vector3df(1.f, 1.f, 1.f) );
- mat.setScale(1.f);
- vector3df v3 = mat.getScale();
- mat.inverseTranslateVect(v1);
- mat.inverseRotateVect(v1);
- mat.rotateVect(v1);
- mat.rotateVect(v1, v2);
- f32 fv3[3];
- mat.rotateVect(fv3, v1);
- mat.transformVect(v1);
- mat.transformVect(v1, v1);
- f32 fv4[4];
- mat.transformVect(fv4, v1);
- mat.transformVec3(fv3, fv3);
- mat.translateVect(v1);
- plane3df p1;
- mat.transformPlane(p1);
- mat.transformPlane(p1, p1);
- aabbox3df bb1;
- mat.transformBox(bb1);
- mat.transformBoxEx(bb1);
- mat.multiplyWith1x4Matrix(fv4);
- mat.makeInverse();
- b = mat.getInversePrimitive(mat2);
- b = mat.getInverse(mat2);
- mat.buildProjectionMatrixPerspectiveFovRH(1.f, 1.f, 1.f, 1000.f);
- mat.buildProjectionMatrixPerspectiveFovLH(1.f, 1.f, 1.f, 1000.f);
- mat.buildProjectionMatrixPerspectiveFovInfinityLH(1.f, 1.f, 1.f);
- mat.buildProjectionMatrixPerspectiveRH(100.f, 100.f, 1.f, 1000.f);
- mat.buildProjectionMatrixPerspectiveLH(10000.f, 10000.f, 1.f, 1000.f);
- mat.buildProjectionMatrixOrthoLH(10000.f, 10000.f, 1.f, 1000.f);
- mat.buildProjectionMatrixOrthoRH(10000.f, 10000.f, 1.f, 1000.f);
- mat.buildCameraLookAtMatrixLH(vector3df(1.f, 1.f, 1.f), vector3df(0.f, 0.f, 0.f), vector3df(0.f, 1.f, 0.f) );
- mat.buildCameraLookAtMatrixRH(vector3df(1.f, 1.f, 1.f), vector3df(0.f, 0.f, 0.f), vector3df(0.f, 1.f, 0.f) );
- mat.buildShadowMatrix(vector3df(1.f, 1.f, 1.f), p1);
- core::rect<s32> a1(0,0,100,100);
- mat.buildNDCToDCMatrix(a1, 1.f);
- mat.interpolate(mat2, 1.f);
- mat = mat.getTransposed();
- mat.getTransposed(mat2);
- mat.buildRotateFromTo(vector3df(1.f, 1.f, 1.f), vector3df(1.f, 1.f, 1.f));
- mat.setRotationCenter(vector3df(1.f, 1.f, 1.f), vector3df(1.f, 1.f, 1.f));
- mat.buildAxisAlignedBillboard(vector3df(1.f, 1.f, 1.f), vector3df(1.f, 1.f, 1.f), vector3df(1.f, 1.f, 1.f), vector3df(1.f, 1.f, 1.f), vector3df(1.f, 1.f, 1.f));
- mat.buildTextureTransform( 1.f,vector2df(1.f, 1.f), vector2df(1.f, 1.f), vector2df(1.f, 1.f));
- mat.setTextureRotationCenter( 1.f );
- mat.setTextureTranslate( 1.f, 1.f );
- mat.setTextureTranslateTransposed(1.f, 1.f);
- mat.setTextureScale( 1.f, 1.f );
- mat.setTextureScaleCenter( 1.f, 1.f );
- f32 fv16[16];
- mat.setM(fv16);
- mat.setDefinitelyIdentityMatrix(false);
- b = mat.getDefinitelyIdentityMatrix();
- b = mat.equals(mat2);
- f1 = f1+f2+f3+f4+*pf1+*pf2; // getting rid of unused variable warnings.
- }
- }
- bool matrixOps(void)
- {
- bool result = true;
- calltest();
- result &= identity();
- result &= rotations();
- result &= isOrthogonal();
- result &= transformations();
- result &= setRotationAxis();
- return result;
- }
|