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 ); }
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 ); }
void GR2ImportImpl::ImportAnimations() { if (info.Animations.size() == 0 || !enableAnimation) return; ClearAnimation(); //for (int anim=0, nanim=info.Animations.size(); anim<nanim; ++anim) //{ // Animation& anim = (*info.Animations[anim]); //} Interval range; range.SetInstant(0); float time = FrameToTime(0); for (int ianim=0, nanim=info.Animations.size(); ianim<nanim; ++ianim) { Animation& anim = (*info.Animations[ianim]); TimeValue animEnd = TimeToFrame(time + anim.Duration); if (animEnd > range.End()) range.SetEnd(animEnd); // Build Default Time int nkeys = anim.Duration / anim.TimeStep; GR2Array<granny_real32> defaultKeys(nkeys); granny_real32 curtime = 0.0f; for (int ikeys=0; ikeys<nkeys; ++ikeys, curtime += anim.TimeStep) defaultKeys[ikeys] = curtime; for (int grp=0, ngrp=anim.TrackGroups.size(); grp<ngrp; ++grp) { TrackGroup& group = (*anim.TrackGroups[grp]); if (INode *root = o->gi->GetINodeByName(group.Name)) { Point3 s( group.InitialPlacement.Scale.m[0][0] , group.InitialPlacement.Scale.m[1][1] , group.InitialPlacement.Scale.m[2][2] ); for (int itrack=0, ntrack=group.TransformTracks.size(); itrack<ntrack; ++itrack) { TransformTrack& track = group.TransformTracks[itrack]; if (INode *node = o->gi->GetINodeByName(track.Name)) { if (Control *c = node->GetTMController()) { DWORD flags=INHERIT_ALL; c->SetInheritanceFlags(INHERIT_ALL,FALSE); ImportPosition(c, track, time, defaultKeys); ImportRotation(c, track, time, defaultKeys); ImportScale(c, track, time, defaultKeys); } } } Matrix3 rot(true); group.InitialPlacement.Rotation.MakeMatrix(rot); Matrix3 m = TransMatrix(group.InitialPlacement.Origin) * Inverse(rot) * ScaleMatrix( s ); PosRotScaleNode(root, m); // TODO: Move to initial transform } } } o->gi->SetAnimRange(range); }
//--------------------------------------------------------------- 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; }
// 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; }
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; }
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) ); } }
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) ); } }
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 ); }
// 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); }
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(); }
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; } }
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 ); }
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 ); }
/** * 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; } }
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 ); }
//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; }
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); }
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); }
// ########################################################### // ####### 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); }
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); } }
/** * 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; } }
/** * 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; } }
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; }
void SkeletonExporter::export_particle_spray(INode *node) { char sval[50]; Interval range = ip->GetAnimRange(); ObjectState os = node->EvalWorldState(0); if (!os.obj) return; SimpleParticle *partsys; Object *p; IDerivedObject *q; Modifier *m; partsys=(SimpleParticle *)os.obj; Point3 row; Matrix3 mat; Mtl *materiale; INode *padre=node->GetParentNode(); int mod_names=0, k, mod_count=0; char modNames[25][50], refname[50]; int sf, sm, mf, n; if ((padre) && (strcmp(padre->GetName(), "Scene Root")!=0)) sf=strlen(padre->GetName())+1; else sf=0; materiale=node->GetMtl(); if (materiale) sm=strlen(materiale->GetName())+1; else sm=0; mf=0; // trovo i modificatori Wind e Gravity con il loro // nome p=node->GetObjOrWSMRef(); if ((p->SuperClassID()==GEN_DERIVOB_CLASS_ID) && (p->ClassID()==Class_ID(WSM_DERIVOB_CLASS_ID, 0))) { q=(IDerivedObject *)p; n=q->NumModifiers(); mod_names=mod_count=0; for (k=0; k<n; k++) { m=q->GetModifier(k); Class_ID cidd = m->ClassID(); if ((cidd==Class_ID(WINDMOD_CLASS_ID, 0)) || (cidd==Class_ID(GRAVITYMOD_CLASS_ID, 0)) || (cidd==Class_ID(BOMB_OBJECT_CLASS_ID, 0))) { SimpleWSMMod *wm=(SimpleWSMMod *)m; strcpy(refname, wm->nodeRef->GetName()); strcpy(modNames[mod_count], refname); mod_names+=(strlen(refname)+1); mod_count++; } } } write_chunk_header(fA3D, SPRAY_PARTICLE_SYSTEM_ID, node->GetName(), 4+sf+4+sm+ // padre, materiale 12+48+ //pivot, matrice world(t=0) 4+mf+ // nome mesh/oggetto 4+4+4+4+ // emitter: width, height, speed , variation 4+4+4+4+ // life, startTime, stopTime, max_particles 4+mod_names // num WSM, nomi WSM ); fprintf(fTXT, "Spray particle system found\n"); fprintf(fTXT, "Name : %s\n", node->GetName()); if (padre) fprintf(fTXT, "Parent name : %s\n", node->GetParentNode()->GetName()); if (materiale) fprintf(fTXT, "Material name : %s\n", materiale->GetName()); if (makeADP) fprintf(fADP, " particle %c%s%c\n {\n", '"', node->GetName(), '"'); // ----------- scrivo il padre (flag, nome) ------------------ fwrite(&sf, sizeof(int), 1, fA3D); if (sf>0) { write_string0(fA3D, padre->GetName()); if (makeADP) fprintf(fADP, " father=%c%s%c;\n", '"', padre->GetName(), '"'); } else if (makeADP) fprintf(fADP, " father=%cNONE%c;\n", '"', '"'); // --------- scrivo il materiale di base (flag, nome) ---------- fwrite(&sm, sizeof(int), 1, fA3D); if (sm>0) { write_string0(fA3D, materiale->GetName()); //if (makeADP) fprintf(fADP, " material=%c%s%c;\n", '"', materiale->GetName(), '"'); } else //if (makeADP) fprintf(fADP, " material=%cNONE%c;\n", '"', '"'); // --------------- scrittura del punto di pivot ---------------- GetPivotOffset(node, &row); fprintf(fTXT, "Pivot point : %f, %f, %f\n", row.x, row.y, row.z); write_point3(&row, fA3D); // ------------------- scrittura matrice ----------------------- mat = node->GetNodeTM(0); write_matrix(&mat, fA3D); // --------- scrittura dell'eventuale nome della mesh ---------- fwrite(&mf, sizeof(int), 1, fA3D); if (mf>0) { write_string0(fA3D, "TO_DO"); if (makeADP) fprintf(fADP, " lod=%cTO_DO, 0, 99999.99%c;\n", '"', '"'); } // ************* ESPORAZIONE DATI DEL PARTCLE SYSTEM ************* float initVel, var, width, height; int count, life, start_time, stop_time; partsys->pblock->GetValue(PB_EMITTERWIDTH, 0, width, FOREVER); partsys->pblock->GetValue(PB_EMITTERHEIGHT, 0, height, FOREVER); partsys->pblock->GetValue(PB_SPEED, 0, initVel, FOREVER); partsys->pblock->GetValue(PB_VARIATION, 0, var, FOREVER); partsys->pblock->GetValue(PB_LIFETIME, 0, life, FOREVER); life=life/ GetTicksPerFrame(); partsys->pblock->GetValue(PB_STARTTIME, 0, start_time, FOREVER); start_time=start_time / GetTicksPerFrame(); stop_time=range.End() / GetTicksPerFrame(); partsys->pblock->GetValue(PB_RNDPARTICLES, 0, count, FOREVER); fprintf(fTXT, "Emitter width: %f\n", width); fprintf(fTXT, "Emitter height: %f\n", height); fprintf(fTXT, "Emitter speed (init vel): %f\n", initVel); fprintf(fTXT, "Emitter variation: %f\n", var); fprintf(fTXT, "Life: %d\n", life); fprintf(fTXT, "Start time: %d\n", start_time); fprintf(fTXT, "Stop time: %d\n", stop_time); fprintf(fTXT, "Max particles: %d\n", count); // informazioni in formato binario (.A3D) fwrite(&width, sizeof(float), 1, fA3D); fwrite(&height, sizeof(float), 1, fA3D); fwrite(&initVel, sizeof(float), 1, fA3D); fwrite(&var, sizeof(float), 1, fA3D); fwrite(&life, sizeof(int), 1, fA3D); fwrite(&start_time, sizeof(int), 1, fA3D); fwrite(&stop_time, sizeof(int), 1, fA3D); fwrite(&count, sizeof(int), 1, fA3D); fwrite(&mod_count, sizeof(int), 1, fA3D); fprintf(fTXT, "Modificatori (wind, gravity, bomb) collegati: %d\n", mod_count); for (k=0; k<mod_count; k++) { fprintf(fTXT, "Modificatore %d: %s\n", k, modNames[k]); write_string0(fA3D, modNames[k]); //if (makeADP) //fprintf(fADP, " modifier=%c%s, ON%c;\n", '"', modNames[k], '"'); } //------------------------ // ESPORTAZIONE KEYFRAMER //------------------------ Control *c; int size_key; // NB: per gli oggetti mesh e quant'altre tipologie di // oggetti che possono essere linkati (ovvero dove e' // possibile implmenetare gerarchie), esporto SEMPRE una key // di posizione, una di rotazione ed una di scaling // POSITION CONTROLLER c=node->GetTMController()->GetPositionController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=36; else if (IsBezierControl(c)) size_key=40; else size_key=16; fprintf(fTXT, "Particle position track present.\n"); write_chunk_header(fA3D, POSITION_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_point3_track(c, 1, fA3D); } else { fprintf(fTXT, "Particle position track present. (1 key case)\n"); if (!c) fprintf(fTXT, "c nullo !\n"); fflush(fTXT); size_key=36; write_chunk_header(fA3D, POSITION_TRACK_ID, node->GetName(), 1+2+4+1*size_key); export_1key_point3_track(c, 1, fA3D); } // ROTATION CONTROLLER c=node->GetTMController()->GetRotationController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=40; else size_key=20; fprintf(fTXT, "Particle rotation track present.\n"); write_chunk_header(fA3D, ROTATION_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_rot_track(c, fA3D); } else { fprintf(fTXT, "Particle rotation track present. (1 key case)\n"); fflush(fTXT); size_key=40; write_chunk_header(fA3D, ROTATION_TRACK_ID, node->GetName(), 1+2+4+1*size_key); export_1key_rot_track(c, fA3D); } // SCALE CONTROLLER c=node->GetTMController()->GetScaleController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=36; else if (IsBezierControl(c)) size_key=40; else size_key=16; fprintf(fTXT, "Particle scaling track present.\n"); write_chunk_header(fA3D, SCALE_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_scale_track(c, fA3D); } else { fprintf(fTXT, "Particle scaling track present. (1 key case)\n"); size_key=36; write_chunk_header(fA3D, SCALE_TRACK_ID, node->GetName(), 1+2+4+1*size_key); export_1key_scale_track(c, fA3D); } // keyframer emitter width c=partsys->pblock->GetController(PB_EMITTERWIDTH); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Particle emitter width track present.\n"); write_chunk_header(fA3D, PARTICLE_EMITTER_WIDTH_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); } // keyframer emitter length c=partsys->pblock->GetController(PB_EMITTERHEIGHT); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Particle emitter length track present.\n"); write_chunk_header(fA3D, PARTICLE_EMITTER_LENGTH_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); } // keyframer particles speed c=partsys->pblock->GetController(PB_SPEED); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Particle emitter speed track present.\n"); write_chunk_header(fA3D, PARTICLE_EMITTER_SPEED_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); } // keyframer particles variations c=partsys->pblock->GetController(PB_VARIATION); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Particle emitter variation track present.\n"); write_chunk_header(fA3D, PARTICLE_EMITTER_VARIATION_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); } if (makeADP) { fprintf(fADP, " texture=%cNONE%c;\n", '"', '"'); my_ftoa(width, sval); fprintf(fADP, " emitter_width=%c%s%c;\n", '"', sval, '"'); my_ftoa(height, sval); fprintf(fADP, " emitter_height=%c%s%c;\n", '"', sval, '"'); fprintf(fADP, " faded_particles=%cOFF%c;\n", '"', '"'); fprintf(fADP, " max_particles=%c%d%c;\n", '"', count, '"'); fprintf(fADP, " start_time=%c%d%c;\n", '"', start_time, '"'); fprintf(fADP, " end_time=%c%d%c;\n", '"', stop_time, '"'); fprintf(fADP, " life=%c%d%c;\n", '"', life, '"'); my_ftoa(initVel, sval); fprintf(fADP, " speed=%c%s%c;\n", '"', sval, '"'); my_ftoa(var, sval); fprintf(fADP, " variation=%c%s%c;\n", '"', sval, '"'); fprintf(fADP, " size_attenuation=%c0.4, 1.0, 0.8, 0.1%c;\n", '"', '"'); fprintf(fADP, " }\n\n"); } fprintf(fTXT, "\n\n"); }
/* ==================== DoExport ==================== */ int G3DAExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD options) { // clear the old data if(mRoot){delete mRoot, mRoot = NULL;} mNodeCount = 0; mSkins.clear(); // normalize the file path Str path = UnifySlashes(name); // get the export dir mPath = UnifySlashes(i->GetDir(APP_EXPORT_DIR)); mPath += '/'; if( !strstr( path.c_str(), mPath.c_str() ) ) { G3DAssert("The export path(%s) is illegal!",name); return 1; } // get the animation range Interval inter = i->GetAnimRange(); mTime = i->GetTime(); mStart = inter.Start(); mEnd = inter.End(); // recursive export all of the node exportNode(i->GetRootNode()); // export all of the skin for(int k = 0; k < mSkins.size(); k++) exportSkin(mSkins[k]); // recursive export all of the animation exportAnimation(mRoot); // check all of the nodes std::set<Str> names, duplicates; check(mRoot, names, duplicates); for(std::set<Str>::iterator it = duplicates.begin(); it != duplicates.end(); ++it) { G3DAssert( "Duplicate node name : %s", (*it).c_str() ); return 1; } #if 0 // write all of the data FILE *output = fopen(path.c_str(), "wb"); if(output==NULL) { G3DAssert("Fail to open the file : %s", path.c_str()); return 1; } // write count of the frame unsigned int frame_count = (mEnd-mStart)/GetTicksPerFrame()+1; fwrite( &frame_count, sizeof(unsigned int), 1, output ); // write number of the node fwrite( &mNodeCount, sizeof(unsigned int), 1, output ); // write count of the action unsigned int action_count = 0; fwrite( &action_count, sizeof(unsigned int), 1, output ); // write all of the node animation wirteAnimation(output,mRoot); // close file fclose(output); #else // write all of the data FILE *output = fopen(path.c_str(), "wb"); if(output==NULL) { G3DAssert("Fail to open the file : %s", path.c_str()); return 1; } // get the count of the frame unsigned int frame_count = (mEnd-mStart)/GetTicksPerFrame()+1; // begin to write the animation fprintf(output, "<animation>\n"); // begin to write the frame fprintf(output, "<frame count=\"%d\">\n", frame_count); // write all of the node frame wirteFrame(output,mRoot); // end to wirte the frame fprintf(output, "</frame>\n"); // end to wirte the animation fprintf(output, "</animation>\n"); // close file fclose(output); #endif // clear all of the data mSkins.clear(); if(mRoot){delete mRoot, mRoot = NULL;} return 1; }
// options dialog message handler INT_PTR Options::ExportOptionsDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM) { ISpinnerControl* spin; // int ticksPerFrame = GetTicksPerFrame(); Interval animRange = mMaxInterface->GetAnimRange(); int sceneStart = animRange.Start(); int sceneEnd = animRange.End(); switch (message) { case WM_INITDIALOG: { CenterWindow(hWnd, GetParent(hWnd)); // grab scene timing details & clip anim start & end if needed if (mAnimationStart < sceneStart) mAnimationStart = sceneStart; if (mAnimationStart > sceneEnd) mAnimationStart = sceneEnd; if (mAnimationEnd < sceneStart) mAnimationEnd = sceneStart; if (mAnimationEnd > sceneEnd) mAnimationEnd = sceneEnd; // setup checkboxes CheckDlgButton(hWnd, IDC_GEOM_NORMALS, mNormals); CheckDlgButton(hWnd, IDC_GEOM_TRIANGLES, mTriangulate); CheckDlgButton(hWnd, IDC_GEOM_XREFS, mIncludeXrefs); CheckDlgButton(hWnd, IDC_GEOM_TANGENTS, mTangents); CheckDlgButton(hWnd, IDC_ANIM_ENABLE, mAnimations); CheckDlgButton(hWnd, IDC_ANIM_SAMPLE, mSampleAnimation); CheckDlgButton(hWnd, IDC_ANIM_CLIP, mCreateClip); CheckDlgButton(hWnd, IDC_LAYERS_TO_CLIPS, mLayersAsClips); CheckDlgButton(hWnd, IDC_BAKE_MATRICES, mBakeMatrices); CheckDlgButton(hWnd, IDC_RELATIVE_PATHS, mRelativePaths); CheckDlgButton(hWnd, IDC_COPY_IMAGES, mCopyImages); CheckDlgButton(hWnd, IDC_EXPORT_USER_PROPERTIES, mExportUserDefinedProperties); // Animation checkboxes depend on the enable button. EnableDlgControl(hWnd, IDC_ANIM_SAMPLE, mAnimations); EnableDlgControl(hWnd, IDC_ANIM_CLIP, mAnimations); #if defined(MAX_RELEASE_R17) && (MAX_RELEASE >= MAX_RELEASE_R17) EnableDlgControl(hWnd, IDC_LAYERS_TO_CLIPS, mAnimations); #else EnableDlgControl(hWnd, IDC_LAYERS_TO_CLIPS, false); #endif // setup spinners spin = GetISpinner(GetDlgItem(hWnd, IDC_ANIM_START_SPIN)); spin->LinkToEdit(GetDlgItem(hWnd,IDC_ANIM_START), EDITTYPE_TIME); spin->SetLimits(sceneStart, sceneEnd, true); spin->SetScale(1.0f); spin->SetValue(mAnimationStart, true); spin->Enable(mSampleAnimation && mAnimations); EnableWindow(GetDlgItem(hWnd, IDC_START_LABEL), mSampleAnimation && mAnimations); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_ANIM_END_SPIN)); spin->LinkToEdit(GetDlgItem(hWnd,IDC_ANIM_END), EDITTYPE_TIME); spin->SetLimits(sceneStart, sceneEnd, true); spin->SetScale(1.0f); spin->SetValue(mAnimationEnd, false); spin->Enable(mSampleAnimation && mAnimations); EnableWindow(GetDlgItem(hWnd, IDC_END_LABEL), mSampleAnimation && mAnimations); ReleaseISpinner(spin); return true; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_ANIM_ENABLE: mAnimations = IsDlgButtonChecked(hWnd, IDC_ANIM_ENABLE) == BST_CHECKED; EnableDlgControl(hWnd, IDC_ANIM_SAMPLE, mAnimations); EnableDlgControl(hWnd, IDC_ANIM_CLIP, mAnimations); #if defined(MAX_RELEASE_R17) && (MAX_RELEASE >= MAX_RELEASE_R17) EnableDlgControl(hWnd, IDC_LAYERS_TO_CLIPS, mAnimations); #else EnableDlgControl(hWnd, IDC_LAYERS_TO_CLIPS, false); #endif /*spin = GetISpinner(GetDlgItem(hWnd, IDC_ANIM_START_SPIN)); //spin->LinkToEdit(GetDlgItem(hWnd,IDC_ANIM_START), EDITTYPE_INT); spin->Enable(sampleAnim && animations); EnableWindow(GetDlgItem(hWnd, IDC_START_LABEL), sampleAnim && animations); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_ANIM_END_SPIN)); //spin->LinkToEdit(GetDlgItem(hWnd,IDC_ANIM_END), EDITTYPE_INT); spin->Enable(sampleAnim && animations); EnableWindow(GetDlgItem(hWnd, IDC_END_LABEL), sampleAnim && animations); ReleaseISpinner(spin); break; */ case IDC_ANIM_SAMPLE: mSampleAnimation = IsDlgButtonChecked(hWnd, IDC_ANIM_SAMPLE) == BST_CHECKED; spin = GetISpinner(GetDlgItem(hWnd, IDC_ANIM_START_SPIN)); spin->Enable(mSampleAnimation && mAnimations); EnableWindow(GetDlgItem(hWnd, IDC_START_LABEL), mSampleAnimation && mAnimations); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_ANIM_END_SPIN)); spin->Enable(mSampleAnimation && mAnimations); EnableWindow(GetDlgItem(hWnd, IDC_END_LABEL), mSampleAnimation && mAnimations); ReleaseISpinner(spin); break; case IDOK: // hit OK, pick up control values & end dialog mBakeMatrices = IsDlgButtonChecked(hWnd, IDC_BAKE_MATRICES) == BST_CHECKED; mRelativePaths = IsDlgButtonChecked(hWnd, IDC_RELATIVE_PATHS) == BST_CHECKED; mAnimations = IsDlgButtonChecked(hWnd, IDC_ANIM_ENABLE) == BST_CHECKED; mSampleAnimation = IsDlgButtonChecked(hWnd, IDC_ANIM_SAMPLE) == BST_CHECKED; mCreateClip = IsDlgButtonChecked(hWnd, IDC_ANIM_CLIP) == BST_CHECKED; mLayersAsClips = IsDlgButtonChecked(hWnd, IDC_LAYERS_TO_CLIPS) == BST_CHECKED; mNormals = IsDlgButtonChecked(hWnd, IDC_GEOM_NORMALS) == BST_CHECKED; mTriangulate = IsDlgButtonChecked(hWnd, IDC_GEOM_TRIANGLES) == BST_CHECKED; mIncludeXrefs = IsDlgButtonChecked(hWnd, IDC_GEOM_XREFS) == BST_CHECKED; mTangents = IsDlgButtonChecked(hWnd, IDC_GEOM_TANGENTS) == BST_CHECKED; mCopyImages = IsDlgButtonChecked(hWnd, IDC_COPY_IMAGES) == BST_CHECKED; mExportUserDefinedProperties = IsDlgButtonChecked(hWnd, IDC_EXPORT_USER_PROPERTIES) == BST_CHECKED; spin = GetISpinner(GetDlgItem(hWnd, IDC_ANIM_START_SPIN)); mAnimationStart = mSampleAnimation ? spin->GetIVal() : sceneStart; ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_ANIM_END_SPIN)); mAnimationEnd = mSampleAnimation ? spin->GetIVal() : sceneEnd; ReleaseISpinner(spin); EndDialog(hWnd, 1); break; case IDCANCEL: EndDialog(hWnd, 0); break; } default: return false; } return true; }
static INT_PTR CALLBACK ElMaxPluginDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { theElMaxPlugin.Init(hWnd); Interval animRange; ISpinnerControl* spin; int frameStart, frameEnd; // Setup the spinner control for the static frame# // We take the frame 0 as the default value animRange = theElMaxPlugin.GetInterface()->GetAnimRange(); frameStart = animRange.Start() / GetTicksPerFrame(); frameEnd = animRange.End() / GetTicksPerFrame(); spin = GetISpinner(GetDlgItem(hWnd, IDC_STATIC_FRAME_SPIN)); spin->LinkToEdit(GetDlgItem(hWnd,IDC_STATIC_FRAME), EDITTYPE_INT); spin->SetLimits(frameStart, frameEnd, TRUE); spin->SetScale(1.0f); spin->SetValue(theElMaxPlugin.GetStaticFrame(), FALSE); ReleaseISpinner(spin); // Setup the spinner controls for the mesh animation start frame spin = GetISpinner(GetDlgItem(hWnd, IDC_MESHANIM_START_SPIN)); spin->LinkToEdit(GetDlgItem(hWnd, IDC_MESHANIM_START), EDITTYPE_INT); spin->SetLimits(frameStart, frameEnd, TRUE); spin->SetScale(1.0f); spin->SetValue(frameStart, FALSE); ReleaseISpinner(spin); // Setup the spinner controls for the mesh animation end frame spin = GetISpinner(GetDlgItem(hWnd, IDC_MESHANIM_END_SPIN)); spin->LinkToEdit(GetDlgItem(hWnd, IDC_MESHANIM_END), EDITTYPE_INT); spin->SetLimits(frameStart, frameEnd, TRUE); spin->SetScale(1.0f); spin->SetValue(frameEnd, FALSE); ReleaseISpinner(spin); // Setup the spinner controls for the mesh animation key sample rate spin = GetISpinner(GetDlgItem(hWnd, IDC_MESHANIM_STEP_SPIN)); spin->LinkToEdit(GetDlgItem(hWnd, IDC_MESHANIM_STEP), EDITTYPE_INT); spin->SetLimits(1, 100, TRUE); spin->SetScale(1.0f); spin->SetValue(theElMaxPlugin.GetMeshAnimFrameStep(), FALSE); ReleaseISpinner(spin); // Setup the spinner controls for the skeletal animation start frame spin = GetISpinner(GetDlgItem(hWnd, IDC_SKELETALANIM_START_SPIN)); spin->LinkToEdit(GetDlgItem(hWnd, IDC_SKELETALANIM_START), EDITTYPE_INT); spin->SetLimits(frameStart, frameEnd, TRUE); spin->SetScale(1.0f); spin->SetValue(frameStart, FALSE); ReleaseISpinner(spin); // Setup the spinner controls for the skeletal animation end frame spin = GetISpinner(GetDlgItem(hWnd, IDC_SKELETALANIM_END_SPIN)); spin->LinkToEdit(GetDlgItem(hWnd, IDC_SKELETALANIM_END), EDITTYPE_INT); spin->SetLimits(frameStart, frameEnd, TRUE); spin->SetScale(1.0f); spin->SetValue(frameEnd, FALSE); ReleaseISpinner(spin); // Setup the spinner controls for the skeletal animation key sample rate spin = GetISpinner(GetDlgItem(hWnd, IDC_SKELETALANIM_STEP_SPIN)); spin->LinkToEdit(GetDlgItem(hWnd, IDC_SKELETALANIM_STEP), EDITTYPE_INT); spin->SetLimits(1, 100, TRUE); spin->SetScale(1.0f); spin->SetValue(theElMaxPlugin.GetSkeletalAnimFrameStep(), FALSE); ReleaseISpinner(spin); } break; case WM_DESTROY: theElMaxPlugin.Destroy(hWnd); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_EXPORT_MESH: if (HIWORD(wParam) == BN_CLICKED) { char filename[MAX_PATH] = {0}; if (GetSaveFileName(hWnd, filename, sizeof(filename), _T("ElMesh(*.ELM)\0*.ELM\0All(*.*)\0*.*\0"), _T("ELM"), _T("Mesh file to save"))) { ISpinnerControl* spin = GetISpinner(GetDlgItem(hWnd, IDC_STATIC_FRAME_SPIN)); theElMaxPlugin.SetStaticFrame(spin->GetIVal()); ReleaseISpinner(spin); theElMaxPlugin.ExportMesh(filename); } } break; case IDC_EXPORT_MESHANIM: if (HIWORD(wParam) == BN_CLICKED) { char filename[MAX_PATH] = {0}; if (GetSaveFileName(hWnd, filename, sizeof(filename), _T("ElMeshAnimation(*.EMA)\0*.EMA\0All(*.*)\0*.*\0"), _T("EMA"), _T("MeshAnimation file to save"))) { ISpinnerControl* spin = GetISpinner(GetDlgItem(hWnd, IDC_STATIC_FRAME_SPIN)); theElMaxPlugin.SetStaticFrame(spin->GetIVal()); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_MESHANIM_START_SPIN)); theElMaxPlugin.SetMeshAnimFrameStart(spin->GetIVal()); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_MESHANIM_END_SPIN)); theElMaxPlugin.SetMeshAnimFrameEnd(spin->GetIVal()); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_MESHANIM_STEP_SPIN)); theElMaxPlugin.SetMeshAnimFrameStep(spin->GetIVal()); ReleaseISpinner(spin); theElMaxPlugin.ExportMeshAnim(filename); } } break; case IDC_EXPORT_SKELETON: if (HIWORD(wParam) == BN_CLICKED) { char filename[MAX_PATH] = {0}; if (GetSaveFileName(hWnd, filename, sizeof(filename), _T("ElSkeleton(*.ELS)\0*.ELS\0All(*.*)\0*.*\0"), _T("ELS"), _T("Skeleton file to save"))) { ISpinnerControl* spin = GetISpinner(GetDlgItem(hWnd, IDC_STATIC_FRAME_SPIN)); theElMaxPlugin.SetStaticFrame(spin->GetIVal()); ReleaseISpinner(spin); theElMaxPlugin.ExportSkeleton(filename); } } break; case IDC_EXPORT_SKELETALANIM: if (HIWORD(wParam) == BN_CLICKED) { char filename[MAX_PATH] = {0}; if (GetSaveFileName(hWnd, filename, sizeof(filename), _T("ElSkeletalAnimation(*.ESA)\0*.ESA\0All(*.*)\0*.*\0"), _T("ESA"), _T("SkeletalAnimation file to save"))) { ISpinnerControl* spin = GetISpinner(GetDlgItem(hWnd, IDC_STATIC_FRAME_SPIN)); theElMaxPlugin.SetStaticFrame(spin->GetIVal()); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_SKELETALANIM_START_SPIN)); theElMaxPlugin.SetSkeletalAnimFrameStart(spin->GetIVal()); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_SKELETALANIM_END_SPIN)); theElMaxPlugin.SetSkeletalAnimFrameEnd(spin->GetIVal()); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd, IDC_SKELETALANIM_STEP_SPIN)); theElMaxPlugin.SetSkeletalAnimFrameStep(spin->GetIVal()); ReleaseISpinner(spin); theElMaxPlugin.ExportSkeletalAnim(filename); } } break; } break; case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MOUSEMOVE: theElMaxPlugin.ip->RollupMouseMessage(hWnd,msg,wParam,lParam); break; default: return 0; } return 1; }
// 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()); } }
void AudioBaseControl::Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int etype) { if(type == AUDIO_FLOAT_CONTROL_CLASS_ID1) { float fval0, fval1, fval2, res = 0.0f; switch (etype) { case ORT_LINEAR: if (t<range.Start()) { GetValueLocalTime(range.Start(),&fval0,valid); GetValueLocalTime(range.Start()+1,&fval1,valid); res = LinearExtrapolate(range.Start(),t,fval0,fval1,fval0); } else { GetValueLocalTime(range.End()-1,&fval0,valid); GetValueLocalTime(range.End(),&fval1,valid); res = LinearExtrapolate(range.End(),t,fval0,fval1,fval1); } break; case ORT_IDENTITY: if (t<range.Start()) { GetValueLocalTime(range.Start(),&fval0,valid); res = IdentityExtrapolate(range.Start(),t,fval0); } else { GetValueLocalTime(range.End(),&fval0,valid); res = IdentityExtrapolate(range.End(),t,fval0); } break; case ORT_RELATIVE_REPEAT: GetValueLocalTime(range.Start(),&fval0,valid); GetValueLocalTime(range.End(),&fval1,valid); GetValueLocalTime(CycleTime(range,t),&fval2,valid); res = RepeatExtrapolate(range,t,fval0,fval1,fval2); break; } valid.Set(t,t); *((float*)val) = res; } else if(type == AUDIO_SCALE_CONTROL_CLASS_ID1) { ScaleValue val0, val1, val2, res; switch (etype) { case ORT_LINEAR: if (t<range.Start()) { GetValueLocalTime(range.Start(),&val0,valid); GetValueLocalTime(range.Start()+1,&val1,valid); res = LinearExtrapolate(range.Start(),t,val0,val1,val0); } else { GetValueLocalTime(range.End()-1,&val0,valid); GetValueLocalTime(range.End(),&val1,valid); res = LinearExtrapolate(range.End(),t,val0,val1,val1); } break; case ORT_IDENTITY: if (t<range.Start()) { GetValueLocalTime(range.Start(),&val0,valid); res = IdentityExtrapolate(range.Start(),t,val0); } else { GetValueLocalTime(range.End(),&val0,valid); res = IdentityExtrapolate(range.End(),t,val0); } break; case ORT_RELATIVE_REPEAT: GetValueLocalTime(range.Start(),&val0,valid); GetValueLocalTime(range.End(),&val1,valid); GetValueLocalTime(CycleTime(range,t),&val2,valid); res = RepeatExtrapolate(range,t,val0,val1,val2); break; } valid.Set(t,t); *((ScaleValue *)val) = res; } else { Point3 val0, val1, val2, res; switch (etype) { case ORT_LINEAR: if (t<range.Start()) { GetValueLocalTime(range.Start(),&val0,valid); GetValueLocalTime(range.Start()+1,&val1,valid); res = LinearExtrapolate(range.Start(),t,val0,val1,val0); } else { GetValueLocalTime(range.End()-1,&val0,valid); GetValueLocalTime(range.End(),&val1,valid); res = LinearExtrapolate(range.End(),t,val0,val1,val1); } break; case ORT_IDENTITY: if (t<range.Start()) { GetValueLocalTime(range.Start(),&val0,valid); res = IdentityExtrapolate(range.Start(),t,val0); } else { GetValueLocalTime(range.End(),&val0,valid); res = IdentityExtrapolate(range.End(),t,val0); } break; case ORT_RELATIVE_REPEAT: GetValueLocalTime(range.Start(),&val0,valid); GetValueLocalTime(range.End(),&val1,valid); GetValueLocalTime(CycleTime(range,t),&val2,valid); res = RepeatExtrapolate(range,t,val0,val1,val2); break; } valid.Set(t,t); *((Point3 *)val) = res; } }