bool OcclusionEngine::addOccluders(const OccluderData occludersData[], const int numberOfOccluders) { if( occludersData == NULL) return false; if( numberOfOccluders <= 0) return false; std::vector<Occluder> occluders; occluders.reserve(numberOfOccluders); for( int occ = 0 ; occ < numberOfOccluders ; occ++) { Occluder::OccluderPoint points[MAX_POINTS_PER_OCCLUDER] = {0}; for ( int i = 0 ; i < occludersData[occ].numberOfPoints ; i++ ) { points[i].x = occludersData[occ].points[i].x; points[i].y = occludersData[occ].points[i].y; points[i].depth = occludersData[occ].points[i].depth; } occluders.push_back(Occluder( points, occludersData[occ].numberOfPoints)); } addOccluders((Occluder*)(&occluders.at(0)), numberOfOccluders); return true; }
void OccluderMap::loadFromXML(const XMLDocument &doc) { clear(); for(int n = 0; n < m_grid.size(); n++) if(m_grid[n].ptr) ASSERT(m_grid[n].occluder_id == -1); XMLNode main_node = doc.child("occluders"); if(main_node) { XMLNode occluder_node = main_node.child("occluder"); vector<int> temp; temp.reserve(m_grid.size()); while(occluder_node) { int occluder_id = size(); m_occluders.push_back(Occluder()); Occluder &occluder = m_occluders.back(); int object_count = occluder_node.attrib<int>("object_count"); ASSERT(object_count < m_grid.size() && object_count > 0); occluder.objects.resize(object_count, -1); XMLNode box_node = occluder_node.child("box"); bool first = true; while(box_node) { FBox bbox(box_node.attrib<float3>("min"), box_node.attrib<float3>("max")); occluder.bbox = first? bbox : sum(occluder.bbox, bbox); first = false; temp.clear(); m_grid.findAll(temp, bbox); for(int n = 0; n < (int)temp.size(); n++) m_grid[temp[n]].occluder_id = occluder_id; box_node = box_node.sibling("box"); } occluder_node = occluder_node.sibling("occluder"); } vector<int> counts(m_occluders.size(), 0); for(int n = 0; n < m_grid.size(); n++) { int occ_id = m_grid[n].occluder_id; if(occ_id != -1 && m_grid[n].ptr) { Occluder &occluder = m_occluders[occ_id]; int count = counts[occ_id]; ASSERT(count < (int)occluder.objects.size()); occluder.objects[count++] = n; counts[occ_id] = count; } } for(int n = 0; n < (int)counts.size(); n++) ASSERT(counts[n] == (int)m_occluders[n].objects.size()); } }
int OccluderMap::addOccluder(int representative_id, int min_height) { DASSERT(representative_id >= 0 && representative_id < m_grid.size()); auto &representative = m_grid[representative_id]; DASSERT(representative.occluder_id == -1); int occluder_id = (int)m_occluders.size(); DASSERT(occluder_id < max_occluders); m_occluders.push_back(Occluder()); Occluder &occluder = m_occluders.back(); vector<int> objects, temp; objects.reserve(1024); temp.reserve(128); representative.occluder_id = occluder_id; objects.push_back(representative_id); occluder.bbox = representative.bbox; min_height = max(min_height, (int)representative.bbox.min.y); while(!objects.empty()) { int object_id = objects.back(); objects.pop_back(); occluder.objects.push_back(object_id); FBox box = m_grid[object_id].bbox; occluder.bbox = sum(occluder.bbox, box); box.min -= float3(1, 0, 1); box.max += float3(1, 256, 1); box.min.y = max(box.min.y - 1, (float)min_height); temp.clear(); m_grid.findAll(temp, box, object_id); for(int n = 0; n < (int)temp.size(); n++) { auto &object = m_grid[temp[n]]; if(object.occluder_id != -1) { Occluder &nextocc = m_occluders[object.occluder_id]; continue; } object.occluder_id = occluder_id; objects.push_back(temp[n]); } } return occluder_id; }