From e84086674d3b4009927b255afc81fcccb50998fe Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sat, 15 Aug 2020 22:32:51 +0300 Subject: [PATCH] new keyframe structure --- animation.h | 26 ++++++-- animationChannel.cpp | 14 ---- animationChannel.h | 5 +- animationController.cpp | 140 +++++++++++++++++++++++----------------- animationController.h | 2 - vbModelReader.cpp | 74 ++++++++++++++------- vec3.h | 17 ----- 7 files changed, 153 insertions(+), 125 deletions(-) delete mode 100644 vec3.h diff --git a/animation.h b/animation.h index 0825399..fa58044 100644 --- a/animation.h +++ b/animation.h @@ -10,7 +10,7 @@ namespace vb01{ class Animation{ public: struct KeyframeGroup{ - struct Keyframe{ + struct KeyframeChannel{ enum Type{ POS_X, POS_Y, @@ -23,17 +23,23 @@ namespace vb01{ SCALE_Y, SCALE_Z }; - enum Interpolation{CONSTANT, LINEAR, BEZIER}; - + struct Keyframe{ + enum Interpolation{CONSTANT, LINEAR, BEZIER}; + + float value; + int frame; + Interpolation interpolation; + }; + Type type; - Interpolation interpolation; - float value; - int frame; + std::vector keyframes; }; + Bone *bone = nullptr; - std::vector keyframes; + std::vector keyframeChannels; }; + Animation(std::string); ~Animation(); void update(); @@ -44,6 +50,12 @@ namespace vb01{ std::string name; std::vector keyframeGroups; }; + + typedef Animation::KeyframeGroup KeyframeGroup; + typedef Animation::KeyframeGroup::KeyframeChannel KeyframeChannel; + typedef Animation::KeyframeGroup::KeyframeChannel::Type KeyframeChannelType; + typedef Animation::KeyframeGroup::KeyframeChannel::Keyframe Keyframe; + typedef Animation::KeyframeGroup::KeyframeChannel::Keyframe::Interpolation KeyframeInterpolation; } #endif diff --git a/animationChannel.cpp b/animationChannel.cpp index 6e74fe3..0b72eb4 100644 --- a/animationChannel.cpp +++ b/animationChannel.cpp @@ -11,18 +11,4 @@ namespace vb01{ 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; - } - } } diff --git a/animationChannel.h b/animationChannel.h index 14c836d..12a6c83 100644 --- a/animationChannel.h +++ b/animationChannel.h @@ -12,7 +12,7 @@ namespace vb01{ public: AnimationChannel(AnimationController*); ~AnimationChannel(); - void setAnimationName(std::string name); + inline void setAnimationName(std::string name){this->animationName = name;} inline std::vector getBones(){return bones;} inline void addBone(Bone *bone){bones.push_back(bone);} inline void removeAllBones(){bones.clear();} @@ -20,14 +20,13 @@ namespace vb01{ 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; + int currentFrame = 0; bool loop = false; std::string animationName; std::vector bones; diff --git a/animationController.cpp b/animationController.cpp index 0a555d8..b5807fa 100644 --- a/animationController.cpp +++ b/animationController.cpp @@ -18,68 +18,90 @@ namespace vb01{ 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; + + Vector3 pastPos, currentPos, nextPos, pastScale, currentScale, nextScale; + Quaternion pastRot, currentRot, nextRot; + + for(Animation::KeyframeGroup::KeyframeChannel &animChannel : keyframeGroup->keyframeChannels){ + for(int i = 0 ; i < animChannel.keyframes.size(); i++){ + Keyframe keyframe = animChannel.keyframes[i]; + if(keyframe.frame > channel->getCurrentFrame()){ + keyframeId = i; + break; + } + } + + Keyframe pastKeyframe = animChannel.keyframes[keyframeId - 1]; + Keyframe nextKeyframe = animChannel.keyframes[keyframeId]; + int pastFrame = pastKeyframe.frame; + int nextFrame = nextKeyframe.frame; + float ratio = (float)(channel->getCurrentFrame() - pastFrame) / (nextFrame - pastFrame); + + switch(animChannel.type){ + case KeyframeChannel::POS_X: + pastPos.x = pastKeyframe.value; + nextPos.x = nextKeyframe.value; + break; + case KeyframeChannel::POS_Y: + pastPos.y = pastKeyframe.value; + nextPos.y = nextKeyframe.value; + break; + case KeyframeChannel::POS_Z: + pastPos.z = pastKeyframe.value; + nextPos.z = nextKeyframe.value; + break; + case KeyframeChannel::ROT_W: + pastRot.w = pastKeyframe.value; + nextRot.w = nextKeyframe.value; + break; + case KeyframeChannel::ROT_X: + pastRot.x = pastKeyframe.value; + nextRot.x = nextKeyframe.value; + break; + case KeyframeChannel::ROT_Y: + pastRot.y = pastKeyframe.value; + nextRot.y = nextKeyframe.value; + break; + case KeyframeChannel::ROT_Z: + pastRot.z = pastKeyframe.value; + nextRot.z = nextKeyframe.value; + break; + case KeyframeChannel::SCALE_X: + pastScale.x = pastKeyframe.value; + nextScale.x = nextKeyframe.value; + break; + case KeyframeChannel::SCALE_Y: + pastScale.y = pastKeyframe.value; + nextScale.y = nextKeyframe.value; + break; + case KeyframeChannel::SCALE_Z: + pastScale.z = pastKeyframe.value; + nextScale.z = nextKeyframe.value; + break; + } + + switch(pastKeyframe.interpolation){ + case Keyframe::CONSTANT: + currentPos = pastPos; + currentRot = pastRot; + currentScale = pastScale; + break; + case Keyframe::LINEAR: + currentPos = pastPos + (nextPos - pastPos) * ratio; + currentRot = pastRot + (nextRot - pastRot) * ratio; + currentScale = pastScale + (nextScale - pastScale) * ratio; + break; + case Keyframe::BEZIER: + currentPos = pastPos + (nextPos - pastPos) * ratio; + currentRot = pastRot + (nextRot - pastRot) * ratio; + currentScale = pastScale + (nextScale - pastScale) * ratio; + 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; + channelBone->setPosePos(currentPos); + channelBone->setPoseRot(currentRot); + channelBone->setPoseScale(currentScale); } } } diff --git a/animationController.h b/animationController.h index 3f7ca8c..0ed1b07 100644 --- a/animationController.h +++ b/animationController.h @@ -18,8 +18,6 @@ namespace vb01{ 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 animations; std::vector channels; diff --git a/vbModelReader.cpp b/vbModelReader.cpp index 003b754..558e61b 100644 --- a/vbModelReader.cpp +++ b/vbModelReader.cpp @@ -127,9 +127,10 @@ namespace vb01{ bone->lookAt(zAxis, yAxis, parent); } + AnimationController *controller = skeleton->getAnimationController(); string animName = ""; Bone *animBone = nullptr; - Animation::KeyframeGroup::Keyframe::Type type; + Animation::KeyframeGroup::KeyframeChannel::Type type; meshData.clear(); readFile(path, meshData, animationStartLine, endLine + 1); for(string l : meshData){ @@ -138,13 +139,13 @@ namespace vb01{ if(preColon == "animationName"){ string postColon = l.substr(colonId + 2, string::npos); animName = postColon; - skeleton->getAnimationController()->addAnimation(new Animation(animName)); + controller->addAnimation(new Animation(animName)); continue; } Bone *b = skeleton->getBone(preColon); if(b){ animBone = b; - Animation *anim = skeleton->getAnimationController()->getAnimation(animName); + Animation *anim = controller->getAnimation(animName); Animation::KeyframeGroup *group = anim->getKeyframeGroup(animBone); if(!group){ Animation::KeyframeGroup kg; @@ -153,38 +154,65 @@ namespace vb01{ } } else{ - Animation::KeyframeGroup::Keyframe::Interpolation interp; + KeyframeGroup *keyframeGroup = controller->getAnimation(animName)->getKeyframeGroup(animBone); + KeyframeInterpolation interp; + KeyframeChannel channel; + if(l == "}") break; - else if(preColon == "pos_x") - type=Animation::KeyframeGroup::Keyframe::Type::POS_X; - else if(preColon == "pos_y") - type = Animation::KeyframeGroup::Keyframe::Type::POS_Y; - else if(preColon == "pos_z") - type = Animation::KeyframeGroup::Keyframe::Type::POS_Z; - else if(preColon == "rot_w") - type = Animation::KeyframeGroup::Keyframe::Type::ROT_W; - else if(preColon == "rot_x") - type = Animation::KeyframeGroup::Keyframe::Type::ROT_X; - else if(preColon == "rot_y") - type = Animation::KeyframeGroup::Keyframe::Type::ROT_Y; - else if(preColon == "rot_z") - type = Animation::KeyframeGroup::Keyframe::Type::ROT_Z; + else if(preColon == "pos_x"){ + type = KeyframeChannelType::POS_X; + channel.type = type; + keyframeGroup->keyframeChannels.push_back(channel); + } + else if(preColon == "pos_y"){ + type = KeyframeChannelType::POS_Y; + channel.type = type; + keyframeGroup->keyframeChannels.push_back(channel); + } + else if(preColon == "pos_z"){ + type = KeyframeChannelType::POS_Z; + channel.type = type; + keyframeGroup->keyframeChannels.push_back(channel); + } + else if(preColon == "rot_w"){ + type = KeyframeChannelType::ROT_W; + channel.type = type; + keyframeGroup->keyframeChannels.push_back(channel); + } + else if(preColon == "rot_x"){ + type = KeyframeChannelType::ROT_X; + channel.type = type; + keyframeGroup->keyframeChannels.push_back(channel); + } + else if(preColon == "rot_y"){ + type = KeyframeChannelType::ROT_Y; + channel.type = type; + keyframeGroup->keyframeChannels.push_back(channel); + } + else if(preColon == "rot_z"){ + type = KeyframeChannelType::ROT_Z; + channel.type = type; + keyframeGroup->keyframeChannels.push_back(channel); + } else{ int numData = 3; string data[numData]; - getLineData(l,data,numData); + getLineData(l, data, numData); float value = atof(data[0].c_str()), frame = atoi(data[1].c_str()); - interp = (Animation::KeyframeGroup::Keyframe::Interpolation)atoi(data[2].c_str()); + interp = (KeyframeInterpolation)atoi(data[2].c_str()); - Animation::KeyframeGroup::Keyframe keyframe; - keyframe.type = type; + Animation::KeyframeGroup::KeyframeChannel::Keyframe keyframe; + //keyframe.type = type; keyframe.interpolation = interp; keyframe.value = value; keyframe.frame = frame; - skeleton->getAnimationController()->getAnimation(animName)->getKeyframeGroup(animBone)->keyframes.push_back(keyframe); + for(KeyframeChannel &channel : keyframeGroup->keyframeChannels) + if(channel.type == type) + channel.keyframes.push_back(keyframe); + //skeleton->getAnimationController()->getAnimation(animName)->getKeyframeGroup(animBone)->keyframes.push_back(keyframe); } } } diff --git a/vec3.h b/vec3.h deleted file mode 100644 index 37dc789..0000000 --- a/vec3.h +++ /dev/null @@ -1,17 +0,0 @@ -#include - -namespace vb01{ - class vec3{ - public: - vec3(float x, float y, float z){ - this->x=x; - this->y=y; - this->z=z; - } - inline vec3 operator+ (vec3 v){return vec3(this->x+v.x,this->y+v.y,this->z+v.z);} - inline float dot(vec3 v){return this->x*v.x+this->y*v.y+this->z*v.z;} - - float x,y,z; - private: - }; -}