C++ (Qt)void SkMotion::apply ( float t, float* buffer, SrBuffer<int>* map_p, InterpType itype, int* lastframe, bool isAdditive, SBRetarget* retarget ){ // new version of apply skMotion int fsize=_frames.size(); if ( fsize<=0 ) return; if ( t!= 0.f && t<=_frames[0].keytime ) {#if DEBUG_T LOG("SkMotion::apply NOTICE: t=%.16f < f[0]:%.16f \n", t, _frames[0].keytime );#endif return; } if ( itype==CubicSpline ) t = _cubic ( t, _frames[0].keytime, _frames[_frames.size() - 1].keytime ); #if DEBUG_T if ( t<_frames[0].keytime ) { LOG("SkMotion::apply ERR: cubic t=%.16f < f[0]:%.16f \n", t, _frames[0].keytime ); }#endif // optimize keytime search for sequenced calls to apply int fini=0; if ( lastframe ) _last_apply_frame = *lastframe; if ( _last_apply_frame>0 && _last_apply_frame<fsize ) { if ( t>_frames[_last_apply_frame].keytime ) fini=_last_apply_frame+1; } int f; for ( f=fini; f<fsize; f++ ) { if ( t<_frames[f].keytime ) break; } if ( f==_frames.size() ) { // Apply last frame //apply_frame( f-1, buffer, map_p ); //return; t = _frames[_frames.size()-1].keytime; f = _frames.size()-1; } if (_frames.size() > 1) { f--; } _last_apply_frame = f; if ( lastframe ) *lastframe = _last_apply_frame; int nxtFrame = _frames.size() > 1 ? f+1 : f; float* fp1 = _frames[f].posture; float* fp2 = _frames[nxtFrame].posture; // convert t to [0,1] according to the keytimes: t = _frames.size() > 1 ? (t-_frames[f].keytime) / (_frames[f+1].keytime-_frames[f].keytime) : 0.f; #if DEBUG_T if ( t<0.0 ) { LOG("SkMotion::apply ERR: mapped t=%.16f < 0.0 \n", t ); }#endif //sr_out<<"t: "<<t<<" frames: "<<f<<srspc<<(f+1)<<"\n"; int num; int csize = _channels.size(); float outValue[4], origValue[4], newValue[4]; // at most 4 // Apply to float* buffer float* v = NULL; int sum = 0; for ( int i=0; i<csize; i++ ) { // Channel size num = _channels[i].size(); // Find mapped buffer location int index = i; if (buffer) { if (map_p) { index = map_p->get( i ); v = buffer + index; } else { v = buffer + sum; } for (int x=0;x<num;x++) origValue[x] = v[x]; } else if (_channels[i].joint) { _channels[i].get(origValue); } else { index = -1; } _channels[i].interp ( newValue, fp1, fp2, t ); if( index >= 0 ) { if (_channels[i].type == SkChannel::Quat) // rotation channel { SrQuat orig(origValue[0], origValue[1], origValue[2], origValue[3]); SrQuat add(newValue[0], newValue[1], newValue[2], newValue[3]); SrQuat final = isAdditive ? orig*add : add; if (retarget) final = retarget->applyRetargetJointRotation(_channels.mappedName(i),final); for (int x = 0; x < 4; x++) outValue[x] = final.getData(x); } else if (num <= 3) // positional channel { for (int x = 0; x < num; x++) { outValue[x] = isAdditive? origValue[x]+newValue[x] : newValue[x]; if (retarget) outValue[x] = retarget->applyRetargetJointTranslation(_channels.mappedName(i),outValue[x]); } } else { // more that 3 channels but not a quaternion? Don't add data, just replace it... for (int x = 0; x < num; x++) { outValue[x] = newValue[x]; if (retarget) outValue[x] = retarget->applyRetargetJointTranslation(_channels.mappedName(i),outValue[x]); } } if (buffer) { for (int x = 0; x < num; x++) v[x] = outValue[x]; } else { _channels[i].set(outValue); } } // Increment frame data pointers fp1+=num; fp2+=num; sum+=num; } }