mirror of
https://github.com/devZoGok/vb01.git
synced 2026-08-26 19:43:30 +00:00
animation controller and channels (beginning)
This commit is contained in:
+1
-1
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user