Пример #1
0
// mouse button handler
static void event_button(struct FTR *f, int k, int m, int x, int y)
{
	struct viewer_state *e = f->userdata;

	// begin dragging a control point in the WINDOW DOMAIN
	if (k == FTR_BUTTON_LEFT)
	{
		int p = hit_point(e, x, y);
		if (p >= 0)
		{
			e->dragging_point = true;
			e->dragged_point = p;
		}
	}

	// end dragging a control point in the WINDOW DOMAIN
	if (e->dragging_point && k == -FTR_BUTTON_LEFT)
	{
		int p = e->dragged_point;
		e->dragging_point = false;
		double X[2] = {x, y};
		map_window_to_view(e, e->c[p], X);
	}

	// begin dragging a control point in the IMAGE DOMAIN
	if (k == FTR_BUTTON_RIGHT)
	{
		int p = hit_point(e, x, y);
		if (p >= 0)
		{
			e->dragging_ipoint = true;
			e->dragged_point = p;
		}
	}

	// end dragging a control point in the IMAGE DOMAIN
	if (e->dragging_ipoint && k == -FTR_BUTTON_RIGHT)
	{
		int p = e->dragged_point;
		e->dragging_ipoint = false;
		double P[2], Q[2] = {x, y};
		map_window_to_image(e, P, Q);
		e->p[p][0] = P[0];
		e->p[p][1] = P[1];
		map_window_to_view(e, e->c[p], Q);
	}

	// zoom in/out
	if (k == FTR_BUTTON_DOWN) change_view_scale(e, x, y, ZOOM_FACTOR);
	if (k == FTR_BUTTON_UP) change_view_scale(e, x, y, 1.0/ZOOM_FACTOR);

	paint_state(f);
}
Пример #2
0
CL_SpanLayout::HitTestResult CL_SpanLayout_Impl::hit_test(CL_GraphicContext &gc, const CL_Point &pos)
{
	CL_SpanLayout::HitTestResult result;

	if(lines.empty())
	{
		result.type = CL_SpanLayout::HitTestResult::no_objects_available;
		return result;
	}

	int x = position.x;
	int y = position.y;

	// Check if we are outside to the top
	if(pos.y < y)
	{
		result.type = CL_SpanLayout::HitTestResult::outside_top;
		result.object_id = lines[0].segments[0].id;
		result.offset = 0;
		return result;
	}

	for (std::vector<Line>::size_type line_index = 0; line_index < lines.size(); line_index++)
	{
		Line &line = lines[line_index];

		// Check if we found current line
		if(pos.y >= y && pos.y <= y + line.height)
		{
			for (std::vector<LineSegment>::size_type segment_index = 0; segment_index < line.segments.size(); segment_index++)
			{
				LineSegment &segment = line.segments[segment_index];

				// Check if we are outside to the left
				if(segment_index == 0 && pos.x < x)
				{
					result.type = CL_SpanLayout::HitTestResult::outside_left;
					result.object_id = segment.id;
					result.offset = segment.start;
					return result;
				}

				// Check if we are inside a segment
				if(pos.x >= x + segment.x_position && pos.x <= x + segment.x_position + segment.width)
				{
					CL_StringRef segment_text = text.substr(segment.start, segment.end-segment.start);
					CL_Point hit_point(pos.x - x - segment.x_position, 0);
					int offset = segment.start + segment.font.get_character_index(gc, segment_text, hit_point);

					result.type = CL_SpanLayout::HitTestResult::inside;
					result.object_id = segment.id;
					result.offset = offset;
					return result;
				}

				// Check if we are outside to the right
				if(segment_index == line.segments.size() - 1 && pos.x > x + segment.x_position + segment.width)
				{
					result.type = CL_SpanLayout::HitTestResult::outside_right;
					result.object_id = segment.id;
					result.offset = segment.end;
					return result;
				}
			}
		}

		y += line.height;
	}

	// We are outside to the bottom
	const Line &last_line = lines[lines.size() - 1];
	const LineSegment &last_segment = last_line.segments[last_line.segments.size() - 1];

	result.type = CL_SpanLayout::HitTestResult::outside_bottom;
	result.object_id = last_segment.id;
	result.offset = last_segment.end;
	return result;
}
Пример #3
0
void determine_hilight()
{
	float min_dist = 1024;
	hl_wrect = NULL;
	hl_fpoly = NULL;
	hl_thing = NULL;

	// List of sectors the camera view ray passes through
	vector<int> sectors;

	// Check Things
	if (render_things > 0)
	{
		for (int t = 0; t < map.n_things; t++)
		{
			int f_height = 0;
			int height = things_3d[t]->sprite->height;

			if (things_3d[t]->parent_sector == -1)
				continue;

			if (sector_info[things_3d[t]->parent_sector].visible)
			{
				if (map.things[t]->ttype->hanging)
					f_height = map.sectors[things_3d[t]->parent_sector]->c_height - height;
				else
					f_height = map.sectors[things_3d[t]->parent_sector]->f_height;
			}

			if (map.things[t]->z != 0 && map.hexen)
				f_height += map.things[t]->z;

			int r = things_3d[t]->sprite->width / 2;
			if (map.things[t]->ttype->radius == -1)
			{
				r = 4;
				height = 8;
				f_height -= 4;
			}

			float x1 = (map.things[t]->x - camera.strafe.x * r) * SCALE_3D;
			float y1 = (map.things[t]->y - camera.strafe.y * r) * SCALE_3D;
			float x2 = (map.things[t]->x + camera.strafe.x * r) * SCALE_3D;
			float y2 = (map.things[t]->y + camera.strafe.y * r) * SCALE_3D;

			float dist = line_intersect(camera.position, camera.view, x1, y1, x2, y2);

			if (dist != -1 && dist < min_dist)
			{
				point3_t direction = camera.view - camera.position;

				point3_t hit_point(camera.position.x + (direction.x * dist),
					camera.position.y + (direction.y * dist),
					camera.position.z + (direction.z * dist));

				if (hit_point.z >= f_height * SCALE_3D && hit_point.z <= (f_height + height) * SCALE_3D)
				{
					min_dist = dist;
					hl_thing = things_3d[t];
				}
			}
		}
	}

	// Check Lines
	for (int a = 0; a < map.n_lines; a++)
	{
		if (!lines_3d[a].visible)
			continue;

		rect_t lrect = map.l_getrect(a);
		float dist = line_intersect(camera.position, camera.view,
									(float)lrect.x1() * SCALE_3D, (float)lrect.y1() * SCALE_3D,
									(float)lrect.x2() * SCALE_3D, (float)lrect.y2() * SCALE_3D);

		if (dist != -1 && dist < min_dist)
		{
			point3_t direction = camera.view - camera.position;
			point3_t hit_point(camera.position.x + (direction.x * dist),
								camera.position.y + (direction.y * dist),
								camera.position.z + (direction.z * dist));

			sectors.push_back(map.l_getsector1(a));
			sectors.push_back(map.l_getsector2(a));

			// For all wallrects on the line
			for (int r = 0; r < lines_3d[a].rects.size(); r++)
			{
				if (!determine_line_side(lines_3d[a].rects[r]->verts[0].x, lines_3d[a].rects[r]->verts[0].y,
										lines_3d[a].rects[r]->verts[1].x, lines_3d[a].rects[r]->verts[1].y,
										camera.position.x, camera.position.y))
					continue;

				float up = get_slope_height_point(lines_3d[a].rects[r]->verts[0], lines_3d[a].rects[r]->verts[1], hit_point);
				float lo = get_slope_height_point(lines_3d[a].rects[r]->verts[3], lines_3d[a].rects[r]->verts[2], hit_point);

				if (up >= hit_point.z && lo <= hit_point.z)
				{
					hl_thing = NULL;
					hl_wrect = lines_3d[a].rects[r];
					min_dist = dist;
					break;
				}
			}
		}
	}

	// Check sectors
	for (int a = 0; a < ssects_3d.size(); a++)
	{
		if (!ssects_3d[a].visible)
			continue;

		point3_t direction = camera.view - camera.position;
		for (int b = 0; b < ssects_3d[a].flats.size(); b++)
		{
			// Get flat plane
			flatpoly_t *poly = ssects_3d[a].flats[b];

			if (!(vector_exists(sectors, poly->parent_sector)))
				continue;

			plane_t plane;

			if (poly->part == PART_CEIL)
				plane = sector_info[poly->parent_sector].c_plane;
			else
				plane = sector_info[poly->parent_sector].f_plane;

			// Check side of plane
			float h = plane_height(plane, camera.position.x, camera.position.y);

			if (poly->part == PART_CEIL)
			{
				if (camera.position.z > h)
					continue;
			}

			if (poly->part == PART_FLOOR)
			{
				if (camera.position.z < h)
					continue;
			}

			float dist = dist_ray_plane(camera.position, direction, plane);
			if (dist <= min_dist && dist > 0.0f)
			{
				point3_t intersection(camera.position.x + (direction.x * dist),
								camera.position.y + (direction.y * dist),
								camera.position.z + (direction.z * dist));

				bool in = true;
				DWORD start = gl_ssects[a].startseg;
				DWORD end = start + gl_ssects[a].n_segs;
				for (DWORD seg = start; seg < end; seg++)
				{
					if (!determine_seg_side(seg, intersection.x, intersection.y))
					{
						in = false;
						break;
					}
				}

				if (in)
				{
					hl_wrect = NULL;
					hl_thing = NULL;
					hl_fpoly = poly;
					min_dist = dist;
				}
			}
		}
	}
}