|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tstream.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tconvert.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcubicbezier.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tundo.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tdoublekeyframe.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tdoubleparamfile.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "texpression.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tgrammar.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tparser.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tunit.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// STD includes
|
|
Toshihiro Shimizu |
890ddd |
#include <set></set>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tdoubleparam.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace std;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===============================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TActualDoubleKeyframe final : public TDoubleKeyframe {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
mutable TExpression m_expression;
|
|
Shinya Kitaoka |
120a6e |
mutable TDoubleParamFileData m_fileData;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe(double frame = 0, double value = 0)
|
|
Shinya Kitaoka |
120a6e |
: TDoubleKeyframe(frame, value), m_unit(0) {}
|
|
Shinya Kitaoka |
120a6e |
explicit TActualDoubleKeyframe(const TDoubleKeyframe &src) : m_unit(0) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::operator=(src);
|
|
Shinya Kitaoka |
120a6e |
if (m_type == Expression || m_type == SimilarShape)
|
|
Shinya Kitaoka |
120a6e |
m_expression.setText(m_expressionText);
|
|
Shinya Kitaoka |
120a6e |
else if (m_type == File)
|
|
Shinya Kitaoka |
120a6e |
m_fileData.setParams(m_fileParams);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe &operator=(const TDoubleKeyframe &src) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::operator=(src);
|
|
Shinya Kitaoka |
120a6e |
m_unit = 0;
|
|
Shinya Kitaoka |
120a6e |
if (m_type == Expression || m_type == SimilarShape) {
|
|
Shinya Kitaoka |
120a6e |
m_expression.setText(m_expressionText);
|
|
Shinya Kitaoka |
120a6e |
} else if (m_type == File) {
|
|
Shinya Kitaoka |
120a6e |
m_fileData.setParams(m_fileParams);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TUnit *updateUnit(const TMeasure *measure) {
|
|
Shinya Kitaoka |
120a6e |
if (!measure) {
|
|
Shinya Kitaoka |
120a6e |
m_unit = 0;
|
|
Shinya Kitaoka |
120a6e |
m_unitName = "";
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (m_unitName != "")
|
|
Shinya Kitaoka |
120a6e |
m_unit = measure->getUnit(::to_wstring(m_unitName));
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_unit = 0;
|
|
Shinya Kitaoka |
120a6e |
if (!m_unit) {
|
|
Shinya Kitaoka |
120a6e |
m_unit = measure->getCurrentUnit();
|
|
Shinya Kitaoka |
120a6e |
if (m_unit) {
|
|
Shinya Kitaoka |
120a6e |
QString app = QString::fromStdWString(m_unit->getDefaultExtension());
|
|
Shinya Kitaoka |
120a6e |
m_unitName = app.toStdString();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(measure || m_unit == 0 && m_unitName == "");
|
|
Shinya Kitaoka |
120a6e |
assert((m_unit == 0) == (m_unitName == ""));
|
|
Shinya Kitaoka |
120a6e |
QString app = QString::fromStdString(m_unitName);
|
|
Shinya Kitaoka |
120a6e |
assert(m_unit == 0 || m_unit->isExtension(app.toStdWString()));
|
|
Shinya Kitaoka |
120a6e |
return m_unit;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double convertFrom(TMeasure *measure, double value) const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_unit) const_cast<tactualdoublekeyframe *="">(this)->updateUnit(measure);</tactualdoublekeyframe>
|
|
Shinya Kitaoka |
120a6e |
if (m_unit) value = m_unit->convertFrom(value);
|
|
Shinya Kitaoka |
120a6e |
return value;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
mutable const TUnit *m_unit;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef vector<tactualdoublekeyframe> DoubleKeyframeVector;</tactualdoublekeyframe>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double getConstantValue(const TActualDoubleKeyframe &k0,
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &k1, double f) {
|
|
Shinya Kitaoka |
120a6e |
return (f == k1.m_frame) ? k1.m_value : k0.m_value;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double getLinearValue(const TActualDoubleKeyframe &k0,
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &k1, double f) {
|
|
Shinya Kitaoka |
120a6e |
return k0.m_value +
|
|
Shinya Kitaoka |
120a6e |
(f - k0.m_frame) * (k1.m_value - k0.m_value) /
|
|
Shinya Kitaoka |
120a6e |
(k1.m_frame - k0.m_frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void truncateSpeeds(double aFrame, double bFrame, TPointD &aSpeedTrunc,
|
|
Campbell Barton |
8c6c57 |
TPointD &bSpeedTrunc) {
|
|
Shinya Kitaoka |
120a6e |
double deltaX = bFrame - aFrame;
|
|
Shinya Kitaoka |
120a6e |
if (aSpeedTrunc.x < 0) aSpeedTrunc.x = 0;
|
|
Shinya Kitaoka |
120a6e |
if (bSpeedTrunc.x > 0) bSpeedTrunc.x = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (aFrame + aSpeedTrunc.x > bFrame) {
|
|
Shinya Kitaoka |
120a6e |
if (aSpeedTrunc.x != 0) {
|
|
Shinya Kitaoka |
120a6e |
aSpeedTrunc = aSpeedTrunc * (deltaX / aSpeedTrunc.x);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (bFrame + bSpeedTrunc.x < aFrame) {
|
|
Shinya Kitaoka |
120a6e |
if (bSpeedTrunc.x != 0) {
|
|
Shinya Kitaoka |
120a6e |
bSpeedTrunc = -bSpeedTrunc * (deltaX / bSpeedTrunc.x);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double getSpeedInOutValue(const TActualDoubleKeyframe &k0,
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &k1,
|
|
Shinya Kitaoka |
120a6e |
const TPointD &speed0, const TPointD &speed1,
|
|
Shinya Kitaoka |
120a6e |
double frame) {
|
|
Shinya Kitaoka |
120a6e |
double aFrame = k0.m_frame;
|
|
Shinya Kitaoka |
120a6e |
double bFrame = k1.m_frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double aValue = k0.m_value;
|
|
Shinya Kitaoka |
120a6e |
double bValue = k1.m_value;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (frame <= aFrame)
|
|
Shinya Kitaoka |
120a6e |
return aValue;
|
|
Shinya Kitaoka |
120a6e |
else if (frame >= bFrame)
|
|
Shinya Kitaoka |
120a6e |
return bValue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD aSpeedTrunc = speed0;
|
|
Shinya Kitaoka |
120a6e |
TPointD bSpeedTrunc = speed1;
|
|
Shinya Kitaoka |
120a6e |
truncateSpeeds(aFrame, bFrame, aSpeedTrunc, bSpeedTrunc);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return getCubicBezierY(frame, TPointD(aFrame, aValue), aSpeedTrunc,
|
|
Shinya Kitaoka |
120a6e |
bSpeedTrunc, TPointD(bFrame, bValue));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DV_EXPORT_API void splitSpeedInOutSegment(TDoubleKeyframe &k,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe &k0,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe &k1) {
|
|
Shinya Kitaoka |
120a6e |
if (k.m_frame <= k0.m_frame) {
|
|
Shinya Kitaoka |
120a6e |
k = k0;
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
} else if (k.m_frame >= k1.m_frame) {
|
|
Shinya Kitaoka |
120a6e |
k = k1;
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD aSpeed = k0.m_speedOut;
|
|
Shinya Kitaoka |
120a6e |
TPointD bSpeed = k1.m_speedIn;
|
|
Shinya Kitaoka |
120a6e |
truncateSpeeds(k0.m_frame, k1.m_frame, aSpeed, bSpeed);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD p0(k0.m_frame, k0.m_value);
|
|
Shinya Kitaoka |
120a6e |
TPointD p3(k1.m_frame, k1.m_value);
|
|
Shinya Kitaoka |
120a6e |
TPointD p1 = p0 + aSpeed;
|
|
Shinya Kitaoka |
120a6e |
TPointD p2 = p3 + bSpeed;
|
|
Shinya Kitaoka |
120a6e |
double t = invCubicBezierX(k.m_frame, p0, aSpeed, bSpeed, p3);
|
|
Shinya Kitaoka |
120a6e |
t = tcrop(t, 0.0, 1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD p01 = (1 - t) * p0 + t * p1;
|
|
Shinya Kitaoka |
120a6e |
TPointD p12 = (1 - t) * p1 + t * p2;
|
|
Shinya Kitaoka |
120a6e |
TPointD p23 = (1 - t) * p2 + t * p3;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD p012 = (1 - t) * p01 + t * p12;
|
|
Shinya Kitaoka |
120a6e |
TPointD p123 = (1 - t) * p12 + t * p23;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD p = (1 - t) * p012 + t * p123;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(fabs(p.x - k.m_frame) < 0.1e-3);
|
|
Shinya Kitaoka |
120a6e |
k.m_value = p.y;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
k0.m_speedOut = p01 - p0;
|
|
Shinya Kitaoka |
120a6e |
k.m_speedIn = p012 - p;
|
|
Shinya Kitaoka |
120a6e |
k.m_speedOut = p123 - p;
|
|
Shinya Kitaoka |
120a6e |
k1.m_speedIn = p23 - p3;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double getEaseInOutValue(const TActualDoubleKeyframe &k0,
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &k1, double frame,
|
|
Shinya Kitaoka |
120a6e |
bool percentage) {
|
|
Shinya Kitaoka |
120a6e |
double x3 = k1.m_frame - k0.m_frame;
|
|
Shinya Kitaoka |
120a6e |
if (x3 <= 0.0) return k0.m_value;
|
|
Shinya Kitaoka |
120a6e |
double x = frame - k0.m_frame;
|
|
Shinya Kitaoka |
120a6e |
if (x <= 0)
|
|
Shinya Kitaoka |
120a6e |
return k0.m_value;
|
|
Shinya Kitaoka |
120a6e |
else if (x >= x3)
|
|
Shinya Kitaoka |
120a6e |
return k1.m_value;
|
|
Shinya Kitaoka |
120a6e |
double e0 = std::max(k0.m_speedOut.x, 0.0);
|
|
Shinya Kitaoka |
120a6e |
double e1 = std::max(-k1.m_speedIn.x, 0.0);
|
|
Shinya Kitaoka |
120a6e |
if (percentage) {
|
|
Shinya Kitaoka |
120a6e |
e0 *= x3 * 0.01;
|
|
Shinya Kitaoka |
120a6e |
e1 *= x3 * 0.01;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (e0 + e1 >= x3) {
|
|
Shinya Kitaoka |
120a6e |
double x = tcrop((e0 + x3 - e1) / 2, 0.0, x3);
|
|
Shinya Kitaoka |
120a6e |
e0 = x;
|
|
Shinya Kitaoka |
120a6e |
e1 = x3 - x;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
double x1 = e0, x2 = x3 - e1;
|
|
Shinya Kitaoka |
120a6e |
if (0 < x1 - x2 && x1 - x2 < 0.1e-5)
|
|
Shinya Kitaoka |
120a6e |
x1 = x2 = (x1 + x2) * 0.5; // against rounding problems
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= x1 && x1 <= x2 && x2 <= x3);
|
|
Shinya Kitaoka |
120a6e |
double v = 2 / (x3 + x2 - x1);
|
|
Shinya Kitaoka |
120a6e |
double value = 0;
|
|
Shinya Kitaoka |
120a6e |
if (x < x1) {
|
|
Shinya Kitaoka |
120a6e |
double a = v / e0;
|
|
Shinya Kitaoka |
120a6e |
value = 0.5 * a * x * x;
|
|
Shinya Kitaoka |
120a6e |
} else if (x > x2) {
|
|
Shinya Kitaoka |
120a6e |
double a = v / e1;
|
|
Shinya Kitaoka |
120a6e |
value = 1 - 0.5 * a * (x3 - x) * (x3 - x);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
double c = -0.5 * v * e0;
|
|
Shinya Kitaoka |
120a6e |
value = x * v + c;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return (1 - value) * k0.m_value + value * k1.m_value;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double getExponentialValue(const TActualDoubleKeyframe &k0,
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &k1,
|
|
Shinya Kitaoka |
120a6e |
double frame) {
|
|
Shinya Kitaoka |
120a6e |
double aFrame = k0.m_frame;
|
|
Shinya Kitaoka |
120a6e |
double bFrame = k1.m_frame;
|
|
Shinya Kitaoka |
120a6e |
double deltaX = bFrame - aFrame;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double aValue = k0.m_value;
|
|
Shinya Kitaoka |
120a6e |
double bValue = k1.m_value;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if min(aValue,bValue)<=0 => error => linear
|
|
Shinya Kitaoka |
120a6e |
if (aValue <= 0 || bValue <= 0) return getLinearValue(k0, k1, frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double t = (frame - aFrame) / deltaX;
|
|
Shinya Kitaoka |
120a6e |
// if aValue
|
|
Shinya Kitaoka |
120a6e |
// if bValue
|
|
Shinya Kitaoka |
120a6e |
if (bValue < aValue) {
|
|
Shinya Kitaoka |
120a6e |
t = 1 - t;
|
|
otakuto |
ed7dcd |
std::swap(aValue, bValue);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return aValue * exp(t * log(bValue / aValue));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double getExpressionValue(const TActualDoubleKeyframe &k0,
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &k1, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TMeasure *measure) {
|
|
Shinya Kitaoka |
120a6e |
double t = 0, rframe = frame - k0.m_frame;
|
|
Shinya Kitaoka |
120a6e |
if (k1.m_frame > k0.m_frame) t = rframe / (k1.m_frame - k0.m_frame);
|
|
Shinya Kitaoka |
120a6e |
TSyntax::Calculator *calculator = k0.m_expression.getCalculator();
|
|
Shinya Kitaoka |
120a6e |
if (calculator) {
|
|
Shinya Kitaoka |
120a6e |
calculator->setUnit(
|
|
Shinya Kitaoka |
120a6e |
(const_cast<tactualdoublekeyframe &="">(k0)).updateUnit(measure));</tactualdoublekeyframe>
|
|
Shinya Kitaoka |
120a6e |
return calculator->compute(t, frame + 1, rframe + 1);
|
|
Shinya Kitaoka |
120a6e |
} else if (measure)
|
|
Shinya Kitaoka |
120a6e |
return measure->getDefaultValue();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double getSimilarShapeValue(const TActualDoubleKeyframe &k0,
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &k1,
|
|
Shinya Kitaoka |
120a6e |
double frame, const TMeasure *measure) {
|
|
Shinya Kitaoka |
120a6e |
double offset = k0.m_similarShapeOffset;
|
|
Shinya Kitaoka |
120a6e |
double rv0 = getExpressionValue(k0, k1, k0.m_frame + offset, measure);
|
|
Shinya Kitaoka |
120a6e |
double rv1 = getExpressionValue(k0, k1, k1.m_frame + offset, measure);
|
|
Shinya Kitaoka |
120a6e |
double rv = getExpressionValue(k0, k1, frame + offset, measure);
|
|
Shinya Kitaoka |
120a6e |
double v0 = k0.m_value;
|
|
Shinya Kitaoka |
120a6e |
double v1 = k1.m_value;
|
|
Shinya Kitaoka |
120a6e |
if (rv1 != rv0)
|
|
Shinya Kitaoka |
120a6e |
return v0 + (v1 - v0) * (rv - rv0) / (rv1 - rv0);
|
|
Shinya Kitaoka |
120a6e |
else if (measure)
|
|
Shinya Kitaoka |
120a6e |
return measure->getDefaultValue();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TDoubleParam::Imp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
const TSyntax::Grammar *m_grammar;
|
|
Shinya Kitaoka |
120a6e |
string m_measureName;
|
|
Shinya Kitaoka |
120a6e |
TMeasure *m_measure;
|
|
Shinya Kitaoka |
120a6e |
double m_defaultValue, m_minValue, m_maxValue;
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector m_keyframes;
|
|
Shinya Kitaoka |
120a6e |
bool m_cycleEnabled;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::set<tparamobserver *=""> m_observers;</tparamobserver>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Imp(double v = 0.0)
|
|
Shinya Kitaoka |
120a6e |
: m_grammar(0)
|
|
Shinya Kitaoka |
120a6e |
, m_measureName()
|
|
Shinya Kitaoka |
120a6e |
, m_measure(0)
|
|
Shinya Kitaoka |
120a6e |
, m_defaultValue(v)
|
|
Shinya Kitaoka |
120a6e |
, m_minValue(-(std::numeric_limits<double>::max)())</double>
|
|
Shinya Kitaoka |
120a6e |
, m_maxValue((std::numeric_limits<double>::max)())</double>
|
|
Shinya Kitaoka |
120a6e |
, m_cycleEnabled(false) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~Imp() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void copy(std::unique_ptr<imp> const &src) {</imp>
|
|
Shinya Kitaoka |
120a6e |
m_grammar = src->m_grammar;
|
|
Shinya Kitaoka |
120a6e |
m_measureName = src->m_measureName;
|
|
Shinya Kitaoka |
120a6e |
m_measure = src->m_measure;
|
|
Shinya Kitaoka |
120a6e |
m_defaultValue = src->m_defaultValue;
|
|
Shinya Kitaoka |
120a6e |
m_minValue = src->m_minValue;
|
|
Shinya Kitaoka |
120a6e |
m_maxValue = src->m_maxValue;
|
|
Shinya Kitaoka |
120a6e |
m_keyframes = src->m_keyframes;
|
|
Shinya Kitaoka |
120a6e |
m_cycleEnabled = src->m_cycleEnabled;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void notify(const TParamChange &change) {
|
|
Shinya Kitaoka |
120a6e |
std::set<tparamobserver *="">::iterator it = m_observers.begin();</tparamobserver>
|
|
Shinya Kitaoka |
120a6e |
for (; it != m_observers.end(); ++it) (*it)->onChange(change);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double getValue(int segmentIndex, double frame);
|
|
Shinya Kitaoka |
120a6e |
double getSpeed(int segmentIndex, double frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD getSpeedIn(int kIndex);
|
|
Shinya Kitaoka |
120a6e |
TPointD getSpeedOut(int kIndex);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double TDoubleParam::Imp::getValue(int segmentIndex, double frame) {
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= segmentIndex && segmentIndex + 1 < (int)m_keyframes.size());
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &k0 = m_keyframes[segmentIndex];
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &k1 = m_keyframes[segmentIndex + 1];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double value = m_defaultValue;
|
|
Shinya Kitaoka |
120a6e |
bool convertUnit = false;
|
|
Shinya Kitaoka |
120a6e |
switch (k0.m_type) {
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::Constant:
|
|
Shinya Kitaoka |
120a6e |
value = getConstantValue(k0, k1, frame);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::Linear:
|
|
Shinya Kitaoka |
120a6e |
value = getLinearValue(k0, k1, frame);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::SpeedInOut:
|
|
Shinya Kitaoka |
120a6e |
value = getSpeedInOutValue(k0, k1, getSpeedOut(segmentIndex),
|
|
Shinya Kitaoka |
120a6e |
getSpeedIn(segmentIndex + 1), frame);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::EaseInOut:
|
|
Shinya Kitaoka |
120a6e |
value = getEaseInOutValue(k0, k1, frame, false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::EaseInOutPercentage:
|
|
Shinya Kitaoka |
120a6e |
value = getEaseInOutValue(k0, k1, frame, true);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::Exponential:
|
|
Shinya Kitaoka |
120a6e |
value = getExponentialValue(k0, k1, frame);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::Expression:
|
|
Shinya Kitaoka |
120a6e |
value = getExpressionValue(k0, k1, frame, m_measure);
|
|
Shinya Kitaoka |
120a6e |
convertUnit = true;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::File:
|
|
Shinya Kitaoka |
120a6e |
value = k0.m_fileData.getValue(frame, m_defaultValue);
|
|
Shinya Kitaoka |
120a6e |
convertUnit = true;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::SimilarShape:
|
|
Shinya Kitaoka |
120a6e |
value = getSimilarShapeValue(k0, k1, frame, m_measure);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Rozhuk Ivan |
823a31 |
default:
|
|
Rozhuk Ivan |
823a31 |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (convertUnit) value = k0.convertFrom(m_measure, value);
|
|
Shinya Kitaoka |
120a6e |
return value;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double TDoubleParam::Imp::getSpeed(int segmentIndex, double frame) {
|
|
Shinya Kitaoka |
120a6e |
const double h = 0.00001;
|
|
Shinya Kitaoka |
120a6e |
return (getValue(segmentIndex, frame + h) -
|
|
Shinya Kitaoka |
120a6e |
getValue(segmentIndex, frame - h)) /
|
|
Shinya Kitaoka |
120a6e |
(2 * h);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD TDoubleParam::Imp::getSpeedIn(int kIndex) {
|
|
Shinya Kitaoka |
120a6e |
assert(1 <= kIndex && kIndex < (int)m_keyframes.size());
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &kf0 = m_keyframes[kIndex - 1];
|
|
Shinya Kitaoka |
120a6e |
const TActualDoubleKeyframe &kf1 = m_keyframes[kIndex];
|
|
Shinya Kitaoka |
120a6e |
assert(kf0.m_type == TDoubleKeyframe::SpeedInOut);
|
|
Shinya Kitaoka |
120a6e |
if (!kf1.m_linkedHandles) return kf1.m_speedIn;
|
|
Shinya Kitaoka |
120a6e |
TPointD speedIn = kf1.m_speedIn;
|
|
Shinya Kitaoka |
120a6e |
if (kIndex + 1 >= (int)m_keyframes.size()) {
|
|
Shinya Kitaoka |
120a6e |
// speedIn.y = 0;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (kf1.m_type != TDoubleKeyframe::SpeedInOut &&
|
|
Shinya Kitaoka |
120a6e |
(kf1.m_type != TDoubleKeyframe::Expression ||
|
|
Shinya Kitaoka |
120a6e |
!kf1.m_expression.isCycling())) {
|
|
Shinya Kitaoka |
120a6e |
double speed = getSpeed(kIndex, kf1.m_frame);
|
|
Shinya Kitaoka |
120a6e |
speedIn.y = speedIn.x * speed;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return speedIn;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD TDoubleParam::Imp::getSpeedOut(int kIndex) {
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= kIndex && kIndex < (int)m_keyframes.size());
|
|
Shinya Kitaoka |
120a6e |
const TDoubleKeyframe &kf1 = m_keyframes[kIndex];
|
|
Shinya Kitaoka |
120a6e |
assert(kf1.m_type == TDoubleKeyframe::SpeedInOut);
|
|
Shinya Kitaoka |
120a6e |
if (!kf1.m_linkedHandles) return kf1.m_speedOut;
|
|
Shinya Kitaoka |
120a6e |
TPointD speedOut = kf1.m_speedOut;
|
|
Shinya Kitaoka |
120a6e |
if (kIndex == 0) {
|
|
Shinya Kitaoka |
120a6e |
// speedOut.y = 0;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
const TDoubleKeyframe &kf0 = m_keyframes[kIndex - 1];
|
|
Shinya Kitaoka |
120a6e |
if (kf0.m_type != TDoubleKeyframe::SpeedInOut) {
|
|
Shinya Kitaoka |
120a6e |
double speed = getSpeed(kIndex - 1, kf1.m_frame);
|
|
Shinya Kitaoka |
120a6e |
speedOut.y = speedOut.x * speed;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return speedOut;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD TDoubleParam::getSpeedIn(int kIndex) const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->getSpeedIn(kIndex);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TPointD TDoubleParam::getSpeedOut(int kIndex) const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->getSpeedOut(kIndex);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=========================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
PERSIST_IDENTIFIER(TDoubleParam, "doubleParam")
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam::TDoubleParam(double v) : m_imp(new TDoubleParam::Imp(v)) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParam::TDoubleParam(const TDoubleParam &src)
|
|
Shinya Kitaoka |
120a6e |
: TParam(src.getName()), m_imp(new TDoubleParam::Imp()) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->copy(src.m_imp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam::~TDoubleParam() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam &TDoubleParam::operator=(const TDoubleParam &dp) {
|
|
Shinya Kitaoka |
120a6e |
setName(dp.getName());
|
|
Shinya Kitaoka |
120a6e |
m_imp->copy(dp.m_imp);
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::copy(TParam *src) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *p = dynamic_cast<tdoubleparam *="">(src);</tdoubleparam>
|
|
Shinya Kitaoka |
120a6e |
if (!p) throw TException("invalid source for copy");
|
|
Shinya Kitaoka |
120a6e |
setName(src->getName());
|
|
Shinya Kitaoka |
120a6e |
m_imp->copy(p->m_imp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::setValueRange(double min, double max, double step) {
|
|
Shinya Kitaoka |
120a6e |
if (min > max) min = max;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_minValue = min;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_maxValue = max;
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_valueStep = step;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDoubleParam::getValueRange(double &min, double &max, double &step) const {
|
|
Shinya Kitaoka |
120a6e |
min = m_imp->m_minValue;
|
|
Shinya Kitaoka |
120a6e |
max = m_imp->m_maxValue;
|
|
Shinya Kitaoka |
120a6e |
step = 1; // m_imp->m_valueStep;
|
|
Shinya Kitaoka |
120a6e |
return min < max;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double TDoubleParam::getDefaultValue() const {
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp);
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_defaultValue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::enableCycle(bool enabled) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_cycleEnabled = enabled;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDoubleParam::isCycleEnabled() const { return m_imp->m_cycleEnabled; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=========================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=========================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double TDoubleParam::getValue(double frame, bool leftmost) const {
|
|
Shinya Kitaoka |
120a6e |
double value = 0;
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp);
|
|
Shinya Kitaoka |
120a6e |
const DoubleKeyframeVector &keyframes = m_imp->m_keyframes;
|
|
Shinya Kitaoka |
120a6e |
if (keyframes.empty()) {
|
|
Shinya Kitaoka |
120a6e |
// no keyframes: return the default value
|
|
Shinya Kitaoka |
120a6e |
value = m_imp->m_defaultValue;
|
|
Shinya Kitaoka |
120a6e |
} else if (keyframes.size() == 1) {
|
|
Shinya Kitaoka |
120a6e |
// a single keyframe. Type must be keyframe based (no expression/file)
|
|
Shinya Kitaoka |
120a6e |
value = keyframes[0].m_value;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// keyframes range is [f0,f1]
|
|
Shinya Kitaoka |
120a6e |
double f0 = keyframes.begin()->m_frame;
|
|
Shinya Kitaoka |
120a6e |
double f1 = keyframes.back().m_frame;
|
|
Shinya Kitaoka |
120a6e |
if (frame < f0)
|
|
Shinya Kitaoka |
120a6e |
frame = f0;
|
|
Shinya Kitaoka |
120a6e |
else if (frame > f1 && !m_imp->m_cycleEnabled)
|
|
Shinya Kitaoka |
120a6e |
frame = f1;
|
|
Shinya Kitaoka |
120a6e |
double valueOffset = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_cycleEnabled) {
|
|
Shinya Kitaoka |
120a6e |
double dist = (f1 - f0);
|
|
Shinya Kitaoka |
120a6e |
double dvalue = keyframes.back().m_value - keyframes.begin()->m_value;
|
|
Shinya Kitaoka |
120a6e |
while (frame >= f1) {
|
|
Shinya Kitaoka |
120a6e |
if (frame != f1 || !leftmost) {
|
|
Shinya Kitaoka |
120a6e |
frame -= dist;
|
|
Shinya Kitaoka |
120a6e |
valueOffset += dvalue;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// frame is in [f0,f1]
|
|
Shinya Kitaoka |
120a6e |
assert(f0 <= frame && frame <= f1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector::const_iterator b;
|
|
Shinya Kitaoka |
120a6e |
b = std::lower_bound(keyframes.begin(), keyframes.end(),
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe(frame));
|
|
Shinya Kitaoka |
120a6e |
assert(b != keyframes.end());
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector::const_iterator a;
|
|
Shinya Kitaoka |
120a6e |
if (b->m_frame == frame && (b + 1) != keyframes.end()) {
|
|
Shinya Kitaoka |
120a6e |
a = b;
|
|
Shinya Kitaoka |
120a6e |
b++;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
assert(b != keyframes.begin());
|
|
Shinya Kitaoka |
120a6e |
a = b - 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (leftmost && frame - a->m_frame < 0.00001 && a != keyframes.begin()) {
|
|
Shinya Kitaoka |
120a6e |
a--;
|
|
Shinya Kitaoka |
120a6e |
b--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// segment (a,b) contains frame
|
|
Shinya Kitaoka |
120a6e |
assert(a != keyframes.end());
|
|
Shinya Kitaoka |
120a6e |
assert(b != keyframes.end());
|
|
Shinya Kitaoka |
120a6e |
assert(a->m_frame <= frame);
|
|
Shinya Kitaoka |
120a6e |
assert(b->m_frame >= frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int kIndex = std::distance(keyframes.begin(), a);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<tactualdoublekeyframe> tmpKeyframe(3);</tactualdoublekeyframe>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if segment is keyframe based ....
|
|
Shinya Kitaoka |
120a6e |
if (TDoubleKeyframe::isKeyframeBased(a->m_type)) {
|
|
Shinya Kitaoka |
120a6e |
// .. and next segment is not then update the b value
|
|
Shinya Kitaoka |
120a6e |
if ((b + 1) != keyframes.end() &&
|
|
Shinya Kitaoka |
120a6e |
!TDoubleKeyframe::isKeyframeBased(b->m_type)) {
|
|
Shinya Kitaoka |
120a6e |
tmpKeyframe[0] = *b;
|
|
Shinya Kitaoka |
120a6e |
if (b->m_type != TDoubleKeyframe::Expression ||
|
|
Shinya Kitaoka |
120a6e |
!b->m_expression.isCycling())
|
|
Shinya Kitaoka |
120a6e |
tmpKeyframe[0].m_value = getValue(b->m_frame);
|
|
Shinya Kitaoka |
120a6e |
b = tmpKeyframe.begin();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// .. and/or if prev segment is not then update the a value
|
|
Shinya Kitaoka |
120a6e |
if (a != keyframes.begin() &&
|
|
Shinya Kitaoka |
120a6e |
!TDoubleKeyframe::isKeyframeBased(a[-1].m_type)) {
|
|
Shinya Kitaoka |
120a6e |
tmpKeyframe[1] = *a;
|
|
Shinya Kitaoka |
120a6e |
tmpKeyframe[1].m_value = getValue(a->m_frame, true);
|
|
Shinya Kitaoka |
120a6e |
a = tmpKeyframe.begin() + 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (a->m_step > 1) {
|
|
Shinya Kitaoka |
120a6e |
tmpKeyframe[2] = *b;
|
|
Shinya Kitaoka |
120a6e |
b = tmpKeyframe.begin() + 2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int relPos = tfloor(b->m_frame - a->m_frame),
|
|
Shinya Kitaoka |
120a6e |
step = std::min(a->m_step, relPos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tmpKeyframe[2].m_frame = a->m_frame + tfloor(relPos, step);
|
|
Shinya Kitaoka |
120a6e |
if (frame > b->m_frame) frame = b->m_frame;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
frame = a->m_frame + tfloor(tfloor(frame - a->m_frame), step);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= kIndex && kIndex + 1 < (int)m_imp->m_keyframes.size());
|
|
Shinya Kitaoka |
120a6e |
value = m_imp->m_defaultValue;
|
|
Shinya Kitaoka |
120a6e |
bool convertUnit = false;
|
|
Shinya Kitaoka |
120a6e |
switch (a->m_type) {
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::Constant:
|
|
Shinya Kitaoka |
120a6e |
value = getConstantValue(*a, *b, frame);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::Linear:
|
|
Shinya Kitaoka |
120a6e |
value = getLinearValue(*a, *b, frame);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::SpeedInOut:
|
|
Shinya Kitaoka |
120a6e |
value = getSpeedInOutValue(*a, *b, getSpeedOut(kIndex),
|
|
Shinya Kitaoka |
120a6e |
getSpeedIn(kIndex + 1), frame);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::EaseInOut:
|
|
Shinya Kitaoka |
120a6e |
value = getEaseInOutValue(*a, *b, frame, false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::EaseInOutPercentage:
|
|
Shinya Kitaoka |
120a6e |
value = getEaseInOutValue(*a, *b, frame, true);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::Exponential:
|
|
Shinya Kitaoka |
120a6e |
value = getExponentialValue(*a, *b, frame);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::Expression:
|
|
Shinya Kitaoka |
120a6e |
value = getExpressionValue(*a, *b, frame, m_imp->m_measure);
|
|
Shinya Kitaoka |
120a6e |
convertUnit = true;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::File:
|
|
Shinya Kitaoka |
120a6e |
value = a->m_fileData.getValue(frame, m_imp->m_defaultValue);
|
|
Shinya Kitaoka |
120a6e |
convertUnit = true;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::SimilarShape:
|
|
Shinya Kitaoka |
120a6e |
value = getSimilarShapeValue(*a, *b, frame, m_imp->m_measure);
|
|
Shinya Kitaoka |
120a6e |
// convertUnit = true;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
value = 0.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
value += valueOffset;
|
|
Shinya Kitaoka |
120a6e |
if (convertUnit) value = a->convertFrom(m_imp->m_measure, value);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if (cropped)
|
|
Shinya Kitaoka |
120a6e |
// value = tcrop(value, m_imp->m_minValue, m_imp->m_maxValue);
|
|
Shinya Kitaoka |
120a6e |
return value;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDoubleParam::setValue(double frame, double value) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp);
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector &keyframes = m_imp->m_keyframes;
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector::iterator it;
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe k(frame);
|
|
Shinya Kitaoka |
120a6e |
it = std::lower_bound(keyframes.begin(), keyframes.end(), k);
|
|
Shinya Kitaoka |
120a6e |
int index = 0;
|
|
Shinya Kitaoka |
120a6e |
bool created = false;
|
|
Shinya Kitaoka |
120a6e |
/*-- キーフレームが見つかった場合 --*/
|
|
Shinya Kitaoka |
120a6e |
if (it != keyframes.end() && it->m_frame == frame) {
|
|
Shinya Kitaoka |
120a6e |
// changing a keyframe value
|
|
Shinya Kitaoka |
120a6e |
index = std::distance(keyframes.begin(), it);
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe oldKeyframe = *it;
|
|
Shinya Kitaoka |
120a6e |
if (oldKeyframe.m_type == TDoubleKeyframe::Expression ||
|
|
Shinya Kitaoka |
120a6e |
oldKeyframe.m_type == TDoubleKeyframe::File)
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
it->m_value = value;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*-- セグメントの部分なので、新たにキーフレームを作る --*/
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
assert(it == keyframes.end() || it->m_frame > frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// can't change value in a file/expression segment
|
|
Shinya Kitaoka |
120a6e |
if (it != keyframes.end() && it > keyframes.begin() &&
|
|
Shinya Kitaoka |
120a6e |
((it - 1)->m_type == TDoubleKeyframe::Expression ||
|
|
Shinya Kitaoka |
120a6e |
(it - 1)->m_type == TDoubleKeyframe::File))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// inserting a new keyframe
|
|
Shinya Kitaoka |
120a6e |
k.m_value = value;
|
|
Shinya Kitaoka |
120a6e |
k.m_isKeyframe = true;
|
|
Shinya Kitaoka |
120a6e |
k.m_expression.setGrammar(m_imp->m_grammar);
|
|
Shinya Kitaoka |
120a6e |
k.m_expression.setOwnerParameter(this);
|
|
Shinya Kitaoka |
120a6e |
it = keyframes.insert(it, k);
|
|
Shinya Kitaoka |
120a6e |
if (it == keyframes.begin())
|
|
Shinya Kitaoka |
120a6e |
it->m_prevType = TDoubleKeyframe::None;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
it->m_prevType = it[-1].m_type;
|
|
Shinya Kitaoka |
120a6e |
/*-- FxGuiでSegment内にKeyを打った場合は、Step値も引き継ぐ --*/
|
|
Shinya Kitaoka |
120a6e |
it->m_step = it[-1].m_step;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (it + 1 != keyframes.end()) it[1].m_prevType = it->m_type;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
index = std::distance(keyframes.begin(), it);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Shinya Kitaoka |
120a6e |
created = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(0 == index || keyframes[index - 1].m_frame < keyframes[index].m_frame);
|
|
Shinya Kitaoka |
120a6e |
assert(getKeyframeCount() - 1 == index ||
|
|
Shinya Kitaoka |
120a6e |
keyframes[index + 1].m_frame > keyframes[index].m_frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return created;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::setKeyframe(int index, const TDoubleKeyframe &k) {
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector &keyframes = m_imp->m_keyframes;
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= index && index < (int)keyframes.size());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe &dst = keyframes[index];
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe oldKeyframe = dst;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
(TDoubleKeyframe &)dst = k;
|
|
Shinya Kitaoka |
120a6e |
dst.updateUnit(m_imp->m_measure);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (dst.m_type == TDoubleKeyframe::Expression ||
|
|
Shinya Kitaoka |
120a6e |
dst.m_type == TDoubleKeyframe::SimilarShape)
|
|
Shinya Kitaoka |
120a6e |
dst.m_expression.setText(dst.m_expressionText);
|
|
Shinya Kitaoka |
120a6e |
if (dst.m_type == TDoubleKeyframe::File)
|
|
Shinya Kitaoka |
120a6e |
dst.m_fileData.setParams(dst.m_fileParams);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(0 == index || keyframes[index - 1].m_frame < keyframes[index].m_frame);
|
|
Shinya Kitaoka |
120a6e |
assert(getKeyframeCount() - 1 == index ||
|
|
Shinya Kitaoka |
120a6e |
keyframes[index + 1].m_frame > keyframes[index].m_frame);
|
|
Shinya Kitaoka |
120a6e |
if (index == 0)
|
|
Shinya Kitaoka |
120a6e |
dst.m_prevType = TDoubleKeyframe::None;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
dst.m_prevType = keyframes[index - 1].m_type;
|
|
DoctorRyan |
ac3cab |
|
|
DoctorRyan |
ac3cab |
if (getKeyframeCount() - 1 != index)
|
|
DoctorRyan |
ac3cab |
keyframes[index + 1].m_prevType = dst.m_type;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::setKeyframes(const std::map<int, tdoublekeyframe=""> &ks) {</int,>
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector &keyframes = m_imp->m_keyframes;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::map<int, tdoublekeyframe="">::const_iterator it;</int,>
|
|
Shinya Kitaoka |
120a6e |
for (it = ks.begin(); it != ks.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
int index = it->first;
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= index && index < (int)keyframes.size());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe oldKeyframe = keyframes[index];
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe &dst = keyframes[index];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
(TDoubleKeyframe &)dst = it->second;
|
|
Shinya Kitaoka |
120a6e |
dst.updateUnit(m_imp->m_measure);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (dst.m_type == TDoubleKeyframe::Expression ||
|
|
Shinya Kitaoka |
120a6e |
dst.m_type == TDoubleKeyframe::SimilarShape)
|
|
Shinya Kitaoka |
120a6e |
dst.m_expression.setText(dst.m_expressionText);
|
|
Shinya Kitaoka |
120a6e |
if (dst.m_type == TDoubleKeyframe::File)
|
|
Shinya Kitaoka |
120a6e |
dst.m_fileData.setParams(dst.m_fileParams);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!keyframes.empty()) {
|
|
Shinya Kitaoka |
120a6e |
keyframes[0].m_prevType = TDoubleKeyframe::None;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 1; i < (int)keyframes.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
keyframes[i].m_prevType = keyframes[i - 1].m_type;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef NDEBUG
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i + 1 < (int)keyframes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
assert(keyframes[i].m_frame <= keyframes[i + 1].m_frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::setKeyframe(const TDoubleKeyframe &k) {
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector &keyframes = m_imp->m_keyframes;
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector::iterator it;
|
|
Shinya Kitaoka |
120a6e |
it = std::lower_bound(keyframes.begin(), keyframes.end(), k);
|
|
Shinya Kitaoka |
120a6e |
if (it != keyframes.end() && it->m_frame == k.m_frame) {
|
|
Shinya Kitaoka |
120a6e |
// int index = std::distance(keyframes.begin(), it);
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe &dst = *it;
|
|
Shinya Kitaoka |
120a6e |
(TDoubleKeyframe &)dst = k;
|
|
Shinya Kitaoka |
120a6e |
dst.updateUnit(m_imp->m_measure);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
it = keyframes.insert(it, TActualDoubleKeyframe(k));
|
|
Shinya Kitaoka |
120a6e |
// int index = std::distance(keyframes.begin(), it);
|
|
Shinya Kitaoka |
120a6e |
// TDoubleKeyframe oldKeyframe = *it;
|
|
Shinya Kitaoka |
120a6e |
it->m_expression.setGrammar(m_imp->m_grammar);
|
|
Shinya Kitaoka |
120a6e |
it->m_expression.setOwnerParameter(this);
|
|
Shinya Kitaoka |
120a6e |
it->updateUnit(m_imp->m_measure);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
it->m_isKeyframe = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (it->m_type == TDoubleKeyframe::Expression)
|
|
Shinya Kitaoka |
120a6e |
it->m_expression.setText(it->m_expressionText);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (it->m_type == TDoubleKeyframe::File)
|
|
Shinya Kitaoka |
120a6e |
it->m_fileData.setParams(it->m_fileParams);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (it == keyframes.begin())
|
|
Shinya Kitaoka |
120a6e |
it->m_prevType = TDoubleKeyframe::None;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
it->m_prevType = it[-1].m_type;
|
|
Shinya Kitaoka |
120a6e |
|
|
DoctorRyan |
ac3cab |
if (it + 1 != keyframes.end()) it[1].m_prevType = it->m_type;
|
|
DoctorRyan |
ac3cab |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(it == keyframes.begin() || (it - 1)->m_frame < it->m_frame);
|
|
Shinya Kitaoka |
120a6e |
assert(it + 1 == keyframes.end() || (it + 1)->m_frame > it->m_frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::setDefaultValue(double value) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp);
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_defaultValue != value) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_defaultValue = value;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// gmt, 19-6-2010; needed to get a notification in the FxParamsGraphicEditor
|
|
Shinya Kitaoka |
120a6e |
// (Camera Stand)
|
|
Shinya Kitaoka |
120a6e |
// when a param (without keyframes) is changed
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDoubleParam::isDefault() const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_keyframes.empty() &&
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_type == Keyframes &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_defaultValue == 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TDoubleParam::getKeyframeCount() const { return m_imp->m_keyframes.size(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::getKeyframes(std::set<double> &frames) const {</double>
|
|
Shinya Kitaoka |
120a6e |
for (DoubleKeyframeVector::iterator it = m_imp->m_keyframes.begin();
|
|
Shinya Kitaoka |
120a6e |
it != m_imp->m_keyframes.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
frames.insert(it->m_frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDoubleParam::hasKeyframes() const { return !m_imp->m_keyframes.empty(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TDoubleKeyframe &TDoubleParam::getKeyframe(int index) const {
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= index && index < (int)m_imp->m_keyframes.size());
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_keyframes[index];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TDoubleKeyframe &TDoubleParam::getKeyframeAt(double frame) const {
|
|
Shinya Kitaoka |
120a6e |
static TDoubleKeyframe k;
|
|
Shinya Kitaoka |
120a6e |
k = TDoubleKeyframe();
|
|
Shinya Kitaoka |
120a6e |
int i = 0;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)m_imp->m_keyframes.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_keyframes[i].m_frame >= frame) break;
|
|
Shinya Kitaoka |
120a6e |
if (i < (int)m_imp->m_keyframes.size() &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes[i].m_frame == frame) {
|
|
Shinya Kitaoka |
120a6e |
k = m_imp->m_keyframes[i];
|
|
Shinya Kitaoka |
120a6e |
return k;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
k.m_frame = frame;
|
|
Shinya Kitaoka |
120a6e |
k.m_value = getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
k.m_isKeyframe = false;
|
|
Shinya Kitaoka |
120a6e |
return k;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDoubleParam::isKeyframe(double frame) const {
|
|
Shinya Kitaoka |
120a6e |
return std::binary_search(m_imp->m_keyframes.begin(),
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.end(), TDoubleKeyframe(frame));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::deleteKeyframe(double frame) {
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector &keyframes = m_imp->m_keyframes;
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector::iterator it;
|
|
Shinya Kitaoka |
120a6e |
it = std::lower_bound(keyframes.begin(), keyframes.end(),
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe(frame));
|
|
Shinya Kitaoka |
120a6e |
if (it == keyframes.end() || it->m_frame != frame) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::Type type = it->m_prevType;
|
|
Shinya Kitaoka |
120a6e |
it = m_imp->m_keyframes.erase(it);
|
|
Shinya Kitaoka |
120a6e |
if (it != keyframes.end()) it->m_prevType = type;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::clearKeyframes() {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.clear();
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::assignKeyframe(double frame, const TParamP &src,
|
|
Shinya Kitaoka |
120a6e |
double srcFrame, bool changedOnly) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP dp = src;
|
|
Shinya Kitaoka |
120a6e |
if (!dp) return;
|
|
Shinya Kitaoka |
120a6e |
double value = dp->getValue(srcFrame);
|
|
Shinya Kitaoka |
120a6e |
if (!changedOnly || getValue(frame) != value) setValue(frame, value);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TDoubleParam::getClosestKeyframe(double frame) const {
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector &keyframes = m_imp->m_keyframes;
|
|
Shinya Kitaoka |
120a6e |
typedef DoubleKeyframeVector::iterator Iterator;
|
|
Shinya Kitaoka |
120a6e |
Iterator it = std::lower_bound(keyframes.begin(), keyframes.end(),
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe(frame));
|
|
Shinya Kitaoka |
120a6e |
if (it == keyframes.end()) {
|
|
Shinya Kitaoka |
120a6e |
// frame > k.m_frame per qualsiasi k.
|
|
Shinya Kitaoka |
120a6e |
// ritorna l'indice dell'ultimo keyframe (o -1 se l'array e' vuoto)
|
|
Shinya Kitaoka |
120a6e |
return keyframes.size() - 1;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
int index = std::distance<iterator>(keyframes.begin(), it);</iterator>
|
|
Shinya Kitaoka |
120a6e |
if (it->m_frame == frame || index == 0)
|
|
Shinya Kitaoka |
120a6e |
return index;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
double nextFrame = it->m_frame;
|
|
Shinya Kitaoka |
120a6e |
double prevFrame = keyframes[index - 1].m_frame;
|
|
Shinya Kitaoka |
120a6e |
assert(prevFrame < frame && frame < nextFrame);
|
|
Shinya Kitaoka |
120a6e |
return (nextFrame - frame < frame - prevFrame) ? index : index - 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TDoubleParam::getNextKeyframe(double frame) const {
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe k(frame);
|
|
Shinya Kitaoka |
120a6e |
typedef DoubleKeyframeVector::const_iterator Iterator;
|
|
Shinya Kitaoka |
120a6e |
Iterator it =
|
|
Shinya Kitaoka |
120a6e |
std::upper_bound(m_imp->m_keyframes.begin(), m_imp->m_keyframes.end(), k);
|
|
Shinya Kitaoka |
120a6e |
if (it == m_imp->m_keyframes.end()) return -1;
|
|
Shinya Kitaoka |
120a6e |
int index = std::distance<iterator>(m_imp->m_keyframes.begin(), it);</iterator>
|
|
Shinya Kitaoka |
120a6e |
if (it->m_frame == frame) {
|
|
Shinya Kitaoka |
120a6e |
++index;
|
|
Shinya Kitaoka |
120a6e |
return index < getKeyframeCount() ? index : -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return index;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TDoubleParam::getPrevKeyframe(double frame) const {
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe k(frame);
|
|
Shinya Kitaoka |
120a6e |
typedef DoubleKeyframeVector::const_iterator Iterator;
|
|
Shinya Kitaoka |
120a6e |
Iterator it =
|
|
Shinya Kitaoka |
120a6e |
std::lower_bound(m_imp->m_keyframes.begin(), m_imp->m_keyframes.end(), k);
|
|
Shinya Kitaoka |
120a6e |
if (it == m_imp->m_keyframes.end()) return m_imp->m_keyframes.size() - 1;
|
|
Shinya Kitaoka |
120a6e |
int index = std::distance<iterator>(m_imp->m_keyframes.begin(), it);</iterator>
|
|
Shinya Kitaoka |
120a6e |
return index - 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double TDoubleParam::keyframeIndexToFrame(int index) const {
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= index && index < getKeyframeCount());
|
|
Shinya Kitaoka |
120a6e |
return getKeyframe(index).m_frame;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::addObserver(TParamObserver *observer) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_observers.insert(observer);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::removeObserver(TParamObserver *observer) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_observers.erase(observer);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const std::set<tparamobserver *=""> &TDoubleParam::observers() const {</tparamobserver>
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_observers;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::loadData(TIStream &is) {
|
|
Shinya Kitaoka |
120a6e |
string tagName;
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
if(is.matchTag(tagName))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
// nuovo formato (29 agosto 2005)
|
|
Shinya Kitaoka |
120a6e |
if(tagName!="type") throw TException("expected <type>");</type>
|
|
Shinya Kitaoka |
120a6e |
int type = 0;
|
|
Shinya Kitaoka |
120a6e |
is >> type;
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_type = TDoubleParam::Type(type);
|
|
Shinya Kitaoka |
120a6e |
if(!is.matchEndTag()) throw TException(tagName + " : missing endtag");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//if(!is.matchTag(tagName) || tagName != "default") throw TException("expected
|
|
Shinya Kitaoka |
120a6e |
<default>");</default>
|
|
Shinya Kitaoka |
120a6e |
//is >> m_imp->m_defaultValue;
|
|
Shinya Kitaoka |
120a6e |
//if(!is.matchEndTag()) throw TException(tagName + " : missing endtag");
|
|
Shinya Kitaoka |
120a6e |
//if(!is.matchTag(tagName) || tagName != "default") throw TException("expected
|
|
Shinya Kitaoka |
120a6e |
<default>");</default>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
// vecchio formato
|
|
Shinya Kitaoka |
120a6e |
is >> m_imp->m_defaultValue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.clear();
|
|
Shinya Kitaoka |
120a6e |
int oldType = -1;
|
|
Shinya Kitaoka |
120a6e |
while (is.matchTag(tagName)) {
|
|
Shinya Kitaoka |
120a6e |
if (tagName == "type") {
|
|
Shinya Kitaoka |
120a6e |
// (old) format 5.2. Since 6.0 param type is no used anymore
|
|
Shinya Kitaoka |
120a6e |
is >> oldType;
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "default") {
|
|
Shinya Kitaoka |
120a6e |
is >> m_imp->m_defaultValue;
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "cycle") {
|
|
Shinya Kitaoka |
120a6e |
string dummy;
|
|
Shinya Kitaoka |
120a6e |
is >> dummy;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_cycleEnabled = true;
|
|
Shinya Kitaoka |
120a6e |
// setExtrapolationAfter(Loop);
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "k") {
|
|
Shinya Kitaoka |
120a6e |
// vecchio formato
|
|
Shinya Kitaoka |
120a6e |
if (oldType != 0) continue;
|
|
Shinya Kitaoka |
120a6e |
int linkStatus = 0;
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe k;
|
|
Shinya Kitaoka |
120a6e |
is >> k.m_frame >> k.m_value >> k.m_speedIn.x >> k.m_speedIn.y >>
|
|
Shinya Kitaoka |
120a6e |
k.m_speedOut.x >> k.m_speedOut.y >> linkStatus;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
k.m_isKeyframe = true;
|
|
Shinya Kitaoka |
120a6e |
k.m_linkedHandles = (linkStatus & 1) != 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((linkStatus & 1) != 0)
|
|
Shinya Kitaoka |
120a6e |
k.m_type = TDoubleKeyframe::SpeedInOut;
|
|
Shinya Kitaoka |
120a6e |
else if ((linkStatus & 2) != 0 || (linkStatus & 4) != 0)
|
|
Shinya Kitaoka |
120a6e |
k.m_type = TDoubleKeyframe::EaseInOut;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
k.m_type = TDoubleKeyframe::Linear;
|
|
Shinya Kitaoka |
120a6e |
k.m_expression.setGrammar(m_imp->m_grammar);
|
|
Shinya Kitaoka |
120a6e |
k.m_expression.setOwnerParameter(this);
|
|
Shinya Kitaoka |
120a6e |
k.m_prevType = m_imp->m_keyframes.empty()
|
|
Shinya Kitaoka |
120a6e |
? TDoubleKeyframe::None
|
|
Shinya Kitaoka |
120a6e |
: m_imp->m_keyframes.back().m_type;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.push_back(k);
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "expr") {
|
|
Shinya Kitaoka |
120a6e |
// vecchio formato
|
|
Shinya Kitaoka |
120a6e |
if (oldType != 1) continue;
|
|
Shinya Kitaoka |
120a6e |
string text = is.getTagAttribute("text");
|
|
Shinya Kitaoka |
120a6e |
string enabled = is.getTagAttribute("enabled");
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe kk1, kk2;
|
|
Shinya Kitaoka |
120a6e |
kk1.m_frame = -1000;
|
|
Shinya Kitaoka |
120a6e |
kk2.m_frame = 1000;
|
|
Shinya Kitaoka |
120a6e |
kk1.m_isKeyframe = true;
|
|
Shinya Kitaoka |
120a6e |
kk2.m_isKeyframe = true;
|
|
Shinya Kitaoka |
120a6e |
kk1.m_expressionText = text;
|
|
Shinya Kitaoka |
120a6e |
kk2.m_expressionText = text;
|
|
Shinya Kitaoka |
120a6e |
kk1.m_type = TDoubleKeyframe::Expression;
|
|
Shinya Kitaoka |
120a6e |
kk2.m_type = TDoubleKeyframe::Expression;
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe k1(kk1);
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe k2(kk2);
|
|
Shinya Kitaoka |
120a6e |
k1.m_expression.setGrammar(m_imp->m_grammar);
|
|
Shinya Kitaoka |
120a6e |
k1.m_expression.setOwnerParameter(this);
|
|
Shinya Kitaoka |
120a6e |
k1.m_prevType = m_imp->m_keyframes.empty()
|
|
Shinya Kitaoka |
120a6e |
? TDoubleKeyframe::None
|
|
Shinya Kitaoka |
120a6e |
: m_imp->m_keyframes.back().m_type;
|
|
Shinya Kitaoka |
120a6e |
k2.m_expression.setGrammar(m_imp->m_grammar);
|
|
Shinya Kitaoka |
120a6e |
k2.m_expression.setOwnerParameter(this);
|
|
Shinya Kitaoka |
120a6e |
k2.m_prevType = m_imp->m_keyframes.empty()
|
|
Shinya Kitaoka |
120a6e |
? TDoubleKeyframe::None
|
|
Shinya Kitaoka |
120a6e |
: m_imp->m_keyframes.back().m_type;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.push_back(k1);
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.push_back(k2);
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "file") {
|
|
Shinya Kitaoka |
120a6e |
// vecchio formato
|
|
Shinya Kitaoka |
120a6e |
if (oldType != 2) continue;
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::FileParams params;
|
|
Shinya Kitaoka |
120a6e |
params.m_path = TFilePath(is.getTagAttribute("path"));
|
|
Shinya Kitaoka |
120a6e |
params.m_fieldIndex = std::stoi(is.getTagAttribute("index"));
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe k1, k2;
|
|
Shinya Kitaoka |
120a6e |
k1.m_frame = -1000;
|
|
Shinya Kitaoka |
120a6e |
k2.m_frame = 1000;
|
|
Shinya Kitaoka |
120a6e |
k1.m_isKeyframe = true;
|
|
Shinya Kitaoka |
120a6e |
k2.m_isKeyframe = true;
|
|
Shinya Kitaoka |
120a6e |
k1.m_fileData.setParams(params);
|
|
Shinya Kitaoka |
120a6e |
k2.m_fileData.setParams(params);
|
|
Shinya Kitaoka |
120a6e |
k1.m_type = TDoubleKeyframe::File;
|
|
Shinya Kitaoka |
120a6e |
k2.m_type = TDoubleKeyframe::File;
|
|
Shinya Kitaoka |
120a6e |
k1.m_expression.setGrammar(m_imp->m_grammar);
|
|
Shinya Kitaoka |
120a6e |
k1.m_expression.setOwnerParameter(this);
|
|
Shinya Kitaoka |
120a6e |
k1.m_prevType = m_imp->m_keyframes.empty()
|
|
Shinya Kitaoka |
120a6e |
? TDoubleKeyframe::None
|
|
Shinya Kitaoka |
120a6e |
: m_imp->m_keyframes.back().m_type;
|
|
Shinya Kitaoka |
120a6e |
k2.m_expression.setGrammar(m_imp->m_grammar);
|
|
Shinya Kitaoka |
120a6e |
k2.m_expression.setOwnerParameter(this);
|
|
Shinya Kitaoka |
120a6e |
k2.m_prevType = m_imp->m_keyframes.empty()
|
|
Shinya Kitaoka |
120a6e |
? TDoubleKeyframe::None
|
|
Shinya Kitaoka |
120a6e |
: m_imp->m_keyframes.back().m_type;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.push_back(k1);
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.push_back(k2);
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "step") {
|
|
Shinya Kitaoka |
120a6e |
int step = 0;
|
|
Shinya Kitaoka |
120a6e |
is >> step;
|
|
Shinya Kitaoka |
120a6e |
// if(step>1)
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_frameStep = step;
|
|
Shinya Kitaoka |
120a6e |
} else if (tagName == "keyframes") {
|
|
Shinya Kitaoka |
120a6e |
while (!is.eos()) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe kk;
|
|
Shinya Kitaoka |
120a6e |
kk.loadData(is);
|
|
DoctorRyan |
ac3cab |
// Throw out invalid interpolation types
|
|
DoctorRyan |
ac3cab |
if (kk.m_type == TDoubleKeyframe::None) continue;
|
|
Shinya Kitaoka |
120a6e |
TActualDoubleKeyframe k(kk);
|
|
Shinya Kitaoka |
120a6e |
k.m_expression.setGrammar(m_imp->m_grammar);
|
|
Shinya Kitaoka |
120a6e |
k.m_expression.setOwnerParameter(this);
|
|
Shinya Kitaoka |
120a6e |
k.m_prevType = m_imp->m_keyframes.empty()
|
|
Shinya Kitaoka |
120a6e |
? TDoubleKeyframe::None
|
|
Shinya Kitaoka |
120a6e |
: m_imp->m_keyframes.back().m_type;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.push_back(k);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
throw TException(tagName + " : unexpected tag");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
if (!is.matchEndTag()) throw TException(tagName + " : missing endtag");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_keyframes.empty() && !is.eos()) {
|
|
Shinya Kitaoka |
120a6e |
// vecchio sistema (prima 16/1/2003)
|
|
Shinya Kitaoka |
120a6e |
while (!is.eos()) {
|
|
Shinya Kitaoka |
120a6e |
double t, v;
|
|
Shinya Kitaoka |
120a6e |
is >> t >> v;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes.push_back(TActualDoubleKeyframe(t, v));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_keyframes.empty()) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes[0].m_prevType = TDoubleKeyframe::None;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 1; i < (int)m_imp->m_keyframes.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes[i].m_prevType = m_imp->m_keyframes[i - 1].m_type;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notify(TParamChange(this, 0, 0, true, false, false));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::saveData(TOStream &os) {
|
|
Shinya Kitaoka |
120a6e |
// os.child("type") << (int)m_imp->m_type;
|
|
Shinya Kitaoka |
120a6e |
os.child("default") << m_imp->m_defaultValue;
|
|
Shinya Kitaoka |
120a6e |
if (isCycleEnabled()) os.child("cycle") << std::string("enabled");
|
|
Shinya Kitaoka |
120a6e |
// if(getExtrapolationAfter() == Loop)
|
|
Shinya Kitaoka |
120a6e |
// os.child("cycle") << string("loop");
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_keyframes.empty()) {
|
|
Shinya Kitaoka |
120a6e |
os.openChild("keyframes");
|
|
Shinya Kitaoka |
120a6e |
DoubleKeyframeVector::const_iterator it;
|
|
Shinya Kitaoka |
120a6e |
for (it = m_imp->m_keyframes.begin(); it != m_imp->m_keyframes.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
it->saveData(os);
|
|
Shinya Kitaoka |
120a6e |
os.closeChild();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
string TDoubleParam::getStreamTag() const { return "doubleParam"; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
string TDoubleParam::getValueAlias(double frame, int precision) {
|
|
Shinya Kitaoka |
120a6e |
return ::to_string(getValue(frame), precision);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::setGrammar(const TSyntax::Grammar *grammar) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_grammar = grammar;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_imp->m_keyframes.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes[i].m_expression.setGrammar(grammar);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TSyntax::Grammar *TDoubleParam::getGrammar() const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_grammar;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::accept(TSyntax::CalculatorNodeVisitor &visitor) {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_imp->m_keyframes.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_keyframes[i].m_type == TDoubleKeyframe::Expression ||
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes[i].m_type == TDoubleKeyframe::SimilarShape)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_keyframes[i].m_expression.accept(visitor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
string TDoubleParam::getMeasureName() const { return m_imp->m_measureName; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDoubleParam::setMeasureName(string name) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_measureName = name;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_measure = TMeasureManager::instance()->get(name);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TMeasure *TDoubleParam::getMeasure() const { return m_imp->m_measure; }
|