diff --git a/changes.txt b/changes.txt index de35a1df..ea8809ca 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,7 @@ Changes in version 1.6 + - Added an startPosition parameter to createFlyCircleAnimator() to allow starting the animator at any position on the circle. + - Many uses of dimension2d changed to dimension2d, including IImage, ITexture and screen dimensions. You will have to change (at least) createDevice() calls to use dimension2d - Added IFileSystem::createMemoryWriteFile() to allow creation of an IWriteFile interface that uses an application supplied memory buffer. diff --git a/include/ISceneManager.h b/include/ISceneManager.h index 3b724bba..5058643a 100644 --- a/include/ISceneManager.h +++ b/include/ISceneManager.h @@ -1039,6 +1039,8 @@ namespace scene \param radius: Radius of the circle. \param speed: The orbital speed, in radians per millisecond. \param direction: Specifies the upvector used for alignment of the mesh. + \param startPosition: The position on the circle where the animator will + begin. Value is in multiples of a circle, i.e. 0.5 is half way around. \return The animator. Attach it to a scene node with ISceneNode::addAnimator() and the animator will animate it. If you no longer need the animator, you should call ISceneNodeAnimator::drop(). @@ -1046,7 +1048,8 @@ namespace scene virtual ISceneNodeAnimator* createFlyCircleAnimator( const core::vector3df& center=core::vector3df(0.f,0.f,0.f), f32 radius=100.f, f32 speed=0.001f, - const core::vector3df& direction=core::vector3df(0.f, 1.f, 0.f)) = 0; + const core::vector3df& direction=core::vector3df(0.f, 1.f, 0.f), + f32 startPosition = 0.f) = 0; //! Creates a fly straight animator, which lets the attached scene node fly or move along a line between two points. /** \param startPoint: Start point of the line. diff --git a/source/Irrlicht/CSceneManager.cpp b/source/Irrlicht/CSceneManager.cpp index 604e7579..50483e75 100644 --- a/source/Irrlicht/CSceneManager.cpp +++ b/source/Irrlicht/CSceneManager.cpp @@ -1521,10 +1521,14 @@ ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df& //! creates a fly circle animator, which lets the attached scene node fly around a center. ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator( const core::vector3df& center, f32 radius, f32 speed, - const core::vector3df& direction) + const core::vector3df& direction, + f32 startPosition) { + const f32 orbitDurationMs = (core::DEGTORAD * 360.f) / speed; + u32 effectiveTime = os::Timer::getTime() + (u32)(orbitDurationMs * startPosition); + ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyCircle( - os::Timer::getTime(), center, + effectiveTime, center, radius, speed, direction); return anim; } diff --git a/source/Irrlicht/CSceneManager.h b/source/Irrlicht/CSceneManager.h index 91e7d164..04256e54 100644 --- a/source/Irrlicht/CSceneManager.h +++ b/source/Irrlicht/CSceneManager.h @@ -281,13 +281,17 @@ namespace scene //! creates a fly circle animator /** Lets the attached scene node fly around a center. \param center Center relative to node origin - \param speed rotation speed - \return Animator. Attach it to a scene node with ISceneNode::addAnimator() - and the animator will animate it. */ + \param speed: The orbital speed, in radians per millisecond. + \param direction: Specifies the upvector used for alignment of the mesh. + \param startPosition: The position on the circle where the animator will + begin. Value is in multiples of a circle, i.e. 0.5 is half way around. + \return The animator. Attach it to a scene node with ISceneNode::addAnimator() + */ virtual ISceneNodeAnimator* createFlyCircleAnimator( const core::vector3df& center=core::vector3df(0.f, 0.f, 0.f), f32 radius=100.f, f32 speed=0.001f, - const core::vector3df& direction=core::vector3df(0.f, 1.f, 0.f)); + const core::vector3df& direction=core::vector3df(0.f, 1.f, 0.f), + f32 startPosition = 0.f); //! Creates a fly straight animator, which lets the attached scene node //! fly or move along a line between two points. diff --git a/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp b/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp index 2276f570..8c7d397d 100644 --- a/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp @@ -38,9 +38,15 @@ void CSceneNodeAnimatorFlyCircle::animateNode(ISceneNode* node, u32 timeMs) if ( 0 == node ) return; - const f32 t = (timeMs-StartTime) * Speed; + f32 time; - node->setPosition(Center + Radius * ((VecU*cosf(t)) + (VecV*sinf(t)))); + // Check for the condition where the StartTime is in the future. + if(StartTime > timeMs) + time = ((s32)timeMs - (s32)StartTime) * Speed; + else + time = (timeMs-StartTime) * Speed; + + node->setPosition(Center + Radius * ((VecU*cosf(time)) + (VecV*sinf(time)))); } diff --git a/tests/flyCircleAnimator.cpp b/tests/flyCircleAnimator.cpp new file mode 100644 index 00000000..ebc73830 --- /dev/null +++ b/tests/flyCircleAnimator.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2008-2009 Colin MacDonald +// No rights reserved: this software is in the public domain. + +#include "testUtils.h" +#include "irrlicht.h" + +using namespace irr; +using namespace core; +using namespace scene; +using namespace video; + +/** Tests the offset capability of the fly circle animator */ +bool flyCircleAnimator(void) +{ + IrrlichtDevice *device = createDevice(video::EDT_BURNINGSVIDEO, + core::dimension2du(160,120), 32); + if (!device) + return false; + + IVideoDriver* driver = device->getVideoDriver(); + ISceneManager* smgr = device->getSceneManager(); + + const f32 offsetDegrees[] = { 0.f, 45.f, 135.f, 270.f }; + + for(u32 i = 0; i < sizeof(offsetDegrees) / sizeof(offsetDegrees[0]); ++i) + { + IBillboardSceneNode * node = smgr->addBillboardSceneNode(); + // Have the animator rotate around the Z axis plane, rather than the default Y axis + ISceneNodeAnimator * animator = + smgr->createFlyCircleAnimator(vector3df(0, 0, 0), 30.f, + 0.001f, vector3df(0, 0, 1), + (offsetDegrees[i] / 360.f)); + if(!node || !animator) + return false; + + node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR ); + node->setMaterialTexture(0, driver->getTexture("../media/particle.bmp")); + node->setMaterialFlag(video::EMF_LIGHTING, false); + + node->addAnimator(animator); + animator->drop(); + } + + (void)smgr->addCameraSceneNode(0, vector3df(0, 0, -50), vector3df(0, 0, 0)); + + bool result = false; + + // Don't do device->run() since I need the time to remain at 0. + if (driver->beginScene(true, true, video::SColor(0, 80, 80, 80))) + { + smgr->drawAll(); + driver->endScene(); + result = takeScreenshotAndCompareAgainstReference(driver, "-flyCircleAnimator.png", 100); + } + + device->drop(); + + return result; +} diff --git a/tests/main.cpp b/tests/main.cpp index 124b49b5..2763dd16 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -87,6 +87,7 @@ int main(int argumentCount, char * arguments[]) TEST(sceneNodeAnimator); TEST(vectorPositionDimension2d); TEST(writeImageToFile); + TEST(flyCircleAnimator); const unsigned int numberOfTests = tests.size(); diff --git a/tests/media/burnings video 0.39b-flyCircleAnimator.png b/tests/media/burnings video 0.39b-flyCircleAnimator.png new file mode 100644 index 00000000..7ce78dc5 Binary files /dev/null and b/tests/media/burnings video 0.39b-flyCircleAnimator.png differ diff --git a/tests/tests-last-passed-at.txt b/tests/tests-last-passed-at.txt index 1da546c1..8a786578 100644 --- a/tests/tests-last-passed-at.txt +++ b/tests/tests-last-passed-at.txt @@ -1,2 +1,2 @@ -Test suite pass at GMT Mon Jan 19 13:42:16 2009 +Test suite pass at GMT Tue Jan 20 12:53:02 2009 diff --git a/tests/tests.cbp b/tests/tests.cbp index f091d3b2..b0fbe233 100644 --- a/tests/tests.cbp +++ b/tests/tests.cbp @@ -46,6 +46,7 @@ + diff --git a/tests/tests_vc8.vcproj b/tests/tests_vc8.vcproj index 0e8a7b7b..73c7ccc8 100644 --- a/tests/tests_vc8.vcproj +++ b/tests/tests_vc8.vcproj @@ -205,6 +205,10 @@ RelativePath=".\fast_atof.cpp" > + + diff --git a/tests/tests_vc9.vcproj b/tests/tests_vc9.vcproj index b6f4c51b..6864e157 100644 --- a/tests/tests_vc9.vcproj +++ b/tests/tests_vc9.vcproj @@ -203,6 +203,10 @@ RelativePath=".\fast_atof.cpp" > + + diff --git a/tests/transparentAlphaChannelRef.cpp b/tests/transparentAlphaChannelRef.cpp index 1f259883..78cc75e3 100644 --- a/tests/transparentAlphaChannelRef.cpp +++ b/tests/transparentAlphaChannelRef.cpp @@ -40,7 +40,7 @@ bool testWithDriver(video::E_DRIVER_TYPE driverType) smgr->drawAll(); driver->endScene(); - bool result = takeScreenshotAndCompareAgainstReference(driver, "-transparentAlphaChannelRef.png", 99.88); + bool result = takeScreenshotAndCompareAgainstReference(driver, "-transparentAlphaChannelRef.png", 99.88f); device->drop();