Пример #1
0
void AnimExportUtil::resamplePositionAnimation( const Vector<Matrix4x4>& tm, Interval animRange, KeyFrameContainer* pos )
{
	// find out maximum acceptable error
	float maxErrPercent = MAX_POSITION_RESAMPLING_ERROR;
	float defr = 1e9f;
	Vector3 minbox( defr, defr, defr );
	Vector3 maxbox(-defr,-defr,-defr );
	for ( int k = 0 ; k < tm.size() ; k += 2 )
	{
		Vector3 pos = tm[k].translation();
		minbox = pos.minElements( minbox );
		maxbox = pos.maxElements( maxbox );
	}
	float maxErr = (minbox-maxbox).length()/100.f * maxErrPercent;
	if ( maxErr < 1e-6f )
		maxErr = 1e-6f;

	int firstFrame = animRange.Start() / SGEXPORT_TICKS_PER_SAMPLE;
	require( firstFrame >= 0 && firstFrame < tm.size() );
	AnimExportUtil::addPositionKey( *pos, tm[firstFrame], TicksToSec(animRange.Start()) );
	AnimExportUtil::addPositionKey( *pos, tm.lastElement(), TicksToSec(animRange.End()) );
	Debug::println( "max position error = {0}", maxErr );
	resamplePositionKeys( *pos, animRange, maxErr, tm );
	if ( pos->keys() == 2 && isEqualValue(pos->getKey(0),pos->getKey(1),3) )
		pos->removeKey( 1 );
}
Пример #2
0
/** 
 * Resamples animation until maximum error is smaller than specified value. 
 * @param maxErr Maximum absolute error
 */
static void resampleFloatKeys( KeyFrameContainer& anim, Interval range, float maxErr, const Vector<float>& frames )
{
	TimeValue dticks = SGEXPORT_TICKS_PER_SAMPLE;
	int frame = range.Start() / dticks;
	require( frame >= 0 && frame < frames.size() );
	TimeValue rangeLen = (range.Duration()/SGEXPORT_TICKS_PER_SAMPLE)*SGEXPORT_TICKS_PER_SAMPLE;

	for ( TimeValue ticks = range.Start() ; ticks < range.End() ; ticks += dticks )
	{
		if ( ticks > range.End() )
			ticks = range.End();

		// find out error (distance) between real and sampled animation
		require( frame >= 0 && frame < frames.size() );
		float realValue = frames[frame++];
		float sampledValue = 0.f;
		anim.getValue( TicksToSec(ticks), &sampledValue, 1 );
		float err = Math::abs( realValue - sampledValue );

		// sample more accurately if needed
		if ( err > maxErr && rangeLen > dticks )
		{
			TimeValue halfRange = alignTicks( (range.End() + range.Start())/2 );
			anim.insertKey( KeyFrame( TicksToSec(halfRange), INTERP_TYPE, &frames[halfRange/dticks], 1 ) );

			if ( ticks <= halfRange )
				resampleFloatKeys( anim, Interval(range.Start(),halfRange), maxErr, frames );
			else
				resampleFloatKeys( anim, Interval(halfRange,range.End()), maxErr, frames );
		}

		if ( ticks == range.End() )
			break;
	}
}
Пример #3
0
void AnimExportUtil::addScaleAnimation( const Vector<Matrix4x4>& tm, Interval animRange, KeyFrameContainer* scale )
{
	int firstFrame = animRange.Start() / SGEXPORT_TICKS_PER_SAMPLE;
	for ( TimeValue ticks = animRange.Start() ; ticks <= animRange.End() ; ticks += SGEXPORT_TICKS_PER_SAMPLE )
	{
		require( firstFrame >= 0 && firstFrame < tm.size() );
		AnimExportUtil::addScaleKey( *scale, tm[firstFrame++], TicksToSec(ticks) );
	}
}
Пример #4
0
void AnimExportUtil::addFloatAnimation( const util::Vector<float>& frames, Interval animRange, KeyFrameContainer* anim, float maxErr )
{
	int firstFrame = animRange.Start() / SGEXPORT_TICKS_PER_SAMPLE;
	for ( TimeValue ticks = animRange.Start() ; ticks <= animRange.End() ; ticks += SGEXPORT_TICKS_PER_SAMPLE )
	{
		require( firstFrame >= 0 && firstFrame < frames.size() );
		anim->insertKey( KeyFrame(TicksToSec(ticks),INTERP_TYPE,&frames[firstFrame++],1) );
	}
}
Пример #5
0
INT_PTR CALLBACK TrackPropDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	BlockControl *blk = (BlockControl*)GetWindowLongPtr(hWnd,GWLP_USERDATA);

	ISpinnerControl *spin;
	static TSTR zero = FormatUniverseValue(0.0f);
	Rect rect;

	switch (msg) {
	case WM_INITDIALOG:
		{
		blk = (BlockControl*)lParam;
		SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam);

		Interval range = GetCOREInterface()->GetAnimRange();

		
		spin = GetISpinner(GetDlgItem(hWnd,IDC_STARTSPIN));
		spin->SetLimits(-999999.0f,9999999.0f, FALSE);
		spin->SetAutoScale();
		spin->LinkToEdit(GetDlgItem(hWnd,IDC_START), EDITTYPE_INT);
		spin->SetValue(range.Start()/GetTicksPerFrame(),FALSE);
		ReleaseISpinner(spin);

		blk->propStart = range.Start()/GetTicksPerFrame();
		CenterWindow(hWnd,GetParent(hWnd));
		break;
		}
		
	case CC_SPINNER_CHANGE:
		spin = (ISpinnerControl*)lParam;
		switch (LOWORD(wParam)) {
		case IDC_STARTSPIN: blk->propStart = spin->GetIVal(); break;
		}
		break;



	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDOK:
			{
			EndDialog(hWnd,1);
			blk->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

			break;
			}
		case IDCANCEL:
			EndDialog(hWnd,0);
			break;
		}
		break;

	default:
		return FALSE;
	}
	return TRUE;
}
Пример #6
0
void AnimExportUtil::resampleFloatAnimation( const util::Vector<float>& frames, Interval animRange, KeyFrameContainer* anim, float maxErr )
{
	int firstFrame = animRange.Start() / SGEXPORT_TICKS_PER_SAMPLE;
	require( firstFrame >= 0 && firstFrame < frames.size() );
	anim->insertKey( KeyFrame(TicksToSec(animRange.Start()),INTERP_TYPE,&frames[firstFrame],1) );
	anim->insertKey( KeyFrame(TicksToSec(animRange.End()),INTERP_TYPE,&frames.lastElement(),1) );
	resampleFloatKeys( *anim, animRange, maxErr, frames );
	if ( anim->keys() == 2 && isEqualValue(anim->getKey(0),anim->getKey(1),3) )
		anim->removeKey( 1 );
}
Пример #7
0
void AnimExportUtil::resampleRotationAnimation( const Vector<Matrix4x4>& tm, Interval animRange, KeyFrameContainer* rot )
{
	float maxErr = Math::toRadians(MAX_ROTATION_RESAMPLING_ERROR);
	int firstFrame = animRange.Start() / SGEXPORT_TICKS_PER_SAMPLE;
	require( firstFrame >= 0 && firstFrame < tm.size() );
	AnimExportUtil::addRotationKey( *rot, tm[firstFrame], TicksToSec(animRange.Start()) );
	AnimExportUtil::addRotationKey( *rot, tm.lastElement(), TicksToSec(animRange.End()) );
	Debug::println( "max rotation error = {0} degrees", Math::toDegrees(maxErr) );
	resampleRotationKeys( *rot, animRange, maxErr, tm );
	if ( rot->keys() == 2 && isEqualValue(rot->getKey(0),rot->getKey(1),4) )
		rot->removeKey( 1 );
}
Пример #8
0
void AnimExportUtil::resampleScaleAnimation( const Vector<Matrix4x4>& tm, Interval animRange, KeyFrameContainer* scale )
{
	float maxErrPercent = MAX_SCALE_RESAMPLING_ERROR;
	int firstFrame = animRange.Start() / SGEXPORT_TICKS_PER_SAMPLE;
	require( firstFrame >= 0 && firstFrame < tm.size() );
	AnimExportUtil::addScaleKey( *scale, tm[firstFrame], TicksToSec(animRange.Start()) );
	AnimExportUtil::addScaleKey( *scale, tm.lastElement(), TicksToSec(animRange.End()) );
	Debug::println( "max scale error = {0}%", maxErrPercent );
	resampleScaleKeys( *scale, animRange, maxErrPercent/100.f, tm );
	if ( scale->keys() == 2 && isEqualValue(scale->getKey(0),scale->getKey(1),3) )
		scale->removeKey( 1 );
}
Пример #9
0
void AnimExportUtil::getTransformAnimation( INode* node, Interval animRange, Vector<math::Matrix4x4>* anim )
{
	require( animRange.Start() <= animRange.End() );

	anim->clear();
	TimeValue dt = SGEXPORT_TICKS_PER_SAMPLE;
	for ( TimeValue t = animRange.Start() ; t <= animRange.End() ; t += dt )
	{
		Matrix4x4 tm = TmUtil::getModelToParentLH( node, t );
		anim->add( tm );
	}

	require( anim->size() > 0 );
}
	//---------------------------------------------------------------
	bool DocumentExporter::showExportOptions(bool suppressPrompts)
	{
		if (!suppressPrompts) 
		{
			// Prompt the user with our dialogbox, and get all the options.
			// The user may cancel the export at this point.
			if (!mOptions.ShowDialog()) 
				return false;
		}
		else
		{
			mOptions.LoadOptions();
			if (!mOptions.getSampleAnimation())
			{
				Interval animRange = GetCOREInterface()->GetAnimRange();
				int sceneStart = animRange.Start();
				int sceneEnd = animRange.End();
				mOptions.setAnimBounds(sceneStart, sceneEnd);
			}
		}

		// Set relative/absolute export
	//	colladaDocument->GetFileManager()->SetForceAbsoluteFlag(!options->ExportRelativePaths());

		return true;
	}
Пример #11
0
// Dialog proc
static INT_PTR CALLBACK ExportDlgProc(HWND hWnd, UINT msg,
	WPARAM wParam, LPARAM lParam)
{
	Interval animRange;
	ISpinnerControl  *spin;

	AscOut *exp = (AscOut*)GetWindowLongPtr(hWnd,GWLP_USERDATA); 
	switch (msg) {
	case WM_INITDIALOG:
		exp = (AscOut*)lParam;
		SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam); 
		CenterWindow(hWnd, GetParent(hWnd)); 

		// Setup the spinner controls for the floating point precision 
		spin = GetISpinner(GetDlgItem(hWnd, IDC_PREC_SPIN)); 
		spin->LinkToEdit(GetDlgItem(hWnd,IDC_PREC), EDITTYPE_INT ); 
		spin->SetLimits(1, 10, TRUE); 
		spin->SetScale(1.0f);
		spin->SetValue(exp->GetPrecision() ,FALSE);
		ReleaseISpinner(spin);

		// Setup the spinner control for the static frame#
		// We take the frame 0 as the default value
		animRange = exp->GetInterface()->GetAnimRange();
		spin = GetISpinner(GetDlgItem(hWnd, IDC_STATIC_FRAME_SPIN)); 
		spin->LinkToEdit(GetDlgItem(hWnd,IDC_STATIC_FRAME), EDITTYPE_INT ); 
		spin->SetLimits(animRange.Start() / GetTicksPerFrame(), animRange.End() / GetTicksPerFrame(), TRUE); 
		spin->SetScale(1.0f);
		spin->SetValue(0, FALSE);
		ReleaseISpinner(spin);
		break;

	case CC_SPINNER_CHANGE:
		spin = (ISpinnerControl*)lParam; 
		break;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDOK:
			spin = GetISpinner(GetDlgItem(hWnd, IDC_PREC_SPIN)); 
			exp->SetPrecision(spin->GetIVal());
			ReleaseISpinner(spin);
		
			spin = GetISpinner(GetDlgItem(hWnd, IDC_STATIC_FRAME_SPIN)); 
			exp->SetStaticFrame(spin->GetIVal() * GetTicksPerFrame());
			ReleaseISpinner(spin);
			
			EndDialog(hWnd, 1);
			break;
		case IDCANCEL:
			EndDialog(hWnd, 0);
			break;
		}
		break;
		default:
			return FALSE;
	}
	return TRUE;
}       
Пример #12
0
Interval Interval::Union(const Interval &i) const {
	Interval ret;

	ret.m_start = std::min(Start(), i.Start());
	ret.m_end = std::max(End(), i.End());
	
	return ret;
}
Пример #13
0
/** 
 * Resamples animation until maximum error is smaller than specified angle (radians). 
 * @param maxErr Maximum absolute error (radians).
 */
static void resampleRotationKeys( KeyFrameContainer& anim, Interval range, float maxErr, const Vector<Matrix4x4>& tm )
{
	TimeValue dticks = SGEXPORT_TICKS_PER_SAMPLE;
	int frame = range.Start() / dticks;
	require( frame >= 0 && frame < tm.size() );
	TimeValue rangeLen = (range.Duration()/SGEXPORT_TICKS_PER_SAMPLE)*SGEXPORT_TICKS_PER_SAMPLE;

	for ( TimeValue ticks = range.Start() ; ticks < range.End() ; ticks += dticks )
	{
		if ( ticks > range.End() )
			ticks = range.End();

		// find out error (distance) between real and sampled animation
		require( frame >= 0 && frame < tm.size() );
		const Matrix4x4& m = tm[frame++];
		Matrix3x3 ref = m.rotation().orthonormalize();
		float q[4];
		anim.getValue( TicksToSec(ticks), q, 4 );
		Matrix3x3 cmp( Quaternion(q[0],q[1],q[2],q[3]) );
		float xang = Math::abs( Math::acos( clamp(cmp.getColumn(0).dot(ref.getColumn(0)), -1.f, 1.f) ) );
		float yang = Math::abs( Math::acos( clamp(cmp.getColumn(1).dot(ref.getColumn(1)), -1.f, 1.f) ) );
		float zang = Math::abs( Math::acos( clamp(cmp.getColumn(2).dot(ref.getColumn(2)), -1.f, 1.f) ) );
		float err = xang;
		if ( yang > err )
			err = yang;
		if ( zang > err )
			err = zang;

		// sample more accurately if needed
		if ( err > maxErr && rangeLen > dticks )
		{
			TimeValue halfRange = alignTicks( (range.End() + range.Start())/2 );
			AnimExportUtil::addRotationKey( anim, tm[halfRange/dticks], TicksToSec(halfRange) );
			if ( ticks <= halfRange )
				resampleRotationKeys( anim, Interval(range.Start(),halfRange), maxErr, tm );
			else
				resampleRotationKeys( anim, Interval(halfRange,range.End()), maxErr, tm );
		}

		if ( ticks == range.End() )
			break;
	}
}
Пример #14
0
void FloatMC::BeginCapture(Interval record,TimeValue sampSize)
	{
	// Set the base point to the controller value at the start time.
	cont->GetValue(record.Start(),&base,FOREVER,CTRL_ABSOLUTE);	

	// Allocate a data buffer
	sampleCount = record.Duration()/sampSize + 1;
	data = new float[sampleCount];
	for (int i=0; i<sampleCount; i++) data[i] = 0.0f;
	}
Пример #15
0
// SAMPLENODEMOTION
// top level function for sampling all the motion on a single node
plSampleVec * SampleNodeMotion(INode* node, INode* parent, int sampleRate, Interface *theInterface)
{
    Interval interval = theInterface->GetAnimRange();
    TimeValue start = interval.Start();                 // in ticks
    TimeValue end = interval.End();

    sampleRate *= GetTicksPerFrame();                   // convert sample rate to ticks

    return SampleNodeMotion(node, parent, sampleRate, start, end);
}
Пример #16
0
void ValuesTable::Move(const Interval &in) {
	if (in.End() < 0 || in.Start() >= (int)m_values.size()) {
		m_values.resize(0);
		m_values.resize(in.End() - in.Start() + 1);
		return;
	}

	while ((in.End() + 1) < (int)m_values.size())
		PopBack();

	for (int i = 0; i < in.Start(); ++i)
		PopFront();

	for (int i = 0; i > in.Start(); --i)
		PushFront();

	for (int i = m_values.size(); i <= in.End() - in.Start(); ++i) 
		PushBack();
}
Пример #17
0
/** 
 * Resamples animation until maximum error is smaller than specified value. 
 * @param maxErr Maximum relative error, i.e. 0.05f == 5%.
 */
static void resampleScaleKeys( KeyFrameContainer& anim, Interval range, float maxErr, const Vector<Matrix4x4>& tm )
{
	TimeValue dticks = SGEXPORT_TICKS_PER_SAMPLE;
	int frame = range.Start() / dticks;
	require( frame >= 0 && frame < tm.size() );
	TimeValue rangeLen = (range.Duration()/SGEXPORT_TICKS_PER_SAMPLE)*SGEXPORT_TICKS_PER_SAMPLE;

	for ( TimeValue ticks = range.Start() ; ticks < range.End() ; ticks += dticks )
	{
		if ( ticks > range.End() )
			ticks = range.End();

		// find out error (distance) between real and sampled animation
		require( frame >= 0 && frame < tm.size() );
		const Matrix4x4& m = tm[frame++];
		Vector3 ref;
		Vector3 a;
		a = getAxis(m,0); ref[0] = a.dot(normalize0(a));
		a = getAxis(m,1); ref[1] = a.dot(normalize0(a));
		a = getAxis(m,2); ref[2] = a.dot(normalize0(a));
		float cmp[3];
		anim.getValue( TicksToSec(ticks), cmp, 3 );
		float err = (Vector3(cmp[0],cmp[1],cmp[2]) - ref).length();
		if ( ref.length() > Float::MIN_VALUE )
			err /= ref.length();

		// sample more accurately if needed
		if ( err > maxErr && rangeLen > dticks )
		{
			TimeValue halfRange = alignTicks( (range.End() + range.Start())/2 );
			AnimExportUtil::addScaleKey( anim, tm[halfRange/dticks], TicksToSec(halfRange) );
			if ( ticks <= halfRange )
				resampleScaleKeys( anim, Interval(range.Start(),halfRange), maxErr, tm );
			else
				resampleScaleKeys( anim, Interval(halfRange,range.End()), maxErr, tm );
		}

		if ( ticks == range.End() )
			break;
	}
}
Пример #18
0
void RandKeysUtil::SetStates()
	{
	if (doTime) {
		iPosTime->Enable();
		EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_POSTIMELABEL),TRUE);
		iNegTime->Enable();
		EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_NEGTIMELABEL),TRUE);
	} else {
		iPosTime->Disable();
		EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_POSTIMELABEL),FALSE);
		iNegTime->Disable();
		EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_NEGTIMELABEL),FALSE);
		}

	if (doVal) {
		iPosVal->Enable();
		EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_POSVALLABEL),TRUE);
		iNegVal->Enable();
		EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_NEGVALLABEL),TRUE);
	} else {
		iPosVal->Disable();
		EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_POSVALLABEL),FALSE);
		iNegVal->Disable();
		EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_NEGVALLABEL),FALSE);
		}

	switch (iu->GetMajorMode()) {
		case TVMODE_EDITKEYS:
		case TVMODE_EDITFCURVE:
			SetDlgItemText(hWnd,IDC_RANDKEYS_TEXT,
				GetString(IDS_RANDKEYS_KEYTEXT));
			EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_APPLY),TRUE);
			break;

		case TVMODE_EDITTIME: {
			Interval iv = iu->GetTimeSelection();
			TSTR buf, start, end;
			TimeToString(iv.Start(),start);
			TimeToString(iv.End(),end);
			buf.printf(GetString(IDS_RANDKEYS_TIMETEXT),start,end);
			SetDlgItemText(hWnd,IDC_RANDKEYS_TEXT,buf);
			EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_APPLY),TRUE);
			break;
			}

		case TVMODE_EDITRANGES:
		case TVMODE_POSRANGES:
			SetDlgItemText(hWnd,IDC_RANDKEYS_TEXT,_T(""));
			EnableWindow(GetDlgItem(hWnd,IDC_RANDKEYS_APPLY),FALSE);
			break;
		
		}
	}
Пример #19
0
void RotationMC::BeginCapture(Interval record,TimeValue sampSize)
	{
	// Set the base point to the controller value at the start time.
	Quat q;
	cont->GetValue(record.Start(),&q,FOREVER,CTRL_ABSOLUTE);	
	QuatToEuler(q,base);

	// Allocate a data buffer
	sampleCount = record.Duration()/sampSize + 1;
	data = new Point3[sampleCount];
	for (int i=0; i<sampleCount; i++) data[i] = Point3(0,0,0);
	}
Пример #20
0
void ScaleMC::BeginCapture(Interval record,TimeValue sampSize)
	{
	// Set the base point to the controller value at the start time.
	ScaleValue s;
	cont->GetValue(record.Start(),&s,FOREVER,CTRL_ABSOLUTE);	
	base = s.s;

	// Allocate a data buffer
	sampleCount = record.Duration()/sampSize + 1;
	data = new Point3[sampleCount];
	for (int i=0; i<sampleCount; i++) data[i] = Point3(1,1,1);
	}
Пример #21
0
void ValuesTable::MoveView(int d) { 

	m_view.Move(d);
	
	if (!m_draw->m_draws_controller->GetDoubleCursor())
		m_stats.Move(d);

	Interval in = m_view.Union(m_stats);
	Interval fin = in;
	fin.m_start = fin.Start() - m_draw->m_draws_controller->GetFilter();
	fin.m_end = fin.End() + m_draw->m_draws_controller->GetFilter();

	Move(fin);

	m_view.Move(-in.Start() + m_draw->m_draws_controller->GetFilter());
	m_stats.Move(-in.Start() + m_draw->m_draws_controller->GetFilter());

	if (!m_draw->m_draws_controller->GetDoubleCursor()) {
		RecalculateStats();
		m_draw->m_observers->NotifyStatsChanged(m_draw);
	}

}
Пример #22
0
void ValuesTable::DragStats(int d) {
	if (!m_draw->m_draws_controller->GetDoubleCursor())
		return;

	if (m_draw->GetDrawInfo() == NULL)
		return;

	m_stats.Drag(d);

	Interval in = m_view.Union(m_stats);
	Interval fin = in;
	fin.m_start -= m_draw->m_draws_controller->GetFilter();
	fin.m_end += m_draw->m_draws_controller->GetFilter();
	Move(fin);

	m_view.Move(-in.Start() + m_draw->m_draws_controller->GetFilter());
	m_stats.Move(-in.Start() + m_draw->m_draws_controller->GetFilter());

	RecalculateStats();

	m_draw->m_observers->NotifyStatsChanged(m_draw);

}
Пример #23
0
void FloatMC::EndCapture(Interval record,TimeValue sampSize, KeyReduceStatus *stat)
	{		
	// Clear any keys out of the record interval
	cont->DeleteTime(record,TIME_INCLEFT|TIME_INCRIGHT|TIME_NOSLIDE);

	// Make keys out of the data
	SuspendAnimate();
	AnimateOn();	
	for (int i=0; i<sampleCount; i++) {
		TimeValue t = record.Start() + i * sampSize;
		cont->SetValue(t,&data[i],1,CTRL_ABSOLUTE);
		if (i%UPDATE_RATE==0) if (stat->Progress(i)!=KEYREDUCE_CONTINUE) goto abort;
		}	

abort:
	ResumeAnimate();
	delete[] data;
	base = 0.0f;
	}
Пример #24
0
Interval AnimExportUtil::getKeyFramedRotationRange( INode* node3ds, Interval animRange )
{
	require( node3ds->GetTMController() );

	TimeValue start = animRange.Start();
	TimeValue end = animRange.End();

	// target defines rotation
	if ( node3ds->GetTarget() )
		return Interval( start, start );

	Control* cont = node3ds->GetTMController()->GetRotationController();
	IKeyControl* ikeys = cont ? GetKeyControlInterface( cont ) : 0;
	if ( ikeys )
	{
		ITCBRotKey key1;
		IBezQuatKey key2;
		ILinRotKey key3;
		IKey* keyp = 0;

		if ( cont->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID, 0) )
			keyp = &key1;
		else if ( cont->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID, 0) )
			keyp = &key2;
		else if ( cont->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID, 0) )
			keyp = &key3;

		if ( keyp )
		{
			if ( 0 == ikeys->GetNumKeys() )
				return Interval( start, start );

			ikeys->GetKey( 0, keyp );
			start = keyp->time;
			ikeys->GetKey( ikeys->GetNumKeys()-1, keyp );
			end = keyp->time;
		}
	}

	return Interval( start, end );
}
Пример #25
0
  TEST(basic, should_measure_intervals) {
      const int iterations = 10000;
      Interval interval;
      for (int i = 0; i < iterations; i++) {
          std::string s("");
          interval.Start("FOO");
          for (int j = 0; j < iterations; j++) {
              s += "a";
          }
          interval.End("FOO");
      }
      auto v = interval.Intervals("FOO");
      ASSERT_EQ(v.size(), iterations);

      float sum = 0;
      for (auto d : v) {
          ASSERT_GT(d.count(), 0);
          sum += d.count();
      }
      printf("avg per concatenation: %.10f\n", sum / v.size() / iterations);
  }
Пример #26
0
void Import::SetSceneParameters()
{
    Interval range;

    range.SetStart(0);
    range.SetEnd(30);
    SetFrameRate(30);

    SetTicksPerFrame(160);

    range.SetStart(range.Start() * GetTicksPerFrame());
    range.SetEnd(range.End() * GetTicksPerFrame());

    m_ip->SetAnimRange(range);

    Point3 bkColor (0.0f, 0.0f, 0.0f);
    m_impip->SetBackGround(0, bkColor);

    Point3 amColor (0.3f, 0.3f, 0.3f);
    m_impip->SetAmbient(0, amColor);
}
Пример #27
0
//from IUnReplaceableControl
Control * EulerExposeControl::GetReplacementClone()
{
	Control *control = NewDefaultRotationController();
	if(control)
	{
		// set key per frame
		Interval range =GetCOREInterface()->GetAnimRange();
		TimeValue tpf = GetTicksPerFrame();	
		SuspendAnimate();
		AnimateOn();
		Quat v;
		for(TimeValue t= range.Start(); t<=range.End();t+=tpf)
		{
			GetValue(t,&v,Interval(t,t));
			control->SetValue(t,&v,1,CTRL_ABSOLUTE);
		}
	
		ResumeAnimate();
	}
	return control;
}
Пример #28
0
// ###########################################################
// #######   EXPORTERs DI SINGOLE ENTITA' DELLA SCENA  #######
// ###########################################################
void SkeletonExporter::export_general_info(void)
{
	int ff, lf, fs;
	Interval range = ip->GetAnimRange();
	Box3 bbox;

	fprintf(fTXT, "[AD]Turbo ROX as usual !! \n\n");

	INode *root = ip->GetRootNode();
	bbox.pmin.x=bbox.pmin.y=bbox.pmin.z=(float)1E10;
	bbox.pmax.x=bbox.pmax.y=bbox.pmax.z=(float)-1E10;
    GetSceneBoundingBox(root, 0, &bbox);

	ff=range.Start() / GetTicksPerFrame();
	lf=range.End() / GetTicksPerFrame();
	fs=GetFrameRate();

	// Start with a file identifier and format version
	fprintf(fTXT, "First frame : %d\n", ff);
	fprintf(fTXT, "Last frame : %d\n", lf);
	fprintf(fTXT, "Frame speed : %d\n", fs);
	fprintf(fTXT, "Scene Bounding Box at time 0\n");
	fprintf(fTXT, "min : %f, %f, %f\n",
		    bbox.pmin.x, bbox.pmin.y, bbox.pmin.z);
	fprintf(fTXT, "max : %f, %f, %f\n",
		    bbox.pmax.x, bbox.pmax.y, bbox.pmax.z);

	write_chunk_header(fA3D, SCENE_GENERAL_INFO_ID, "Scene Root", 36);
	fwrite(&ff, sizeof(int), 1, fA3D);
	fwrite(&lf, sizeof(int), 1, fA3D);
	fwrite(&fs, sizeof(int), 1, fA3D);
	write_bbox(&bbox, fA3D);

	if (makeRAY) write_chunk_header(fRAY, SCENE_GENERAL_INFO_ID, "Scene Root", 36);
	if (makeRAY) fwrite(&ff, sizeof(int), 1, fRAY);
	if (makeRAY) fwrite(&lf, sizeof(int), 1, fRAY);
	if (makeRAY) fwrite(&fs, sizeof(int), 1, fRAY);
	if (makeRAY) write_bbox(&bbox, fRAY);
}
Пример #29
0
// Output float keys if this is a known float controller that
// supports key operations. Otherwise we will sample the controller 
// once for each frame to get the value.
void AsciiExp::DumpFloatKeys(Control* cont, int indentLevel) 
{
	if (!cont)
		return;
	
	int i;
	TSTR indent = GetIndent(indentLevel);
	IKeyControl *ikc = NULL;

	// If the user wants us to always sample, we will ignore the KeyControlInterface
	if (!GetAlwaysSample())
		ikc = GetKeyControlInterface(cont);
	
	// TCB float
	if (ikc && cont->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID, 0)) {
		_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_FLOAT_TCB); 
		for (i=0; i<ikc->GetNumKeys(); i++) {
			ITCBFloatKey key;
			ikc->GetKey(i, &key);
			_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"),
				indent.data(),
				ID_TCB_FLOAT_KEY,
				key.time,
				Format(key.val));
			_ftprintf(pStream, _T("\t%s\t%s\t%s\t%s\t%s\n"), Format(key.tens), Format(key.cont), Format(key.bias), Format(key.easeIn), Format(key.easeOut));
		}
		_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
	}
	// Bezier float
	else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID, 0)) {
		_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_FLOAT_BEZIER); 
		for (i=0; i<ikc->GetNumKeys(); i++) {
			IBezFloatKey key;
			ikc->GetKey(i, &key);
			_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"),
				indent.data(),
				ID_BEZIER_FLOAT_KEY,
				key.time, 
				Format(key.val));
			_ftprintf(pStream, _T("\t%s\t%s\t%d\n"), Format(key.intan), Format(key.outtan), key.flags);
		}
		_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
	}
	else if (ikc && cont->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID, 0)) {
		_ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_FLOAT_LINEAR); 
		for (i=0; i<ikc->GetNumKeys(); i++) {
			ILinFloatKey key;
			ikc->GetKey(i, &key);
			_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"),
				indent.data(),
				ID_FLOAT_KEY,
				key.time,
				Format(key.val));
		}
		_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
	}
	else {
		
		// Unknown controller, no key interface or sample on demand -
		// This might be a procedural controller or something else we
		// don't know about. The last resort is to get the value from the 
		// controller at every n frames.
		
		TSTR name;
		cont->GetClassName(name);
		TSTR className = FixupName(name);
		Interface14 *iface = GetCOREInterface14();
		UINT codepage  = iface-> DefaultTextSaveCodePage(true);
		const char* className_locale = className.ToCP(codepage);
		_ftprintf(pStream, _T("%s\t\t%s \"%hs\" {\n"), indent.data(), ID_CONTROL_FLOAT_SAMPLE,
			className_locale);
		
		// If it is animated at all...
		if (cont->IsAnimated()) {
			// Get the range of the controller animation 
			Interval range; 
			// Get range of full animation
			Interval animRange = ip->GetAnimRange(); 
			TimeValue t = cont->GetTimeRange(TIMERANGE_ALL).Start();
			float value;
			
			// While we are inside the animation... 
			while (animRange.InInterval(t)) {
				// Sample the controller
				range = FOREVER;
				cont->GetValue(t, &value, range);
				
				// Set time to start of controller validity interval 
				t = range.Start();
				
				// Output the sample
				_ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"),
					indent.data(),
					ID_FLOAT_KEY,
					t,
					Format(value));
				
				// If the end of the controller validity is beyond the 
				// range of the animation
				if (range.End() > cont->GetTimeRange(TIMERANGE_ALL).End()) {
					break;
				}
				else {
					t = (range.End()/GetTicksPerFrame()+GetKeyFrameStep()) * GetTicksPerFrame();
				}
			}
		}
		_ftprintf(pStream, _T("%s\t\t}\n"), indent.data());
	}
}
Пример #30
0
int		LinkTimeControl::PaintFCurves( ParamDimensionBase *dim, HDC hdc, Rect& rcGraph, Rect& rcPaint,
			float tzoom, int tscroll, float vzoom, int vscroll, DWORD flags )
{
	const int n = NumKeys();
	if ( n == 0 )
		return 0;

	Interval valid;
	int h = rcGraph.h()-1;
	HPEN dpen,spen;
	BOOL init=FALSE;		
	Interval range = GetTimeRange(TIMERANGE_ALL);	
	SetBkMode(hdc,TRANSPARENT);	

	dpen = CreatePen(PS_DOT,0,GetColorManager()->GetColor(kFunctionCurveFloat));
	spen = CreatePen(PS_SOLID,0,GetColorManager()->GetColor(kFunctionCurveFloat));

	SIZE size;
	GetTextExtentPoint( hdc, _T("0"), 1, &size );

	float val;
	TimeValue leftTime = ScreenToTime(rcPaint.left,tzoom,tscroll);
	TimeValue rightTime = ScreenToTime(rcPaint.right,tzoom,tscroll);
	int x, y;

	// dotted line to left of keys
	if ( leftTime < range.Start() )
	{
		SelectObject(hdc,dpen);
		GetValue(range.Start(),&val,valid);
		y = ValueToScreen(dim->Convert(val),h,vzoom,vscroll);
		MoveToEx(hdc,rcPaint.left,y,NULL);
		LineTo(hdc,TimeToScreen(range.Start(),tzoom,tscroll),y);
	}

	SelectObject(hdc,spen);

	// first node text
	{
		TimeValue t = GetKeyTime( 0 );
		if ( t >= leftTime && t <= rightTime )
		{
			GetValue(t,&val,valid);
			y = ValueToScreen(dim->Convert(val),h,vzoom,vscroll);
			x = TimeToScreen(t,tzoom,tscroll);
			INode* node = fOwner->GetNode( 0 );
			DLTextOut( hdc, x, y-1-size.cy, node ? node->GetName() : _T("World") );
		}
	}

	// solid line between keys
	for ( int i=1; i<n; ++i )
	{
		TimeValue t0 = GetKeyTime( i-1 );
		TimeValue t1 = GetKeyTime( i );
		if ( t1 < leftTime || t0 > rightTime )
			continue;
		GetValue(t0,&val,valid);
		y = ValueToScreen(dim->Convert(val),h,vzoom,vscroll);
		MoveToEx(hdc,TimeToScreen(t0,tzoom,tscroll),y,NULL);
		x = TimeToScreen(t1,tzoom,tscroll);
		LineTo(hdc,x,y);
		GetValue(t1,&val,valid);
		y = ValueToScreen(dim->Convert(val),h,vzoom,vscroll);
		LineTo(hdc,x,y);

		INode* node = fOwner->GetNode( i );
		DLTextOut( hdc, x, y-1-size.cy, node ? node->GetName() : _T("World") );
	}

	// dotted line to right of keys
	if ( rightTime > range.End() )
	{
		SelectObject(hdc,dpen);
		GetValue(range.End(),&val,valid);
		y = ValueToScreen(dim->Convert(val),h,vzoom,vscroll);
		MoveToEx(hdc,TimeToScreen(range.End(),tzoom,tscroll),y,NULL);
		LineTo(hdc,rcPaint.right,y);
	}

	SelectObject( hdc, spen );
	HBRUSH hUnselBrush = CreateSolidBrush(GetColorManager()->GetColor(kTrackbarKeys));
	HBRUSH hSelBrush = CreateSolidBrush(GetColorManager()->GetColor(kTrackbarSelKeys));

	// render keys themselves
	for ( int i=0; i<n; ++i )
	{
		TimeValue t = GetKeyTime( i );
		if ( t < leftTime || t > rightTime )
			continue;
		GetValue(t,&val,valid);
		y = ValueToScreen(dim->Convert(val),h,vzoom,vscroll);
		x = TimeToScreen(t,tzoom,tscroll);
		SelectObject( hdc, IsKeySelected( i ) ? hSelBrush : hUnselBrush );
		Rectangle(hdc,x-3,y-3,x+3,y+3);
	}

	SetBkMode(hdc,OPAQUE);
	SelectObject(hdc,GetStockObject(BLACK_PEN));	

	DeleteObject(spen);
	DeleteObject(dpen);
	DeleteObject(hUnselBrush);
	DeleteObject(hSelBrush);

	return 0;
}