/** * This method will add all the position keys found in the controller to * the animation path. */ void OSGExp::exportPosKeys(osg::AnimationPath* animationPath, Control* cont){ if (!cont) return; int i; IKeyControl *ikc = GetKeyControlInterface(cont); // TCB position if (ikc && cont->ClassID() == Class_ID(TCBINTERP_POSITION_CLASS_ID, 0)) { int numKeys; if (numKeys = ikc->GetNumKeys()) { for (i=0; i<numKeys; i++) { ITCBPoint3Key key; ikc->GetKey(i, &key); ; // NOT SUPPORTED YET } } } // Bezier position else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID, 0)){ int numKeys; if(numKeys = ikc->GetNumKeys()){ for (i=0; i<numKeys; i++) { IBezPoint3Key key; ikc->GetKey(i, &key); ; // NOT SUPPORTED YET } } } // Linear position else if (ikc && cont->ClassID() == Class_ID(LININTERP_POSITION_CLASS_ID, 0)) { int numKeys; if(numKeys = ikc->GetNumKeys()){ for (i=0; i<numKeys; i++) { ILinPoint3Key key; ikc->GetKey(i, &key); addControlPos(animationPath, (key.time/(float)TIME_TICKSPERSEC),key.val); } } } }
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 ); }
// ADJUSTROTKEYS void AdjustRotKeys(INode *node) { Control *controller = node->GetTMController(); Control *rotControl = controller->GetRotationController(); IKeyControl *rotKeyCont = GetKeyControlInterface(rotControl); int numKeys = rotKeyCont->GetNumKeys(); for(int i = 0; i < numKeys; i++) { ITCBKey key; rotKeyCont->GetKey(i, &key); key.cont = 0; rotKeyCont->SetKey(i, &key); } }
void AsciiExp::DumpScaleKeys(Control* cont, int indentLevel) { if (!cont) return; int i; TSTR indent = GetIndent(indentLevel); IKeyControl *ikc = GetKeyControlInterface(cont); if (ikc && cont->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0)) { int numKeys = ikc->GetNumKeys(); if (numKeys != 0) { _ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_SCALE_TCB); for (i=0; i<numKeys; i++) { ITCBScaleKey key; ikc->GetKey(i, &key); _ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"), indent.data(), ID_TCB_SCALE_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()); } } else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0)) { int numKeys = ikc->GetNumKeys(); if (numKeys != 0) { _ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_SCALE_BEZIER); for (i=0; i<numKeys; i++) { IBezScaleKey key; ikc->GetKey(i, &key); _ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"), indent.data(), ID_BEZIER_SCALE_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_SCALE_CLASS_ID, 0)) { int numKeys = ikc->GetNumKeys(); if (numKeys != 0) { _ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_SCALE_LINEAR); for (i=0; i<numKeys; i++) { ILinScaleKey key; ikc->GetKey(i, &key); _ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"), indent.data(), ID_SCALE_KEY, key.time, Format(key.val)); } _ftprintf(pStream, _T("%s\t\t}\n"), indent.data()); } } }
void AsciiExp::DumpRotKeys(Control* cont, int indentLevel) { if (!cont) return; int i; TSTR indent = GetIndent(indentLevel); IKeyControl *ikc = GetKeyControlInterface(cont); if (ikc && cont->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID, 0)) { int numKeys = ikc->GetNumKeys(); if (numKeys != 0) { _ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_ROT_TCB); for (i=0; i<numKeys; i++) { ITCBRotKey key; ikc->GetKey(i, &key); _ftprintf(pStream, _T("%s\t\t\t%s %d\t%s"), indent.data(), ID_TCB_ROT_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()); } } else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID, 0)) { int numKeys = ikc->GetNumKeys(); if (numKeys != 0) { _ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_ROT_BEZIER); for (i=0; i<numKeys; i++) { IBezQuatKey key; ikc->GetKey(i, &key); _ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"), indent.data(), // Quaternions are converted to AngAxis when written to file ID_ROT_KEY, key.time, Format(key.val)); // There is no intan/outtan for Quat Rotations } _ftprintf(pStream, _T("%s\t\t}\n"), indent.data()); } } else if (ikc && cont->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID, 0)) { int numKeys = ikc->GetNumKeys(); if (numKeys != 0) { _ftprintf(pStream, _T("%s\t\t%s {\n"), indent.data(), ID_CONTROL_ROT_LINEAR); for (i=0; i<numKeys; i++) { ILinRotKey key; ikc->GetKey(i, &key); _ftprintf(pStream, _T("%s\t\t\t%s %d\t%s\n"), indent.data(), // Quaternions are converted to AngAxis when written to file ID_ROT_KEY, key.time, Format(key.val)); } _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()); } }
void XsiExp::DumpScaleKeys( INode * node, int indentLevel) { Control * cont = node->GetTMController()->GetScaleController(); IKeyControl * ikc = GetKeyControlInterface(cont); INode * parent = node->GetParentNode(); if (!cont || !parent || (parent && parent->IsRootNode()) || !ikc) { // no controller or root node return; } int numKeys = ikc->GetNumKeys(); if (numKeys <= 1) { return; } Object * obj = node->EvalWorldState(0).obj; BOOL isBone = obj && obj->ClassID() == Class_ID(BONE_CLASS_ID, 0) ? TRUE : FALSE; // anim keys header TSTR indent = GetIndent(indentLevel); fprintf(pStream,"%s\tSI_AnimationKey {\n", indent.data()); fprintf(pStream,"%s\t\t1;\n", indent.data()); // 1 means scale keys fprintf(pStream,"%s\t\t%d;\n", indent.data(), numKeys); int t, delta = GetTicksPerFrame(); Matrix3 matrix; AffineParts ap; for (int i = 0; i < numKeys; i++) { // get the key's time if (cont->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0)) { ITCBRotKey key; ikc->GetKey(i, &key); t = key.time; } else if (cont->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0)) { IBezQuatKey key; ikc->GetKey(i, &key); t = key.time; } else if (cont->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID, 0)) { ILinRotKey key; ikc->GetKey(i, &key); t = key.time; } // sample the node's matrix matrix = node->GetNodeTM(t) * Inverse(node->GetParentTM(t)); if (!isBone) { matrix = matrix * topMatrix; } decomp_affine(matrix, &ap); fprintf(pStream, "%s\t\t%d; 3; %.6f, %.6f, %.6f;;%s\n", indent.data(), t / delta, ap.k.x, ap.k.z, ap.k.y, i == numKeys - 1 ? ";\n" : ","); } // anim keys close fprintf(pStream,"%s\t}\n\n", indent.data()); }
void KeyTest() { int i, numKeys; INode * n; Control * c; Quat newQuat, prevQuat; IKeyControl* ikeys; ITCBPoint3Key tcbPosKey; ITCBRotKey tcbRotKey; ITCBScaleKey tcbScaleKey; IBezPoint3Key bezPosKey; IBezQuatKey bezRotKey; IBezScaleKey bezScaleKey; ILinPoint3Key linPosKey; ILinRotKey linRotKey; ILinScaleKey linScaleKey; // Get the first node in the selection set if (!CMaxEnv::singleton().m_pInterace->GetSelNodeCount()) return; n = CMaxEnv::singleton().m_pInterace->GetSelNode(0); // --- Process the position keys --- c = n->GetTMController()->GetPositionController(); ikeys = GetKeyControlInterface(c); if (!ikeys) { // No interface available to access the keys... // Just sample the controller to get the position // data at each key... SampleController(n, c); return; } numKeys = ikeys->GetNumKeys(); DebugPrint(_T("\nThere are %d position key(s)"), numKeys); if (c->ClassID() == Class_ID(TCBINTERP_POSITION_CLASS_ID, 0)) { for (i = 0; i < numKeys; i++) { ikeys->GetKey(i, &tcbPosKey); //DebugPrint(_T("\nTCB Position Key: %d=(%.1f, %.1f, %.1f)"), // i, tcbPosKey.val.x, tcbPosKey.val.y, tcbPosKey.val.z); } } else if (c->ClassID() == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID, 0)) { for (i = 0; i < numKeys; i++) { ikeys->GetKey(i, &bezPosKey); //DebugPrint(_T("\nBezier Position Key: %d=(%.1f, %.1f, %.1f)"), // i, bezPosKey.val.x, bezPosKey.val.y, bezPosKey.val.z); } } else if (c->ClassID() == Class_ID(LININTERP_POSITION_CLASS_ID, 0)) { for (i = 0; i < numKeys; i++) { ikeys->GetKey(i, &linPosKey); //DebugPrint(_T("\nLinear Position Key: %d=(%.1f, %.1f, %.1f)"), // i, linPosKey.val.x, linPosKey.val.y, linPosKey.val.z); } } // --- Process the rotation keys --- c = n->GetTMController()->GetRotationController(); ikeys = GetKeyControlInterface(c); if (!ikeys) return; numKeys = ikeys->GetNumKeys(); //DebugPrint(_T("\nThere are %d rotation key(s)"), numKeys); if (c->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID, 0)) { for (i = 0; i < numKeys; i++) { ikeys->GetKey(i, &tcbRotKey); newQuat = QFromAngAxis(tcbRotKey.val.angle, tcbRotKey.val.axis); if (i) newQuat = prevQuat * newQuat; prevQuat = newQuat; //DebugPrint(_T("\nTCB Rotation Key: %d=(%.1f, %.1f, %.1f, %.1f)"), // i, newQuat.x, newQuat.y, newQuat.z, newQuat.w); } } else if (c->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID, 0)) { for (i = 0; i < numKeys; i++) { ikeys->GetKey(i, &bezRotKey); newQuat = bezRotKey.val; if (i) newQuat = prevQuat * newQuat; prevQuat = newQuat; //DebugPrint(_T("\nBezier Rotation Key: %d=(%.1f, %.1f, %.1f, %.1f)"), // i, newQuat.x, newQuat.y, newQuat.z, newQuat.w); } } else if (c->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID, 0)) { for (i = 0; i < numKeys; i++) { ikeys->GetKey(i, &linRotKey); newQuat = linRotKey.val; if (i) newQuat = prevQuat * newQuat; prevQuat = newQuat; //DebugPrint(_T("\nLinear Rotation Key: %d=(%.1f, %.1f, %.1f, %.1f)"), // i, newQuat.x, newQuat.y, newQuat.z, newQuat.w); } } // --- Process the scale keys --- c = n->GetTMController()->GetScaleController(); ikeys = GetKeyControlInterface(c); if (!ikeys) return; numKeys = ikeys->GetNumKeys(); //DebugPrint(_T("\nThere are %d scale key(s)"), numKeys); if (c->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID, 0)) { for (i = 0; i < numKeys; i++) { ikeys->GetKey(i, &tcbScaleKey); //DebugPrint(_T("\nTCB Scale Key: %2d=(%.1f, %.1f, %.1f)"), // i, tcbScaleKey.val.s.x, tcbScaleKey.val.s.y, // tcbScaleKey.val.s.z); } } else if (c->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID, 0)) { for (i = 0; i < numKeys; i++) { ikeys->GetKey(i, &bezScaleKey); //DebugPrint(_T("\nBezier Scale Key: %2d=(%.1f, %.1f, %.1f)"), // i, bezScaleKey.val.s.x, bezScaleKey.val.s.y, // bezScaleKey.val.s.z); } } else if (c->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID, 0)) { for (i = 0; i < numKeys; i++) { ikeys->GetKey(i, &linScaleKey); DebugPrint(_T("\nLinear Scale Key: %2d=(%.1f, %.1f, %.1f)"), i, linScaleKey.val.s.x, linScaleKey.val.s.y, linScaleKey.val.s.z); } } }
//BOOL TbsAnimObj::IsKnownController(Control* cont) //{ // ulong partA, partB; // // if (!cont) // return FALSE; // ////Listed below are the first ULONG of the 8 byte ID. ////The second ULONG is 0 for all built-in classes (unless noted otherwise). ////For example a Class_ID for a TriObject would read: ////Class_ID(TRIOBJ_CLASS_ID, 0); ////Note that only built-in classes should have the second ULONG equal to 0. ////All plug-in developers should use both ULONGs. // // // // ClassID는 두개의 ULONG변수로 구성되며 내장된 클래스들은 모두 두번째 // // 변수는 0의 값을 갖고 있다. // // 단, 개발자의 플로그인은 두번째 값을 갖게 된다. // partA = cont->ClassID().PartA(); // partB = cont->ClassID().PartB(); // // if (partB != 0x00) // return FALSE; // // switch (partA) { // case TCBINTERP_POSITION_CLASS_ID: // case TCBINTERP_ROTATION_CLASS_ID: // case TCBINTERP_SCALE_CLASS_ID: // case HYBRIDINTERP_POSITION_CLASS_ID: // case HYBRIDINTERP_ROTATION_CLASS_ID: // case HYBRIDINTERP_SCALE_CLASS_ID: // case LININTERP_POSITION_CLASS_ID: // case LININTERP_ROTATION_CLASS_ID: // case LININTERP_SCALE_CLASS_ID: // return TRUE; // } // // return FALSE; //} void TbsAnimObj::DumpFloatKeys(Control* cont, TMesh* pMesh) { if (!cont) return; int i; IKeyControl *ikc = NULL; ikc = GetKeyControlInterface(cont); TAnimTrack Anim; // TCB float if (ikc && cont->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID, 0)) { for (i=0; i<ikc->GetNumKeys(); i++) { ITCBFloatKey key; ikc->GetKey(i, &key); Anim.iTick = key.time; Anim.vValue.x = key.val; pMesh->m_VisTrack.push_back( Anim ); } } // Bezier float else if (ikc && cont->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID, 0)) { for (i=0; i<ikc->GetNumKeys(); i++) { IBezFloatKey key; ikc->GetKey(i, &key); Anim.iTick = key.time; Anim.vValue.x = key.val; pMesh->m_VisTrack.push_back( Anim ); } } else if (ikc && cont->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID, 0)) { for (i=0; i<ikc->GetNumKeys(); i++) { ILinFloatKey key; ikc->GetKey(i, &key); Anim.iTick = key.time; Anim.vValue.x = key.val; pMesh->m_VisTrack.push_back( Anim ); } } else { TSTR name; cont->GetClassName(name); // 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 = m_p3dsMax->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(); Anim.iTick = t; Anim.vValue.x = value; pMesh->m_VisTrack.push_back( Anim ); if (range.End() > cont->GetTimeRange(TIMERANGE_ALL).End()) { break; } else { //t = (range.End()/GetTicksPerFrame()+GetKeyFrameStep()) * GetTicksPerFrame(); t = (range.End()/GetTicksPerFrame()) * GetTicksPerFrame(); } } } } }
void bgAnimMax::DumpFloatKeys(Control* pControl, bgMesh* pMesh) { if (!pControl) return; int i; bgAnimTrack Anim; IKeyControl *ikc = NULL; ikc = GetKeyControlInterface(pControl); if (ikc && pControl->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID, 0)) { for (i = 0; i < ikc->GetNumKeys(); i++) { ITCBFloatKey key; ikc->GetKey(i, &key); Anim.iTick = key.time; Anim.vValue.x = key.val; pMesh->AlpTrack.push_back(Anim); } } else if (ikc && pControl->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID, 0)) { for (i = 0; i < ikc->GetNumKeys(); i++) { IBezFloatKey key; ikc->GetKey(i, &key); Anim.iTick = key.time; Anim.vValue.x = key.val; pMesh->AlpTrack.push_back(Anim); } } else if (ikc && pControl->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID, 0)) { for (i = 0; i < ikc->GetNumKeys(); i++) { ILinFloatKey key; ikc->GetKey(i, &key); Anim.iTick = key.time; Anim.vValue.x = key.val; pMesh->AlpTrack.push_back(Anim); } } else { TSTR name; pControl->GetClassName(name); if (pControl->IsAnimated()) { float value; Interval range; Interval animRange = m_p3DMax->GetAnimRange(); TimeValue t = pControl->GetTimeRange(TIMERANGE_ALL).Start(); while (animRange.InInterval(t)) { range = FOREVER; pControl->GetValue(t, &value, range); t = range.Start(); Anim.iTick = t; Anim.vValue.x = value; pMesh->AlpTrack.push_back(Anim); if (range.End() > pControl->GetTimeRange(TIMERANGE_ALL).End()) { break; } else { t = (range.End() / GetTicksPerFrame()) * GetTicksPerFrame(); } } } } }
void RandKeysUtil::Apply() { BOOL timeMode = iu->GetMajorMode()==TVMODE_EDITTIME; BOOL fcurveMode = iu->GetMajorMode()==TVMODE_EDITFCURVE; Interval iv = iu->GetTimeSelection(); if (!doTime && !doVal) return; theHold.Begin(); // Turn animation on SuspendAnimate(); AnimateOn(); for (int i=0; i<iu->GetNumTracks(); i++) { if ((timeMode||fcurveMode) && !iu->IsSelected(i)) continue; // Get Interfaces Animatable *anim = iu->GetAnim(i); Animatable *client = iu->GetClient(i); int subNum = iu->GetSubNum(i); Control *cont = GetControlInterface(anim); IKeyControl *ikc = GetKeyControlInterface(anim); IKey *key = GetKeyPointer(anim->SuperClassID(),anim->ClassID()); if (!ikc || !cont || !key) continue; if (fcurveMode && !anim->IsCurveSelected()) continue; // Get the param dim float min = negVal, max = posVal; ParamDimension *dim = client->GetParamDimension(subNum); if (dim) { min = dim->UnConvert(min); max = dim->UnConvert(max); } for (int j=0; j<ikc->GetNumKeys(); j++) { // Get the key data ikc->GetKey(j,key); // Check if it's selected if (timeMode && !iv.InInterval(key->time)) continue; if (!timeMode && !(key->flags&IKEY_SELECTED)) continue; // Randomize time if (doTime) { key->time = (int)CompRand( float(key->time-negTime), float(key->time+posTime)); ikc->SetKey(j,key); } } if (doTime) ikc->SortKeys(); for (j=0; j<ikc->GetNumKeys(); j++) { // Get the key data ikc->GetKey(j,key); // Check if it's selected if (timeMode && !iv.InInterval(key->time)) continue; if (!timeMode && !(key->flags&IKEY_SELECTED)) continue; // Randomize value if (doVal) { Point3 pt, ang; Point4 p4; float f; Quat q; ScaleValue s; BOOL doX, doY, doZ, doW; doX = doY = doZ = doW = TRUE; if (!fcurveMode) { if (!(key->flags&IKEY_XSEL)) doX = FALSE; if (!(key->flags&IKEY_YSEL)) doY = FALSE; if (!(key->flags&IKEY_ZSEL)) doZ = FALSE; if (!(key->flags&IKEY_WSEL)) doW = FALSE; } switch (anim->SuperClassID()) { case CTRL_FLOAT_CLASS_ID: cont->GetValue(key->time,&f,FOREVER); f = CompRand(f-min,f+max); cont->SetValue(key->time,&f); break; case CTRL_POSITION_CLASS_ID: case CTRL_POINT3_CLASS_ID: cont->GetValue(key->time,&pt,FOREVER); if (doX) pt.x = CompRand(pt.x-min,pt.x+max); if (doY) pt.y = CompRand(pt.y-min,pt.y+max); if (doZ) pt.z = CompRand(pt.z-min,pt.z+max); cont->SetValue(key->time,&pt); break; case CTRL_POINT4_CLASS_ID: cont->GetValue(key->time,&p4,FOREVER); if (doX) p4.x = CompRand(p4.x-min,p4.x+max); if (doY) p4.y = CompRand(p4.y-min,p4.y+max); if (doZ) p4.z = CompRand(p4.z-min,p4.z+max); if (doW) p4.w = CompRand(p4.w-min,p4.w+max); cont->SetValue(key->time,&p4); break; case CTRL_ROTATION_CLASS_ID: cont->GetValue(key->time,&q,FOREVER); QuatToEuler(q, ang); ang.x = CompRand(ang.x-min,ang.x+max); ang.y = CompRand(ang.y-min,ang.y+max); ang.z = CompRand(ang.z-min,ang.z+max); EulerToQuat(ang,q); cont->SetValue(key->time,&q); break; case CTRL_SCALE_CLASS_ID: cont->GetValue(key->time,&s,FOREVER); if (doX) s.s.x = CompRand(s.s.x-min,s.s.x+max); if (doY) s.s.y = CompRand(s.s.y-min,s.s.y+max); if (doZ) s.s.z = CompRand(s.s.z-min,s.s.z+max); cont->SetValue(key->time,&s); break; } } } } ResumeAnimate(); theHold.Accept(GetString(IDS_RB_RANDOMIZEKEYS)); ip->RedrawViews(ip->GetTime()); }