-
Notifications
You must be signed in to change notification settings - Fork 409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optional optimised format #52
Comments
This is the exact same thing I was thinking about. pros/cons: |
I actually had a go at this, encoding some voxels in the XYZI+CUBE format. For my own voxels which dont use a lot of different colours the size difference is even greater (1/24): I wrote a cube finding algorithm thats pretty fast (i can read file, find cubes and write file, all in under 200ms for any of the models) so performance shouldnt be much of an issue.
For the algorithm to work you first need to put the colour indexes in a matrix. |
I also had an idea to make it even smaller but at the cost of even slower decoding and encoding. The simplest example is a checker board which the current algorimth wouldn't be able to do much with. So, to fix this, we could implement an hierarchy system for the chunks which would essentially allows for chunk overlapping. Taking our board, we would take one of the colors (normally the one with the most amount of chunks) and make it (in our specific case) fill the entire model. This leave use with the other voxels (that can also be air) which we would simply save at their normal location but as childrens of the big chunk so that the decoder would know what to overlaps with what. This would reduce by half the size of the checker board which is a win and even more other models. But this comes at the cost of encoding/decoding speed so that could be optional. |
Having air overwrite voxels will in a lot of cases increase size (compared to the XYZI+CUBE format) because now we would have to store air too. I think a better solution to the checkerbox problem would be: alternatively (not as widely applicable but would be even better at this specific problem): These could even be combined (finding cubes first, then checkerboxes and then 45 degree lines). |
In conclusion, I am not sure if the checkerbox problem warrants fixing. It is the worst case scenario where we effectively only store XYZI and not CUBE, so same as the current MagicaVoxel format. I do not estimate this to be a common type of model. I might run some tests to see if storing 45 degree lines can achieve a significant size reduction in my earlier mentioned test sets. |
I thought about this some more and figured out that there is even more to gain by storing colour mapping more efficiently. If we sort our voxels/cubes by colour, we can then create an extra chunk to map the colours to our voxels/cubes. The way we do this is we create a new chunk VMAP (for voxels) and store in this 4 bytes for each colour actually used. Additional compression using this technique: My own voxels (which don't use a lot of colours): Sorting the voxels/cubes by colour is pretty fast, so the performance loss is negligible. PS: Note that with this method we could also easily remove the need for the RGBA palette chunk by instead of using indexes, just writing the full colour (4 bytes to represent a colour instead of 1) in the maps. This would remove the 255 colour limitation. |
@Xless-Qu-dev @ephtracy I have made a github repository to describe this optimised file format in more detail: https://github.com/JelleBouma/cvox |
Feature
An optional optimised version of the normal vox format which would use less disk space.
How
If i understand correctly, every voxels of a model are saved in the file. This is an easy way of doing it but not the most optimised.
I would suggest a "Group/*Chunk" saving technique. It would save not every voxels but chunk of voxels with the same property.
Ex : A cube with a side of voxel with pallet index 1 and the other with index 2.
Old : Every voxel would be saved.
New : 2 chunk whould be saved.
Format(xs, ys, zs, xe, ye, ze, index)
The first 6 values represents the start/end of the chunk bounds.
The last value represents the pallet index of the voxels inside that chunk.
The text was updated successfully, but these errors were encountered: