Zarbuz / FileToVoxCore

FileToVoxCore is a library that allows you to read and write MagicaVoxel (.vox) file easily
MIT License
4 stars 3 forks source link

Iterate through filled voxels only? #7

Closed BenMcLean closed 6 months ago

BenMcLean commented 6 months ago

Currently, I have my app using FileToVoxCore inside a constructor like this:

public VoxFileModel(FileToVoxCore.Vox.VoxModel model, int frame = 0)
{
    Palette = new uint[256];
    uint[] palette = model.Palette.Take(Palette.Length).Select(Color).ToArray();
    System.Array.Copy(
        sourceArray: palette,
        sourceIndex: 0,
        destinationArray: Palette,
        destinationIndex: 1,
        length: Math.Min(palette.Length, Palette.Length) - 1);
    FileToVoxCore.Vox.VoxelData voxelData = model.VoxelFrames[frame];
    SizeX = (ushort)(voxelData.VoxelsWide - 1);
    SizeY = (ushort)(voxelData.VoxelsTall - 1);
    SizeZ = (ushort)(voxelData.VoxelsDeep - 1);
    for (ushort x = 0; x < SizeX; x++)
        for (ushort y = 0; y < SizeY; y++)
            for (ushort z = 0; z < SizeZ; z++)
                if (voxelData.GetSafe(x, y, z) is byte voxel && voxel != 0)
                    this[x, y, z] = voxel;
}

But those nested for loops at the end are very inefficient. It is doing an exhaustive search of the 3D space, which wastes CPU on models that are mostly empty space.

It would be better to expose an iterator which returns all the filled voxels without having to check all the empty ones. And I mean in a way that increases efficiency, not just an iterator that checks all the empty spaces behind the scenes.

Zarbuz commented 6 months ago

You can already iterate on all voxels with voxelData.Colors. This is a dictionary with contains all filled voxels inside a frame. The key is the index of the voxel inside the 3D array and the value is the color palette index. You can write something like this (pseudo code):

foreach (var voxel in voxelData.Colors)

voxelData.Get3DPos(voxel.Key, out int x, out int y, out int z) //to get the coordinate in X, Y, Z this[x, y, z] = voxel.Value;

BenMcLean commented 6 months ago

That works. Thanks!