1
\$\begingroup\$

I'm currently using a tridimensional grid for pathfinding, think of it as a huge cube with voxels (3d nodes) inside it, each voxel ita a class containing information about the voxel, if its an obstacle, its costs (for A*) and position. The problem is, there are too much nodes, which consumes a lot of memory, if I increase it too much it like a 120x90x120 volume it consumes 1gb of ram. I know that its obvious it will be this huge because there are 1.296.000 voxels, but how could I solve it with less memory?

I'm using C# and Unity for it.

\$\endgroup\$
  • \$\begingroup\$ 1 gigabyte of memory should provide space for 134217728 double precision floats. If you have 1296000 cells, there would be ca 103 floats per cell, and even more integers (used for indexing). The data for pathfinding (= the node graph) should absolutely not consume that much. Maybe the problem is other data than the actual graph data? \$\endgroup\$ – Stormwind Aug 28 '17 at 20:57
  • 1
    \$\begingroup\$ Unity is really not designed for making Minecraft clones, if that's what you are trying to do. \$\endgroup\$ – Philipp Aug 28 '17 at 23:18
  • 3
    \$\begingroup\$ what's in your class? \$\endgroup\$ – Reuben Crimp Aug 28 '17 at 23:19
4
\$\begingroup\$

class containing information about the voxel, its costs (for A*) and position ...

Why do you need to store a voxels position, are they going to move? just use the array indices as the position. i.e. if you want voxel at position (3, 5, 9) then just access your voxel datastructure at index [3][5][9].

The only thing you NEED to store for each voxel is the type, i.e. is it air, water, ground etc... and if you can make do with 256 different types then we can use a byte to store the voxel type.

120 * 90 * 120 = 1,296,000 That's only 1.2 million, and if we can represent each voxel with a single byte, then it'll only be 1.3 MB, which is tiny. Don't maintain an array of 1 million classes, that's not what they're designed for. An array of bytes should do fine.

int width = 120; int depth = 120; int height = 90;
byte[][][] voxels = new byte[width][depth][height];

If you also need to store A* information, then consider a separate data structure

byte[][][] voxel_costs = new byte[width][depth][height];

Which brings us to 2.6 MB, still tiny. Having this separation might also help enforce encapsulation, i.e. the rendering code needs to know what each voxel will look like, but it doesn't care about path finding information.

This is not the most ideal solution, as Philipp said, Unity isn't really geared towards making a minecraft clone. Any decent voxel engine is a HUGE undertaking. But it's definitely a fun project that I've considered myself numerous times, and there are plenty of resources online. A Mojang developer has posted a couple relevant blog posts you should check out http://tomcc.github.io/2014/08/31/visibility-1.html

\$\endgroup\$
  • \$\begingroup\$ Thanks man! I will definetly look into that, I thought I had to store each voxel as a class because of the information within it, but i will try something like your example \$\endgroup\$ – khofez Aug 29 '17 at 16:56
  • \$\begingroup\$ If you need more information, you could try looking into structs. If C# is like C, structs should be very lightweight. something like ... struct voxel { byte type; byte cost; } voxel[][][] voxel_map = new voxel[120][120][90]; \$\endgroup\$ – Reuben Crimp Aug 29 '17 at 22:20
1
\$\begingroup\$

Look into spatial subdivision and defining implicit spaces.

You do not need to specify all voxels at a time in memory. For the current location, you just generate them from a function taking that location as a parameter.

The algorithms that define how the world is generated should do the rest, as you move to a new area.

This is much like the way y = ax^2 + bx + c defines a parabola, even if you currently haven't plotted the points on a line that would show that curve. Indeed, in computational geometry, implicit surfaces are defined the same way - by some mathematical function.

\$\endgroup\$
  • \$\begingroup\$ Perlin noise is a great way to generate voxel landscapes, and Unity has a function built in Mathf.PerlinNoise \$\endgroup\$ – Reuben Crimp Aug 29 '17 at 15:30

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.