🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

OpenGL 4 mouse picking

Started by
0 comments, last by taby 1 year, 7 months ago

I added in mouse picking. The bounding boxes need not be axis aligned, although I'm too lazy to rename them from AABBs to just BBs. I ended up breaking the game board into 8x8 cells, each with a bounding box, so triangle-ray intersection is speedy-ish.

The relevant code is:


void get_collision_location(size_t x, size_t y)
{
	// Get intersection point closest to camera

	vec3 ray = screen_coords_to_world_coords(x, y, win_x, win_y);

	float t = 0;

	clicked_col_loc = background;
	bool first_assignment = true;

	mat4 inv = inverse(board_mesh.model_mat);
	vec4 start = inv * vec4(main_camera.eye, 1.0);
	vec4 direction = inv * vec4(ray, 0.0);
	direction = normalize(direction);

	if (true == board_mesh.intersect_AABB(start, direction))
	{
		vec3 closest_intersection_point;

		for (size_t cell_x = 0; cell_x < board_mesh.num_cells_wide; cell_x++)
		{
			for (size_t cell_y = 0; cell_y < board_mesh.num_cells_wide; cell_y++)
			{
				if (true == board_mesh.intersect_triangles(start, direction, closest_intersection_point, cell_x, cell_y))
				{
					closest_intersection_point = board_mesh.model_mat * vec4(closest_intersection_point, 1);

					clicked_collision_location = closest_intersection_point;
					clicked_col_loc = game_board;
					clicked_cell_x = cell_x;
					clicked_cell_y = cell_y;
					first_assignment = false;
				}
			}
		}
	}

	for (size_t i = 0; i < player_game_piece_meshes.size(); i++)
	{
		mat4 inv = inverse(player_game_piece_meshes[i].model_mat);
		vec4 start = inv * vec4(main_camera.eye, 1.0);
		vec4 direction = inv * vec4(ray, 0.0);
		direction = normalize(direction);

		if (true == player_game_piece_meshes[i].intersect_AABB(start, direction))
		{
			vec3 closest_intersection_point;

			if (true == player_game_piece_meshes[i].intersect_triangles(start, direction, closest_intersection_point, false))
			{
				closest_intersection_point = player_game_piece_meshes[i].model_mat * vec4(closest_intersection_point, 1);

				if (first_assignment)
				{
					clicked_collision_location = closest_intersection_point;

					clicked_col_loc = player_game_piece;
					clicked_collision_location_index = i;

					first_assignment = false;
				}
				else
				{
					vec3 c0 = vec3(main_camera.eye) - closest_intersection_point;
					vec3 c1 = vec3(main_camera.eye) - clicked_collision_location;

					if (length(c0) < length(c1))
					{
						clicked_collision_location = closest_intersection_point;

						clicked_col_loc = player_game_piece;
						clicked_collision_location_index = i;
					}
				}
			}
		}
	}

	// Nothing was clicked on, so the background is set
	if (first_assignment)
	{
		clicked_collision_location = vec3(0, 0, 0);
		clicked_col_loc = background;
	}
}

It was @joej who taught me about the model matrix, and how it can be oriented in any direction, because it's basically a orthonormal basis + translation wrapped into one.

orange board part is highlighted. depth of field is working good

rose period

This topic is closed to new replies.

Advertisement