1
\$\begingroup\$

I'm currently developing a 3-dimensional game (the first I've ever done and it's not as hard as I thought it would be!), but I've run into a little bit of a snag. I want to find the current block the crosshairs of the camera are pointed to, and I'm not sure how exactly to do it. The only thing I can think of is starting at the view position and moving like 0.1 units until I hit a space that is occupied by a block, but I feel like that would be a little... brute-force style? Is there an easier/better way to find it?

Here's what I have:

  • The vector3 of the camera position.
  • An array of block positions which may or may not be filled with blocks. The block centres are at whole-numbered intervals.

I promise this isn't a minecraft clone. ;)

\$\endgroup\$
1
\$\begingroup\$

You want to get real familiar with a handy-dandy 3D math operation called Dot Product. Pretty much all 3D graphics libraries include this 3D math function; for example http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector3.dot.aspx

The dot product can be used for a number of things, but every use boils down to: when you take the dot product of two vectors, the resulting number tells you how close they are to pointing in the same direction. Exactly the same direction results in 1, perpendicular gives 0, and exactly opposite directions gives -1.

For this specific problem, one vector is the direction the camera is facing, and one vector is the direction from camera to a block (subtract the position of the block from the position of the camera). Get the dot product of these two vectors, and if the result is close to 1 then the camera is pointed at that block. Do this in a loop for all the blocks.


I should mention, the more general method for detecting geometry at a specific camera position is to use raycasting, shooting a ray out from the camera. For example, this link explains how to cast a ray from the camera in XNA http://www.enchantedage.com/xna-picking

Such an approach is unnecessarily expensive for a 2D grid of blocks, but would be necessary for a 3D grid of blocks. You didn't specify this in your question, so I assumed "an array of block positions" meant a 2D grid but just realized you may have meant a 3D grid.

The issue is that you don't only need to determine what blocks are being faced; you also need to determine which faced block is nearest. In a 2D grid this is a non-issue since all of the blocks lie on the same plane. However in a 3D grid many blocks overlap each other, which means there could be multiple overlapping blocks all in the direction the camera points toward. Raycasting will detect the first block hit.

\$\endgroup\$
  • \$\begingroup\$ I'm not sure if this solves my problem. For one, I'm worried about the preciseness of it. I need it to know when the camera is pointed to a block when it's barely a pixel from the edge of it, and to make sure that it doesn't think it's pointed to the block when it's barely a pixel away from it. Secondly, looping through a bajillion blocks seems like it would get a little pricey, especially when recalculating a lot of times. Although I suppose I could just cut out a lot of them by only testing the ones in the chunks which I cut out using the same method. \$\endgroup\$ – Mackenzie McClane Oct 14 '14 at 4:38
  • \$\begingroup\$ I should have specified this in the question (in face, I think I will), but there's crosshairs in the centre of the screen and that's what I need to get a block from. \$\endgroup\$ – Mackenzie McClane Oct 14 '14 at 4:39
  • \$\begingroup\$ On the other hand, thank you for this answer! I didn't know about dot product--I've seen it in both C# and HLSL code and didn't know what it meant. I have a feeling it'll come in handy in the future! \$\endgroup\$ – Mackenzie McClane Oct 14 '14 at 4:40
  • \$\begingroup\$ Dot products are extremely fast calculations, so doing it for a large number of blocks should be fine. Obviously you might need to optimize chunks for a really large number of blocks, but then you'd need to optimize even more for any other method. \$\endgroup\$ – jhocking Oct 14 '14 at 8:09
  • \$\begingroup\$ Well, it is a 3D game, with 3D block placement, but the blocks are stored code-wise in a 1D array. The new part of your answer is what I was looking for--thank you! \$\endgroup\$ – Mackenzie McClane Oct 14 '14 at 9:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.