// return all occluders in all cells that intersect the triangle (p1,p2,p3) // these occluders do not necessarily intersect (p1,p2,p3), but all possible intersections are included in this set void Grid::triangleIntersections(Vec3r p0,Vec3r p1,Vec3r p2, set<Polygon3r*> & possibleIntersections) { Vec3r triverts[3] = {p0,p1,p2}; // find the bbox of the triangle vector<Vec3r> vertices; vertices.push_back(triverts[0]); vertices.push_back(triverts[1]); vertices.push_back(triverts[2]); Vec3r dummy; Polygon3r triangle(vertices,dummy); Vec3r min, max; triangle.getBBox(min, max); // Compute the cell coordinates for the bbox Vec3u imax, imin; getCellCoordinates(max, imax); getCellCoordinates(min, imin); // We are now going to iterate over the cells overlapping with the // polygon bbox. for (unsigned z = imin[2]; z <= imax[2]; z++) for (unsigned y = imin[1]; y <= imax[1]; y++) for (unsigned x = imin[0]; x <= imax[0]; x++) { Vec3u coord; Vec3r boxmin, boxmax; coord[0] = x; coord[1] = y; coord[2] = z; // We retrieve the box coordinates of the current cell getCellBox(coord, boxmin, boxmax); // We check whether the triangle and the box ovewrlap: Vec3r boxcenter((boxmin + boxmax) / 2.0); Vec3r boxhalfsize(_cell_size / 2.0); Cell * cell = getCell(coord); if (cell != NULL && GeomUtils::overlapTriangleBox(boxcenter, boxhalfsize, triverts)) for(OccludersSet::iterator it = cell->getOccluders().begin(); it != cell->getOccluders().end(); ++it) possibleIntersections.insert(*it); } }
void BoxGrid::assignCells (OccluderSource& /*source*/, GridDensityProvider& density, ViewMap *viewMap) { _cellSize = density.cellSize(); _cellsX = density.cellsX(); _cellsY = density.cellsY(); _cellOrigin[0] = density.cellOrigin(0); _cellOrigin[1] = density.cellOrigin(1); if (G.debug & G_DEBUG_FREESTYLE) { cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl; cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl; } // Now allocate the cell table and fill it with default (empty) cells _cells.resize(_cellsX * _cellsY); for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) { (*i) = NULL; } // Identify cells that will be used, and set the dimensions for each ViewMap::fedges_container& fedges = viewMap->FEdges(); for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f) { if ((*f)->isInImage()) { Vec3r point = transform((*f)->center3d()); unsigned int i, j; getCellCoordinates(point, i, j); if (_cells[i * _cellsY + j] == NULL) { // This is an uninitialized cell real x, y, width, height; x = _cellOrigin[0] + _cellSize * i; width = _cellSize; y = _cellOrigin[1] + _cellSize * j; height = _cellSize; // Initialize cell Cell *b = _cells[i * _cellsY + j] = new Cell(); b->setDimensions(x, y, width, height); } } } }
BoxGrid::Cell *BoxGrid::findCell(const Vec3r& point) { unsigned int x, y; getCellCoordinates(point, x, y); return _cells[x * _cellsY + y]; }
void Grid::insertOccluder(Polygon3r* occluder) { const vector<Vec3r> vertices = occluder->getVertices(); if (vertices.size() == 0) return; // add this occluder to the grid's occluders list addOccluder(occluder); // find the bbox associated to this polygon Vec3r min, max; occluder->getBBox(min, max); // Retrieve the cell x, y, z cordinates associated with these min and max Vec3u imax, imin; getCellCoordinates(max, imax); getCellCoordinates(min, imin); // We are now going to fill in the cells overlapping with the // polygon bbox. // If the polygon is a triangle (most of cases), we also // check for each of these cells if it is overlapping with // the triangle in order to only fill in the ones really overlapping // the triangle. unsigned i, x, y, z; vector<Vec3r>::const_iterator it; Vec3u coord; if (vertices.size() == 3) { // Triangle case Vec3r triverts[3]; i = 0; for(it = vertices.begin(); it != vertices.end(); it++) { triverts[i] = Vec3r(*it); i++; } Vec3r boxmin, boxmax; for (z = imin[2]; z <= imax[2]; z++) for (y = imin[1]; y <= imax[1]; y++) for (x = imin[0]; x <= imax[0]; x++) { coord[0] = x; coord[1] = y; coord[2] = z; // We retrieve the box coordinates of the current cell getCellBox(coord, boxmin, boxmax); // We check whether the triangle and the box ovewrlap: Vec3r boxcenter((boxmin + boxmax) / 2.0); Vec3r boxhalfsize(_cell_size / 2.0); if (GeomUtils::overlapTriangleBox(boxcenter, boxhalfsize, triverts)) { // We must then create the Cell and add it to the cells list // if it does not exist yet. // We must then add the occluder to the occluders list of this cell. Cell* cell = getCell(coord); if (!cell) { cell = new Cell(boxmin); fillCell(coord, *cell); } cell->addOccluder(occluder); } } } else { // The polygon is not a triangle, we add all the cells overlapping the polygon bbox. for (z = imin[2]; z <= imax[2]; z++) for (y = imin[1]; y <= imax[1]; y++) for (x = imin[0]; x <= imax[0]; x++) { coord[0] = x; coord[1] = y; coord[2] = z; Cell* cell = getCell(coord); if (!cell) { Vec3r orig; getCellOrigin(coord, orig); cell = new Cell(orig); fillCell(coord, *cell); } cell->addOccluder(occluder); } } }