2

I am working on a project which allows users to pick 3d objects in a scene and I was wondering what everyone thought would be the best way to approach this particular scenario.

Basically we have a scene with at least 100 objects (they are low-poly but made from at least ~12-15 triangles) and up to about 1000-2000 objects.

Not all the objects will be "pickable" at all times because some objects will occlude others so "pickable" objects probably land in the range between 800-1500 (depending on the complexity of the scene).

When an object is "picked" we want it to be highlighted in some way so this means rendering it differently, this is trivial but we want picking to be done not only on single clicks but also drags - which means we want to run the picking algorithm a lot in a short space of time. Ideally the user would see objects highlighted while they were still in a "drag" operation - (meaning the picking should probably be done asynchronously as to not lag the main rendering?).

I have tried simple ray trace picking but this is obviously quite slow as we loop through all triangles in the scene to find the object.

I have also tried GPU-based picking - rendering the scene using a pixelbuffer that gives a unique color to each object but with the dragging operation this means multiple renders and GPU-to-CPU data transfer which doesn't have great performance.

Are there any other possibilities I could explore to try and get the performance and functionality I want?

Thanks for your time.

poncho
  • 1,100
  • 2
  • 15
  • 38
  • Additionally to the Octree approach, you should test for simpler bounding volumes first. E.g. a test for sphere-ray intersection is very cheap. If the ray does not hit the bounding volume, you don't need to try if the ray hits the mesh. – Nico Schertler Aug 17 '13 at 12:18
  • So you're saying it would be beneficial to create an octree of spheres as well as bounding boxes and test the spheres first? – poncho Aug 21 '13 at 09:39
  • No, if you found potential hits in the octree, you need to analyze if there is really a hit. This can be accelerated by checking bounding volumes first. – Nico Schertler Aug 21 '13 at 12:06

1 Answers1

1

I have used an Octree before for this sort of thing and it seemed to be my best option. Every object can be placed in the corresponding node and tested through the usual Octree protocol. The real benefits come from offsetting the ray cast to the end of a spatial node when the current node is empty. This will surely give you significant gains over brute-forcing it.

The following link should give you a base with Octree's and how it is set up: Introduction to Octrees

While the link is only giving you a base, the use of the Octree is simply for reducing necessary checks, so judging by your question, you seem to already have the knowledge required to perform the actual picking.

Joseph Pla
  • 1,600
  • 1
  • 10
  • 21
  • Ah okay, I don't think I've come across this method, do you have a link to somewhere that explains it nicely? – poncho Aug 16 '13 at 12:36
  • @poncho I can't find any links that provide exactly that, but have you ever used an octree before? If not, once you familiarize yourself with it, you'll find that you can narrow down the intersection tests that you perform. To further optimize, you can "accelerate" the ray past empty nodes because you know that you don't have to perform tests there. – Joseph Pla Aug 16 '13 at 13:29
  • Ah okay thanks, no I've never used Octrees before but I found quite a nice explanation here (http://castle-engine.sourceforge.net/vrml_engine_doc/output/xsl/html/chapter.octree.html#section.octree_collision_detection) and so I'll have a go at implementing it now. – poncho Aug 21 '13 at 09:40
  • I'm currently working on adding Octrees to my picking but I'm a little confused. I have a dynamic environment so if my environment looks like this: http://castle-engine.sourceforge.net/vrml_engine_doc/output/xsl/html/examples/octree_example_screen_mini.png - and then I add a Cube to the left of the nearest cube in the image, how does my Octree know it must "grow" and which Octree leaf adopts the new cube?? – poncho Aug 23 '13 at 14:42
  • @Poncho whenever you add an object to an octree, you just have your nodes divide until it satisfies a certain condition. What I usually do is a condition where there can only be one object per node. – Joseph Pla Aug 23 '13 at 14:49
  • Ah here is a great explanation of what to do with a growing/shrinking octree: http://www.piko3d.com/tutorials/space-partitioning-tutorial-piko3ds-dynamic-octree – poncho Aug 23 '13 at 15:00
  • Oops only just saw your reply Joey, thanks for the info - it's starting to make sense now. – poncho Aug 23 '13 at 15:01
  • @poncho no worries, I'll actually look into it. It will probably help me out too :P – Joseph Pla Aug 23 '13 at 15:11