Picking objects

Started by
12 comments, last by Jason Z 11 years, 1 month ago

I know picking objects is well covered topic, nevertheless I have problems with it and asking you to help me.

So, my objective is to select (pick) some primitive on the screen, surround picked object with some border (for visibility) and return list of it's vertices.

Code samples, which I found in internet are built about "primitive structures" - each primitive, like line, triangle, rectangle, etc. has it's representation class with data of each primitive. In my program I use a little different approach: I have 1 global vertexBuffer and IndexBuffer. Those buffers contain locked data of whole figure, which can have very much different primitives. I need to pick some of those primitives. Is it possible with such project structure?

Advertisement

you could theoretically do ray->triangle test, iterate over all the triangles on your mesh and discover what polygon you are intersecting. But that's horrible inefficient. Do note that you could speed this up with quad trees, and such, but overall it's not an approach i'd use.

Unless this is an modeling software, then i'd likely store simpler objects to represent your object(or objects), and test against those, instead of the entire model.

Could you be a bit more descriptive on what your setup and goal is?

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

Typically picking and "vertex / index buffers" don't fit in the same sentence. Reading data from vertex buffer isn't usually good idea. You should keep a separate copy of your vertex / primitive data and use it for picking.

The general work flow for picking goes something like:

- generate ray based on mouse position on screen and camera location

- for each object / entity / mesh calculate inverse world matrix to transform ray from the world space to the meshes local space

- test each surface/triangle with ray-triangle hit test. Choose the closest hit to the camera.

Cheers!

Reading data from vertex buffer isn't usually good idea.

VertexBuffer + IndexBuffer are very nice for my type of data settings. Comfortably to build and use.

In general, I have very massive models, more then 6 000 000 primitives, and VB + IB shows great efficient in working with such models. Can you say the same about separate copies of primitives? If yes, I'm ready to rebuild geometry for using this method.


you could theoretically do ray->triangle test, iterate over all the triangles on your mesh and discover what polygon you are intersecting. But that's horrible inefficient. Do note that you could speed this up with quad trees, and such, but overall it's not an approach i'd use.

Unless this is an modeling software, then i'd likely store simpler objects to represent your object(or objects), and test against those, instead of the entire model.

Could you be a bit more descriptive on what your setup and goal is?

So, I have 2 collections: a collection of Elements, and a collection of Vertices. I take all vertices and add them to the vertex buffer.

Then I build IndexBuffer, using information from the collection of elements. Each element store information (ID) of vertices, which belongs to it. Several different elements can contain same vertex (or vertices).

By picking I want choose some element (primitive) on the screen and print information about it's vertices.

Since your scene content is not sorted in a data structure already, you will have a hard time to do any intelligent optimization of the ray picking. Is it possible for you to use your vertex buffer as a data structure and store the vertex information related to its spatial location? If so, you could then only do the ray intersection tests on a subset of the total primitives, which is what you are really after.

Other than that, you could try just clustering the vertex data near eachother, or perhaps even store separate buffers for different regions of your scene.

you could theoretically do ray->triangle test, iterate over all the triangles on your mesh and discover what polygon you are intersecting. But that's horrible inefficient. Do note that you could speed this up with quad trees, and such, but overall it's not an approach i'd use.

Unless this is an modeling software, then i'd likely store simpler objects to represent your object(or objects), and test against those, instead of the entire model.

Could you be a bit more descriptive on what your setup and goal is?

So, I have 2 collections: a collection of Elements, and a collection of Vertices. I take all vertices and add them to the vertex buffer.

Then I build IndexBuffer, using information from the collection of elements. Each element store information (ID) of vertices, which belongs to it. Several different elements can contain same vertex (or vertices).

By picking I want choose some element (primitive) on the screen and print information about it's vertices.

So, from my understanding the easiest method right now(but also the slowest), is to iterate over each polyon, and do ray testing.

However, If i were doing this, and knew i needed to be able to pick certain vertices(or polygons). I would probably try to create quad tree's for better optimizing what to select.

Remember that you don't have to use that vertex/index buffer for anything other than rendering. It's common practice to use highly detailed models for actual rendering, and simple primitive's(aabb, obb, sphere's, etc) to represent the object in your game's logic. I don't know what your full goal is(do you need to be able to pick a face, and modify that face, or...?)

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

Remember that you don't have to use that vertex/index buffer for anything other than rendering. It's common practice to use highly detailed models for actual rendering, and simple primitive's(aabb, obb, sphere's, etc) to represent the object in your game's logic. I don't know what your full goal is(do you need to be able to pick a face, and modify that face, or...?)

Interesting.. And if I'll make those simple primitives classes, would it help? If I'll keep my buffers for rendering and create such classes for each element representation? How do I then connect those classes with image on the screen ?

I need fast method, I have prety much primitives and iteration over them all is not a good solution for me..

My full goal is to get information about picked element - it's type and vertices. No other manipulations are needed (at least yet smile.png )

Since your scene content is not sorted in a data structure already, you will have a hard time to do any intelligent optimization of the ray picking. Is it possible for you to use your vertex buffer as a data structure and store the vertex information related to its spatial location? If so, you could then only do the ray intersection tests on a subset of the total primitives, which is what you are really after.

Other than that, you could try just clustering the vertex data near eachother, or perhaps even store separate buffers for different regions of your scene.

It is sorted, but quite specifically. I have Elements - generic collection, which contain data about each primitive (list of vertices, type, etc). I can't change it (it's a library), but I can try to use it in my purposes, to represent the object in logic, for example... I can use some technics or patterns to expand this collection with needed methods, like intersection. But I dont understand one thing - how do I connect those classes with image on the screen, image, taken from buffers ?

- how do I connect those classes with image on the screen, image, taken from buffers ?

Have already implemented the basic functionality of picking. I mean Pick ray calculation, from picked screen coordinates, etc?

In case you have a lot of 3D objects in scene you can make the map table of relationships between 3D object in scene and object in your application data model. You have to do it once per scene/level creation.

- how do I connect those classes with image on the screen, image, taken from buffers ?

Have already implemented the basic functionality of picking. I mean Pick ray calculation, from picked screen coordinates, etc?

In case you have a lot of 3D objects in scene you can make the map table of relationships between 3D object in scene and object in your application data model. You have to do it once per scene/level creation.

I had found some methods to check picking, like this:


public static bool CheckPicking(Viewport viewport, BoundingBox bBox, Vector2 coord, Matrix mViewProj, out float distance)
        {
            Vector3 ZNearPlane = Vector3.Unproject(new Vector3(coord, 0), 0, 0, viewport.Width, viewport.Height, viewport.MinZ, viewport.MaxZ, mViewProj);
            Vector3 ZFarPlane = Vector3.Unproject(new Vector3(coord, 1), 0, 0, viewport.Width, viewport.Height, viewport.MinZ, viewport.MaxZ, mViewProj);

            Vector3 direction = ZFarPlane - ZNearPlane;
            direction.Normalize();

            Ray ray = new Ray(ZNearPlane, direction);

            if (ray.Intersects(ref bBox, out distance))
                return true;
            
            return false;
        }

This method checks intersection with some object (Bounding box, triangle, sphere or plane). It can be used to calculate intersection with concrette figure by iteration over all collection, but it is not the best desision. I'm looking for better solution...

This topic is closed to new replies.

Advertisement