Пример #1
0
	Intersection WorldViewer::pixelIntersect(const int2 &screen_pos, const FindFilter &filter) const {
		Intersection out;
		FBox out_bbox;

		if(filter.flags() & Flags::tile) {
			const TileMap &tile_map = m_world->tileMap();
			vector<int> inds;
			tile_map.findAll(inds, IRect(screen_pos, screen_pos + int2(1, 1)), filter.flags() | Flags::visible);

			for(int i = 0; i < (int)inds.size(); i++) {
				const auto &desc = tile_map[inds[i]];
				
				FBox bbox = desc.bbox;
				
				if(out.empty() || drawingOrder(bbox, out_bbox) == 1)
					if(desc.ptr->testPixel(screen_pos - worldToScreen((int3)bbox.min))) {
						out = ObjectRef(inds[i], false);
						out_bbox = bbox;
					}
			}
		}

		if(filter.flags() & Flags::entity) {
			int ignore_index = m_world->filterIgnoreIndex(filter);

			for(int n = 0; n < (int)m_entities.size(); n++) {
				const Entity *entity = refEntity(n);
				if(!entity || !m_occluder_config.isVisible(m_entities[n].occluder_id) || !Flags::test(entity->flags(), filter.flags()) || n == ignore_index)
					continue;
				if(!entity->testPixel(screen_pos))
					continue;
				FBox bbox = entity->boundingBox();

				//TODO: check this
				if(out.empty() || drawingOrder(bbox, out_bbox) == 1) {
					out = ObjectRef(n, true);
					out_bbox = bbox;
				}
			}
		}

		if(out.empty())
			return Intersection();
		return Intersection(out, intersection(screenRay(screen_pos), out_bbox));
	}
std::pair<util::guidance::EntryClass, util::guidance::BearingClass>
classifyIntersection(Intersection intersection)
{
    if (intersection.empty())
        return {};

    std::sort(intersection.begin(),
              intersection.end(),
              [](const ConnectedRoad &left, const ConnectedRoad &right) {
                  return left.bearing < right.bearing;
              });

    util::guidance::EntryClass entry_class;
    util::guidance::BearingClass bearing_class;

    const bool canBeDiscretized = [&]() {
        if (intersection.size() <= 1)
            return true;

        DiscreteBearing last_discrete_bearing = util::guidance::BearingClass::getDiscreteBearing(
            std::round(intersection.back().bearing));
        for (const auto road : intersection)
        {
            const DiscreteBearing discrete_bearing =
                util::guidance::BearingClass::getDiscreteBearing(std::round(road.bearing));
            if (discrete_bearing == last_discrete_bearing)
                return false;
            last_discrete_bearing = discrete_bearing;
        }
        return true;
    }();

    // finally transfer data to the entry/bearing classes
    std::size_t number = 0;
    if (canBeDiscretized)
    {
        if (util::guidance::BearingClass::getDiscreteBearing(intersection.back().bearing) <
            util::guidance::BearingClass::getDiscreteBearing(intersection.front().bearing))
        {
            intersection.insert(intersection.begin(), intersection.back());
            intersection.pop_back();
        }
        for (const auto &road : intersection)
        {
            if (road.entry_allowed)
                entry_class.activate(number);
            auto discrete_bearing_class =
                util::guidance::BearingClass::getDiscreteBearing(std::round(road.bearing));
            bearing_class.add(std::round(discrete_bearing_class *
                                         util::guidance::BearingClass::discrete_step_size));
            ++number;
        }
    }
    else
    {
        for (const auto &road : intersection)
        {
            if (road.entry_allowed)
                entry_class.activate(number);
            bearing_class.add(std::round(road.bearing));
            ++number;
        }
    }
    return std::make_pair(entry_class, bearing_class);
}