Creating a sphere out of cubes. C#

Started by
3 comments, last by SpikeViper 8 years, 8 months ago

?Hey everyone! I have come to these forums because I cannot find the answer to this anywhere... I am building a voxel game, and this game will include planets. I wanted to create a planet starting with the core (Center) block, and adding layers onto it (Densest materials to least dense), and then spherifying it (Is that a word?) Problem is, I have no clue how to turn that into code. I've tried a few different ways, and I've only been able to make an X and an Star. I know how I messed up, but now I don't understand how to do this correctly - it seems extremely complicated.

To set a block in the planet:

blocks[posx, posy, posz] = new Block();

?

I'm making an open source voxel space game called V0xel_Sp4ce! Help me out with the repository here: https://github.com/SpikeViper/V0xel_Sp4ce

Advertisement

For more clarification, by "Sphere" I mean something like this:

http://www.plotz.co.uk/plotz-model.php?model=Sphere

I'm making an open source voxel space game called V0xel_Sp4ce! Help me out with the repository here: https://github.com/SpikeViper/V0xel_Sp4ce

Since the interior needs to be filled and you want concentric shells, what I would do is treat the sphere as a layers of pixels and use the midpoint circle algorithm to fill the layers with concentric circles.

This process would be two step:

Assuming, as in the pic, that -y is up, +x is right and +z points into the screen...

1.) Generate, but do not draw, a quadrant of a circle in the x-y plane. The distance of the from the origin to edge of the quadrant will be the radius of each outer slice. If the algorithm generates more than one pixel on a scanline, the one farthest from the origin is the radius for that slice. Store these in an array.

2.) For each slice, generate a concentric circles in the x-z plane, with the y coordinate being used as an offset into the stored quadrant array to determine the maximum radii for that slice.

Does that make any sense? I can picture it, but am having trouble describing it.

The easiest algorithm I can think of might not be the most efficient. But it's not horrifically slow, either, and should be particularly easy to understand, to implement, and to adjust. It should also give you more than sufficient quality with little mental effort.

The overall process is to simply iterate over all of the voxels within the cube that will contain the planet; the usual three nested for-loops will do. Given a center point cp = (cx, cy, cz) and a radius r, that would be the cube from (cx - r, cy - r, cz - r) to (cx + r, cy + r, cz + r), inclusive.

Inside that innermost loop, for each voxel, calculate the distance from the voxel's point vp = (vx, vy, vz) to the center of the planet using the standard formula for Euclidean distance: d = sqrt((cx - vx)2 + (cy - vy)2 + (cz - vz)2). Based on that distance, determine what type of block you want. Small distances will be the solid or molten core. Medium distances will be the mantle. Distances just slightly less than the radius will be the crust and surface bits. Anything larger than the radius will remain empty.

You'll need to make each layer thick enough to guarantee that layers aren't strangely spotty, but as long as your planets aren't low resolution (like 9 voxels wide or something), you should have plenty of room to work with. Just don't make your crust as thin as it would realistically be, because you won't have enough voxel resolution to make it work, and you'll end up with a bunch of the mantle showing everywhere.

Beyond that caveat, it should be pretty easy to adjust the radius at which each layer ends, you'll get a nearly perfect sphere, and there won't be any accidental gaps inside the planet. Trying to build the planet up layer by layer might seem intuitive, but it actually makes the process way harder than it needs to be, once you get into the implementation. However, if you want to guarantee that the crust is only one voxel thick, it would probably be sufficient to do the above generation without the crust, and then just add a single layer of the crust on top of the mantle. (Setting any voxel that is empty but adjacent to a mantle voxel would work.)

"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke

Thanks guys! I think I have figured it out, thanks to you, gonna do alot of tweaking!

I'm making an open source voxel space game called V0xel_Sp4ce! Help me out with the repository here: https://github.com/SpikeViper/V0xel_Sp4ce

This topic is closed to new replies.

Advertisement