sandrofigo / VoxReader

A C# library to read .vox files created with MagicaVoxel
MIT License
63 stars 3 forks source link

Access palette notes #14

Closed wihrl closed 1 year ago

wihrl commented 1 year ago

Hello, I would like to access palette notes per voxel. image

I managed to get the notes out of the note chunk with the following code:

        var noteChunk = vox.Chunks.Single(x => x.Type == ChunkType.Note);
        var noteList = new List<string>();

        var i = 4; // skip row count
        while (i < noteChunk.Content.Length)
        {
            var noteLength = BitConverter.ToInt32(noteChunk.Content, i);
            i += 4;

            var note = Encoding.ASCII.GetString(noteChunk.Content[i..(i + noteLength)]).Trim();
            i += noteLength;

            noteList.Add(note);
        }

This creates an array with 32 names that match with what's in the editor. Unfortunately, I have not been able to match colors to the actual group names. The color indexes don't match up at all, in fact, they aren't even in the same order.

I've noticed the existence of ChunkType.IndexMap, maybe I need to use that somehow? Also, it would be nice if you could access the color index from the public Voxel struct. As things are right now, I had to clone this repo and modify it to expose it.

sandrofigo commented 1 year ago

Thank you for bringing this up. I'm going to have a closer look at the color indices and notes.

The features to add would include:

I will add these features in the next release if I have time to work on the project (probably in the next weeks).

sandrofigo commented 1 year ago

@wihrl In the meantime, if you want to have a look for yourself you can try to map the indices with the IMAP chunk (described at the bottom here https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox-extension.txt)

wihrl commented 1 year ago

Already found a solution based on this: https://github.com/ephtracy/voxel-model/issues/19#issuecomment-739324018

        // voxel color indexes do not correspond to the palette indexes => need to remap indexes using the index map chunk
        var mapChunk = voxFile.Chunks.Single(x => x.Type == ChunkType.IndexMap);
        var inverseMap = new byte[256];
        for (var i = 0; i < mapChunk.Content.Length; i++)
            inverseMap[mapChunk.Content[i]] = (byte) i;

...

            var paletteIndex = inverseMap[modelVoxel.ColorIndex];
            var noteIndex = 31 - (paletteIndex / 8);
            var note = notes[noteIndex];

Haven't tested it much yet, but it seems to work.

sandrofigo commented 1 year ago

@wihrl Do you have a .vox file I can use to verify the upcoming features?

wihrl commented 1 year ago

Not really, but for testing you can just add colors where the R and G values correspond to their X and Y position within the palette. Checking if the lookup works is trivial then.

sandrofigo commented 1 year ago

@wihrl With the new version https://github.com/sandrofigo/VoxReader/releases/tag/v4.0.0 most of the requested features are implemented.

Please let me know if you encounter any problems.

wihrl commented 1 year ago

Thanks, everything seems to work.