animation controller and channels (beginning)

This commit is contained in:
devZoGok
2021-10-19 19:06:41 +03:00
parent dd9ad38a34
commit 1bcfc39b90
9 changed files with 165 additions and 23 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ set(utils util.cpp)
set(math quaternion.cpp vector.cpp matrix.cpp ray.cpp)
set(render waterPlane.cpp particleEmitter.cpp camera.cpp light.cpp material.cpp mesh.cpp model.cpp node.cpp quad.cpp box.cpp root.cpp shader.cpp texture.cpp)
set(model modelReader.cpp assimpModelReader.cpp vbModelReader.cpp)
set(anim animationChannel.cpp animation.cpp)
set(anim animationController.cpp animationChannel.cpp animation.cpp)
set(armature skeleton.cpp bone.cpp)
add_library(vb01 SHARED main.cpp ${render} ${math} ${model} ${utils} ${gui} ${armature} ${anim})
+2 -2
View File
@@ -23,14 +23,14 @@ namespace vb01{
SCALE_Y,
SCALE_Z
};
enum Interpolation{CONSTANT,LINEAR,BEZIER};
enum Interpolation{CONSTANT, LINEAR, BEZIER};
Type type;
Interpolation interpolation;
float value;
int frame;
};
Bone *bone=nullptr;
Bone *bone = nullptr;
std::vector<Keyframe> keyframes;
};
+28
View File
@@ -0,0 +1,28 @@
#include "animationChannel.h"
#include "animationController.h"
#include "animation.h"
using namespace std;
namespace vb01{
AnimationChannel::AnimationChannel(AnimationController *controller){
this->controller = controller;
}
AnimationChannel::~AnimationChannel(){
}
void AnimationChannel::setAnimationName(string animName){
this->animationName = animName;
Animation *animation = controller->getAnimation(animName);
Animation::KeyframeGroup *startGroup = animation->getKeyframeGroup(bones[0]);
int maxStartFrame = startGroup->keyframes[startGroup->keyframes.size() - 1].frame;
for(int i = 0; i < bones.size() ; i++){
Animation::KeyframeGroup *group = animation->getKeyframeGroup(bones[i]);
int maxFrame = group->keyframes[group->keyframes.size() - 1].frame;
if(maxStartFrame < maxFrame)
maxStartFrame = maxFrame;
}
}
}
+25 -2
View File
@@ -1,13 +1,36 @@
#ifndef ANIMATION_CHANNEL_H
#define ANIMATION_CHANNEL_H
#include <vector>
#include <string>
namespace vb01{
class AnimationController;
class Bone;
class AnimationChannel{
public:
AnimationChannel();
AnimationChannel(AnimationController*);
~AnimationChannel();
void update();
void setAnimationName(std::string name);
inline std::vector<Bone*> getBones(){return bones;}
inline void addBone(Bone *bone){bones.push_back(bone);}
inline void removeAllBones(){bones.clear();}
inline void setSpeed(float speed){this->speed = speed;}
inline float getSpeed(){return speed;}
inline int getCurrentFrame(){return currentFrame;}
inline void setCurrentFrame(int frame){this->currentFrame = frame;}
inline int getNumFrames(){return numFrames;}
inline void setLoop(bool loop){this->loop = loop;}
inline bool isLoop(){return loop;}
inline std::string getAnimationName(){return animationName;}
private:
AnimationController *controller = nullptr;
float speed = 1.f;
int currentFrame = 0, numFrames;
bool loop = false;
std::string animationName;
std::vector<Bone*> bones;
};
}
+85 -1
View File
@@ -1,12 +1,96 @@
#include "animationController.h"
#include "animationChannel.h"
#include "skeleton.h"
using namespace std;
namespace vb01{
AnimationController::AnimationController(){
AnimationController::AnimationController(Skeleton *skeleton){
this->skeleton = skeleton;
}
AnimationController::~AnimationController(){
}
void AnimationController::update(){
for(AnimationChannel *channel : channels){
Animation *animation = skeleton->getAnimationController()->getAnimation(channel->getAnimationName());
for(Bone *channelBone : channel->getBones()){
Animation::KeyframeGroup *keyframeGroup = animation->getKeyframeGroup(channelBone);
int keyframeId = -1;
for(int i = 0 ; i < keyframeGroup->keyframes.size(); i++){
Animation::KeyframeGroup::Keyframe keyframe = keyframeGroup->keyframes[i];
if(keyframe.frame > channel->getCurrentFrame()){
keyframeId = i;
break;
}
}
Animation::KeyframeGroup::Keyframe pastKeyframe = keyframeGroup->keyframes[keyframeId - 1];
int pastFrame = pastKeyframe.frame;
int nextFrame = keyframeGroup->keyframes[keyframeId].frame;
float ratio = (float)(channel->getCurrentFrame() - pastFrame) / (nextFrame - pastFrame);
switch(pastKeyframe.interpolation){
case Animation::KeyframeGroup::Keyframe::CONSTANT:
break;
case Animation::KeyframeGroup::Keyframe::LINEAR:
break;
case Animation::KeyframeGroup::Keyframe::BEZIER:
break;
}
}
}
}
void AnimationController::applyBoneTransforms(Animation::KeyframeGroup *keyframeGroup){
Bone *bone = keyframeGroup->bone;
Vector3 pos, scale;
Quaternion rot;
for(Animation::KeyframeGroup::Keyframe keyframe : keyframeGroup->keyframes){
switch(keyframe.type){
case Animation::KeyframeGroup::Keyframe::POS_X:
pos.x = keyframe.value;
break;
case Animation::KeyframeGroup::Keyframe::POS_Y:
pos.y = keyframe.value;
break;
case Animation::KeyframeGroup::Keyframe::POS_Z:
pos.z = keyframe.value;
break;
case Animation::KeyframeGroup::Keyframe::ROT_W:
rot.x = keyframe.value;
break;
case Animation::KeyframeGroup::Keyframe::ROT_X:
rot.x = keyframe.value;
break;
case Animation::KeyframeGroup::Keyframe::ROT_Y:
rot.x = keyframe.value;
break;
case Animation::KeyframeGroup::Keyframe::ROT_Z:
rot.x = keyframe.value;
break;
case Animation::KeyframeGroup::Keyframe::SCALE_X:
scale.x = keyframe.value;
break;
case Animation::KeyframeGroup::Keyframe::SCALE_Y:
scale.y = keyframe.value;
break;
case Animation::KeyframeGroup::Keyframe::SCALE_Z:
scale.z = keyframe.value;
break;
}
}
}
Animation* AnimationController::getAnimation(string name){
Animation *anim = nullptr;
for(Animation *a : animations)
if(a->getName() == name){
anim = a;
break;
}
return anim;
}
}
+15 -2
View File
@@ -1,15 +1,28 @@
#ifndef ANIMATION_CONTROLLER_H
#define ANIMATION_CONTROLLER_H
#include<string>
#include <string>
#include <vector>
#include "animation.h"
namespace vb01{
class Skeleton;
class AnimationChannel;
class AnimationController{
public:
AnimationController();
AnimationController(Skeleton*);
~AnimationController();
void update();
Animation* getAnimation(std::string);
inline void addAnimation(Animation *anim){animations.push_back(anim);}
inline void addAnimationChannel(AnimationChannel *channel){channels.push_back(channel);}
private:
void applyBoneTransforms(Animation::KeyframeGroup*);
Skeleton *skeleton = nullptr;
std::vector<Animation*> animations;
std::vector<AnimationChannel*> channels;
protected:
void onAnimationEnd(std::string){}
void onAnimationStart(std::string){}
+2 -9
View File
@@ -1,5 +1,6 @@
#include"skeleton.h"
#include"animation.h"
#include"animationController.h"
#include"box.h"
using namespace std;
@@ -7,6 +8,7 @@ using namespace std;
namespace vb01{
Skeleton::Skeleton(string name){
this->name=name;
controller = new AnimationController(this);
}
void Skeleton::update(){
@@ -31,13 +33,4 @@ namespace vb01{
return bone;
}
Animation* Skeleton::getAnimation(string name){
Animation *anim=nullptr;
for(Animation *a : animations)
if(a->getName()==name){
anim=a;
break;
}
return anim;
}
}
+3 -3
View File
@@ -7,6 +7,7 @@
namespace vb01{
class Animation;
class AnimationController;
class Skeleton{
public:
@@ -14,8 +15,7 @@ namespace vb01{
void update();
void addBone(Bone*,Bone*);
Bone* getBone(std::string);
Animation* getAnimation(std::string);
inline void addAnimation(Animation *anim){animations.push_back(anim);}
inline AnimationController* getAnimationController(){return controller;}
inline Bone* getBone(int i){return bones[i];}
inline Bone* getRootBone(){return bones[0];}
inline std::vector<Bone*>& getBones(){return bones;}
@@ -24,7 +24,7 @@ namespace vb01{
private:
std::string name;
std::vector<Bone*> bones;
std::vector<Animation*> animations;
AnimationController *controller = nullptr;
};
}
+4 -3
View File
@@ -6,6 +6,7 @@
#include"bone.h"
#include"model.h"
#include"animation.h"
#include"animationController.h"
#include<vector>
#include<fstream>
@@ -137,13 +138,13 @@ namespace vb01{
if(preColon == "animationName"){
string postColon = l.substr(colonId + 2, string::npos);
animName = postColon;
skeleton->addAnimation(new Animation(animName));
skeleton->getAnimationController()->addAnimation(new Animation(animName));
continue;
}
Bone *b = skeleton->getBone(preColon);
if(b){
animBone = b;
Animation *anim = skeleton->getAnimation(animName);
Animation *anim = skeleton->getAnimationController()->getAnimation(animName);
Animation::KeyframeGroup *group = anim->getKeyframeGroup(animBone);
if(!group){
Animation::KeyframeGroup kg;
@@ -183,7 +184,7 @@ namespace vb01{
keyframe.interpolation = interp;
keyframe.value = value;
keyframe.frame = frame;
skeleton->getAnimation(animName)->getKeyframeGroup(animBone)->keyframes.push_back(keyframe);
skeleton->getAnimationController()->getAnimation(animName)->getKeyframeGroup(animBone)->keyframes.push_back(keyframe);
}
}
}