Commit 622bd16b authored by cutealien's avatar cutealien

SceneNodeAnimatorFollowSpline can now loop and pingpong.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2966 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 3d4ff2a6
Changes in 1.7 Changes in 1.7
- SceneNodeAnimatorFollowSpline can now loop and pingpong
- Meshviewer.example got some fast-scale buttons.
- Support AES-encrypted zip files. Should work with 128, 196, and 256 bit AES. This addition also adds a new PRNG, SHA, and other algorithms to the engine, though no interface is yet added for them. The implementation of the encryption algorithms is provided by Dr Brian Gladman. - Support AES-encrypted zip files. Should work with 128, 196, and 256 bit AES. This addition also adds a new PRNG, SHA, and other algorithms to the engine, though no interface is yet added for them. The implementation of the encryption algorithms is provided by Dr Brian Gladman.
- Added geometry shaders for OpenGL. A first version of the code was submitted by Matthew Kielan (devsh). - Added geometry shaders for OpenGL. A first version of the code was submitted by Matthew Kielan (devsh).
......
...@@ -1188,7 +1188,7 @@ namespace scene ...@@ -1188,7 +1188,7 @@ namespace scene
See IReferenceCounted::drop() for more information. */ See IReferenceCounted::drop() for more information. */
virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
const core::array< core::vector3df >& points, const core::array< core::vector3df >& points,
f32 speed = 1.0f, f32 tightness = 0.5f) = 0; f32 speed = 1.0f, f32 tightness = 0.5f, bool loop=true, bool pingpong=false) = 0;
//! Creates a simple ITriangleSelector, based on a mesh. //! Creates a simple ITriangleSelector, based on a mesh.
/** Triangle selectors /** Triangle selectors
......
...@@ -1685,10 +1685,10 @@ ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnima ...@@ -1685,10 +1685,10 @@ ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnima
//! Creates a follow spline animator. //! Creates a follow spline animator.
ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime, ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime,
const core::array< core::vector3df >& points, const core::array< core::vector3df >& points,
f32 speed, f32 tightness) f32 speed, f32 tightness, bool loop, bool pingpong)
{ {
ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points, ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points,
speed, tightness); speed, tightness, loop, pingpong);
return a; return a;
} }
......
...@@ -337,7 +337,7 @@ namespace scene ...@@ -337,7 +337,7 @@ namespace scene
//! Creates a follow spline animator. //! Creates a follow spline animator.
virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
const core::array< core::vector3df >& points, const core::array< core::vector3df >& points,
f32 speed = 1.0f, f32 tightness = 0.5f); f32 speed, f32 tightness, bool loop, bool pingpong);
//! Creates a simple ITriangleSelector, based on a mesh. //! Creates a simple ITriangleSelector, based on a mesh.
......
...@@ -13,8 +13,9 @@ namespace scene ...@@ -13,8 +13,9 @@ namespace scene
//! constructor //! constructor
CSceneNodeAnimatorFollowSpline::CSceneNodeAnimatorFollowSpline(u32 time, CSceneNodeAnimatorFollowSpline::CSceneNodeAnimatorFollowSpline(u32 time,
const core::array<core::vector3df>& points, f32 speed, const core::array<core::vector3df>& points, f32 speed,
f32 tightness) f32 tightness, bool loop, bool pingpong)
: Points(points), Speed(speed), Tightness(tightness), StartTime(time) : ISceneNodeAnimatorFinishing(0), Points(points), Speed(speed), Tightness(tightness), StartTime(time)
, Loop(loop), PingPong(pingpong)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CSceneNodeAnimatorFollowSpline"); setDebugName("CSceneNodeAnimatorFollowSpline");
...@@ -36,18 +37,37 @@ void CSceneNodeAnimatorFollowSpline::animateNode(ISceneNode* node, u32 timeMs) ...@@ -36,18 +37,37 @@ void CSceneNodeAnimatorFollowSpline::animateNode(ISceneNode* node, u32 timeMs)
const u32 pSize = Points.size(); const u32 pSize = Points.size();
if (pSize==0) if (pSize==0)
{
if ( !Loop )
HasFinished = true;
return; return;
}
if (pSize==1) if (pSize==1)
{ {
node->setPosition(Points[0]); if ( timeMs > StartTime )
{
node->setPosition(Points[0]);
if ( !Loop )
HasFinished = true;
}
return; return;
} }
const f32 dt = ( (timeMs-StartTime) * Speed * 0.001f ); const f32 dt = ( (timeMs-StartTime) * Speed * 0.001f );
const f32 u = core::fract ( dt ); const s32 unwrappedIdx = core::floor32( dt );
const s32 idx = core::floor32( dt ) % pSize; if ( !Loop && unwrappedIdx >= (s32)pSize-1 )
{
node->setPosition(Points[pSize-1]);
HasFinished = true;
return;
}
const bool pong = PingPong && (unwrappedIdx/(pSize-1))%2;
const f32 u = pong ? 1.f-core::fract ( dt ) : core::fract ( dt );
const s32 idx = pong ? (pSize-2) - (unwrappedIdx % (pSize-1))
: (PingPong ? unwrappedIdx % (pSize-1)
: unwrappedIdx % pSize);
//const f32 u = 0.001f * fmodf( dt, 1000.0f ); //const f32 u = 0.001f * fmodf( dt, 1000.0f );
const core::vector3df& p0 = Points[ clamp( idx - 1, pSize ) ]; const core::vector3df& p0 = Points[ clamp( idx - 1, pSize ) ];
const core::vector3df& p1 = Points[ clamp( idx + 0, pSize ) ]; // starting point const core::vector3df& p1 = Points[ clamp( idx + 0, pSize ) ]; // starting point
const core::vector3df& p2 = Points[ clamp( idx + 1, pSize ) ]; // end point const core::vector3df& p2 = Points[ clamp( idx + 1, pSize ) ]; // end point
...@@ -73,6 +93,8 @@ void CSceneNodeAnimatorFollowSpline::serializeAttributes(io::IAttributes* out, i ...@@ -73,6 +93,8 @@ void CSceneNodeAnimatorFollowSpline::serializeAttributes(io::IAttributes* out, i
{ {
out->addFloat("Speed", Speed); out->addFloat("Speed", Speed);
out->addFloat("Tightness", Tightness); out->addFloat("Tightness", Tightness);
out->addBool("Loop", Loop);
out->addBool("PingPong", PingPong);
u32 count = Points.size(); u32 count = Points.size();
...@@ -98,6 +120,8 @@ void CSceneNodeAnimatorFollowSpline::deserializeAttributes(io::IAttributes* in, ...@@ -98,6 +120,8 @@ void CSceneNodeAnimatorFollowSpline::deserializeAttributes(io::IAttributes* in,
{ {
Speed = in->getAttributeAsFloat("Speed"); Speed = in->getAttributeAsFloat("Speed");
Tightness = in->getAttributeAsFloat("Tightness"); Tightness = in->getAttributeAsFloat("Tightness");
Loop = in->getAttributeAsBool("Loop");
PingPong = in->getAttributeAsBool("PingPong");
Points.clear(); Points.clear();
for(u32 i=1; true; ++i) for(u32 i=1; true; ++i)
...@@ -125,7 +149,7 @@ void CSceneNodeAnimatorFollowSpline::deserializeAttributes(io::IAttributes* in, ...@@ -125,7 +149,7 @@ void CSceneNodeAnimatorFollowSpline::deserializeAttributes(io::IAttributes* in,
ISceneNodeAnimator* CSceneNodeAnimatorFollowSpline::createClone(ISceneNode* node, ISceneManager* newManager) ISceneNodeAnimator* CSceneNodeAnimatorFollowSpline::createClone(ISceneNode* node, ISceneManager* newManager)
{ {
CSceneNodeAnimatorFollowSpline * newAnimator = CSceneNodeAnimatorFollowSpline * newAnimator =
new CSceneNodeAnimatorFollowSpline(StartTime, Points, Speed, Tightness); new CSceneNodeAnimatorFollowSpline(StartTime, Points, Speed, Tightness);
return newAnimator; return newAnimator;
......
...@@ -7,21 +7,22 @@ ...@@ -7,21 +7,22 @@
#include "ISceneNode.h" #include "ISceneNode.h"
#include "irrArray.h" #include "irrArray.h"
#include "ISceneNodeAnimatorFinishing.h"
namespace irr namespace irr
{ {
namespace scene namespace scene
{ {
//! Scene node animator based free code Matthias Gall wrote and sent in. (Most of //! Scene node animator based free code Matthias Gall wrote and sent in. (Most of
//! this code is written by him, I only modified bits.) //! this code is written by him, I only modified bits.)
class CSceneNodeAnimatorFollowSpline : public ISceneNodeAnimator class CSceneNodeAnimatorFollowSpline : public ISceneNodeAnimatorFinishing
{ {
public: public:
//! constructor //! constructor
CSceneNodeAnimatorFollowSpline(u32 startTime, CSceneNodeAnimatorFollowSpline(u32 startTime,
const core::array< core::vector3df >& points, const core::array< core::vector3df >& points,
f32 speed = 1.0f, f32 tightness = 0.5f); f32 speed = 1.0f, f32 tightness = 0.5f, bool loop=true, bool pingpong=false);
//! animates a scene node //! animates a scene node
virtual void animateNode(ISceneNode* node, u32 timeMs); virtual void animateNode(ISceneNode* node, u32 timeMs);
...@@ -34,7 +35,7 @@ namespace scene ...@@ -34,7 +35,7 @@ namespace scene
//! Returns type of the scene node animator //! Returns type of the scene node animator
virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_FOLLOW_SPLINE; } virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_FOLLOW_SPLINE; }
//! Creates a clone of this animator. //! Creates a clone of this animator.
/** Please note that you will have to drop /** Please note that you will have to drop
(IReferenceCounted::drop()) the returned pointer after calling (IReferenceCounted::drop()) the returned pointer after calling
...@@ -50,6 +51,8 @@ namespace scene ...@@ -50,6 +51,8 @@ namespace scene
f32 Speed; f32 Speed;
f32 Tightness; f32 Tightness;
u32 StartTime; u32 StartTime;
bool Loop;
bool PingPong;
}; };
......
...@@ -582,6 +582,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index) ...@@ -582,6 +582,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index)
#ifdef _IRR_COMPILE_WITH_ZLIB_ #ifdef _IRR_COMPILE_WITH_ZLIB_
const u32 uncompressedSize = e.header.DataDescriptor.UncompressedSize; const u32 uncompressedSize = e.header.DataDescriptor.UncompressedSize;
const u32 compressedSize = e.header.DataDescriptor.CompressedSize;
c8* pBuf = new c8[ uncompressedSize ]; c8* pBuf = new c8[ uncompressedSize ];
if (!pBuf) if (!pBuf)
{ {
...@@ -595,7 +596,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index) ...@@ -595,7 +596,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index)
u8 *pcData = decryptedBuf; u8 *pcData = decryptedBuf;
if (!pcData) if (!pcData)
{ {
pcData = new u8[decryptedSize]; pcData = new u8[compressedSize];
if (!pcData) if (!pcData)
{ {
swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() ); swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() );
...@@ -606,7 +607,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index) ...@@ -606,7 +607,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index)
//memset(pcData, 0, decryptedSize); //memset(pcData, 0, decryptedSize);
File->seek(e.Offset); File->seek(e.Offset);
File->read(pcData, decryptedSize); File->read(pcData, compressedSize);
} }
// Setup the inflate stream. // Setup the inflate stream.
...@@ -614,7 +615,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index) ...@@ -614,7 +615,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index)
s32 err; s32 err;
stream.next_in = (Bytef*)pcData; stream.next_in = (Bytef*)pcData;
stream.avail_in = (uInt)decryptedSize; stream.avail_in = (uInt)compressedSize;
stream.next_out = (Bytef*)pBuf; stream.next_out = (Bytef*)pBuf;
stream.avail_out = uncompressedSize; stream.avail_out = uncompressedSize;
stream.zalloc = (alloc_func)0; stream.zalloc = (alloc_func)0;
......
Test suite pass at GMT Mon Nov 30 17:33:50 2009 Test suite pass at GMT Tue Dec 1 18:25:07 2009
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment