From 0614f7b034387b8688274a968397ce3c052cbddf Mon Sep 17 00:00:00 2001 From: devZoGok Date: Mon, 9 Nov 2020 21:01:05 +0200 Subject: [PATCH] animation classes refactoring --- animation.cpp | 10 +- animationChannel.cpp | 19 ++-- animationChannel.h | 1 + animationController.cpp | 224 ++++++++++++++++++++++++---------------- animationController.h | 7 ++ 5 files changed, 157 insertions(+), 104 deletions(-) diff --git a/animation.cpp b/animation.cpp index 4fa8822..cddadcd 100644 --- a/animation.cpp +++ b/animation.cpp @@ -14,12 +14,12 @@ namespace vb01{ } Animation::KeyframeGroup* Animation::getKeyframeGroup(Bone *b){ - int id=-1; - for(int i=0;i-1?&(keyframeGroups[id]):nullptr; + return id > -1 ? &(keyframeGroups[id]) : nullptr; } } diff --git a/animationChannel.cpp b/animationChannel.cpp index 18bcb63..1c402fd 100644 --- a/animationChannel.cpp +++ b/animationChannel.cpp @@ -29,14 +29,18 @@ namespace vb01{ void AnimationChannel::setAnimationName(string animName){ this->animationName = animName; + numFrames = getMaxKeyframeNum(animName); + } + + int AnimationChannel::getMaxKeyframeNum(string animName){ + int maxKeyframeNum; Animation *animation = controller->getAnimation(animName); KeyframeGroup *startGroup = animation->getKeyframeGroup(bones[0]); int numStartKeyframes = startGroup->keyframeChannels[0].keyframes.size(); - numFrames = startGroup->keyframeChannels[0].keyframes[numStartKeyframes - 1].frame; - //firstFrame = startGroup->keyframeChannels[0].keyframes[0].frame; + 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]); for(int j = 0 ; j < kg->keyframeChannels.size(); j++){ @@ -45,16 +49,13 @@ namespace vb01{ for(int k = 0; k < ch.keyframes.size(); k++){ int numKeyframes = ch.keyframes.size(); int maxFrame = ch.keyframes[numKeyframes - 1].frame; - int minFrame = ch.keyframes[0].frame; if(numFrames < maxFrame) - numFrames = maxFrame; - /* - if(firstFrame > minFrame) - firstFrame = minFrame; - */ + maxKeyframeNum = maxFrame; } } } + + return maxKeyframeNum; } } diff --git a/animationChannel.h b/animationChannel.h index ba60633..db23b7c 100644 --- a/animationChannel.h +++ b/animationChannel.h @@ -30,6 +30,7 @@ namespace vb01{ inline std::string getAnimationName(){return animationName;} private: inline bool canUpdate(){return getTime() - lastUpdateTime > updateRate;} + int getMaxKeyframeNum(std::string); s64 lastUpdateTime = 0; int updateRate = 16; diff --git a/animationController.cpp b/animationController.cpp index cb6d43e..52173ad 100644 --- a/animationController.cpp +++ b/animationController.cpp @@ -16,99 +16,143 @@ namespace vb01{ for(AnimationChannel *channel : channels){ channel->update(); - Animation *animation = skeleton->getAnimationController()->getAnimation(channel->getAnimationName()); - for(Bone *channelBone : channel->getBones()){ - Animation::KeyframeGroup *keyframeGroup = animation->getKeyframeGroup(channelBone); - int pastKeyframeId = -1; - - Vector3 pastPos, currentPos, nextPos, pastScale, currentScale, nextScale; - Quaternion pastRot, currentRot, nextRot; - - for(KeyframeChannel animChannel : keyframeGroup->keyframeChannels){ - for(int i = 0 ; i < animChannel.keyframes.size(); i++){ - Keyframe keyframe = animChannel.keyframes[i]; - if(channel->getCurrentFrame() >= keyframe.frame){ - pastKeyframeId = i; - } - } - - Keyframe pastKeyframe = animChannel.keyframes[pastKeyframeId]; - Keyframe nextKeyframe = animChannel.keyframes[pastKeyframeId + 1]; - 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; - } - } - swap(currentRot.y, currentRot.z); - currentRot.z = -currentRot.z; - - channelBone->setPosePos(currentPos); - channelBone->setPoseRot(currentRot); - //channelBone->setPoseScale(currentScale); - } + transformBones(channel); } } + void AnimationController::transformBones(AnimationChannel *channel){ + Animation *animation = getAnimation(channel->getAnimationName()); + + for(Bone *channelBone : channel->getBones()){ + Animation::KeyframeGroup *keyframeGroup = animation->getKeyframeGroup(channelBone); + Vector3 pastPos, nextPos, pastScale, nextScale; + Quaternion pastRot, nextRot; + Keyframe::Interpolation interp; + float ratio; + + prepareAdjacentValues(pastPos, nextPos, pastRot, nextRot, pastScale, nextScale, interp, ratio, keyframeGroup, channel); + + 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); + } + } + + void AnimationController::prepareAdjacentValues( + Vector3 &pastPos, + Vector3 &nextPos, + Quaternion &pastRot, + Quaternion &nextRot, + Vector3 &pastScale, + Vector3 &nextScale, + KeyframeInterpolation &interpMode, + float &ratio, + Animation::KeyframeGroup *keyframeGroup, + AnimationChannel *channel + ){ + + int pastKeyframeId = -1; + for(KeyframeChannel animChannel : keyframeGroup->keyframeChannels){ + for(int i = 0 ; i < animChannel.keyframes.size(); i++){ + Keyframe keyframe = animChannel.keyframes[i]; + if(channel->getCurrentFrame() >= keyframe.frame){ + pastKeyframeId = i; + } + } + + Keyframe pastKeyframe = animChannel.keyframes[pastKeyframeId]; + Keyframe nextKeyframe = animChannel.keyframes[pastKeyframeId + 1]; + int pastFrame = pastKeyframe.frame; + int nextFrame = nextKeyframe.frame; + ratio = (float)(channel->getCurrentFrame() - pastFrame) / (nextFrame - pastFrame); + interpMode = pastKeyframe.interpolation; + + 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; + } + + } + } + + Vector3 AnimationController::interpolate(Vector3 pastPos, Vector3 nextPos, Keyframe::Interpolation mode, float ratio){ + Vector3 currentPos; + switch(mode){ + case Keyframe::CONSTANT: + currentPos = pastPos; + break; + case Keyframe::LINEAR: + currentPos = pastPos + (nextPos - pastPos) * ratio; + break; + case Keyframe::BEZIER: + currentPos = pastPos + (nextPos - pastPos) * ratio; + break; + } + return currentPos; + } + + Quaternion AnimationController::interpolate(Quaternion pastRot, Quaternion nextRot, Keyframe::Interpolation mode, float ratio){ + Quaternion currentRot; + switch(mode){ + case Keyframe::CONSTANT: + currentRot = pastRot; + break; + case Keyframe::LINEAR: + currentRot = pastRot + (nextRot - pastRot) * ratio; + break; + case Keyframe::BEZIER: + currentRot = pastRot + (nextRot - pastRot) * ratio; + break; + } + return currentRot; + } + Animation* AnimationController::getAnimation(string name){ Animation *anim = nullptr; for(Animation *a : animations) diff --git a/animationController.h b/animationController.h index 0ed1b07..237dba5 100644 --- a/animationController.h +++ b/animationController.h @@ -8,6 +8,8 @@ namespace vb01{ class Skeleton; class AnimationChannel; + class Vector3; + class Quaternion; class AnimationController{ public: @@ -21,6 +23,11 @@ namespace vb01{ Skeleton *skeleton = nullptr; std::vector animations; std::vector channels; + + void transformBones(AnimationChannel*); + void prepareAdjacentValues(Vector3&, Vector3&, Quaternion&, Quaternion&, Vector3&, Vector3&, Keyframe::Interpolation&, float&, KeyframeGroup*, AnimationChannel*); + Vector3 interpolate(Vector3, Vector3, Keyframe::Interpolation, float); + Quaternion interpolate(Quaternion, Quaternion, Keyframe::Interpolation, float); protected: void onAnimationEnd(std::string){} void onAnimationStart(std::string){}