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;
}
Esempio n. 2
0
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;
}