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

Rotation bug on .vox write #5

Open BenMcLean opened 7 months ago

BenMcLean commented 7 months ago

FileToVoxCore seems to rotate models unexpectedly when writing.

I first mentioned this to Zarbuz on the MagicaVoxel Discord on 2023-10-15 and he asked me to make a reproduction of the bug.

I have created a unit test that minimally reproduces the issue here: https://github.com/BenMcLean/FileToVoxCore/blob/062939c5876cef1e9285713ee8829974720d00c2/FileToVoxCoreTest/UnitTest1.cs

Take any asymmetrical model (so you can see which way it is facing) as your Input.vox and run the unit test. Your Output.vox will be rotated.

BenMcLean commented 7 months ago

I might not keep that fork around forever so here's the code:

namespace FileToVoxCoreTest
{
    public class UnitTest1
    {
        public const string InputPath = @"..\..\..\Input.vox",
            OutputPath = @"..\..\..\Output.vox";
        [Fact]
        public void Test1()
        {
            Assert.True(File.Exists(InputPath));
            if (File.Exists(OutputPath))
                File.Delete(OutputPath);
            FileToVoxCore.Vox.VoxModel voxModel = new FileToVoxCore.Vox.VoxReader().LoadModel(InputPath);
            FileToVoxCore.Vox.VoxelData voxelData = voxModel.VoxelFrames[0];
            List<FileToVoxCore.Schematics.Voxel> voxels = new();
            ushort 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)
                            voxels.Add(new FileToVoxCore.Schematics.Voxel(
                                x: x,
                                y: y,
                                z: z,
                                color: (uint)voxModel.Palette[voxel].ToArgb()));
            new FileToVoxCore.Vox.VoxWriter().WriteModel(
                absolutePath: OutputPath,
                palette: voxModel.Palette.ToList(),
                schematic: new FileToVoxCore.Schematics.Schematic(voxels));
            Assert.True(File.Exists(OutputPath));
        }
    }
}