QStringList LPGUtils::revertDir(QString oldPath, QString newPath){ //Note: this is a recursive function and can take quite a while to perform lots of file copies //Load the directories and create it if necessary QDir oDir(oldPath); QDir nDir(newPath); bool ok=true; if( !nDir.exists() ){ //Create the new Directory qDebug() << "Re-Create parent directory structure:" << newPath; nDir.cdUp(); ok = nDir.mkpath(newPath.section("/",-1)); //also create all parent directories if necessary if(ok){ qDebug() << " - Reset permissions on the main parent dir to match snapshot"; nDir.cd(newPath.section("/",-1)); QFile::setPermissions(newPath, QFile::permissions(oldPath)); //make sure the new dir has the old permissions QFileInfo FI(oldPath); system( QString("chown "+FI.owner()+":"+FI.group()+" "+newPath).toUtf8() ); } } //Get a list of any files that error QStringList errors; if(!ok){ errors << newPath; return errors; } //Get a list of all the files in the old dir and copy them over QStringList fList = oDir.entryList(QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDir::Name); for(int i=0; i<fList.length(); i++){ if( !revertFile(oldPath+"/"+fList[i], newPath+"/"+fList[i]) ){ errors << newPath+"/"+fList[i]; } } //Now list all the directories in the old dir and recursively copy them over fList = oDir.entryList(QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot, QDir::Name); for(int i=0; i<fList.length(); i++){ QStringList errs = revertDir(oldPath+"/"+fList[i], newPath+"/"+fList[i]); if( !errs.isEmpty() ){ errors << errs; } } return errors; }
bool Intersect(const Terrain &t, const WFMath::Point<3> &sPt, const WFMath::Vector<3>& dir, WFMath::Point<3> &intersection, WFMath::Vector<3> &normal, float &par) { //FIXME early reject using segment max //FIXME handle height point getting in a more optimal way //FIXME early reject for vertical ray // check if startpoint is below ground if (HOT(t, sPt) < 0.0) return true; float paraX=0.0, paraY=0.0; //used to store the parametric gap between grid crossings float pX, pY; //the accumulators for the parametrics as we traverse the ray float h1,h2,h3,h4,height; WFMath::Point<3> last(sPt), next(sPt); WFMath::Vector<3> nDir(dir); nDir.normalize(); float dirLen = dir.mag(); //work out where the ray first crosses an X grid line if (dir[0] != 0.0f) { paraX = 1.0f/dir[0]; float crossX = (dir[0] > 0.0f) ? gridceil(last[0]) : gridfloor(last[0]); pX = (crossX - last[0]) * paraX; pX = std::min(pX, 1.0f); } else { //parallel: never crosses pX = 1.0f; } //work out where the ray first crosses a Y grid line if (dir[1] != 0.0f) { paraY = 1.0f/dir[1]; float crossY = (dir[1] > 0.0f) ? gridceil(last[1]) : gridfloor(last[1]); pY = (crossY - sPt[1]) * paraY; pY = std::min(pY, 1.0f); } else { //parallel: never crosses pY = 1.0f; } //ensure we traverse the ray forwards paraX = std::abs(paraX); paraY = std::abs(paraY); bool endpoint = false; //check each candidate tile for an intersection while (1) { last = next; if (pX < pY) { // cross x grid line first next = sPt + (pX * dir); pX += paraX; // set x accumulator to current p } else { //cross y grid line first next = sPt + (pY * dir); if (pX == pY) { pX += paraX; //unusual case where ray crosses corner } pY += paraY; // set y accumulator to current p } //FIXME these gets could be optimized a bit float x= (dir[0] > 0) ? std::floor(last[0]) : std::floor(next[0]); float y= (dir[1] > 0) ? std::floor(last[1]) : std::floor(next[1]); h1 = t.get(x, y); h2 = t.get(x, y+1); h3 = t.get(x+1, y+1); h4 = t.get(x+1, y); height = std::max( std::max(h1, h2), std::max(h3, h4)); if ( (last[2] < height) || (next[2] < height) ) { // possible intersect with this tile if (cellIntersect(h1, h2, h3, h4, x, y, nDir, dirLen, sPt, intersection, normal, par)) { return true; } } if ((pX >= 1.0f) && (pY >= 1.0f)) { if (endpoint) { break; } else endpoint = true; } } return false; }