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
- 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.
- Added geometry shaders for OpenGL. A first version of the code was submitted by Matthew Kielan (devsh).
......
......@@ -1188,7 +1188,7 @@ namespace scene
See IReferenceCounted::drop() for more information. */
virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
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.
/** Triangle selectors
......
......@@ -1685,10 +1685,10 @@ ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnima
//! Creates a follow spline animator.
ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime,
const core::array< core::vector3df >& points,
f32 speed, f32 tightness)
f32 speed, f32 tightness, bool loop, bool pingpong)
{
ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points,
speed, tightness);
speed, tightness, loop, pingpong);
return a;
}
......
......@@ -337,7 +337,7 @@ namespace scene
//! Creates a follow spline animator.
virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
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.
......
......@@ -13,8 +13,9 @@ namespace scene
//! constructor
CSceneNodeAnimatorFollowSpline::CSceneNodeAnimatorFollowSpline(u32 time,
const core::array<core::vector3df>& points, f32 speed,
f32 tightness)
: Points(points), Speed(speed), Tightness(tightness), StartTime(time)
f32 tightness, bool loop, bool pingpong)
: ISceneNodeAnimatorFinishing(0), Points(points), Speed(speed), Tightness(tightness), StartTime(time)
, Loop(loop), PingPong(pingpong)
{
#ifdef _DEBUG
setDebugName("CSceneNodeAnimatorFollowSpline");
......@@ -36,18 +37,37 @@ void CSceneNodeAnimatorFollowSpline::animateNode(ISceneNode* node, u32 timeMs)
const u32 pSize = Points.size();
if (pSize==0)
{
if ( !Loop )
HasFinished = true;
return;
}
if (pSize==1)
{
node->setPosition(Points[0]);
if ( timeMs > StartTime )
{
node->setPosition(Points[0]);
if ( !Loop )
HasFinished = true;
}
return;
}
const f32 dt = ( (timeMs-StartTime) * Speed * 0.001f );
const f32 u = core::fract ( dt );
const s32 idx = core::floor32( dt ) % pSize;
const s32 unwrappedIdx = core::floor32( dt );
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 core::vector3df& p0 = Points[ clamp( idx - 1, pSize ) ];
const core::vector3df& p1 = Points[ clamp( idx + 0, pSize ) ]; // starting point
const core::vector3df& p2 = Points[ clamp( idx + 1, pSize ) ]; // end point
......@@ -73,6 +93,8 @@ void CSceneNodeAnimatorFollowSpline::serializeAttributes(io::IAttributes* out, i
{
out->addFloat("Speed", Speed);
out->addFloat("Tightness", Tightness);
out->addBool("Loop", Loop);
out->addBool("PingPong", PingPong);
u32 count = Points.size();
......@@ -98,6 +120,8 @@ void CSceneNodeAnimatorFollowSpline::deserializeAttributes(io::IAttributes* in,
{
Speed = in->getAttributeAsFloat("Speed");
Tightness = in->getAttributeAsFloat("Tightness");
Loop = in->getAttributeAsBool("Loop");
PingPong = in->getAttributeAsBool("PingPong");
Points.clear();
for(u32 i=1; true; ++i)
......@@ -125,7 +149,7 @@ void CSceneNodeAnimatorFollowSpline::deserializeAttributes(io::IAttributes* in,
ISceneNodeAnimator* CSceneNodeAnimatorFollowSpline::createClone(ISceneNode* node, ISceneManager* newManager)
{
CSceneNodeAnimatorFollowSpline * newAnimator =
CSceneNodeAnimatorFollowSpline * newAnimator =
new CSceneNodeAnimatorFollowSpline(StartTime, Points, Speed, Tightness);
return newAnimator;
......
......@@ -7,21 +7,22 @@
#include "ISceneNode.h"
#include "irrArray.h"
#include "ISceneNodeAnimatorFinishing.h"
namespace irr
{
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.)
class CSceneNodeAnimatorFollowSpline : public ISceneNodeAnimator
class CSceneNodeAnimatorFollowSpline : public ISceneNodeAnimatorFinishing
{
public:
//! constructor
CSceneNodeAnimatorFollowSpline(u32 startTime,
CSceneNodeAnimatorFollowSpline(u32 startTime,
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
virtual void animateNode(ISceneNode* node, u32 timeMs);
......@@ -34,7 +35,7 @@ namespace scene
//! Returns type of the scene node animator
virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_FOLLOW_SPLINE; }
//! Creates a clone of this animator.
/** Please note that you will have to drop
(IReferenceCounted::drop()) the returned pointer after calling
......@@ -50,6 +51,8 @@ namespace scene
f32 Speed;
f32 Tightness;
u32 StartTime;
bool Loop;
bool PingPong;
};
......
......@@ -582,6 +582,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index)
#ifdef _IRR_COMPILE_WITH_ZLIB_
const u32 uncompressedSize = e.header.DataDescriptor.UncompressedSize;
const u32 compressedSize = e.header.DataDescriptor.CompressedSize;
c8* pBuf = new c8[ uncompressedSize ];
if (!pBuf)
{
......@@ -595,7 +596,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index)
u8 *pcData = decryptedBuf;
if (!pcData)
{
pcData = new u8[decryptedSize];
pcData = new u8[compressedSize];
if (!pcData)
{
swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() );
......@@ -606,7 +607,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index)
//memset(pcData, 0, decryptedSize);
File->seek(e.Offset);
File->read(pcData, decryptedSize);
File->read(pcData, compressedSize);
}
// Setup the inflate stream.
......@@ -614,7 +615,7 @@ IReadFile* CZipReader::createAndOpenFile(u32 index)
s32 err;
stream.next_in = (Bytef*)pcData;
stream.avail_in = (uInt)decryptedSize;
stream.avail_in = (uInt)compressedSize;
stream.next_out = (Bytef*)pBuf;
stream.avail_out = uncompressedSize;
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