bool PathManager::deleteThisDirectoryAndEverythingBelow(QString topDirPath) { { QDir topDir(topDirPath); if (!topDir.exists()) { WLog(QString("The given topDir does not exists: %1").arg(topDirPath)); return true; } //First delete any files in the current directory QFileInfoList files = topDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Hidden | QDir::System/* | QDir::NoSymLinks*/); for(int i = 0; i < files.count(); i++) { QString currFileInPath = files.at(i).fileName(); /*QString currFileAbsolutePath = files.at(i).absoluteFilePath(); if(QFileInfo(currFileAbsolutePath).isSymLink()) { // it's a symlink simply remove it PATH_MANAGER_INTERNAL_LOG_TO_DATABASE(QString("The dir is a symlink file [%1]. Simply remove it.").arg(currDirAbsolutePath)); QDir().remove(currDirAbsolutePath); } else */ if( !topDir.remove(currFileInPath) ) { WLogS << " ! The specified file cannot be removed: " << currFileInPath; WLog(QString("The specified file cannot be removed: %1").arg(files.at(i).absoluteFilePath())); return false; } } //Now recursively delete any child directories QFileInfoList dirs = topDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs); for(int i = 0; i < dirs.count(); i++) { QString currDirAbsolutePath = dirs.at(i).absoluteFilePath(); if(QFileInfo(currDirAbsolutePath).isSymLink()) { // it's a symlink to a dir, simply remove this symlink file WLog(QString("The dir is a symlink file [%1]. Simply remove it.").arg(currDirAbsolutePath)); QDir().remove(currDirAbsolutePath); } else if( !PathManager::deleteThisDirectoryAndEverythingBelow( currDirAbsolutePath ) ) { return false; } } } //Finally, remove empty top directory // if( !topDir.rmdir(topDir.path()) ) { if( !QDir().rmdir(topDirPath) ) { WLog(QString("The specified directory cannot be removed: %1. Maybe it's still not empty.").arg(topDirPath)); return false; } return true; }
glm::ivec3 LightClusters::updateClusters() { // Make sure resource are in good shape updateClusterResource(); // Clean up last info uint32_t numClusters = (uint32_t)_clusterGrid.size(); std::vector< std::vector< LightIndex > > clusterGridPoint(numClusters); std::vector< std::vector< LightIndex > > clusterGridSpot(numClusters); _clusterGrid.clear(); _clusterGrid.resize(numClusters, EMPTY_CLUSTER); uint32_t maxNumIndices = (uint32_t)_clusterContent.size(); _clusterContent.clear(); _clusterContent.resize(maxNumIndices, INVALID_LIGHT); auto theFrustumGrid(_frustumGridBuffer.get()); glm::ivec3 gridPosToOffset(1, theFrustumGrid.dims.x, theFrustumGrid.dims.x * theFrustumGrid.dims.y); uint32_t numClusterTouched = 0; uint32_t numLightsIn = _visibleLightIndices[0]; uint32_t numClusteredLights = 0; for (size_t lightNum = 1; lightNum < _visibleLightIndices.size(); ++lightNum) { auto lightId = _visibleLightIndices[lightNum]; auto light = _lightStage->getLight(lightId); if (!light) { continue; } auto worldOri = light->getPosition(); auto radius = light->getMaximumRadius(); bool isSpot = light->isSpot(); // Bring into frustum eye space auto eyeOri = theFrustumGrid.frustumGrid_worldToEye(glm::vec4(worldOri, 1.0f)); // Remove light that slipped through and is not in the z range float eyeZMax = eyeOri.z - radius; if (eyeZMax > -theFrustumGrid.rangeNear) { continue; } float eyeZMin = eyeOri.z + radius; bool beyondFar = false; if (eyeZMin < -theFrustumGrid.rangeFar) { beyondFar = true; } // Get z slices int zMin = theFrustumGrid.frustumGrid_eyeDepthToClusterLayer(eyeZMin); int zMax = theFrustumGrid.frustumGrid_eyeDepthToClusterLayer(eyeZMax); // That should never happen if (zMin == -2 && zMax == -2) { continue; } // Before Range NEar just apss, range neatr == true near for now if ((zMin == -1) && (zMax == -1)) { continue; } // CLamp the z range zMin = std::max(0, zMin); auto xLeftDistance = radius - distanceToPlane(eyeOri, _gridPlanes[0][0]); auto xRightDistance = radius + distanceToPlane(eyeOri, _gridPlanes[0].back()); auto yBottomDistance = radius - distanceToPlane(eyeOri, _gridPlanes[1][0]); auto yTopDistance = radius + distanceToPlane(eyeOri, _gridPlanes[1].back()); if ((xLeftDistance < 0.f) || (xRightDistance < 0.f) || (yBottomDistance < 0.f) || (yTopDistance < 0.f)) { continue; } // find 2D corners of the sphere in grid int xMin { 0 }; int xMax { theFrustumGrid.dims.x - 1 }; int yMin { 0 }; int yMax { theFrustumGrid.dims.y - 1 }; float radius2 = radius * radius; auto eyeOriH = glm::vec3(eyeOri); auto eyeOriV = glm::vec3(eyeOri); eyeOriH.y = 0.0f; eyeOriV.x = 0.0f; float eyeOriLen2H = glm::length2(eyeOriH); float eyeOriLen2V = glm::length2(eyeOriV); if ((eyeOriLen2H > radius2)) { float eyeOriLenH = sqrt(eyeOriLen2H); auto eyeOriDirH = glm::vec3(eyeOriH) / eyeOriLenH; float eyeToTangentCircleLenH = sqrt(eyeOriLen2H - radius2); float eyeToTangentCircleCosH = eyeToTangentCircleLenH / eyeOriLenH; float eyeToTangentCircleSinH = radius / eyeOriLenH; // rotate the eyeToOriDir (H & V) in both directions glm::vec3 leftDir(eyeOriDirH.x * eyeToTangentCircleCosH + eyeOriDirH.z * eyeToTangentCircleSinH, 0.0f, eyeOriDirH.x * -eyeToTangentCircleSinH + eyeOriDirH.z * eyeToTangentCircleCosH); glm::vec3 rightDir(eyeOriDirH.x * eyeToTangentCircleCosH - eyeOriDirH.z * eyeToTangentCircleSinH, 0.0f, eyeOriDirH.x * eyeToTangentCircleSinH + eyeOriDirH.z * eyeToTangentCircleCosH); auto lc = theFrustumGrid.frustumGrid_eyeToClusterDirH(leftDir); if (lc > xMax) { lc = xMin; } auto rc = theFrustumGrid.frustumGrid_eyeToClusterDirH(rightDir); if (rc < 0) { rc = xMax; } xMin = std::max(xMin, lc); xMax = std::min(rc, xMax); assert(xMin <= xMax); } if ((eyeOriLen2V > radius2)) { float eyeOriLenV = sqrt(eyeOriLen2V); auto eyeOriDirV = glm::vec3(eyeOriV) / eyeOriLenV; float eyeToTangentCircleLenV = sqrt(eyeOriLen2V - radius2); float eyeToTangentCircleCosV = eyeToTangentCircleLenV / eyeOriLenV; float eyeToTangentCircleSinV = radius / eyeOriLenV; // rotate the eyeToOriDir (H & V) in both directions glm::vec3 bottomDir(0.0f, eyeOriDirV.y * eyeToTangentCircleCosV + eyeOriDirV.z * eyeToTangentCircleSinV, eyeOriDirV.y * -eyeToTangentCircleSinV + eyeOriDirV.z * eyeToTangentCircleCosV); glm::vec3 topDir(0.0f, eyeOriDirV.y * eyeToTangentCircleCosV - eyeOriDirV.z * eyeToTangentCircleSinV, eyeOriDirV.y * eyeToTangentCircleSinV + eyeOriDirV.z * eyeToTangentCircleCosV); auto bc = theFrustumGrid.frustumGrid_eyeToClusterDirV(bottomDir); auto tc = theFrustumGrid.frustumGrid_eyeToClusterDirV(topDir); if (bc > yMax) { bc = yMin; } if (tc < 0) { tc = yMax; } yMin = std::max(yMin, bc); yMax =std::min(tc, yMax); assert(yMin <= yMax); } // now voxelize auto& clusterGrid = (isSpot ? clusterGridSpot : clusterGridPoint); if (beyondFar) { numClusterTouched += scanLightVolumeBoxSlice(theFrustumGrid, _gridPlanes, zMin, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), clusterGrid); } else { numClusterTouched += scanLightVolumeSphere(theFrustumGrid, _gridPlanes, zMin, zMax, yMin, yMax, xMin, xMax, lightId, glm::vec4(glm::vec3(eyeOri), radius), clusterGrid); } numClusteredLights++; } // Lights have been gathered now reexpress in terms of 2 sequential buffers // Start filling from near to far and stops if it overflows bool checkBudget = false; if (numClusterTouched > maxNumIndices) { checkBudget = true; } uint16_t indexOffset = 0; for (int i = 0; i < (int) clusterGridPoint.size(); i++) { auto& clusterPoint = clusterGridPoint[i]; auto& clusterSpot = clusterGridSpot[i]; uint8_t numLightsPoint = ((uint8_t)clusterPoint.size()); uint8_t numLightsSpot = ((uint8_t)clusterSpot.size()); uint16_t numLights = numLightsPoint + numLightsSpot; uint16_t offset = indexOffset; // Check for overflow if (checkBudget) { if ((indexOffset + numLights) > (uint16_t) maxNumIndices) { break; } } // Encode the cluster grid: [ ContentOffset - 16bits, Num Point LIghts - 8bits, Num Spot Lights - 8bits] _clusterGrid[i] = (uint32_t)((0xFF000000 & (numLightsSpot << 24)) | (0x00FF0000 & (numLightsPoint << 16)) | (0x0000FFFF & offset)); if (numLightsPoint) { memcpy(_clusterContent.data() + indexOffset, clusterPoint.data(), numLightsPoint * sizeof(LightIndex)); indexOffset += numLightsPoint; } if (numLightsSpot) { memcpy(_clusterContent.data() + indexOffset, clusterSpot.data(), numLightsSpot * sizeof(LightIndex)); indexOffset += numLightsSpot; } } // update the buffers _clusterGridBuffer._buffer->setData(_clusterGridBuffer._size, (gpu::Byte*) _clusterGrid.data()); _clusterContentBuffer._buffer->setSubData(0, indexOffset * sizeof(LightIndex), (gpu::Byte*) _clusterContent.data()); return glm::ivec3(numLightsIn, numClusteredLights, numClusterTouched); }
bool PathHelper::deleteThisDirectoryAndEverythingBelow(QString topDirPath) { DLog("-- deleteThisDirectoryAndEverythingBelow: ") << topDirPath; { QDir topDir(topDirPath); if (!topDir.exists()) { WLog(QString("The given topDir does not exists: %1").arg(topDirPath)); return true; } //First delete any files in the current directory + symlinks to anything except directories QFileInfoList files = topDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Hidden | QDir::System | QDir::Drives/* | QDir::NoSymLinks*/); for(int i = 0; i < files.count(); i++) { QString currFileInPath = files.at(i).fileName(); QString currFileFullPath = topDir.filePath(currFileInPath); QFileInfo currFileInfo(currFileFullPath); if( !currFileInfo.isSymLink() && !currFileInfo.isFile() ) { WLog("Not a symlink and not a file! Cannot remove it!") << currFileFullPath; return false; } if( !topDir.remove(currFileInPath) ) { WLog(QString("The specified file cannot be removed: %1 | full path: %2").arg(currFileInPath).arg(files.at(i).absoluteFilePath())); return false; } } // Now recursively delete any child directories QFileInfoList dirs = topDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Hidden); for(int i = 0; i < dirs.count(); i++) { QString currDirAbsolutePath = dirs.at(i).absoluteFilePath(); if(QFileInfo(currDirAbsolutePath).isSymLink()) { // it's a symlink to a dir, simply remove this symlink file DLog(QString("The dir is a symlink file [%1]. Simply remove it.").arg(currDirAbsolutePath)); if(!QDir().remove(currDirAbsolutePath)) { WLog("Failed to remove the symlink file: " << currDirAbsolutePath); return false; } } else if( !PathHelper::deleteThisDirectoryAndEverythingBelow( currDirAbsolutePath ) ) { WLog("Failed to delete subdir: ") << currDirAbsolutePath; return false; } } } //Finally, remove empty top directory if( !QDir().rmdir(topDirPath) ) { WLog(QString("The specified directory cannot be removed: %1. Maybe it's still not empty.").arg(topDirPath)); return false; } return true; }