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(renderTest nodeTest.cpp cameraTest.cpp shaderTest.cpp particleEmitterTest.cpp)
|
||||||
set(armatureTest boneTest.cpp ikSolverTest.cpp)
|
set(armatureTest boneTest.cpp ikSolverTest.cpp)
|
||||||
set(modelTest vbModelReaderTest.cpp)
|
set(modelTest vbModelReaderTest.cpp)
|
||||||
set(animationTest animationChannelTest.cpp)
|
set(animationTest animationControllerTest.cpp animationChannelTest.cpp)
|
||||||
set(test ${library} ${renderTest} ${armatureTest} ${modelTest} ${animationTest})
|
set(test ${library} ${renderTest} ${armatureTest} ${modelTest} ${animationTest})
|
||||||
|
|
||||||
add_executable(vb01Tests main.cpp ${test})
|
add_executable(vb01Tests main.cpp ${test})
|
||||||
|
|||||||
+31
-13
@@ -1,6 +1,5 @@
|
|||||||
#include "animationChannel.h"
|
#include "animationChannel.h"
|
||||||
#include "animationController.h"
|
#include "animationController.h"
|
||||||
#include "animation.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -28,32 +27,51 @@ namespace vb01{
|
|||||||
void AnimationChannel::setAnimationName(string animName){
|
void AnimationChannel::setAnimationName(string animName){
|
||||||
this->animationName = animName;
|
this->animationName = animName;
|
||||||
numFrames = getMaxKeyframeNum(animName);
|
numFrames = getMaxKeyframeNum(animName);
|
||||||
|
firstFrame = getFirstFrameNum(animName);
|
||||||
|
currentFrame = firstFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AnimationChannel::getMaxKeyframeNum(string animName){
|
vector<Keyframe> AnimationChannel::getAllKeyframes(string animName){
|
||||||
int maxKeyframeNum;
|
vector<Keyframe> keyframes;
|
||||||
|
|
||||||
Animation *animation = controller->getAnimation(animName);
|
Animation *animation = controller->getAnimation(animName);
|
||||||
KeyframeGroup *startGroup = animation->getKeyframeGroup(bones[0]);
|
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++){
|
for(int i = 0; i < bones.size(); i++){
|
||||||
KeyframeGroup *kg = animation->getKeyframeGroup(bones[i]);
|
KeyframeGroup *kg = animation->getKeyframeGroup(bones[i]);
|
||||||
|
|
||||||
for(int j = 0 ; j < kg->keyframeChannels.size(); j++){
|
for(int j = 0 ; j < kg->keyframeChannels.size(); j++){
|
||||||
KeyframeChannel ch = kg->keyframeChannels[j];
|
KeyframeChannel ch = kg->keyframeChannels[j];
|
||||||
|
|
||||||
for(int k = 0; k < ch.keyframes.size(); k++){
|
for(int k = 0; k < ch.keyframes.size(); k++)
|
||||||
int numKeyframes = ch.keyframes.size();
|
keyframes.push_back(ch.keyframes[k]);
|
||||||
int maxFrame = ch.keyframes[numKeyframes - 1].frame;
|
}
|
||||||
|
}
|
||||||
|
return keyframes;
|
||||||
|
}
|
||||||
|
|
||||||
if(numFrames < maxFrame)
|
int AnimationChannel::getMaxKeyframeNum(string animName){
|
||||||
maxKeyframeNum = maxFrame;
|
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;
|
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 <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "animation.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
namespace vb01{
|
namespace vb01{
|
||||||
@@ -32,6 +34,8 @@ namespace vb01{
|
|||||||
private:
|
private:
|
||||||
inline bool canUpdate(){return getTime() - lastUpdateTime > updateRate;}
|
inline bool canUpdate(){return getTime() - lastUpdateTime > updateRate;}
|
||||||
int getMaxKeyframeNum(std::string);
|
int getMaxKeyframeNum(std::string);
|
||||||
|
int getFirstFrameNum(std::string);
|
||||||
|
std::vector<Keyframe> getAllKeyframes(std::string);
|
||||||
|
|
||||||
s64 lastUpdateTime = 0;
|
s64 lastUpdateTime = 0;
|
||||||
int updateRate = 16;
|
int updateRate = 16;
|
||||||
@@ -42,6 +46,7 @@ namespace vb01{
|
|||||||
std::vector<Bone*> bones;
|
std::vector<Bone*> bones;
|
||||||
|
|
||||||
friend class AnimationChannelTest;
|
friend class AnimationChannelTest;
|
||||||
|
friend class AnimationControllerTest;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,14 +47,14 @@ namespace vb01{
|
|||||||
channel->setLoop(false);
|
channel->setLoop(false);
|
||||||
channel->setForward(true);
|
channel->setForward(true);
|
||||||
channel->update();
|
channel->update();
|
||||||
CPPUNIT_ASSERT(channel->getCurrentFrame() == 2);
|
CPPUNIT_ASSERT(channel->getCurrentFrame() == firstFrame + 1);
|
||||||
|
|
||||||
channel->lastUpdateTime = 0;
|
channel->lastUpdateTime = 0;
|
||||||
channel->setCurrentFrame(numFrames - 1);
|
channel->setCurrentFrame(numFrames - 1);
|
||||||
channel->setLoop(false);
|
channel->setLoop(false);
|
||||||
channel->setForward(true);
|
channel->setForward(true);
|
||||||
channel->update();
|
channel->update();
|
||||||
CPPUNIT_ASSERT(channel->getCurrentFrame() == 10);
|
CPPUNIT_ASSERT(channel->getCurrentFrame() == numFrames);
|
||||||
|
|
||||||
channel->lastUpdateTime = 0;
|
channel->lastUpdateTime = 0;
|
||||||
channel->setCurrentFrame(1);
|
channel->setCurrentFrame(1);
|
||||||
@@ -82,4 +82,9 @@ namespace vb01{
|
|||||||
int numFrames = channel->getMaxKeyframeNum("anim");
|
int numFrames = channel->getMaxKeyframeNum("anim");
|
||||||
CPPUNIT_ASSERT(numFrames == 10);
|
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_SUITE(AnimationChannelTest);
|
||||||
CPPUNIT_TEST(testUpdate);
|
CPPUNIT_TEST(testUpdate);
|
||||||
CPPUNIT_TEST(testGetMaxKeyframeNum);
|
CPPUNIT_TEST(testGetMaxKeyframeNum);
|
||||||
|
CPPUNIT_TEST(testGetFirstFrame);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -25,6 +26,7 @@ namespace vb01{
|
|||||||
|
|
||||||
void testUpdate();
|
void testUpdate();
|
||||||
void testGetMaxKeyframeNum();
|
void testGetMaxKeyframeNum();
|
||||||
|
void testGetFirstFrame();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-14
@@ -35,12 +35,6 @@ namespace vb01{
|
|||||||
Vector3 currentPos = interpolate(pastPos, nextPos, interp, ratio);
|
Vector3 currentPos = interpolate(pastPos, nextPos, interp, ratio);
|
||||||
Quaternion currentRot = interpolate(pastRot, nextRot, interp, ratio);
|
Quaternion currentRot = interpolate(pastRot, nextRot, interp, ratio);
|
||||||
Vector3 currentScale = interpolate(pastScale, nextScale, 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->setPosePos(currentPos);
|
||||||
channelBone->setPoseRot(currentRot);
|
channelBone->setPoseRot(currentRot);
|
||||||
}
|
}
|
||||||
@@ -59,23 +53,24 @@ namespace vb01{
|
|||||||
AnimationChannel *channel
|
AnimationChannel *channel
|
||||||
){
|
){
|
||||||
|
|
||||||
int pastKeyframeId = -1;
|
for(KeyframeChannel keyframeChannel : keyframeGroup->keyframeChannels){
|
||||||
for(KeyframeChannel animChannel : keyframeGroup->keyframeChannels){
|
int pastKeyframeId = -1, nextKeyframeId = -1;
|
||||||
for(int i = 0 ; i < animChannel.keyframes.size(); i++){
|
for(int i = 0; i < keyframeChannel.keyframes.size(); i++){
|
||||||
Keyframe keyframe = animChannel.keyframes[i];
|
Keyframe keyframe = keyframeChannel.keyframes[i];
|
||||||
if(channel->getCurrentFrame() >= keyframe.frame){
|
if(channel->getCurrentFrame() >= keyframe.frame){
|
||||||
pastKeyframeId = i;
|
pastKeyframeId = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nextKeyframeId = pastKeyframeId + 1;
|
||||||
|
|
||||||
Keyframe pastKeyframe = animChannel.keyframes[pastKeyframeId];
|
Keyframe pastKeyframe = keyframeChannel.keyframes[pastKeyframeId];
|
||||||
Keyframe nextKeyframe = animChannel.keyframes[pastKeyframeId + 1];
|
Keyframe nextKeyframe = keyframeChannel.keyframes[nextKeyframeId];
|
||||||
int pastFrame = pastKeyframe.frame;
|
int pastFrame = pastKeyframe.frame;
|
||||||
int nextFrame = nextKeyframe.frame;
|
int nextFrame = nextKeyframe.frame;
|
||||||
ratio = (float)(max(0, channel->getCurrentFrame() - pastFrame)) / (nextFrame - pastFrame);
|
ratio = (float)(max(0, channel->getCurrentFrame() - pastFrame)) / (nextFrame - pastFrame);
|
||||||
interpMode = pastKeyframe.interpolation;
|
interpMode = pastKeyframe.interpolation;
|
||||||
|
|
||||||
switch(animChannel.type){
|
switch(keyframeChannel.type){
|
||||||
case KeyframeChannel::POS_X:
|
case KeyframeChannel::POS_X:
|
||||||
pastPos.x = pastKeyframe.value;
|
pastPos.x = pastKeyframe.value;
|
||||||
nextPos.x = nextKeyframe.value;
|
nextPos.x = nextKeyframe.value;
|
||||||
@@ -117,7 +112,6 @@ namespace vb01{
|
|||||||
nextScale.z = nextKeyframe.value;
|
nextScale.z = nextKeyframe.value;
|
||||||
break;
|
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));
|
parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_ZERO));
|
||||||
|
|
||||||
Quaternion parentSpacePoseRot = Quaternion(r.getAngle(), rotAxis);
|
Quaternion parentSpacePoseRot = Quaternion(r.getAngle(), rotAxis);
|
||||||
|
|
||||||
setOrientation(parentSpacePoseRot * restRot);
|
setOrientation(parentSpacePoseRot * restRot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "shaderTest.h"
|
#include "shaderTest.h"
|
||||||
#include "particleEmitterTest.h"
|
#include "particleEmitterTest.h"
|
||||||
#include "ikSolverTest.h"
|
#include "ikSolverTest.h"
|
||||||
|
#include "animationControllerTest.h"
|
||||||
|
|
||||||
using namespace CppUnit;
|
using namespace CppUnit;
|
||||||
using namespace vb01;
|
using namespace vb01;
|
||||||
|
|||||||
Reference in New Issue
Block a user