Add an ISceneNodeAnimator::hasFinished() method. It can only return true for non-looping delete, fly straight and texture animators.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1980 dfc29bdd-3216-0410-991c-e03cc46cb475
master
Rogerborg 2008-12-19 23:21:26 +00:00
parent baa858b66c
commit 04a344c75d
14 changed files with 150 additions and 89 deletions

View File

@ -1,5 +1,7 @@
Changes in version 1.6
- ISceneNodeAnimator now has a hasFinished() method.
- ISceneNodeAnimatorCollisionResponse exposes the target node. Setting the node again resets the last position, allowing the node to be teleported.
- Add a hitPosition out parameter to ISceneCollisionManager::getCollisionResultPosition() - this is a (small) API breaking change.

View File

@ -64,6 +64,14 @@ namespace scene
{
return ESNAT_UNKNOWN;
}
//! Returns if the animator has finished.
/** This is only valid for non-looping animators with a discrete end state.
\return true if the animator has finished, false if it is still running. */
virtual bool hasFinished(void) const
{
return false;
}
};

View File

@ -13,7 +13,7 @@ namespace scene
//! constructor
CSceneNodeAnimatorDelete::CSceneNodeAnimatorDelete(ISceneManager* manager, u32 time)
: DeleteTime(time), SceneManager(manager)
: ISceneNodeAnimatorFinishing(time), SceneManager(manager)
{
#ifdef _DEBUG
setDebugName("CSceneNodeAnimatorDelete");
@ -32,18 +32,22 @@ CSceneNodeAnimatorDelete::~CSceneNodeAnimatorDelete()
//! animates a scene node
void CSceneNodeAnimatorDelete::animateNode(ISceneNode* node, u32 timeMs)
{
if (timeMs > DeleteTime && node && SceneManager)
if (timeMs > FinishTime)
{
// don't delete if scene manager is attached to an editor
if (!SceneManager->getParameters()->getAttributeAsBool(IRR_SCENE_MANAGER_IS_EDITOR))
SceneManager->addToDeletionQueue(node);
HasFinished = true;
if(node && SceneManager)
{
// don't delete if scene manager is attached to an editor
if (!SceneManager->getParameters()->getAttributeAsBool(IRR_SCENE_MANAGER_IS_EDITOR))
SceneManager->addToDeletionQueue(node);
}
}
}
ISceneNodeAnimator* CSceneNodeAnimatorDelete::createClone(ISceneNode* node, ISceneManager* newManager)
{
CSceneNodeAnimatorDelete * newAnimator =
new CSceneNodeAnimatorDelete(SceneManager, DeleteTime);
new CSceneNodeAnimatorDelete(SceneManager, FinishTime);
return newAnimator;
}

View File

@ -5,13 +5,13 @@
#ifndef __C_SCENE_NODE_ANIMATOR_DELETE_H_INCLUDED__
#define __C_SCENE_NODE_ANIMATOR_DELETE_H_INCLUDED__
#include "ISceneNode.h"
#include "ISceneNodeAnimatorFinishing.h"
namespace irr
{
namespace scene
{
class CSceneNodeAnimatorDelete : public ISceneNodeAnimator
class CSceneNodeAnimatorDelete : public ISceneNodeAnimatorFinishing
{
public:
@ -38,7 +38,6 @@ namespace scene
private:
u32 DeleteTime;
ISceneManager* SceneManager;
};

View File

@ -14,17 +14,19 @@ namespace scene
CSceneNodeAnimatorFlyStraight::CSceneNodeAnimatorFlyStraight(const core::vector3df& startPoint,
const core::vector3df& endPoint, u32 timeForWay,
bool loop, u32 now)
: Start(startPoint), End(endPoint), WayLength(0.0f), TimeFactor(0.0f), StartTime(now), TimeForWay(timeForWay), Loop(loop)
: ISceneNodeAnimatorFinishing(now + timeForWay),
Start(startPoint), End(endPoint), WayLength(0.0f),
TimeFactor(0.0f), StartTime(now), TimeForWay(timeForWay), Loop(loop)
{
#ifdef _DEBUG
setDebugName("CSceneNodeAnimatorFlyStraight");
#endif
recalculateImidiateValues();
recalculateIntermediateValues();
}
void CSceneNodeAnimatorFlyStraight::recalculateImidiateValues()
void CSceneNodeAnimatorFlyStraight::recalculateIntermediateValues()
{
Vector = End - Start;
WayLength = (f32)Vector.getLength();
@ -53,9 +55,15 @@ void CSceneNodeAnimatorFlyStraight::animateNode(ISceneNode* node, u32 timeMs)
core::vector3df pos = Start;
if (!Loop && t >= TimeForWay)
{
pos = End;
HasFinished = true;
}
else
{
pos += Vector * (f32)fmod((f32)t, (f32)TimeForWay) * TimeFactor;
}
node->setPosition(pos);
}
@ -78,7 +86,7 @@ void CSceneNodeAnimatorFlyStraight::deserializeAttributes(io::IAttributes* in, i
TimeForWay = in->getAttributeAsInt("TimeForWay");
Loop = in->getAttributeAsBool("Loop");
recalculateImidiateValues();
recalculateIntermediateValues();
}
ISceneNodeAnimator* CSceneNodeAnimatorFlyStraight::createClone(ISceneNode* node, ISceneManager* newManager)

View File

@ -5,13 +5,13 @@
#ifndef __C_SCENE_NODE_ANIMATOR_FLY_STRAIGHT_H_INCLUDED__
#define __C_SCENE_NODE_ANIMATOR_FLY_STRAIGHT_H_INCLUDED__
#include "ISceneNode.h"
#include "ISceneNodeAnimatorFinishing.h"
namespace irr
{
namespace scene
{
class CSceneNodeAnimatorFlyStraight : public ISceneNodeAnimator
class CSceneNodeAnimatorFlyStraight : public ISceneNodeAnimatorFinishing
{
public:
@ -44,7 +44,7 @@ namespace scene
private:
void recalculateImidiateValues();
void recalculateIntermediateValues();
core::vector3df Start;
core::vector3df End;

View File

@ -14,7 +14,8 @@ namespace scene
//! constructor
CSceneNodeAnimatorTexture::CSceneNodeAnimatorTexture(const core::array<video::ITexture*>& textures,
s32 timePerFrame, bool loop, u32 now)
: TimePerFrame(timePerFrame), StartTime(now), Loop(loop)
: ISceneNodeAnimatorFinishing(0),
TimePerFrame(timePerFrame), StartTime(now), Loop(loop)
{
#ifdef _DEBUG
setDebugName("CSceneNodeAnimatorTexture");
@ -28,7 +29,7 @@ CSceneNodeAnimatorTexture::CSceneNodeAnimatorTexture(const core::array<video::IT
Textures.push_back(textures[i]);
}
EndTime = now + (timePerFrame * Textures.size());
FinishTime = now + (timePerFrame * Textures.size());
}
@ -61,10 +62,15 @@ void CSceneNodeAnimatorTexture::animateNode(ISceneNode* node, u32 timeMs)
const u32 t = (timeMs-StartTime);
u32 idx = 0;
if (!Loop && timeMs >= EndTime)
if (!Loop && timeMs >= FinishTime)
{
idx = Textures.size() - 1;
HasFinished = true;
}
else
{
idx = (t/TimePerFrame) % Textures.size();
}
if (idx < Textures.size())
node->setMaterialTexture(0, Textures[idx]);

View File

@ -6,13 +6,13 @@
#define __C_SCENE_NODE_ANIMATOR_TEXTURE_H_INCLUDED__
#include "irrArray.h"
#include "ISceneNode.h"
#include "ISceneNodeAnimatorFinishing.h"
namespace irr
{
namespace scene
{
class CSceneNodeAnimatorTexture : public ISceneNodeAnimator
class CSceneNodeAnimatorTexture : public ISceneNodeAnimatorFinishing
{
public:
@ -48,7 +48,6 @@ namespace scene
core::array<video::ITexture*> Textures;
u32 TimePerFrame;
u32 StartTime;
u32 EndTime;
bool Loop;
};

View File

@ -0,0 +1,42 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __I_SCENE_NODE_ANIMATOR_FINISHING_H_INCLUDED__
#define __I_SCENE_NODE_ANIMATOR_FINISHING_H_INCLUDED__
#include "ISceneNode.h"
namespace irr
{
namespace scene
{
//! This is an abstract base class for animators that have a discrete end time.
class ISceneNodeAnimatorFinishing : public ISceneNodeAnimator
{
public:
//! constructor
ISceneNodeAnimatorFinishing(u32 finishTime)
: HasFinished(false), FinishTime(finishTime) { }
//! destructor
virtual ~ISceneNodeAnimatorFinishing() { }
//! This is a pure virtual class, so it can't be cloned directly.
virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0) = 0;
virtual bool hasFinished(void) const { return HasFinished; }
protected:
u32 FinishTime;
bool HasFinished;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -5,6 +5,7 @@
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <vector>
// This is an MSVC pragma to link against the Irrlicht library.
// Other builds must link against it in the project files.
@ -12,21 +13,11 @@
#pragma comment(lib, "Irrlicht.lib")
#endif // _MSC_VER
/* Each test must have the same signature. Test should (but are not
* required to) live in a .cpp file of the same name. There is no
* need to #include anything since the test entry points can be
* declared as extern before calling them.
*/
#define RUN_TEST(testEntryPoint)\
extern bool testEntryPoint(void);\
logTestString("\nStarting test '" #testEntryPoint "'\n");\
if(!testEntryPoint()) \
{\
(void)printf("\n\n\n******** Test failure ********\nTest '" #testEntryPoint "' failed\n"\
"******** Test failure ********\n\nPress return to continue\n");\
(void)getc(stdin);\
fails++;\
}
typedef struct _STestDefinition
{
bool(*testSignature)(void);
const char * testName;
} STestDefinition;
//! This is the main entry point for the Irrlicht test suite.
/** \return The number of test that failed, i.e. 0 is success. */
@ -42,50 +33,38 @@ int main(int argumentCount, char * arguments[])
return 9999;
}
extern bool disambiguateTextures(void);
extern bool softwareDevice(void);
extern bool exports(void);
extern bool testVector3d(void);
extern bool testVector2d(void);
extern bool planeMatrix(void);
extern bool fast_atof(void);
extern bool line2dIntersectWith(void);
extern bool drawPixel(void);
extern bool md2Animation(void);
extern bool b3dAnimation(void);
extern bool guiDisabledMenu(void);
extern bool collisionResponseAnimator(void);
extern bool sceneCollisionManager(void);
typedef struct _STest
{
bool(*testSignature)(void);
const char * testName;
} STest;
#define TEST(x)\
{\
extern bool x(void);\
STestDefinition newTest;\
newTest.testSignature = x;\
newTest.testName = #x;\
tests.push_back(newTest);\
}
#define TEST(x) { x, #x }
std::vector<STestDefinition> tests;
static const STest tests[] =
{
// Note that to interactively debug a test, you will generally want to move it
// (temporarily) to the beginning of the list, since each test runs in its own
// process.
TEST(disambiguateTextures), // Normally you should run this first, since it validates the working directory.
TEST(sceneCollisionManager),
TEST(collisionResponseAnimator),
TEST(exports),
TEST(testVector3d),
TEST(testVector2d),
TEST(planeMatrix),
TEST(fast_atof),
TEST(line2dIntersectWith),
TEST(drawPixel),
TEST(md2Animation),
TEST(guiDisabledMenu),
TEST(softwareDevice),
TEST(b3dAnimation)
};
static const unsigned int numberOfTests = sizeof tests / sizeof tests[0];
// Note that to interactively debug a test, you will generally want to move it
// (temporarily) to the beginning of the list, since each test runs in its own
// process.
TEST(disambiguateTextures); // Normally you should run this first, since it validates the working directory.
TEST(sceneNodeAnimator);
TEST(sceneCollisionManager);
TEST(collisionResponseAnimator);
TEST(exports);
TEST(testVector3d);
TEST(testVector2d);
TEST(planeMatrix);
TEST(fast_atof);
TEST(line2dIntersectWith);
TEST(drawPixel);
TEST(md2Animation);
TEST(guiDisabledMenu);
TEST(softwareDevice);
TEST(b3dAnimation);
const unsigned int numberOfTests = tests.size();
unsigned int testToRun = 0;
unsigned int fails = 0;
@ -119,10 +98,22 @@ int main(int argumentCount, char * arguments[])
}
testToRun++;
if(testToRun == numberOfTests)
if(testToRun < numberOfTests)
{
logTestString("\nTests finished. %d test%s failed.\n", fails, 1 == fails ? "" : "s");
closeTestLog();
char runNextTest[256];
(void)sprintf(runNextTest, "%s %d %d", arguments[0], testToRun, fails);
fails = system(runNextTest);
}
if(1 == testToRun)
{
(void)openTestLog(false);
const int passed = numberOfTests - fails;
logTestString("\nTests finished. %d test%s of %d passed.\n",
passed, 1 == passed ? "" : "s", numberOfTests);
if(0 == fails)
{
time_t rawtime;
@ -139,13 +130,6 @@ int main(int argumentCount, char * arguments[])
}
closeTestLog();
}
else
{
closeTestLog();
char runNextTest[256];
(void)sprintf(runNextTest, "%s %d %d", arguments[0], testToRun, fails);
fails = system(runNextTest);
}
return fails;
}

View File

@ -1,2 +1,2 @@
Test suite pass at GMT Fri Dec 19 11:49:34 2008
Test suite pass at GMT Fri Dec 19 23:15:53 2008

View File

@ -49,6 +49,7 @@
<Unit filename="md2Animation.cpp" />
<Unit filename="planeMatrix.cpp" />
<Unit filename="sceneCollisionManager.cpp" />
<Unit filename="sceneNodeAnimator.cpp" />
<Unit filename="softwareDevice.cpp" />
<Unit filename="testUtils.cpp" />
<Unit filename="testVector2d.cpp" />

View File

@ -217,6 +217,10 @@
RelativePath=".\sceneCollisionManager.cpp"
>
</File>
<File
RelativePath=".\sceneNodeAnimator.cpp"
>
</File>
<File
RelativePath=".\softwareDevice.cpp"
>

View File

@ -213,6 +213,10 @@
RelativePath=".\sceneCollisionManager.cpp"
>
</File>
<File
RelativePath=".\sceneNodeAnimator.cpp"
>
</File>
<File
RelativePath=".\softwareDevice.cpp"
>