Simulation::Simulation(QObject* parent) : QObject(parent), scoreCalculator_(gripper_, info_), scripting(*this) { // Load a shape QFile shapeFile(":/shapes/triangle.shape"); shapeFile.open(QIODevice::ReadOnly | QIODevice::Text); object_.polygon() = ObjectIO::readPolygon(&shapeFile); connect(&gripper_, &Gripper::geometryChanged, this, &Simulation::check); connect(&xChanger, &LinearValueChanger::valueChanged, [this](double newValue) { gripper_.setXOffset(newValue); }); connect(&yChanger, &LinearValueChanger::valueChanged, [this](double newValue) { gripper_.setYOffset(newValue); }); connect(&openChanger, &LinearValueChanger::valueChanged, [this](double newValue) { gripper_.setOpenDistance(newValue); }); connect(&angleChanger, &LinearValueChanger::valueChanged, [this](double newValue) { gripper_.setAngle(newValue); }); connect(&advancedRotator, &AdvancedRotator::newPosition, [this](const QPointF& newPosition) { gripper_.setXOffset(newPosition.x()); gripper_.setYOffset(newPosition.y()); }); connect(&gripper_, &Gripper::geometryChanged, &scoreCalculator_, &ScoreCalculator::gripperGeometryChanged); connect(&scoreCalculator_, &ScoreCalculator::scoreChanged, this, &Simulation::scoreChangedInternal); advancedRotator.setCenter(QPointF(0, 0)); }
void TSLastDetail::update( bool forceUpdate ) { // This should never be called on a dedicated server or // anywhere else where we don't have a GFX device! AssertFatal( GFXDevice::devicePresent(), "TSLastDetail::update() - Cannot update without a GFX device!" ); // Clear the materialfirst. SAFE_DELETE( mMatInstance ); if ( mMaterial ) { mMaterial->deleteObject(); mMaterial = NULL; } // Make sure imposter textures have been flushed (and not just queued for deletion) TEXMGR->cleanupCache(); // Get the real path to the source shape for doing modified time // comparisons... this might be different if the DAEs have been // deleted from the install. String shapeFile( mCachePath ); if ( !Platform::isFile( shapeFile ) ) { Torque::Path path(shapeFile); path.setExtension("cached.dts"); shapeFile = path.getFullPath(); if ( !Platform::isFile( shapeFile ) ) { Con::errorf( "TSLastDetail::update - '%s' could not be found!", mCachePath.c_str() ); return; } } // Do we need to update the imposter? const String diffuseMapPath = _getDiffuseMapPath(); if ( forceUpdate || Platform::compareModifiedTimes( diffuseMapPath, shapeFile ) <= 0 ) _update(); // If the time check fails now then the update must have not worked. if ( Platform::compareModifiedTimes( diffuseMapPath, shapeFile ) < 0 ) { Con::errorf( "TSLastDetail::update - Failed to create imposters for '%s'!", mCachePath.c_str() ); return; } // Figure out what our vertex format will be. // // If we're on SM 3.0 we can do multiple vertex streams // and the performance win is big as we send 3x less data // on each imposter instance. // // The problem is SM 2.0 won't do this, so we need to // support fallback to regular single stream imposters. // //mImposterVertDecl.copy( *getGFXVertexFormat<ImposterCorner>() ); //mImposterVertDecl.append( *getGFXVertexFormat<ImposterState>(), 1 ); //mImposterVertDecl.getDecl(); mImposterVertDecl.clear(); mImposterVertDecl.copy( *getGFXVertexFormat<ImposterState>() ); // Setup the material for this imposter. mMaterial = MATMGR->allocateAndRegister( String::EmptyString ); mMaterial->mAutoGenerated = true; mMaterial->mDiffuseMapFilename[0] = diffuseMapPath; mMaterial->mNormalMapFilename[0] = _getNormalMapPath(); mMaterial->mImposterLimits.set( (mNumPolarSteps * 2) + 1, mNumEquatorSteps, mPolarAngle, mIncludePoles ); mMaterial->mTranslucent = true; mMaterial->mTranslucentBlendOp = Material::None; mMaterial->mTranslucentZWrite = true; mMaterial->mDoubleSided = true; mMaterial->mAlphaTest = true; mMaterial->mAlphaRef = 84; // Create the material instance. FeatureSet features = MATMGR->getDefaultFeatures(); features.addFeature( MFT_ImposterVert ); mMatInstance = mMaterial->createMatInstance(); if ( !mMatInstance->init( features, &mImposterVertDecl ) ) { delete mMatInstance; mMatInstance = NULL; } // Get the diffuse texture and from its size and // the imposter dimensions we can generate the UVs. GFXTexHandle diffuseTex( diffuseMapPath, &GFXDefaultStaticDiffuseProfile, String::EmptyString ); Point2I texSize( diffuseTex->getWidth(), diffuseTex->getHeight() ); _validateDim(); S32 downscaledDim = mDim >> GFXTextureManager::getTextureDownscalePower(&GFXDefaultStaticDiffuseProfile); // Ok... pack in bitmaps till we run out. Vector<RectF> imposterUVs; for ( S32 y=0; y+downscaledDim <= texSize.y; ) { for ( S32 x=0; x+downscaledDim <= texSize.x; ) { // Store the uv for later lookup. RectF info; info.point.set( (F32)x / (F32)texSize.x, (F32)y / (F32)texSize.y ); info.extent.set( (F32)downscaledDim / (F32)texSize.x, (F32)downscaledDim / (F32)texSize.y ); imposterUVs.push_back( info ); x += downscaledDim; } y += downscaledDim; } AssertFatal( imposterUVs.size() != 0, "hey" ); mMaterial->mImposterUVs = imposterUVs; }
void MainWindow::downloadFinished(QNetworkReply *reply) { QScrollBar *sb = ui->textBrowser->verticalScrollBar(); QUrl url = reply->url(); if (reply->error()) { if ( !url.toString().contains("hgt.zip") ) { ui->textBrowser->append("Download of " + QString(url.toEncoded().constData()) + " failed: " + QString(reply->errorString())); sb->setValue(sb->maximum()); // get the info shown } QString fileUrl = url.toEncoded().constData(); } else { QString path = url.path(); QString fileName = QFileInfo(path).fileName(); if (fileName.isEmpty()) fileName = "download"; QDir dir(dataDirectory); dir.mkpath(dataDirectory); QFile file(dataDirectory+"/"+fileName); if (fileName.contains("dl")) { // obtain url QFile file(dataDirectory+"/"+fileName); } else if (fileName.contains("hgt")) { // obtain elevation files dir.mkpath(dataDirectory+"/SRTM-3/"); file.setFileName(dataDirectory+"/SRTM-3/"+fileName); GUILog( url.toString() + "\n", "download" ); } if (file.open(QIODevice::WriteOnly)) { file.write(reply->readAll()); file.close(); } // download actual shapefile package if (fileName.contains("dl")) { QFile dlFile(dataDirectory+"/"+fileName); if (!dlFile.open(QIODevice::ReadOnly | QIODevice::Text)) return; QTextStream textStream( &dlFile); QString dlUrl = textStream.readAll(); dlUrl.remove("<p>The document has moved <a href=\""); dlUrl.remove("\">here</a></p>\n"); QNetworkReply *r = _manager->get(QNetworkRequest("http://mapserver.flightgear.org"+dlUrl)); connect(r, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadShapefilesProgressBar(qint64, qint64))); } ui->textBrowser->append("Download of "+QString(url.toEncoded().constData())+" succeded saved to: "+QString(fileName)); sb->setValue(sb->maximum()); // get the info shown // unzip shapefile package if (fileName.contains("-")) { // unpack zip QString arguments; #ifdef Q_OS_WIN arguments += "7z.exe x \""+dataDirectory+"/"+fileName+"\" -o\""+dataDirectory+"\" -aoa"; #endif #ifdef Q_OS_UNIX arguments += "unzip -o "+dataDirectory+"/"+fileName+" -d "+dataDirectory; #endif //ui->textBrowser->append(arguments); GUILog( arguments + "\n", "download" ); QProcess proc; proc.start(arguments, QIODevice::ReadWrite); proc.waitForReadyRead(); proc.waitForFinished(-1); // delete temporary files QFile shapeFile(dataDirectory+"/"+fileName); shapeFile.remove(); QFile dlshpFile(dataDirectory+"/dlshp"); dlshpFile.remove(); // re-enable download button ui->downloadShapefilesButton->setText("Download shapefiles"); ui->downloadShapefilesButton->setEnabled(1); } if (fileName.contains(".hgt.zip")){ // adjust progress bar ui->downloadElevationProgressBar->setValue(ui->downloadElevationProgressBar->value()+1); } } // re-enable download button if (ui->downloadElevationProgressBar->value() == ui->downloadElevationProgressBar->maximum()) { ui->downloadElevationButton->setEnabled(1); } }
//-------------------------------------------------------------------- // read a shape file and convert to ShapeDefn ShapeDefn* ChunkWorld::readShape( const char* fileName) { const void* value; if (m_shapes.lookup(fileName, value)) return (ShapeDefn*) value; ShapeFile shapeFile(fileName); // convert into a shape defn ShapeDefn* shape = new ShapeDefn(); m_shapes.setAt(fileName, shape); // get count of vertexes int vertexCount = 0; for (int i = 0; i < shapeFile.m_triangles.length(); i++) { TrianglesTag* tag = (TrianglesTag*) shapeFile.m_triangles[i]; int inputCount = tag->m_ambientID.isEmpty() ? 3 : 4; vertexCount += tag->m_len/inputCount; // indexes per triangle } // allocate vertex array for shape shape->m_len = vertexCount; shape->m_vertexes = new ShapePoint[shape->m_len]; // copy the vertexes int posn = 0; for (int i = 0; i < shapeFile.m_triangles.length(); i++) { TrianglesTag* tag = (TrianglesTag*) shapeFile.m_triangles[i]; int inputCount = tag->m_ambientID.isEmpty() ? 3 : 4; // find the arrays if (!shapeFile.m_arrays.lookup(tag->m_positionsID, value)) continue; FloatArrayTag* positions = (FloatArrayTag*) value; if (!shapeFile.m_arrays.lookup(tag->m_normalsID, value)) continue; FloatArrayTag* normals = (FloatArrayTag*) value; if (!shapeFile.m_arrays.lookup(tag->m_texcoordsID, value)) continue; FloatArrayTag* texcoords = (FloatArrayTag*) value; FloatArrayTag* ambient = NULL; if (shapeFile.m_arrays.lookup(tag->m_ambientID, value)) ambient = (FloatArrayTag*) value; // scale to 1 unit cube double xsize = 1.0/(shapeFile.m_xmax - shapeFile.m_xmin); double ysize = 1.0/(shapeFile.m_ymax - shapeFile.m_ymin); double zsize = 1.0/(shapeFile.m_zmax - shapeFile.m_zmin); for (int j = 0; j < tag->m_len; j+= inputCount) { int positionIndex = 3*tag->m_values[j]; int normalIndex = 3*tag->m_values[j+1]; int texcoordIndex = 2*tag->m_values[j+2]; int ambientIndex = -1; if (inputCount == 4) ambientIndex = tag->m_values[j+3]; ShapePoint* point = &shape->m_vertexes[posn]; point->m_pt.x = positions->m_values[positionIndex]; point->m_pt.y = positions->m_values[positionIndex+1]; point->m_pt.z = positions->m_values[positionIndex+2]; // adjust position and scale to place shape in unit cube point->m_pt.x = (point->m_pt.x - shapeFile.m_xmin) * xsize; point->m_pt.y = (point->m_pt.y - shapeFile.m_ymin) * ysize; point->m_pt.z = (point->m_pt.z - shapeFile.m_zmin) * zsize; point->m_normal.x = normals->m_values[normalIndex]; point->m_normal.y = normals->m_values[normalIndex+1]; point->m_normal.z = normals->m_values[normalIndex+2]; point->m_texcoord.x = texcoords->m_values[texcoordIndex]; point->m_texcoord.y = texcoords->m_values[texcoordIndex+1]; point->m_texcoord.z = tag->m_material; if (ambientIndex != -1) point->m_ambient = ambient->m_values[ambientIndex]; else point->m_ambient = 1.0; posn++; // next vertex } } return shape; }
// Print shifted shape parameters. Given that the data read in at the // outset were scaled, data will need to be read in again and appropriately // shifted. This can be done on-the-fly given that the shifts have been // computed and stored in the matrix S. void shapeAlign::printShiftedProfiles(void){ // Loop over all shape files for (size_t i = 0; i < m; i++){ // Generate an output file name int lastidx = shapeFiles[i].find_last_of("."); string shapeOutFile = shapeFiles[i].substr(0,lastidx) + ".aligned" + shapeFiles[i].substr(lastidx,shapeFiles[i].length()); ofstream shapeOut(shapeOutFile.c_str()); if (shapeOut.is_open()){ // Open the original shape data file ifstream shapeFile(shapeFiles[i].c_str()); int idx = 0; string line; // Loop through all sites in the original shape data file while(getline(shapeFile,line)){ stringstream linestream(line); string s; vector <string> temp; string name; int ctr = 0; // Column counter while(linestream >> s){ // Clip the first three columns if (ctr==0) name = s; if (ctr >2) temp.push_back(s); ctr++; } // Get rid of the last two columns temp.pop_back(); temp.pop_back(); // Get the optimal shift stored in S int shift = gsl_matrix_get(S,idx,cIdx); // If the shape data need to be reversed w.r.t. centroid, // do this now if (gsl_matrix_get(R,idx,cIdx)) std::reverse(temp.begin(),temp.end()); // Output data -- again, the first three columns and the // last two columns need to be trimmed because these // contain non-numeric information. There are two cases // depending on whether the columns were reversed or not shapeOut << name << "\t"; for (size_t j = 0; j < temp.size(); j++){ if (j > 0) shapeOut << "\t"; if (j + shift >= 0 && j + shift < temp.size()){ shapeOut << temp[j+shift]; } else { shapeOut << "NA"; } } shapeOut << endl; idx++; } shapeFile.close(); } else {
// Constructor shapeAlign::shapeAlign(const string& nameList, const vector<string> &files, const int &minS, const int &maxS, const bool &win, const int &wS, const int &wE, const bool &ign, const int &iS, const int &iE, const int &E): nameFile(nameList), shapeFiles(files), shiftMin(minS), shiftMax(maxS), window(win), winStart(wS), winEnd(wE), ignore(ign), ignStart(iS), ignEnd(iE), thresh(E) { // Get number of shape parameters -- one file for each parameter, // so this is effectively the number of files m = files.size(); // Get site names by reading the single-column file containing // names of sites ifstream file(nameFile.c_str()); string line; while(getline(file,line)) names.push_back(line); file.close(); // Get number of sites nSites = names.size(); cerr << "Read " << nSites << " site names." << endl; // Initialize matrices for tracking pairwise comparison info D = gsl_matrix_calloc(nSites,nSites); S = gsl_matrix_calloc(nSites,nSites); R = gsl_matrix_calloc(nSites,nSites); cerr << "Reading shape files." << endl; matrices.resize(nSites); // Initialize an empty list of matrix references // create matrices containing the shape information. Add data // to these matrices on the fly. for (size_t f = 0; f < files.size(); f++){ cerr << "\t" << files[f] << endl; ifstream shapeFile(files[f].c_str()); int idx = 0; // line/site counter while(getline(shapeFile,line)){ // Each line in the shape files represent a single site stringstream linestream(line); string s; vector <string> temp; while(linestream >> s) // Split on spaces and store data from each position in site temp.push_back(s); int n = temp.size(); // Get number of positions // there are five columns that need to be trimmed off: // The first three columns (identifier and NAs) and the // last two columns (NAs) // Initialize the matrix if the matrix has not previously been // initialized if (f == 0) matrices[idx] = gsl_matrix_alloc(m,n-5); for (size_t i = 0; i < matrices[idx]->size2; i++){ double d; stringstream stod(temp[i+3]); stod >> d; gsl_matrix_set(matrices[idx],f,i,d); } // Increment the line counter idx++; } } cerr << "\tDone reading shape files." << endl; // Scale each matrix such that values to go from 1->2 cerr << "Scaling matrices." << endl; for (size_t i = 0; i < nSites; i++) scaleMatrixZscore(matrices[i]); cerr << "\tDone scaling matrices." << endl; // Loop over the sites and compute all pairwise distances -- note that // distances are symmetric: D[a,b] = D[b,a]. But, the shifts computed // are not symmetric: S[a,b] = -S[b,a]. for (size_t i = 0; i < nSites; i++){ if ((i+1) % 100 == 0) cerr << "\tProcessing " << i+1 << " of " << nSites << endl; // Parallelize this portion: data races shouldn't be a concern // since no threads should be writing to the same block of // memory #pragma omp parallel { #pragma omp master if (i==0) cerr << "Beginning all-by-all distance calculation using " << omp_get_num_threads() << " threads." << endl; #pragma omp for for (size_t j = i; j < nSites; j++){ // Get optimal shift and distances for the simple comparison alignData results = getOptimalShift(matrices[i],matrices[j]); // Get the matrix representing the reverse of the matrices[j] gsl_matrix* rev = gsl_matrix_alloc(matrices[j]->size1,matrices[j]->size2); gsl_matrix_memcpy(rev,matrices[j]); reverse(rev); // Get the optimal shift and distance for the reverse matrix alignData resultsRev = getOptimalShift(matrices[i],rev); if (results.score >= resultsRev.score){ results.rev = 0; } else { results.score = resultsRev.score; results.shift = resultsRev.shift; results.rev = 1; } // Store the data in the matrices used for tracking // pairwise comparisons gsl_matrix_set(D,i,j,results.score); gsl_matrix_set(S,i,j,results.shift); gsl_matrix_set(R,i,j,results.rev); gsl_matrix_set(D,j,i,results.score); gsl_matrix_set(S,j,i,-1*results.shift); gsl_matrix_set(R,j,i,results.rev); // Clean up -- free memory associated with rev gsl_matrix_free(rev); } } } cerr << "\tDone with distance calculation." << endl; cerr << "Finding centroid." << endl; pair<int,double> C = getCentroid(); cIdx = C.first; // Index (w.r.t. names vector) of centroid cDist = C.second; // Distance of centroid to other sequences cerr << "\tCentroid: Site \"" << names[C.first] << "\"" << endl; cerr << "\tDistance: " << C.second << endl; printCentroid(); printShifts(); // cerr << "Printing matrices to files." << endl; // printShiftMatrix(); // printDistanceMatrix(); // printRevMatrix(); // cerr << "\tDone." << endl; cerr << "Printing aligned data." << endl; printShiftedProfiles(); cerr << "\tDone." << endl; cerr << "Job successfully completed." << endl; }
void ShapesBufferReader::loadShapesBuffer(bool isGT, std::string& shapePath, std::string& shapeFormat, int startFrame, int numTrackingFrames) { int numPnts = m_nHeight * m_nWidth; int uselessPntsNum = 0; char buffer[BUFFER_SIZE]; CoordinateType* pTrackingResults; double* pCenter; if(isGT) { pTrackingResults = m_pTrackingResultsBufferGT; pCenter = centerGT; } else { pTrackingResults = m_pTrackingResultsBuffer; pCenter = centerEST; } for(int i = startFrame; i <= numTrackingFrames; i = i + nFrameStep) { std::stringstream shapeFilePath; sprintf(buffer, shapeFormat.c_str(), i); shapeFilePath << shapePath << buffer; //memset(&buffer[0], 0, sizeof(buffer)); std::cout << shapeFilePath.str() << std::endl; if(!bfs::exists(shapeFilePath.str())) { cout << shapeFilePath.str() << " does not exist" << endl; break; } ++m_nGoodFrames; std::ifstream shapeFile(shapeFilePath.str().c_str()); // int frame = i - startFrame; int bufferPos = (i - startFrame) / nFrameStep; int pntsInd = 0; int saveInd = 0; int width = m_nWidth; int height = m_nHeight; if(m_colMajor) { width = m_nHeight; height = m_nWidth; } for(unsigned int j = 0; j < height; ++j) { for(unsigned int k = 0; k < width; ++k) { if(m_colMajor) saveInd = j + k * m_nWidth; // In this case, k is row number really else saveInd = k + j * m_nWidth; // In this case, j is row number if(useMask) { if(maskImage[saveInd] > 0) { shapeFile >> pTrackingResults[ bufferPos*3*numPnts + 3*saveInd ]; shapeFile >> pTrackingResults[ bufferPos*3*numPnts + 3*saveInd + 1 ]; shapeFile >> pTrackingResults[ bufferPos*3*numPnts + 3*saveInd + 2 ]; } else { if(bufferPos == 0) uselessPntsNum++; continue; } } else { shapeFile >> pTrackingResults[ bufferPos*3*numPnts + 3*saveInd ]; shapeFile >> pTrackingResults[ bufferPos*3*numPnts + 3*saveInd + 1 ]; shapeFile >> pTrackingResults[ bufferPos*3*numPnts + 3*saveInd + 2 ]; // if( pTrackingResults[ bufferPos*3*numPnts + 3*saveInd ] == 0 // && pTrackingResults[ bufferPos*3*numPnts + 3*saveInd + 1 ] == 0 // && pTrackingResults[ bufferPos*3*numPnts + 3*saveInd + 2 ] == 0) if(pTrackingResults[ bufferPos*3*numPnts + 3*saveInd + 2 ] == 0) { maskImage[saveInd] = 0; if(bufferPos == 0) uselessPntsNum++; continue; } } if(bufferPos == 0) { pCenter[0] = pCenter[0] + pTrackingResults[ bufferPos*3*numPnts + 3*saveInd ]; pCenter[1] = pCenter[1] + pTrackingResults[ bufferPos*3*numPnts + 3*saveInd + 1 ]; pCenter[2] = pCenter[2] + pTrackingResults[ bufferPos*3*numPnts + 3*saveInd + 2 ]; } }
int main(int argc, char *args[]) { char *file = '\0'; char *sep = '\0'; int skip = 0; int rows = -1; int indexX = -1; int indexY = -1; char *lastArg = ""; for (int index = 0; index < argc; index++) { if (0 == strcmp("-f", lastArg)) { file = args[index]; } else if (0 == strcmp("-sep", lastArg)) { sep = args[index]; if (0 == strcmp("\\t", sep)) { sep = "\t"; } } else if (0 == strcmp("-skip", lastArg)) { skip = atoi(args[index]); if (skip < 0) { skip = 0; } } else if (0 == strcmp("-rows", lastArg)) { rows = atoi(args[index]); } else if (0 == strcmp("-idxx", lastArg)) { indexX = atoi(args[index]); } else if (0 == strcmp("-idxy", lastArg)) { indexY = atoi(args[index]); } std::cout << args[index] << " "; lastArg = args[index]; } std::cout << std::endl; if ('\0' == file || '\0' == sep || -1 == indexX || -1 == indexY) { std::cout << "Usage: -f /temp/points.csv -sep \\t -idxx 4 -idxy 3 [optional: -skip 1 -rows 100]" << std::endl; return -1; } std::unique_ptr<const char> wkbFile(convertCsvFileToWkb(file, sep, skip, rows, indexX, indexY)); if (nullptr == wkbFile) { return -1; } std::unique_ptr<const char> wktFile(convertWkbFileToWkt(wkbFile.get())); if (nullptr == wktFile) { return -1; } std::unique_ptr<const char> shapeFile(convertWkbFileToShape(wkbFile.get())); if (nullptr == shapeFile) { return -1; } return 0; }
bool ShapeSequenceReader::loadShape(bool isGT, std::string& shapePath, std::string& shapeFormat, int curFrame) { int numPnts = m_nHeight * m_nWidth; int uselessPntsNum = 0; char buffer[BUFFER_SIZE]; CoordinateType* pCurTrackingResult; double* pCenter; if(isGT) { pCurTrackingResult = m_pCurTrackingResultGT; pCenter = centerGT; } else { pCurTrackingResult = m_pCurTrackingResult; pCenter = centerEST; } std::stringstream shapeFilePath; sprintf(buffer, shapeFormat.c_str(), curFrame); shapeFilePath << shapePath << buffer; //memset(&buffer[0], 0, sizeof(buffer)); if(!bfs::exists(shapeFilePath.str())) { cout << shapeFilePath.str() << " does not exist" << endl; return false; } std::ifstream shapeFile(shapeFilePath.str().c_str()); int frame = curFrame - startFrameNo; int pntsInd = 0; int saveInd = 0; int width = m_nWidth; int height = m_nHeight; if(m_colMajor) { width = m_nHeight; height = m_nWidth; } for(unsigned int j = 0; j < height; ++j) { for(unsigned int k = 0; k < width; ++k) { if(m_colMajor) saveInd = j + k * m_nWidth; else saveInd = k + j * m_nWidth; if(useMask) { if(maskImage[saveInd] > 0) { shapeFile >> pCurTrackingResult[ 3*saveInd ]; shapeFile >> pCurTrackingResult[ 3*saveInd + 1]; shapeFile >> pCurTrackingResult[ 3*saveInd + 2]; } else { if(frame == 0) uselessPntsNum++; continue; } } else {