Basically, I am creating a voxel-based game. I have an object Chunk
with a 3 dimensional array of the object Voxel
. In the array of Voxels
, the Voxel currently has an isAir bool on it that signifies no voxel being there.
I am trying to add a property to Chunk
which returns a 2 dimensional array of Voxel
's that are on the surface of the chunk. Currently, this array will always have Voxel.isAir == false
in the lower Y values and Voxel.isAir == true
in the higher Y values, there is never a clear run on the "Y" axis of the array that is either all "air"s or all Voxel
's, and there is never a "air" below a Voxel
in the array.
To get only the "Surface" Voxel
's, I have added this code to the Chunk
:
public Voxel[,,] Voxels { get; set; }
private Voxel[,] _surfaceVoxels = null;
public Voxel[,] SurfaceVoxels
{
get
{
if (_surfaceVoxels == null)
{
_surfaceVoxels = new Voxel[this.Voxels.GetLength(0), this.Voxels.GetLength(2)];
for (var x = 0; x < this.Voxels.GetLength(0); x++)
{
for (var z = 0; z < this.Voxels.GetLength(2); z++)
{
for (var y = 0; y < this.Voxels.GetLength(1); y++)
{
Voxel v = this.Voxels[x, y, z];
var solidAbove = false;
var solidBelow = false;
if (y - 1 >= 0)
{
Voxel vBelow = this.Voxels[x, y - 1, z];
solidBelow = !vBelow.isAir;
}
if (y + 1 < this.Voxels.GetLength(1))
{
Voxel vAbove = this.Voxels[x, y + 1, z];
solidAbove = !vAbove.isAir;
}
if (!v.isAir && !solidAbove && solidBelow)
{
_surfaceVoxels[x, z] = v;
}
}
}
}
}
return _surfaceVoxels;
}
}
Calculating the surface voxels this way is computationally expensive, and i cannot see a faster way of doing this. Because of this I effectively "cache" the surface array, which is fine until the underlying 3 dimensional array is changed, as then the surface voxels will obviously need to be recalculated.
Is there some way on the get
of public Voxel[,,]
it only returns a clone of the array and not the array itself, and on the set
set the entire array and set _surfaceVoxels
to NULL
, or even better is there some inexpensive way to execute code when values in an array are changed?
Is there some a more efficient way to accomplish what I have explained here that I have overlooked?