Vertex selection for large objects

Hello,

I use a Vertex buffer object (VBO) to render a large object of about 400K vertices. Rendering performance is amazing.

However, I need to be able to pick vertices from such an object. Is it possible to use the VBO for selection??

Right now I have to render all 400K vertices using the following:


// For all vertices
for (pVertex = v_begin(); v_end(); pVertex++) 
{
	Point p = pVertex->point();

	glPushName(pVertex->id());
	glBegin(GL_POINTS);

	glVertex3f(p[0], p[1], p[2]);

	glEnd();
	glPopName();
}

Sure… Feed your vertices into something like Coldet (Sourceforge) and then use Ray-Intersection collision on that data on the client side.
http://www.opengl.org/resources/faq/technical/selection.htm

You may or may not be able to use the same data structure that you draw from to draw either using Arrays from the client side, or even by mapping the VBO to client space for intersection checks. More likely (and I would recommend initially) you’ll need to duplicate the data so you have a collision structure on the client side that works separately from the VBO on the GPU.

Start simple with a slow recursive check on the data for collisions, and then get more technical later by feeding the data into something like an Octree, so you can discard large chunks of data to speed up collisions.

In any case this will be faster than picking and direct drawing, as you are doing now. :slight_smile:

Ultimately you should be able to merge the two structures in some way, perhaps “fence” the area it’s stored in so that it’s shared between the GPU and CPU, and then save some memory.

Thanks scratt!

This is sort of what I ended up doing. I basically did a Ray-sphere intersection between a ray coming from the camera with the direction of the mouse click and a small sphere around the vertex (I used average smallest edge length / 2 for the radius).

I think my solution is not the most elegant or efficient but selecting vertices now works in real time. Which is way better than the 3 seconds I had to wait for :slight_smile:

Here is the pseudo code for my quick, dirty way:


// For all vertices
for (pVertex = v_begin(); v_end(); pVertex++) 
{
	Point p = pVertex->point();
	sphere_o = Vec(p[0], p[1], p[2]);     //  vertex position
	
	dst = ray_o - sphere_o;     // ray_o = ray origin from camera

	B = (dst * ray_dir);     // ray_dir  = ray direction from camera towards the world
	C = (dst * dst) - r2;
	D = (B*B) - C;

	// Do we have an intersection
	if (D >= 0)
	{
		// Make sure we choose the closest to the ray's origin
		if(dst.norm() < smallest_distance)
		{
			vertex_index = pVertex->id();
			smallest_distance = dst.norm();
		}
	}
}

vertex_index is the index of the selected vertex. The code is based on http://www.devmaster.net/wiki/Ray-sphere_intersection

I hope this helps others out there :slight_smile: