Bezier interpolation

This commit is contained in:
devZoGok
2021-10-19 19:06:41 +03:00
parent 84a594e670
commit 8f9e657d14
6 changed files with 46 additions and 16 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ namespace vb01{
float ratio = (float)(max(0, currentFrame - pastFrame)) / (nextFrame - pastFrame);
Keyframe::Interpolation interp = pastKeyframe.interpolation;
float value = KeyframeChannel::interpolate(pastKeyframe.value, nextKeyframe.value, interp, ratio);
float value = KeyframeChannel::interpolate(pastKeyframe, nextKeyframe, ratio);
animatable->animate(value, keyframeChannel);
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ namespace vb01{
ratio = 0;
Keyframe::Interpolation interp = pastKeyframe.interpolation;
float value = KeyframeChannel::interpolate(pastKeyframe.value, nextKeyframe.value, interp, ratio);
float value = KeyframeChannel::interpolate(pastKeyframe, nextKeyframe, ratio);
keyframeChannel.animatable->animate(value, keyframeChannel);
}
+18 -6
View File
@@ -3,22 +3,34 @@
using namespace std;
namespace vb01{
float KeyframeChannel::interpolate(float pastValue, float nextValue, Keyframe::Interpolation mode, float ratio){
float KeyframeChannel::interpolate(Keyframe pastKeyframe, Keyframe nextKeyframe, float ratio){
float currentValue;
switch(mode){
switch(pastKeyframe.interpolation){
case Keyframe::CONSTANT:
currentValue = pastValue;
currentValue = pastKeyframe.value;
break;
case Keyframe::LINEAR:
currentValue = pastValue + (nextValue - pastValue) * ratio;
break;
case Keyframe::BEZIER:
currentValue = pastValue + (nextValue - pastValue) * ratio;
vector<float> points = vector<float>({pastKeyframe.value, pastKeyframe.rightHandleValue, nextKeyframe.leftHandleValue, nextKeyframe.value});
currentValue = interpolateBezier(points, ratio);
break;
}
return currentValue;
}
float KeyframeChannel::interpolateBezier(vector<float> points, float ratio){
int numPoints = points.size();
vector<float> newPoints;
for(int i = 0; i < numPoints - 1; i++)
newPoints.push_back(points[i] + (points[i + 1] - points[i]) * ratio);
if(newPoints.size() >= 2)
return interpolateBezier(newPoints, ratio);
else
return newPoints[0];
}
KeyframeChannelType KeyframeChannel::getKeyframeChannelType(string typeString){
KeyframeChannelType type;
if(typeString == "pos_x")
+3 -2
View File
@@ -26,7 +26,7 @@ namespace vb01{
struct Keyframe{
enum Interpolation{CONSTANT, LINEAR, BEZIER};
float value, frame;
float value, leftHandleValue, rightHandleValue, frame, leftHandleFrame, rightHandleFrame;
Interpolation interpolation;
};
@@ -34,8 +34,9 @@ namespace vb01{
Animatable *animatable = nullptr;
std::vector<Keyframe> keyframes;
static float interpolateBezier(std::vector<float>, float);
static KeyframeChannel::Type getKeyframeChannelType(std::string);
static float interpolate(float, float, Keyframe::Interpolation, float);
static float interpolate(Keyframe, Keyframe, float);
static Keyframe findKeyframe(float, KeyframeChannel, bool);
static void transform();
};
+18 -5
View File
@@ -149,10 +149,12 @@ def getChannelType(channel):
def readChannel(channel):
channelType = getChannelType(channel)
for keyframe in channel.keyframe_points:
numKeyframes = len(channel.keyframe_points)
for i in range(numKeyframes):
keyframe = channel.keyframe_points[i]
keyframeId = keyframe.co[0]
interp = keyframe.interpolation
interpInt = - 1
interpInt = -1
if interp == 'CONSTANT':
interpInt = 0
@@ -163,9 +165,20 @@ def readChannel(channel):
keyframeValue = keyframe.co[1]
file.write(str(keyframeValue) + ' ' + str(keyframeId) + ' ' + str(interpInt))
if interp == 'BEZIER':
file.write(' ' + str(keyframe.handle_left.x) + ' ' + str(keyframe.handle_left.y) + ' ')
file.write(str(keyframe.handle_right.x) + ' ' + str(keyframe.handle_right.y) + ' ')
leftHandleValue = (keyframe.handle_left[1])
leftHandleFrame = (keyframe.handle_left[0])
rightHandleValue = (keyframe.handle_right[1])
rightHandleFrame = (keyframe.handle_right[0])
if interp != 'BEZIER':
rightHandleValue = keyframeValue
rightHandleFrame = keyframeId
if i > 0 and channel.keyframe_points[i - 1].interpolation != 'BEZIER':
leftHandleValue = keyframeValue
leftHandleFrame = keyframeId
file.write(' ' + str(leftHandleValue) + ' ' + str(leftHandleFrame) + ' ')
file.write(str(rightHandleValue) + ' ' + str(rightHandleFrame) + ' ')
file.write('\n')
def readDriver(channel, driverName):
+5 -1
View File
@@ -259,8 +259,12 @@ namespace vb01{
Keyframe keyframe;
keyframe.value = atof(keyframeData[0].c_str());
keyframe.frame = atoi(keyframeData[1].c_str());
keyframe.frame = atof(keyframeData[1].c_str());
keyframe.interpolation = (KeyframeInterpolation)atoi(keyframeData[2].c_str());
keyframe.leftHandleValue = atof(keyframeData[3].c_str());
keyframe.leftHandleFrame = atof(keyframeData[4].c_str());
keyframe.rightHandleValue = atof(keyframeData[5].c_str());
keyframe.rightHandleFrame = atof(keyframeData[6].c_str());
keyframeChannels[currentChannel].keyframes.push_back(keyframe);
numCurrentTypeKeyframes++;