diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cfe53d..5a44ce1 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,8 @@ target_link_libraries(vb01 freetype) set(renderTest nodeTest.cpp cameraTest.cpp) set(armatureTest boneTest.cpp) set(modelTest vbModelReaderTest.cpp) -set(test ${library} ${renderTest} ${armatureTest} ${modelTest}) +set(animationTest animationChannelTest.cpp) +set(test ${library} ${renderTest} ${armatureTest} ${modelTest} ${animationTest}) add_executable(vb01Tests main.cpp ${test}) target_link_libraries(vb01Tests cppunit) diff --git a/animationChannel.cpp b/animationChannel.cpp index 1c402fd..72fef48 100644 --- a/animationChannel.cpp +++ b/animationChannel.cpp @@ -14,14 +14,12 @@ namespace vb01{ void AnimationChannel::update(){ if(canUpdate()){ - if(firstFrame < currentFrame && currentFrame < numFrames) - currentFrame += (forward? 1 : -1); - else if(loop){ - if(!forward && currentFrame <= firstFrame) - currentFrame = numFrames - 1; - else if(forward && currentFrame >= numFrames) - currentFrame = firstFrame + 1; - } + if(firstFrame <= currentFrame && currentFrame <= numFrames) + currentFrame += (forward ? 1 : -1); + if(currentFrame < firstFrame) + currentFrame = (loop ? numFrames : firstFrame); + else if(currentFrame > numFrames) + currentFrame = (loop ? firstFrame : numFrames); lastUpdateTime = getTime(); } diff --git a/animationChannel.h b/animationChannel.h index db23b7c..989ae8e 100644 --- a/animationChannel.h +++ b/animationChannel.h @@ -20,9 +20,10 @@ namespace vb01{ inline void removeAllBones(){bones.clear();} inline void setUpdateRate(float updateRate){this->updateRate = updateRate;} inline int getUpdateRate(){return updateRate;} + inline int getFirstFrame(){return firstFrame;} inline int getCurrentFrame(){return currentFrame;} inline void setCurrentFrame(int frame){this->currentFrame = frame;} - inline int getNumnFrames(){return numFrames;} + inline int getNumFrames(){return numFrames;} inline void setLoop(bool loop){this->loop = loop;} inline bool isLoop(){return loop;} inline void setForward(bool forward){this->forward = forward;} @@ -39,6 +40,8 @@ namespace vb01{ bool loop = false, forward = true; std::string animationName; std::vector bones; + + friend class AnimationChannelTest; }; } diff --git a/animationChannelTest.cpp b/animationChannelTest.cpp new file mode 100644 index 0000000..6ab0c8a --- /dev/null +++ b/animationChannelTest.cpp @@ -0,0 +1,85 @@ +#include "animationChannelTest.h" +#include "skeleton.h" +#include "animationController.h" +#include "animationChannel.h" +#include "animation.h" +#include "bone.h" + +#include + +using namespace std; + +namespace vb01{ + void AnimationChannelTest::setUp(){ + Bone *bone = new Bone("bone", 1, Vector3(0, 0, 0), Quaternion::QUAT_I, Vector3::VEC_IJK); + skeleton = new Skeleton(); + skeleton->addBone(bone, nullptr); + AnimationController *controller = skeleton->getAnimationController(); + + Keyframe k1, k2; + k1.frame = 0; + k2.frame = 10; + KeyframeChannel kc; + kc.type = KeyframeChannel::Type::POS_X; + kc.keyframes = vector({k1, k2}); + KeyframeGroup kg; + kg.bone = bone; + kg.keyframeChannels = vector({kc}); + Animation *anim = new Animation("anim"); + anim->addKeyframeGroup(kg); + + channel = new AnimationChannel(controller); + controller->addAnimationChannel(channel); + controller->addAnimation(anim); + channel->addBone(bone); + channel->setAnimationName("anim"); + } + + void AnimationChannelTest::tearDown(){ + } + + void AnimationChannelTest::testUpdate(){ + int numFrames = 10; + int firstFrame = channel->getFirstFrame(); + channel->numFrames = numFrames; + + channel->lastUpdateTime = 0; + channel->setLoop(false); + channel->setForward(true); + channel->update(); + CPPUNIT_ASSERT(channel->getCurrentFrame() == 2); + + channel->lastUpdateTime = 0; + channel->setCurrentFrame(numFrames - 1); + channel->setLoop(false); + channel->setForward(true); + channel->update(); + CPPUNIT_ASSERT(channel->getCurrentFrame() == 10); + + channel->lastUpdateTime = 0; + channel->setCurrentFrame(1); + channel->setLoop(false); + channel->setForward(false); + channel->update(); + CPPUNIT_ASSERT(channel->getCurrentFrame() == firstFrame); + + channel->lastUpdateTime = 0; + channel->setCurrentFrame(numFrames); + channel->setLoop(true); + channel->setForward(true); + channel->update(); + CPPUNIT_ASSERT(channel->getCurrentFrame() == firstFrame); + + channel->lastUpdateTime = 0; + channel->setCurrentFrame(firstFrame); + channel->setLoop(true); + channel->setForward(false); + channel->update(); + CPPUNIT_ASSERT(channel->getCurrentFrame() == numFrames); + } + + void AnimationChannelTest::testGetMaxKeyframeNum(){ + int numFrames = channel->getMaxKeyframeNum("anim"); + CPPUNIT_ASSERT(numFrames == 10); + } +} diff --git a/animationChannelTest.h b/animationChannelTest.h new file mode 100644 index 0000000..a830a72 --- /dev/null +++ b/animationChannelTest.h @@ -0,0 +1,32 @@ +#ifndef ANIMATION_CHANNEL_TEST +#define ANIMATION_CHANNEL_TES + +#include +#include + +namespace vb01{ + class Skeleton; + class AnimationChannel; + + class AnimationChannelTest : public CppUnit::TestFixture{ + CPPUNIT_TEST_SUITE(AnimationChannelTest); + CPPUNIT_TEST(testUpdate); + CPPUNIT_TEST(testGetMaxKeyframeNum); + CPPUNIT_TEST_SUITE_END(); + + public: + AnimationChannelTest(){} + ~AnimationChannelTest(){} + void setUp(); + void tearDown(); + private: + Skeleton *skeleton = nullptr; + AnimationChannel *channel = nullptr; + + void testUpdate(); + void testGetMaxKeyframeNum(); + }; +} + + +#endif diff --git a/animationController.cpp b/animationController.cpp index 52173ad..bb5c81b 100644 --- a/animationController.cpp +++ b/animationController.cpp @@ -72,7 +72,7 @@ namespace vb01{ Keyframe nextKeyframe = animChannel.keyframes[pastKeyframeId + 1]; int pastFrame = pastKeyframe.frame; int nextFrame = nextKeyframe.frame; - ratio = (float)(channel->getCurrentFrame() - pastFrame) / (nextFrame - pastFrame); + ratio = (float)(max(0, channel->getCurrentFrame() - pastFrame)) / (nextFrame - pastFrame); interpMode = pastKeyframe.interpolation; switch(animChannel.type){ diff --git a/bone.cpp b/bone.cpp index 18068c5..211cb13 100644 --- a/bone.cpp +++ b/bone.cpp @@ -4,7 +4,7 @@ using namespace std; namespace vb01{ - Bone::Bone(string name, float length, Vector3 pos,Quaternion rot, Vector3 scale) : Node(pos,rot,scale,name){ + Bone::Bone(string name, float length, Vector3 pos, Quaternion rot, Vector3 scale) : Node(pos, rot, scale, name){ this->name = name; this->length = length; } diff --git a/main.cpp b/main.cpp index b5417cf..41613ae 100755 --- a/main.cpp +++ b/main.cpp @@ -7,6 +7,7 @@ #include "nodeTest.h" #include "boneTest.h" #include "vbModelReaderTest.h" +#include "animationChannelTest.h" using namespace CppUnit; using namespace vb01; @@ -17,6 +18,7 @@ int main(){ runner.addTest(NodeTest::suite()); runner.addTest(BoneTest::suite()); runner.addTest(VbModelReaderTest::suite()); + runner.addTest(AnimationChannelTest::suite()); runner.run(); return 0; }