mirror of
https://github.com/devZoGok/vb01.git
synced 2026-08-26 19:43:30 +00:00
animation channel improvements
beginning of animation controller test
This commit is contained in:
+1
-1
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -70,7 +70,6 @@ namespace vb01{
|
||||
parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_ZERO));
|
||||
|
||||
Quaternion parentSpacePoseRot = Quaternion(r.getAngle(), rotAxis);
|
||||
|
||||
setOrientation(parentSpacePoseRot * restRot);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user