0
\$\begingroup\$

My question is quite simple, but the answer may be not.

I am studying and making a voxel engine, generating block vertices around its center position with TriangleList primitive at C#/XNA.

The problem is that I don't want that my game make those ugly "stairs" of cubes in mountains or hills. I want that the cube turns into a ramp when needed (when it has no connection with blocks at some sides, for example: no connection at top and east, then it turns into a ramp from west top to east bottom).

Another example that already exists may be found at SimCity 2000 maps. Edges become ramps, in many types, depending of how the squares of the terrain grid are modeled. Even corners between two directions of ramps become a new type of ramp, with two triangles.

I don't know how to detect that in a easy way, like, do I have to test each side and then check between the sides detected for selecting the type of ramp to create?... Or what should I test first, and then select the way of placing the vertices?

Thanks for any answer. And sorry for my English, if something is wrong.

\$\endgroup\$
  • 1
    \$\begingroup\$ One more tiny thing I just wanted to add: I've never played Sim City 2000, but Sim City 3000 and Sim City 4. I'm quite sure they don't store the actual height of single squares of landscape (so no real blocks). Instead, they store the height of the vertices/points between them. \$\endgroup\$ – Mario Sep 8 '14 at 6:38
  • \$\begingroup\$ You may be right, but the example I gave was about the way the "square" on the terrain would stay after configured. The way they made it in SimCity was totally different, I know, but the results are similar. In my case, I'm using blocks with different formats, so I can do it underground too. \$\endgroup\$ – Arthur 'Gibraltar' Condino Sep 11 '14 at 0:47
  • \$\begingroup\$ @Byte56: I just got it. I'm drawing different blocks for different situations: they turn into ramps when needed. I'll add more formats of ramps when I can, but I did the basic, ignoring the underground for now. I do a scan of which blocks should be turned to ramps before doing any vertex placement. Thanks for all the help. Now I just need to learn how to light vertexes and add textures... Well, one step at a time. :c) \$\endgroup\$ – Arthur 'Gibraltar' Condino Sep 11 '14 at 0:54
  • \$\begingroup\$ @Mario: and thanks! The solution you posted is really good. I just can't understand the algorithm for now. \$\endgroup\$ – Arthur 'Gibraltar' Condino Sep 11 '14 at 1:09
  • 1
    \$\begingroup\$ No worries, if you understood Byte56's solution, it's just a few steps more for this more generic approach. Actually what you described in your comment above (picking the right piece based on the "situation") is really pretty much what Walking Squares/Cubes is about. \$\endgroup\$ – Mario Sep 11 '14 at 6:34
2
\$\begingroup\$

As far as I know, there's no existing algorithm for this, you'll just have to create one. You're already on the right track. For each cube, check the surrounding cubes to see if converting the current cube is reasonable.

For example, say we're looking at cube #5 on a hill side. (green is solid, while is air).

enter image description here

This image will represent the X axis. You'd perform this test for the Z axis as well. Basically, we can simplify the check to:

if(isSolid(x-1, y, z) && !isSolid(x+1, y, z))
    ConvertToRamp(x, y, z, RampDirection.TopWest);
else if (!isSolid(x-1, y, z) && isSolid(x+1, y, z))
    ConvertToRamp(x, y, z, RampDirection.TopEast);

In this case, we'll trigger the second option, because 4 (x-1) is not solid, and 6 (x+1) is solid. This will convert 5 into a ramp with its top toward the East (top in the X plus direction), as shown with the red line.

The same check can be performed for the z axis. Then you'll find that you have a case where a ramp is valid in two directions. You can either choose a direction to make the ramp, or create some kind of dual direction ramp.

So what about performance? Running this check on every cube might get crazy when generating terrain. There's a few things you can do:

  • Only check surface level cubes. Don't worry about making ramps underground.
  • Don't perform this test on cubes that are air.
    • Or only perform it on cubes that are air with solid cubes below them. This would add new ramps to your existing blocky terrain.
  • Store a byte for each cube that describes if its neighbors are solid or not (for example, a 1 for solid and 0 for air). Then you can do a quick bit check to test if a cube should be a ramp. This sort of offsets the performance hit to another stage of world generation, but it's likely a stage the user is either expecting (loading screen) or they're not watching and waiting for it to happen (chunk generation out of view).
\$\endgroup\$
  • \$\begingroup\$ This is perfect! I mean, I couldn't organize a way to check which blocks are ramps, but as you posted we can test the X and then the Z axis, and convert when necessary. I'll try that and see what happens. Maybe I can make the check on all solid cubes before placing the vertexes, and flag the ones that are ramps. \$\endgroup\$ – Arthur 'Gibraltar' Condino Sep 7 '14 at 17:53
  • 1
    \$\begingroup\$ To add for optimization, I'd think about some additional flag or map to mark sections or parts of your landscape/chunk as "dirty". Whenever the surface is edited in some way, the flag is set, which will trigger the mesh update process. \$\endgroup\$ – Mario Sep 8 '14 at 6:35
1
\$\begingroup\$

I guess what you're looking for is the Marching Cubes algorithm or some variation of it.

Basically, you do exactly what you described: Look at the surroundings and then pick an actual "piece" that fits in.

\$\endgroup\$
  • \$\begingroup\$ It's unlikely to be like marching cubes, as that's an algorithm for converting point clouds into meshes. \$\endgroup\$ – MichaelHouse Sep 7 '14 at 14:50
  • \$\begingroup\$ It depends on where/how you define your points. Just take the voxel vertices as points and you're able to use the standard algorithm. Think about it. Voxels aren't that different to point clouds. \$\endgroup\$ – Mario Sep 7 '14 at 17:30
  • 1
    \$\begingroup\$ Of course it's possible to use marching cubes instead. But the question is asking about using blocks. And when to use a ramp shaped block instead of a cube shaped block. It's not asking for an entirely new way of generating the terrain mesh. Switching to marching cubes would be an entirely new way of generating the terrain mesh. \$\endgroup\$ – MichaelHouse Sep 7 '14 at 17:38
  • \$\begingroup\$ Marching Cubes is too much for what I can understand for now. \o/ I'm pretty newbie on all this and I'm still learning, but it would be very different for what I have until now. Thank you, anyway. I'll try to understand it too. \$\endgroup\$ – Arthur 'Gibraltar' Condino Sep 7 '14 at 17:55
  • \$\begingroup\$ @Byte56: Yep sure, although I don't know what's generated so far. \$\endgroup\$ – Mario Sep 8 '14 at 6:34

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.