dilevin / CSC417-a2-mass-spring-3d

Assignment 2 for CSC2549
11 stars 13 forks source link

pick_nearest_vertices How we should pick? #6

Closed mshoe closed 4 years ago

mshoe commented 5 years ago

I am wondering are we supposed to pick vertices that are close enough around the mouse cursor in screen space after shooting the ray? If we do it this way, it is possible no vertices are close enough to the mouse in screen space, despite being attached to the face that was hit. Then you can't control the bunny even if you are clicking on one of the bunny's faces. It seems like just picking all three of the vertices that are in the face that the ray hit would be more robust, and works pretty well in practice.

dilevin commented 5 years ago

Good question ! (We'll cover this in detail in class but I'll put an explanation here)

You find nearest vertices via raycasting.

The window coordinate (win in the code) is the point clicked by the user on the screen. Notice this is 3D. The screen itself lies at the z=0 in this 3D screen space. The camera is at (win_x, win_y, 1).

You can use ligigl::unprotect to convert these coordinates from window space to world space.

Then we can cast a ray through these two points and see what it hits (use igl::ray_mesh_intersect).

This method will return a hit triangle and the barycentric coordinates of the ray-triangle intersection. You can now compute the distance, in the world space, between all vertices and this hit point. Selected vertices are ones that are within the user defined radius (r).

dilevin commented 5 years ago

Actually this is already enough detail to implement the method (I think). If you have questions don't hesitate to ask though.

mshoe commented 5 years ago

So the radius passed into the function pick_nearest_vertices is supposed to be used to compute the distance between the hit point and the face vertices in world space? I tried that but since the radius passed into the function is 0.1 (in visualization.cpp line 403), it seems like I would need to scale it up by quite a bit. Or does that selection radius need to get scaled by the amount the ray traveled? Or is there supposed to be an imgui option to modify the selection radius?

Also, if the ray misses the mesh, but is very close to one of the vertices (within selection radius in world space, does that vertex need to be added to the picked vertices?

dilevin commented 5 years ago

I've hand tuned the radius so it doesn't need to be scaled up. It's the radius around the hit point (0.1 = 10cm) so it's quite a big sphere.

If the ray misses the mesh you can count it as no selection.

kevincxie commented 5 years ago

I might be doing something wrong here but the bunny is really quite big then. For an arbitrary face: (V.row(face(1)) - V.row(face(0))).norm() gives me 7.7. So should we assume that the vertices are in units of centimeters and that the radius is in meters (i.e. x100 conversion factor)?

dilevin commented 5 years ago

You shouldn’t have to do any conversion to get vertex picking to work.

The bunny is very big relative to its mass and stiffness. We will talk about why that is in Wednesday’s lecture.

dilevin commented 5 years ago

Correction: the one thing I do in the solution is snap the hit point to the nearest vertex. You can do this by finding the maximum barycentric coordinate of the hit point.

AtheMathmo commented 5 years ago

Is there some documentation for these libigl functions somewhere? I'm having a hard time finding any and progress is slow trying to decipher the source code (what is the difference between igl::Hit.id and igl::Hit.gid? The barycentric coords sum to 1? Which triangle vertices does each correspond to?)

Thanks!

dilevin commented 5 years ago

The headers for the libigl functions are quite well documented. There is also an excellent tutorial available here which contains instructions on how to use almost all of the library.