How to target voxel, Minecraft - style?

Blitz3D Forums/Blitz3D Tutorials/How to target voxel, Minecraft - style?

Liimbix(Posted 2015) [#1]
Hi all, I am very experienced with Blitz3D, and I am going to create a *very* basic and small voxel engine, just to mess around in. I notice in games such as Minecraft and the trillion ripoffs of it, when you point at a block, a black outline appears around it to show that you have it selected and you know what block you are pointing at. Just a question, what code / function / etc would I use to be able to target a block in an array? Let's say you're pointing to block[0,0,0] in coordinates. How would I highlight that block. I'm just confused as to how to get what coordinates you are looking at. Like I think I need mouse pitch and yaw or something to tell where you are looking, but I'm not sure. Sorry if this was confusing, and if you need me to help clarify, I would be happy to restate something. (this is an example of what I mean: http://forum.unity3d.com/attachments/77876/ ) Thanks!! (sorry for bad english btw I am learning) (:


xlsior(Posted 2015) [#2]
Overlay the block at that location with a slightly-larger wireframe cube object, which would highlight the edges?


Liimbix(Posted 2015) [#3]
Yeah, I pretty much know how to do it, I am sorry if I didn't word my question right, I was just wondering how to tell where the mouse is pointing, and then highlight the block the mouse is pointing at. I believe I need to use the camera z and x coordinates and mouse pitch and yaw.. I'm just not sure exactly what the algorithm would be.


Kryzon(Posted 2015) [#4]
Hello Liimbix.
Your computer screen is aligned perfectly with the near-plane of the camera in the 3D world. The default near-plane distance in Blitz3D is 1.0.

At a distance of 1.0 units from the camera in its viewing direction you'll find your near-plane. At this distance, with the default zoom of 1.0 (which is equivalent to a 90º degree field-of-view), the size of the near-plane is 2.0 x 2*(height / width) in 3D units.
So imagine a 3D rectangle of size 2.0 x 2*(height / width), centered on the camera viewing direction.

You want to map the mouse coordinates -- a 2D point on the near plane with the origin at the top-left corner -- to 3D units so that you can find the ray that goes from the camera position through the mouse coordinates on the near plane to far away into infinity. You can compute that with the following:



Since that Minecraft clone has the mouse always centered you don't need all these calculations, but they're good to know nonetheless.
The normalised direction of the ray coming from the camera to the centre of the screen is this:
;Get the normalised vector going from the camera in its view direction, in world-space coordinates.
;The position of the camera is already its centre, so there's no need for any offset.

TFormNormal( 0, 0, 1, myCamera, 0 )

Const RAY_LENGTH# = 1000000.0

rayStartX# = EntityX( myCamera, True )
rayStartY# = EntityY( myCamera, True )
rayStartZ# = EntityZ( myCamera, True )

rayEndX# = rayStartX + ( TFormedX() * RAY_LENGTH )
rayEndY# = rayStartY + ( TFormedY() * RAY_LENGTH )
rayEndZ# = rayStartZ + ( TFormedZ() * RAY_LENGTH )



Liimbix(Posted 2015) [#5]
Kryzon, that helped a lot! I wasn't sure how to raycast straight from the camera to the centre of the screen, and I was going to use a makeshift cube and use the cameras pitch values to locate where the camera is pointing, but your method is better. Thanks so much (:


Kryzon(Posted 2015) [#6]
I changed the first section in that post to a practical example, there were some things I had written wrong.
The size of the near plane depends on the zoom of the camera (it's related to its field-of-view angle). The FOV angle dictates how wide the near-plane is depending on how far you go from the camera.

If you imagine a 90º FOV split in the middle, each half has tangents of 45º and this results in 1.0. Because of this, with a 90º FOV the near-plane is always twice as wide as it is far from the camera.
When you go 1.0 units in front of the camera, the near plane has 1.0 units to either side, which totals 2.0 width.
The height of the near-plane is always derived from its width and the inverse resolution ratio, so it's (screenHeight / screenWidth) * (planeWidth), with 'planeWidth' being 2.0.





Liimbix(Posted 2015) [#7]
Thanks Kryzon for all the help, but I am not using rays. I am using MousePick, and it is working great! Thank you though (:


Kryzon(Posted 2015) [#8]
Perhaps you mean CameraPick? That's a good alternative, I had forgotten about it.

It uses the internal picking system from Blitz3D. If you start noticing performance issues from picking scenes with thousands of cubes, you'll have to use ray-casting and an octree structure (to be implemented in code).