void QuatOpsTest::testQuatVectorSub()
   {
      // test out mult( result, quat, quat )
      const float eps = 0.0001f;
      gmtl::Quat<float> q3( 1, 2, 3, 4 ), q5, q6( 2, 3, 4, 5 );
      gmtl::sub( q5, q3, q6 );

      gmtl::Quat<float> expected_result1( -1, -1, -1, -1 );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result1, q5, eps ) );
   }
   void QuatOpsTest::testQuatVectorMult()
   {
      // test out mult( result, quat, quat )
      const float eps = 0.0001f;
      gmtl::Quat<float> q3( 1, 2, 3, 4 ), q5;
      gmtl::mult( q5, q3, 23.0f );

      gmtl::Quat<float> expected_result1( 1 * 23.0f, 2 * 23.0f, 3 * 23.0f, 4 * 23.0f );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result1, q5, eps ) );
   }
   void QuatOpsTest::testQuatConj()
   {
      const float eps = 0.0001f;
      gmtl::Quat<float> q3( 0,0,342334,0 ), q5( 342334,-342334,342334,-342334 );
      gmtl::conj( q3 );
      gmtl::conj( q5 );

      gmtl::Quat<float> expected_result1( 0, 0, -342334, 0 ), expected_result2( -342334,342334,-342334,-342334 );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result1, q3, eps ) );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result2, q5, eps ) );
   }
   void QuatOpsTest::testQuatNormalize()
   {
      const float eps = 0.0001f;
      gmtl::Quat<float> q3( 0,0,342334,0 ), q5( 342334,-342334,342334,-342334 );
      gmtl::normalize( q3 );
      gmtl::normalize( q5 );

      gmtl::Quat<float> expected_result1( 0, 0, 1, 0 ), expected_result2( 0.5, -0.5, 0.5, -0.5 );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result1, q3, eps ) );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result2, q5, eps ) );

      CPPUNIT_ASSERT( gmtl::isNormalized( expected_result1 ) );
      CPPUNIT_ASSERT( gmtl::isNormalized( expected_result2 ) );
   }
   void QuatOpsTest::testQuatLerp()
   {
      const float eps = 0.0001f;
      gmtl::Quat<float> q1( 1, 2, 3, 4 ), q2( 9, 8, 7, 6 );
      gmtl::normalize( q1 ); // make sure they are valid rotation quaternions
      gmtl::normalize( q2 );
      gmtl::Quat<float> expected_result1( q1 ), res1;
      gmtl::Quat<float> expected_result2( q2 ), res2;

      gmtl::lerp( res1, 0.0f, q1, q2 );
      gmtl::lerp( res2, 1.0f, q1, q2 );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result1, res1, eps ) );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result2, res2, eps ) );

      /// @todo, test interpolated values...
   }
   void QuatOpsTest::testQuatNegate()
   {
      const float eps = 0.0001f;
      gmtl::Quat<float> q3( 0,0,342334,0 ), q5( 342334,-342334,342334,-342334 );
      gmtl::Quat<float> expected_result1( 0, 0, -342334, 0 ), expected_result2( -342334,342334,-342334,342334 );

      // test operator-
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result1, -q3, eps ) );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result2, -q5, eps ) );

      // test negate(quat)
      gmtl::negate( q3 );
      gmtl::negate( q5 );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result1, q3, eps ) );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result2, q5, eps ) );
   }
Example #7
0
   void QuatGenTest::testQuatMakeRot()
   {
      const float eps = 0.0001f;
      gmtl::Quat<float> q1, q2;
      q1 = gmtl::make<gmtl::Quat<float> >( gmtl::AxisAnglef( gmtl::Math::deg2Rad( 90.0f ), 1.0f, 0.0f, 0.0f ) );
      q2 = gmtl::make<gmtl::Quat<float> >( gmtl::AxisAnglef( gmtl::Math::deg2Rad( 32.0f ), 0.0f, 1.0f, 0.0f ) );
      gmtl::Quat<float> expected_result1( 0.707107f, 0, 0, 0.707107f );
      gmtl::Quat<float> expected_result2( 0, 0.275637f, 0, 0.961262f );

      CPPUNIT_ASSERT( gmtl::isEqual( expected_result1, q1, eps ) );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result2, q2, eps ) );
      CPPUNIT_ASSERT( gmtl::isNormalized( q1, eps ) );
      CPPUNIT_ASSERT( gmtl::isNormalized( q2, eps ) );

      // values from VR Juggler math lib...
      std::vector< gmtl::Quat<float> > quats;
      quats.push_back( gmtl::Quat<float>( 0, 0, 0, -1       ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.173648f, -0, -0.984808f) );
      quats.push_back( gmtl::Quat<float>( -0, -0.34202f, -0, -0.939693f ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.5f, -0, -0.866025f     ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.642788f, -0, -0.766044f) );
      quats.push_back( gmtl::Quat<float>( -0, -0.766044f, -0, -0.642788f) );
      quats.push_back( gmtl::Quat<float>( -0, -0.866025f, -0, -0.5f     ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.939693f, -0, -0.34202f ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.984808f, -0, -0.173648f) );
      quats.push_back( gmtl::Quat<float>( -0, -1, -0, 0    ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.984808f, -0, 0.173648f ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.939693f, -0, 0.34202f  ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.866025f, -0, 0.5f      ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.766044f, -0, 0.642788f ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.642788f, -0, 0.766044f ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.5f, -0, 0.866025f      ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.34202f, -0, 0.939693f  ) );
      quats.push_back( gmtl::Quat<float>( -0, -0.173648f, -0, 0.984808f ) );
      quats.push_back( gmtl::Quat<float>( 0, 0, 0, 1                  ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.173648f, 0, 0.984808f    ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.34202f, 0, 0.939693f     ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.5f, 0, 0.866025f         ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.642788f, 0, 0.766044f    ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.766044f, 0, 0.642788f    ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.866025f, 0, 0.5f         ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.939693f, 0, 0.34202f     ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.984808f, 0, 0.173648f    ) );
      quats.push_back( gmtl::Quat<float>( 0, 1, 0, 0       ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.984808f, 0, -0.173648f   ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.939693f, 0, -0.34202f    ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.866025f, 0, -0.5f        ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.766044f, 0, -0.642788f   ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.642788f, 0, -0.766044f   ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.5f, 0, -0.866025f        ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.34202f, 0, -0.939693f    ) );
      quats.push_back( gmtl::Quat<float>( 0, 0.173648f, 0, -0.984808f   ) );
      quats.push_back( gmtl::Quat<float>( -0, 0, -0, -1    ) );

      /// @todo check this against another math lib other than VR Juggler...
      int count = 0;
      for (int x = -360; x <= 360; x += 20)
      {
         gmtl::Quat<float> q3;
         CPPUNIT_ASSERT( count >= 0 );
         gmtl::set( q2, gmtl::AxisAnglef( gmtl::Math::deg2Rad( float(x) ), 0.0f, 1.0f, 0.0f ) );
         gmtl::set( q3, gmtl::AxisAnglef( gmtl::Math::deg2Rad( float(x) ), gmtl::Vec3f( 0.0f, 1.0f, 0.0f ) ) );
         CPPUNIT_ASSERT( gmtl::isEqual( quats[count], q2, eps ) );
         CPPUNIT_ASSERT( gmtl::isEqual( q3, q2, eps ) );

         // make sure that makeRot and setRot do the same thing...
         CPPUNIT_ASSERT( gmtl::make<gmtl::Quat<float> >( gmtl::AxisAnglef( gmtl::Math::deg2Rad( float(x) ), 0.0f, 1.0f, 0.0f ) ) == q2 );
         CPPUNIT_ASSERT( gmtl::make<gmtl::Quat<float> >( gmtl::AxisAnglef( gmtl::Math::deg2Rad( float(x) ), gmtl::Vec3f( 0.0f, 1.0f, 0.0f ) ) ) == q3 );
         count++;
      }

   }
   void QuatOpsTest::testQuatSlerp()
   {
      const float eps = 0.0001f;
      gmtl::Quat<float> q1( 100, 2, 3, 4 ), q2( 9.01f, 8.4f, 7.1f, 6 );
      gmtl::normalize( q1 ); // make sure they are valid rotation quaternions
      gmtl::normalize( q2 );
      gmtl::Quat<float> expected_result1( q1 ), res1;
      gmtl::Quat<float> expected_result2( q2 ), res2;

      gmtl::slerp( res1, 0.0f, q1, q2 );
      gmtl::slerp( res2, 1.0f, q1, q2 );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result1, res1, eps ) );
      CPPUNIT_ASSERT( gmtl::isEqual( expected_result2, res2, eps ) );

      /// test interpolated values...
      gmtl::Vec3f quadrant[8];
      quadrant[0].set(  1.0f,  1.0f,  1.0f );
      quadrant[1].set( -1.0f,  1.0f,  1.0f );
      quadrant[2].set( -1.0f,  1.0f, -1.0f );
      quadrant[3].set(  1.0f,  1.0f, -1.0f );
      quadrant[4].set(  1.0f, -1.0f, -1.0f );
      quadrant[5].set(  1.0f, -1.0f,  1.0f );
      quadrant[6].set( -1.0f, -1.0f,  1.0f );
      quadrant[7].set( -1.0f, -1.0f, -1.0f );

      //gmtl::Quatf expected_result0, expected_result180, expected_result90, expected_result_0001;

      // create one quat for each of the 8 quadrants...
      gmtl::Quatf q0[8], q180[8], q90[8], q_0001[8];
      for (unsigned int x = 0; x < 8; ++x)
      {
         gmtl::normalize( quadrant[x] );
         gmtl::setRot( q0[x],     gmtl::AxisAnglef( gmtl::Math::deg2Rad( 0.0f ),    quadrant[x] ) );
         gmtl::setRot( q180[x],   gmtl::AxisAnglef( gmtl::Math::deg2Rad( 180.0f ),  quadrant[x] ) );
         gmtl::setRot( q90[x],    gmtl::AxisAnglef( gmtl::Math::deg2Rad( 90.0f ),   quadrant[x] ) );
         gmtl::setRot( q_0001[x], gmtl::AxisAnglef( gmtl::Math::deg2Rad( 0.0001f ), quadrant[x] ) );

         /// @todo test these:

         // same yields same
         // gmtl::slerp( result, 0.0f, q0[x], q0[x] ); // yields q0
         // gmtl::slerp( result, 0.5f, q0[x], q0[x] ); // yields q0
         // gmtl::slerp( result, 1.0f, q0[x], q0[x] ); // yields q0

         // 180 deg - there is more than one valid path to take,
         // gmtl::slerp( result, 0.0f, q0[x], q180[x] ); // yields q0
         // gmtl::slerp( result, 0.5f, q0[x], q180[x] ); // not sure what to test here...
         // gmtl::slerp( result, 1.0f, q0[x], q180[x] ); // yields q180

         // 90 deg
         // gmtl::slerp( result, 0.0f, q0[x], q90[x] ); // yields q0
         // gmtl::slerp( result, 0.5f, q0[x], q90[x] ); // yields shortest path
         // gmtl::slerp( result, 1.0f, q0[x], q90[x] ); // yields q90

         // .0001 deg
         // gmtl::slerp( result, 0.0f, q0[x], q_0001[x] ); // yields q0
         // gmtl::slerp( result, 0.5f, q0[x], q_0001[x] ); // yields shortest path (very close to q0 or q_0001)
         // gmtl::slerp( result, 1.0f, q0[x], q_0001[x] ); // yields q_0001
      }

      /// @todo given 8 quadrants, (8 quats), test each quat against every other quat (56 total checks)
      //        note: might have to test with two different angled quats, not sure...
   }