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