示例#1
0
/* 
Algorithm as describe by: 
http://devmag.org.za/2009/05/03/poisson-disk-sampling/
*/
void NoiseProcessor::poissonDisk(Image *img) {
    
    float minDist = size_.get().x;
    minDist /= poissonDotsAlongX_; //min pixel distance between samples
    auto minDist2 = minDist*minDist;
    size2_t gridSize = size2_t(1)+ size2_t(vec2(size_.get()) * (1.0f / minDist));

    auto gridImg = util::make_unique<Image>(gridSize, DataVec2INT32::get());
    auto grid = gridImg->getColorLayer()->getEditableRepresentation<LayerRAM>();

    auto imgData = static_cast<float*>(img->getColorLayer()->getEditableRepresentation<LayerRAM>()->getData());
    auto gridData = static_cast<glm::i32vec2*>(grid->getData());
    util::IndexMapper2D imgIndex(size_.get());
    util::IndexMapper2D gridIndex(gridSize);


    for (size_t i = 0; i < gridSize.x*gridSize.y; i++) {
        gridData[i] = glm::i32vec2(-2 * minDist);
    }

    std::uniform_int_distribution<int> rx(0, size_.get().x);
    std::uniform_int_distribution<int> ry(0, size_.get().y);
    std::uniform_real_distribution<float> rand(0, 1);

    std::vector<glm::i32vec2>  processList;
    std::vector<glm::i32vec2>  samplePoints;

    auto firstPoint = glm::i32vec2(rx(mt_), ry(mt_));
    processList.push_back(firstPoint);
    samplePoints.push_back(firstPoint);

    auto toGrid = [minDist](glm::i32vec2 p)->glm::i32vec2 { return glm::i32vec2(vec2(p)/minDist); };

    gridData[gridIndex(toGrid(firstPoint))] = firstPoint;

    int  someNumber = 30;

    while (processList.size() != 0 && samplePoints.size()  < static_cast<size_t>(poissonMaxPoints_)) {
        std::uniform_int_distribution<size_t> ri(0, processList.size()-1);
        auto i = ri(mt_);
        auto p = processList[i];
        processList.erase(processList.begin() + i);


        for (int j = 0; j < someNumber; j++) {
            auto newPoint = generateRandomPointAround(p, minDist, rand, mt_);
            if (newPoint.x < 0) continue;
            if (newPoint.y < 0) continue;
            if (newPoint.x >= size_.get().x) continue;
            if (newPoint.y >= size_.get().y) continue;

            auto newGridPoint = toGrid(newPoint);
            bool neighbourhood = false;

            int startX = std::max(0, newGridPoint.x - 2);
            int startY = std::max(0, newGridPoint.y - 2);
            int endX = std::min(static_cast<int>(gridSize.x) - 1, newGridPoint.x + 2);
            int endY = std::min(static_cast<int>(gridSize.y) - 1, newGridPoint.y + 2);

            for (int x = startX; x <= endX && !neighbourhood; x++) {
                for (int y = startY; y <= endY && !neighbourhood; y++) {
                    auto p2 = gridData[gridIndex(glm::i32vec2(x, y))];
                    auto dist = glm::distance2(vec2(newPoint), vec2(p2));
                    if (dist < minDist2) {
                        neighbourhood = true;
                    }
                }
            }//*/
            if (!neighbourhood) {
                processList.push_back(newPoint);
                samplePoints.push_back(newPoint);
                auto idx = gridIndex(newGridPoint);
                gridData[idx] = newPoint;
                imgData[imgIndex(newPoint)] = 1;
            }
        }

    }

}
示例#2
0
void NavGrid::UnBlockCell(const CU::Vector3f& aWorldPos)
{
	CU::Vector2i gridIndex(static_cast<int>(aWorldPos.x), static_cast<int>(aWorldPos.z));
	UnBlockCell(gridIndex);
}