1 module voxd.rawvox;
2 
3 import std.range,
4        std.file,
5        std.array,
6        std.string;
7 
8 import voxd.utils;
9 
10 /// Supports the VOX format used by the Build engine.
11 /// It is just a raw bitmap of 8-bit values.
12 
13 /// Decodes a VOX file.
14 /// Throws: VoxdException on error.
15 VOX decodeRawVOXFromFile(string filepath)
16 {
17     auto bytes = cast(ubyte[]) std.file.read(filepath);
18     return decodeRawVOXFromMemory(bytes);
19 }
20 
21 /// Decodes a VOX.
22 /// Throws: VoxdException on error.
23 VOX decodeRawVOXFromMemory(ubyte[] input)
24 {
25 
26     // check header
27     int width = popLE!int(input);
28     int height = popLE!int(input);
29     int depth = popLE!int(input);
30 
31     if (width < 0 || height < 0 || depth < 0)
32         throw new VoxdException("Strange value for dimensions, probably not such a VOX file");
33 
34     ubyte[] indices;
35     indices.length = width * height * depth;
36     for (size_t i = 0; i < indices.length; ++i)
37     {
38         indices[i] = popUbyte(input);
39     }
40 
41     struct PalColor
42     {
43         ubyte r, g, b;
44     }
45 
46     PalColor[256] palette;
47     for (int i = 0; i < 256; i++)
48     {
49         palette[i].r = popUbyte(input);
50         palette[i].g = popUbyte(input);
51         palette[i].b = popUbyte(input);
52     }
53 
54     VOX result;
55     result.width = width;
56     result.height = height;
57     result.depth = depth;
58     result.voxels.length = width * height * depth;
59 
60     for(int x = 0; x < width; x++)
61         for(int y = 0; y < height; y++)
62             for(int z = 0; z < depth; z++)
63             {
64                 int position = z + y * depth + x * width * height;
65                 auto color = palette[indices[position]];
66                 result.voxel(x, y, z) = VoxColor(color.tupleof, 255);
67             }
68 
69     return result;
70 }
71