Monday, October 29, 2018

xna - Building a chunk w/ blocks: making ramps. How to detect if blocks are making "stairs" (like in a mountain) and should be turned into ramps?


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.



Answer



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).


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...