void XsiExp::WriteConfig() { TSTR filename = GetCfgFilename(); FILE* cfgStream; cfgStream = fopen(filename, "wb"); if (!cfgStream) { return; } // Write CFG version _putw(CFG_VERSION, cfgStream); fputc(GetIncludeAnim(), cfgStream); fputc(GetIncludeVertexColors(), cfgStream); fputc(GetAlwaysSample(), cfgStream); _putw(GetMeshFrameStep(), cfgStream); _putw(GetKeyFrameStep(), cfgStream); _putw(GetPrecision(), cfgStream); fclose(cfgStream); }
void AsciiExp::DumpRotSample(INode* node, int indentLevel) { TSTR indent = GetIndent(indentLevel); _ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_ROT_TRACK); TimeValue start = ip->GetAnimRange().Start(); TimeValue end = ip->GetAnimRange().End(); TimeValue t; int delta = GetTicksPerFrame() * GetKeyFrameStep(); Matrix3 tm; AffineParts ap; Quat prevQ; prevQ.Identity(); for (t=start; t<=end; t+=delta) { tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t)); decomp_affine(tm, &ap); // Rotation keys should be relative, so we need to convert these // absolute samples to relative values. Quat q = ap.q / prevQ; prevQ = ap.q; if (q.IsIdentity()) { // No point in exporting null keys... continue; } // Output the sample _ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"), indent.data(), ID_ROT_SAMPLE, t, Format(q)); } _ftprintf(pStream, _T("%s\t\t}\n"), indent.data()); }
void AsciiExp::DumpPosSample(INode* node, int indentLevel) { TSTR indent = GetIndent(indentLevel); _ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_POS_TRACK); TimeValue start = ip->GetAnimRange().Start(); TimeValue end = ip->GetAnimRange().End(); TimeValue t; int delta = GetTicksPerFrame() * GetKeyFrameStep(); Matrix3 tm; AffineParts ap; Point3 prevPos; for (t=start; t<=end; t+=delta) { tm = node->GetNodeTM(t) * Inverse(node->GetParentTM(t)); decomp_affine(tm, &ap); Point3 pos = ap.t; if (t!= start && EqualPoint3(pos, prevPos)) { // Skip identical keys continue; } prevPos = pos; // Output the sample _ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"), indent.data(), ID_POS_SAMPLE, t, Format(pos)); } _ftprintf(pStream, _T("%s\t\t}\n"), indent.data()); }
// 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()); } }