animation channel improvements

beginning of animation controller test
This commit is contained in:
devZoGok
2021-10-19 19:06:41 +03:00
parent 347286aa1f
commit f8d5beb5d6
10 changed files with 155 additions and 31 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ target_link_libraries(vb01 freetype)
set(renderTest nodeTest.cpp cameraTest.cpp shaderTest.cpp particleEmitterTest.cpp)
set(armatureTest boneTest.cpp ikSolverTest.cpp)
set(modelTest vbModelReaderTest.cpp)
set(animationTest animationChannelTest.cpp)
set(animationTest animationControllerTest.cpp animationChannelTest.cpp)
set(test ${library} ${renderTest} ${armatureTest} ${modelTest} ${animationTest})
add_executable(vb01Tests main.cpp ${test})
+31 -13
View File
@@ -1,6 +1,5 @@
#include "animationChannel.h"
#include "animationController.h"
#include "animation.h"
using namespace std;
@@ -28,32 +27,51 @@ namespace vb01{
void AnimationChannel::setAnimationName(string animName){
this->animationName = animName;
numFrames = getMaxKeyframeNum(animName);
firstFrame = getFirstFrameNum(animName);
currentFrame = firstFrame;
}
int AnimationChannel::getMaxKeyframeNum(string animName){
int maxKeyframeNum;
vector<Keyframe> AnimationChannel::getAllKeyframes(string animName){
vector<Keyframe> keyframes;
Animation *animation = controller->getAnimation(animName);
KeyframeGroup *startGroup = animation->getKeyframeGroup(bones[0]);
int numStartKeyframes = startGroup->keyframeChannels[0].keyframes.size();
maxKeyframeNum = startGroup->keyframeChannels[0].keyframes[numStartKeyframes - 1].frame;
for(int i = 0; i < bones.size(); i++){
KeyframeGroup *kg = animation->getKeyframeGroup(bones[i]);
for(int j = 0 ; j < kg->keyframeChannels.size(); j++){
KeyframeChannel ch = kg->keyframeChannels[j];
for(int k = 0; k < ch.keyframes.size(); k++){
int numKeyframes = ch.keyframes.size();
int maxFrame = ch.keyframes[numKeyframes - 1].frame;
if(numFrames < maxFrame)
maxKeyframeNum = maxFrame;
}
for(int k = 0; k < ch.keyframes.size(); k++)
keyframes.push_back(ch.keyframes[k]);
}
}
return keyframes;
}
int AnimationChannel::getMaxKeyframeNum(string animName){
vector<Keyframe> keyframes = getAllKeyframes(animName);
int maxKeyframeNum = 0;
for(int i = 0; i < keyframes.size(); i++){
int curFrameNum = keyframes[i].frame;
if(maxKeyframeNum < curFrameNum)
maxKeyframeNum = curFrameNum;
}
return maxKeyframeNum;
}
int AnimationChannel::getFirstFrameNum(string animName){
vector<Keyframe> keyframes = getAllKeyframes(animName);
int minKeyframeNum = keyframes[0].frame;
for(int i = 0; i < keyframes.size(); i++){
int curFrameNum = keyframes[i].frame;
if(minKeyframeNum > curFrameNum)
minKeyframeNum = curFrameNum;
}
return minKeyframeNum;
}
}
+5
View File
@@ -3,6 +3,8 @@
#include <vector>
#include <string>
#include "animation.h"
#include "util.h"
namespace vb01{
@@ -32,6 +34,8 @@ namespace vb01{
private:
inline bool canUpdate(){return getTime() - lastUpdateTime > updateRate;}
int getMaxKeyframeNum(std::string);
int getFirstFrameNum(std::string);
std::vector<Keyframe> getAllKeyframes(std::string);
s64 lastUpdateTime = 0;
int updateRate = 16;
@@ -42,6 +46,7 @@ namespace vb01{
std::vector<Bone*> bones;
friend class AnimationChannelTest;
friend class AnimationControllerTest;
};
}
+7 -2
View File
@@ -47,14 +47,14 @@ namespace vb01{
channel->setLoop(false);
channel->setForward(true);
channel->update();
CPPUNIT_ASSERT(channel->getCurrentFrame() == 2);
CPPUNIT_ASSERT(channel->getCurrentFrame() == firstFrame + 1);
channel->lastUpdateTime = 0;
channel->setCurrentFrame(numFrames - 1);
channel->setLoop(false);
channel->setForward(true);
channel->update();
CPPUNIT_ASSERT(channel->getCurrentFrame() == 10);
CPPUNIT_ASSERT(channel->getCurrentFrame() == numFrames);
channel->lastUpdateTime = 0;
channel->setCurrentFrame(1);
@@ -82,4 +82,9 @@ namespace vb01{
int numFrames = channel->getMaxKeyframeNum("anim");
CPPUNIT_ASSERT(numFrames == 10);
}
void AnimationChannelTest::testGetFirstFrame(){
int firstFrame = channel->getFirstFrameNum("anim");
CPPUNIT_ASSERT(firstFrame == 0);
}
}
+2
View File
@@ -12,6 +12,7 @@ namespace vb01{
CPPUNIT_TEST_SUITE(AnimationChannelTest);
CPPUNIT_TEST(testUpdate);
CPPUNIT_TEST(testGetMaxKeyframeNum);
CPPUNIT_TEST(testGetFirstFrame);
CPPUNIT_TEST_SUITE_END();
public:
@@ -25,6 +26,7 @@ namespace vb01{
void testUpdate();
void testGetMaxKeyframeNum();
void testGetFirstFrame();
};
}
+8 -14
View File
@@ -35,12 +35,6 @@ namespace vb01{
Vector3 currentPos = interpolate(pastPos, nextPos, interp, ratio);
Quaternion currentRot = interpolate(pastRot, nextRot, interp, ratio);
Vector3 currentScale = interpolate(pastScale, nextScale, interp, ratio);
/*
swap(currentRot.y, currentRot.z);
currentRot.z = -currentRot.z;
//channelBone->setPoseScale(currentScale);
*/
channelBone->setPosePos(currentPos);
channelBone->setPoseRot(currentRot);
}
@@ -59,23 +53,24 @@ namespace vb01{
AnimationChannel *channel
){
int pastKeyframeId = -1;
for(KeyframeChannel animChannel : keyframeGroup->keyframeChannels){
for(int i = 0 ; i < animChannel.keyframes.size(); i++){
Keyframe keyframe = animChannel.keyframes[i];
for(KeyframeChannel keyframeChannel : keyframeGroup->keyframeChannels){
int pastKeyframeId = -1, nextKeyframeId = -1;
for(int i = 0; i < keyframeChannel.keyframes.size(); i++){
Keyframe keyframe = keyframeChannel.keyframes[i];
if(channel->getCurrentFrame() >= keyframe.frame){
pastKeyframeId = i;
}
}
nextKeyframeId = pastKeyframeId + 1;
Keyframe pastKeyframe = animChannel.keyframes[pastKeyframeId];
Keyframe nextKeyframe = animChannel.keyframes[pastKeyframeId + 1];
Keyframe pastKeyframe = keyframeChannel.keyframes[pastKeyframeId];
Keyframe nextKeyframe = keyframeChannel.keyframes[nextKeyframeId];
int pastFrame = pastKeyframe.frame;
int nextFrame = nextKeyframe.frame;
ratio = (float)(max(0, channel->getCurrentFrame() - pastFrame)) / (nextFrame - pastFrame);
interpMode = pastKeyframe.interpolation;
switch(animChannel.type){
switch(keyframeChannel.type){
case KeyframeChannel::POS_X:
pastPos.x = pastKeyframe.value;
nextPos.x = nextKeyframe.value;
@@ -117,7 +112,6 @@ namespace vb01{
nextScale.z = nextKeyframe.value;
break;
}
}
}
+70
View File
@@ -0,0 +1,70 @@
#include "animationControllerTest.h"
#include "skeleton.h"
#include "animation.h"
#include "animationController.h"
#include "animationChannel.h"
#include <vector>
using namespace std;
namespace vb01{
void AnimationControllerTest::createAnimation(){
Keyframe k0;
k0.frame = 0;
k0.value = 1;
k0.interpolation = KeyframeInterpolation::LINEAR;
Keyframe k1;
k1.frame = 1;
k1.value = 0;
k1.interpolation = KeyframeInterpolation::LINEAR;
KeyframeChannel ch0;
ch0.type = KeyframeChannelType::POS_X;
ch0.keyframes = vector<Keyframe>({k0});
KeyframeChannel ch1;
ch1.type = KeyframeChannelType::POS_Y;
ch1.keyframes = vector<Keyframe>({k1});
Bone *bone = skeleton->getBone(0);
KeyframeGroup kg;
kg.bone = bone;
kg.keyframeChannels = vector<KeyframeChannel>({ch0, ch1});
controller = skeleton->getAnimationController();
Animation *anim = new Animation("anim");
anim->addKeyframeGroup(kg);
controller->addAnimation(anim);
channel = new AnimationChannel(controller);
channel->addBone(bone);
channel->setAnimationName("anim");
channel->setLoop(true);
controller->addAnimationChannel(channel);
}
void AnimationControllerTest::setUp(){
Node *rootNode = Root::getSingleton()->getRootNode();
skeleton = new Skeleton();
Bone *bone = new Bone("bone", 1.f, Vector3::VEC_ZERO, Quaternion::QUAT_W, Vector3::VEC_IJK);
skeleton->addBone(bone, (Bone*)rootNode);
createAnimation();
}
void AnimationControllerTest::tearDown(){
}
void AnimationControllerTest::testPrepareAdjacentValues(){
channel->currentFrame = 4;
controller->update();
Bone *bone = skeleton->getBone("bone");
Vector3 posePos = bone->getPosePos();
/*
CPPUNIT_ASSERT(posePos.y == 0);
CPPUNIT_ASSERT(posePos.x == 1);
*/
}
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef ANIMATION_CONTROLLER_TEST_H
#define ANIMATION_CONTROLLER_TEST_H
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
namespace vb01{
class Skeleton;
class AnimationChannel;
class AnimationController;
class AnimationControllerTest : public CppUnit::TestFixture{
CPPUNIT_TEST_SUITE(AnimationControllerTest);
CPPUNIT_TEST(testPrepareAdjacentValues);
CPPUNIT_TEST_SUITE_END();
public:
AnimationControllerTest(){}
void setUp();
void tearDown();
private:
void createAnimation();
void testPrepareAdjacentValues();
Skeleton *skeleton = nullptr;
AnimationController *controller = nullptr;
AnimationChannel *channel = nullptr;
};
}
#endif
-1
View File
@@ -70,7 +70,6 @@ namespace vb01{
parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_ZERO));
Quaternion parentSpacePoseRot = Quaternion(r.getAngle(), rotAxis);
setOrientation(parentSpacePoseRot * restRot);
}
+1
View File
@@ -11,6 +11,7 @@
#include "shaderTest.h"
#include "particleEmitterTest.h"
#include "ikSolverTest.h"
#include "animationControllerTest.h"
using namespace CppUnit;
using namespace vb01;