END_TEST;
}
-int UtcDaliAnimationAnimateByActorOrientationP(void)
+int UtcDaliAnimationAnimateByActorOrientationP1(void)
{
TestApplication application;
END_TEST;
}
+int UtcDaliAnimationAnimateByActorOrientationP2(void)
+{
+ TestApplication application;
+
+ tet_printf("Testing that rotation angle > 360 performs full rotations\n");
+
+ Actor actor = Actor::New();
+ actor.SetOrientation( Quaternion( Dali::ANGLE_0, Vector3::ZAXIS ) );
+ Stage::GetCurrent().Add(actor);
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion( Dali::ANGLE_0, Vector3::ZAXIS ), ROTATION_EPSILON, TEST_LOCATION );
+
+ // Build the animation
+ float durationSeconds(1.0f);
+ Animation animation = Animation::New(durationSeconds);
+ Degree relativeRotationDegrees(710.0f);
+ Radian relativeRotationRadians(relativeRotationDegrees);
+
+ animation.AnimateBy( Property( actor, Actor::Property::ORIENTATION ), AngleAxis( relativeRotationRadians, Vector3::ZAXIS ) );
+
+ // Start the animation
+ animation.Play();
+
+ bool signalReceived(false);
+ AnimationFinishCheck finishCheck(signalReceived);
+ animation.FinishedSignal().Connect(&application, finishCheck);
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
+
+ // We didn't expect the animation to finish yet
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(relativeRotationRadians * 0.25f, Vector3::ZAXIS), ROTATION_EPSILON, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
+
+ // We didn't expect the animation to finish yet
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(relativeRotationRadians * 0.5f, Vector3::ZAXIS), ROTATION_EPSILON, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
+
+ // We didn't expect the animation to finish yet
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(relativeRotationRadians * 0.75f, Vector3::ZAXIS), ROTATION_EPSILON, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds*250.0f) + 1u/*just beyond the animation duration*/);
+
+ // We did expect the animation to finish
+ application.SendNotification();
+ finishCheck.CheckSignalReceived();
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(relativeRotationRadians, Vector3::ZAXIS), ROTATION_EPSILON, TEST_LOCATION );
+ END_TEST;
+}
+
+
+int UtcDaliAnimationAnimateByActorOrientationP3(void)
+{
+ TestApplication application;
+
+ tet_printf("Testing that rotation angle > 360 performs partial rotations when cast to Quaternion\n");
+
+ Actor actor = Actor::New();
+ actor.SetOrientation( Quaternion( Dali::ANGLE_0, Vector3::ZAXIS ) );
+ Stage::GetCurrent().Add(actor);
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion( Dali::ANGLE_0, Vector3::ZAXIS ), ROTATION_EPSILON, TEST_LOCATION );
+
+ // Build the animation
+ float durationSeconds(1.0f);
+ Animation animation = Animation::New(durationSeconds);
+ Degree relativeRotationDegrees(730.0f);
+ Radian relativeRotationRadians(relativeRotationDegrees);
+
+ Radian actualRotationRadians( Degree(10.0f) );
+
+ animation.AnimateBy( Property( actor, Actor::Property::ORIENTATION ), Quaternion( relativeRotationRadians, Vector3::ZAXIS ) );
+
+ // Start the animation
+ animation.Play();
+
+ bool signalReceived(false);
+ AnimationFinishCheck finishCheck(signalReceived);
+ animation.FinishedSignal().Connect(&application, finishCheck);
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
+
+ // We didn't expect the animation to finish yet
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(actualRotationRadians * 0.25f, Vector3::ZAXIS), ROTATION_EPSILON, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
+
+ // We didn't expect the animation to finish yet
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(actualRotationRadians * 0.5f, Vector3::ZAXIS), ROTATION_EPSILON, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
+
+ // We didn't expect the animation to finish yet
+ application.SendNotification();
+ finishCheck.CheckSignalNotReceived();
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(actualRotationRadians * 0.75f, Vector3::ZAXIS), ROTATION_EPSILON, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render(static_cast<unsigned int>(durationSeconds*250.0f) + 1u/*just beyond the animation duration*/);
+
+ // We did expect the animation to finish
+ application.SendNotification();
+ finishCheck.CheckSignalReceived();
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(actualRotationRadians, Vector3::ZAXIS), ROTATION_EPSILON, TEST_LOCATION );
+ DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(relativeRotationRadians, Vector3::ZAXIS), ROTATION_EPSILON, TEST_LOCATION );
+ END_TEST;
+}
+
+
int UtcDaliAnimationAnimateByActorOrientationAlphaFunctionP(void)
{
TestApplication application;
int UtcDaliPropertyValueConstructorsQuaternionP(void)
{
- Quaternion v( Vector4(1.0,1.0,1.0,1.0) );
+ Quaternion v( Radian( Math::PI ), Vector3::ZAXIS );
Property::Value value(v);
DALI_TEST_CHECK( value.GetType() == Property::ROTATION );
- DALI_TEST_CHECK( value.Get<Quaternion>() == v );
+ DALI_TEST_EQUALS( v, value.Get<Quaternion>(), 0.001, TEST_LOCATION);
END_TEST;
}
int UtcDaliPropertyValueAssignmentOperatorQuaternionP(void)
{
Property::Value value;
- value = Property::Value( Quaternion(1,1,1,1) ); // mismatch
- DALI_TEST_CHECK( Quaternion(1,1,1,1) == value.Get<Quaternion>() );
+ Quaternion result( Radian( Math::PI_2 ), Vector3::YAXIS );
+ value = Property::Value( result );
+
+ DALI_TEST_EQUALS( value.Get<Quaternion>(), result, 0.001, TEST_LOCATION );
+
Property::Value copy( Property::ROTATION );
copy = value; // match
- DALI_TEST_CHECK( Quaternion(1,1,1,1) == copy.Get<Quaternion>() );
+ DALI_TEST_EQUALS( copy.Get<Quaternion>(), result, 0.001, TEST_LOCATION );
END_TEST;
}
int UtcDaliPropertyValueGetQuaternionP(void)
{
- Property::Value value( Quaternion(1.f,2.f,3.f,4.f) );
- Quaternion result;
- DALI_TEST_EQUALS( Quaternion(1.f,2.f,3.f,4.f), value.Get< Quaternion >(), TEST_LOCATION );
- DALI_TEST_EQUALS( true, value.Get( result ), TEST_LOCATION );
- DALI_TEST_EQUALS( Quaternion(1.f,2.f,3.f,4.f), result, TEST_LOCATION );
+ Vector3 axis(1, 1, 0);
+ axis.Normalize();
+
+ Quaternion result( Radian( 1.f ), axis );
+ Property::Value value( result );
+
+ DALI_TEST_EQUALS( result, value.Get< Quaternion >(), TEST_LOCATION );
+ Quaternion test2;
+ DALI_TEST_EQUALS( true, value.Get( test2 ), TEST_LOCATION );
END_TEST;
}
int UtcDaliPropertyValueGetQuaternionN(void)
{
Property::Value value;
- Quaternion result(1.f,2.f,3.f,4.f);
+ Vector3 axis(1, 1, 0);
+ axis.Normalize();
+ Quaternion result( Radian( 1.f ), axis );
+ Quaternion test(result);
+
DALI_TEST_EQUALS( Quaternion(), value.Get< Quaternion >(), TEST_LOCATION );
- DALI_TEST_EQUALS( false, value.Get( result ), TEST_LOCATION );
- DALI_TEST_EQUALS( Quaternion(1.f,2.f,3.f,4.f), result, TEST_LOCATION );
+ DALI_TEST_EQUALS( false, value.Get( test ), TEST_LOCATION );
+ DALI_TEST_EQUALS( test, result, TEST_LOCATION );
Property::Value value2("");
- DALI_TEST_EQUALS( false, value2.Get( result ), TEST_LOCATION );
- DALI_TEST_EQUALS( Quaternion(1.f,2.f,3.f,4.f), result, TEST_LOCATION );
+ DALI_TEST_EQUALS( false, value2.Get( test ), TEST_LOCATION );
+ DALI_TEST_EQUALS( test, result, TEST_LOCATION );
END_TEST;
}
*
*/
+// EXTERNAL INCLUDES
+#include <iosfwd>
+#include <ostream>
+
// INTERNAL INCLUDES
#include <dali/public-api/math/radian.h>
#include <dali/public-api/math/vector3.h>
}
/**
+ * @brief Print an angle axis
+ *
+ * @SINCE_1_1.33
+ * @param [in] o The output stream operator.
+ * @param [in] angleAxis The angle axis to print
+ * @return The output stream operator.
+ */
+inline std::ostream& operator<< (std::ostream& o, const Dali::AngleAxis& angleAxis)
+{
+ return o << "[ Axis: [" << angleAxis.axis.x << ", " << angleAxis.axis.y << ", " << angleAxis.axis.z << "], Angle: " << Degree( angleAxis.angle ).degree << " degrees ]";
+}
+
+/**
* @}
*/
} // namespace Dali
Impl( const AngleAxis& angleAxisValue )
: type( Property::ROTATION ),
- quaternionValue( new Quaternion( angleAxisValue.angle, angleAxisValue.axis ) )
+ angleAxisValue( new AngleAxis(angleAxisValue) )
{
}
Impl( const Quaternion& quaternionValue )
: type( Property::ROTATION ),
- quaternionValue( new Quaternion( quaternionValue ) )
+ angleAxisValue( new AngleAxis() )
{
+ quaternionValue.ToAxisAngle( angleAxisValue->axis, angleAxisValue->angle );
}
Impl(const std::string& stringValue)
}
case Property::ROTATION:
{
- delete quaternionValue;
+ delete angleAxisValue;
break;
}
case Property::STRING:
Vector4* vector4Value;
Matrix3* matrix3Value;
Matrix* matrixValue;
- Quaternion* quaternionValue;
+ AngleAxis* angleAxisValue;
std::string* stringValue;
Rect<int>* rectValue;
Property::Array* arrayValue;
}
case Property::ROTATION:
{
- mImpl = new Impl( Quaternion() );
+ mImpl = new Impl( AngleAxis() );
break;
}
case Property::STRING:
}
case Property::ROTATION:
{
- *mImpl->quaternionValue = *value.mImpl->quaternionValue; // type cannot change in mImpl so quaternion is allocated
+ *mImpl->angleAxisValue = *value.mImpl->angleAxisValue; // type cannot change in mImpl so quaternion is allocated
break;
}
case Property::STRING:
}
case Property::ROTATION:
{
- newImpl = new Impl( *value.mImpl->quaternionValue ); // type cannot change in mImpl so quaternion is allocated
+ newImpl = new Impl( *value.mImpl->angleAxisValue ); // type cannot change in mImpl so quaternion is allocated
break;
}
case Property::MATRIX3:
bool Property::Value::Get( AngleAxis& angleAxisValue ) const
{
bool converted = false;
- if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so quaternion is allocated
+ if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so angleAxis is allocated
{
- mImpl->quaternionValue->ToAxisAngle( angleAxisValue.axis, angleAxisValue.angle );
+ angleAxisValue = *(mImpl->angleAxisValue);
converted = true;
}
return converted;
bool Property::Value::Get( Quaternion& quaternionValue ) const
{
bool converted = false;
- if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so quaternion is allocated
+ if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so angleAxis is allocated
{
- quaternionValue = *(mImpl->quaternionValue);
+ quaternionValue = Quaternion(mImpl->angleAxisValue->angle, mImpl->angleAxisValue->axis );
converted = true;
}
return converted;
}
case Dali::Property::ROTATION:
{
- stream << *impl.quaternionValue;
+ stream << *impl.angleAxisValue;
break;
}
case Dali::Property::STRING: