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