void
TrackerNodePrivate::computeTransformParamsFromTracks()
{
    boost::shared_ptr<TrackerParamsProvider> thisShared = shared_from_this();

#ifndef TRACKER_GENERATE_DATA_SEQUENTIALLY
    lastSolveRequest.cpWatcher.reset();
    lastSolveRequest.tWatcher.reset( new QFutureWatcher<TransformData>() );
    QObject::connect( lastSolveRequest.tWatcher.get(), SIGNAL(finished()), publicInterface, SLOT(onTransformSolverWatcherFinished()) );
    QObject::connect( lastSolveRequest.tWatcher.get(), SIGNAL(progressValueChanged(int)), publicInterface, SLOT(onTransformSolverWatcherProgress(int)) );

    lastSolveRequest.tWatcher->setFuture( QtConcurrent::mapped( lastSolveRequest.keyframes, boost::bind(&TrackerHelper::computeTransformParamsFromTracksAtTime,
                                                                                                        lastSolveRequest.refTime,
                                                                                                        _1,
                                                                                                        lastSolveRequest.jitterPeriod,
                                                                                                        lastSolveRequest.jitterAdd,
                                                                                                        lastSolveRequest.robustModel,
                                                                                                        thisShared,
                                                                                                        center.lock(),
                                                                                                        lastSolveRequest.allMarkers)) );
#else
    NodePtr thisNode = publicInterface->getNode();
    QList<TransformData> validResults;
    {
        int nKeys = lastSolveRequest.keyframes.size();
        int keyIndex = 0;
        for (std::set<double>::const_iterator it = lastSolveRequest.keyframes.begin(); it != lastSolveRequest.keyframes.end(); ++it, ++keyIndex) {
            TransformData data = tracker->computeTransformParamsFromTracksAtTime(lastSolveRequest.refTime, *it, lastSolveRequest.jitterPeriod, lastSolveRequest.jitterAdd, lastSolveRequest.robustModel, thisShared, center.lock(), lastSolveRequest.allMarkers);
            if (data.valid) {
                validResults.push_back(data);
            }
            double progress = (keyIndex + 1) / (double)nKeys;
            thisNode->getApp()->progressUpdate(thisNode, progress);
        }
    }
    computeTransformParamsFromTracksEnd(lastSolveRequest.refTime, lastSolveRequest.maxFittingError, validResults);
#endif
} // TrackerContextPrivate::computeTransformParamsFromTracks