bool MeshPyramidReader::trackFrame(int nFrame, unsigned char* pColorImageRGB,
                                    TrackerOutputInfo** pOutputInfo)
{
    if(!setCurrentFrame(nFrame))
    return false;

    // set up the color used later
    memcpy(pCurrentColorImageRGB, pColorImageRGB, 3*m_nWidth*m_nHeight);
    cv::Mat tempColorImageRGB(m_nHeight, m_nWidth, CV_8UC3, pCurrentColorImageRGB);
    tempColorImageRGB.convertTo(colorImage, cv::DataType<Vec3d>::type, 1./255);
    cv::split(colorImage, colorImageSplit);
    
    setMeshPyramid();

    // cout << "frame " << nFrame << ":" << endl;
    // //print mesh center
    // for(int i = 0; i < currentMeshPyramid.numLevels; ++i)
    // {
    //     cout << "level " << i << ":" << endl;
    //     cout << "center: " << currentMeshPyramid.levels[i].center[0] << " "
    //          << currentMeshPyramid.levels[i].center[1] << " "
    //          << currentMeshPyramid.levels[i].center[2] << " "
    //          << endl;
    // }

    // cout << "number of pyramid levels " << outputInfoPyramid.size() << endl;
    // *pOutputInfo = &outputInfoPyramid[0];
    if(!trackerInitialized)
    {
        *pOutputInfo = &outputInfoPyramid[0];
        trackerInitialized = true;
    }

    return true;
}
MeshBufferReader::MeshBufferReader(MeshLoadingSettings& settings, int width,
                                   int height, double K[3][3], int startFrame, int numTrackingFrames): trackerInitialized(false)
{
  m_nWidth = width;
  m_nHeight = height;
  startFrameNo = startFrame;
  currentFrameNo = startFrame;

  pCurrentColorImageRGB = new unsigned char[3*width*height];
  // in this case camPose will always be zero
  for(int i = 0; i < 6; ++i)
    camPose[i] = 0;

  useVisibilityMask = settings.visibilityMask;

  setIntrinsicMatrix(K);

  nRenderingLevel = 0;
  m_nNumMeshLevels = settings.meshLevelList.size();

  // a bit ugly
  nFrameStep = imageSourceSettings.frameStep;

  // loading meshes into buffer
  // outputInfoPyramidBuffer.resize(numTrackingFrames);
  // outputPropPyramidBuffer.resize(numTrackingFrames);
  int bufferSize = (numTrackingFrames - startFrameNo)/nFrameStep + 1;
  outputInfoPyramidBuffer.resize(bufferSize);
  outputPropPyramidBuffer.resize(bufferSize);

  m_nGoodFrames = 0;

  TICK("loadingMeshBuffer");

  for(int i = startFrameNo; i <= numTrackingFrames; i = i + nFrameStep)
    {

      // TICK("loadingOneFrame");

      if(!existenceTest(settings.meshPath, settings.meshLevelFormat,
                        i, settings.meshLevelList))
        break;

      ++m_nGoodFrames;
      currentMeshPyramid = std::move(PangaeaMeshPyramid(settings.meshPath,
                                                        settings.meshLevelFormat, i, settings.meshLevelList));

      // TOCK("loadingOneFrame");

      if(settings.loadProp)
        {
          propMeshPyramid = std::move(PangaeaMeshPyramid(settings.meshPath,
                                                         settings.propLevelFormat, i, settings.meshLevelList));
        }
      if(!settings.fastLoading)
        propMeshPyramid = currentMeshPyramid;


      // TICK("setOneFrame");

      setMeshPyramid();

      int bufferPos = (i-startFrameNo)/nFrameStep;
      outputInfoPyramidBuffer[ bufferPos ] = std::move(outputInfoPyramid);
      outputPropPyramidBuffer[ bufferPos ] = std::move(outputPropPyramid);

      // TOCK("setOneFrame");

      cout << "loading frame " << i << endl;
    }

  TOCK("loadingMeshBuffer");

}