Changeset - r28383:adb3b78ce2d2
[Not reviewed]
master
0 1 0
Peter Nelson - 4 months ago 2024-01-03 18:36:34
peter1138@openttd.org
Codechange: Use vehicle viewport hash to find clicked vehicle. (#11675)

This avoids having to iterate all vehicles, which can be an performance improvement when there are many vehicles.
1 file changed with 32 insertions and 13 deletions:
0 comments (0 inline, 0 general)
src/vehicle.cpp
Show inline comments
 
@@ -1222,21 +1222,40 @@ Vehicle *CheckClickOnVehicle(const Viewp
 
	x = ScaleByZoom(x, vp->zoom) + vp->virtual_left;
 
	y = ScaleByZoom(y, vp->zoom) + vp->virtual_top;
 

	
 
	for (Vehicle *v : Vehicle::Iterate()) {
 
		if ((v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0 &&
 
				x >= v->coord.left && x <= v->coord.right &&
 
				y >= v->coord.top && y <= v->coord.bottom) {
 

	
 
			dist = std::max(
 
				abs(((v->coord.left + v->coord.right) >> 1) - x),
 
				abs(((v->coord.top + v->coord.bottom) >> 1) - y)
 
			);
 

	
 
			if (dist < best_dist) {
 
				found = v;
 
				best_dist = dist;
 
	/* Border size of MAX_VEHICLE_PIXEL_xy */
 
	const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE;
 
	const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE;
 

	
 
	/* The hash area to scan */
 
	int xl = GEN_HASHX(x - xb);
 
	int xu = GEN_HASHX(x);
 
	int yl = GEN_HASHY(y - yb);
 
	int yu = GEN_HASHY(y);
 

	
 
	for (int hy = yl;; hy = (hy + GEN_HASHY_INC) & GEN_HASHY_MASK) {
 
		for (int hx = xl;; hx = (hx + GEN_HASHX_INC) & GEN_HASHX_MASK) {
 
			Vehicle *v = _vehicle_viewport_hash[hx + hy]; // already masked & 0xFFF
 

	
 
			while (v != nullptr) {
 
				if ((v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0 &&
 
					x >= v->coord.left && x <= v->coord.right &&
 
					y >= v->coord.top && y <= v->coord.bottom) {
 

	
 
					dist = std::max(
 
						abs(((v->coord.left + v->coord.right) >> 1) - x),
 
						abs(((v->coord.top + v->coord.bottom) >> 1) - y)
 
					);
 

	
 
					if (dist < best_dist) {
 
						found = v;
 
						best_dist = dist;
 
					}
 
				}
 
				v = v->hash_viewport_next;
 
			}
 
			if (hx == xu) break;
 
		}
 
		if (hy == yu) break;
 
	}
 

	
 
	return found;
0 comments (0 inline, 0 general)