forked from ephtracy/voxel-model
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMagicaVoxel-file-format-vox-extension.txt
148 lines (119 loc) · 3.56 KB
/
MagicaVoxel-file-format-vox-extension.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
* there can be multiple SIZE and XYZI chunks for multiple models; model id is their index in the stored order
* the palette chunk is always stored into the file, so default palette is not needed any more
* the MATT chunk is deprecated, replaced by the MATL chunk, see (4)
* (a), (b), (c) are special data types; (d) is the scene graph in the world editor
=================================
(a) STRING type
int32 : buffer size (in bytes)
int8xN : buffer (without the ending "\0")
=================================
(b) DICT type
int32 : num of key-value pairs
// for each key-value pair
{
STRING : key
STRING : value
}xN
=================================
(c) ROTATION type
store a row-major (XZY) rotation in the bits of a byte
for example :
R =
0 1 0
0 0 -1
-1 0 0
==>
unsigned char _r = (1 << 0) | (2 << 2) | (0 << 4) | (1 << 5) | (1 << 6)
bit | value
0-1 : 1 : index of the non-zero entry in the first row
2-3 : 2 : index of the non-zero entry in the second row
4 : 0 : the sign in the first row (0 : positive; 1 : negative)
5 : 1 : the sign in the second row (0 : positive; 1 : negative)
6 : 1 : the sign in the third row (0 : positive; 1 : negative)
Note: the index of the non-zero entry of the third row is remaining
complimentary index to the first and second, i.e. if first index = 1
and second index = 2, then the third = 0.
=================================
(d) Scene Graph
T : Transform Node
G : Group Node
S : Shape Node
T
|
G
/ \
T T
| |
G S
/ \
T T
| |
S S
Note: in order to build transformations, you need to traverse the scene
graph recursively, starting with root Transform node, and then for every
next transform:
* Translations are added when traversing
* Rotation matrices are multiplied (parent * transform)
It's preferable to maintain two separate stacks for translations
(vec3 stack), and a matrix stack. For every Transfrom node, you peek the
stacks, and add vector in a stack to Transform node's translation vector,
and multiply stack's rotation matrix by Transform node's rotation matrix,
and push these values to their respective stacks.
For every Shape node, you can just pop both values and use them.
=================================
(1) Transform Node Chunk : "nTRN"
int32 : node id
DICT : node attributes
(_name : string)
(_hidden : "0" or "1")
int32 : child node id
int32 : reserved id (must be -1)
int32 : layer id
int32 : num of frames (must be 1)
// for each frame
{
DICT : frame attributes
(_r : int8) ROTATION in STRING (i.e. "36"), see (c)
(_t : int32x3) translation in STRING format separated
by spaces (i.e. "-1 10 4"). The anchor
for these translations is center of the
box.
}xN
=================================
(2) Group Node Chunk : "nGRP"
int32 : node id
DICT : node attributes
int32 : num of children nodes
// for each child
{
int32 : child node id
}xN
=================================
(3) Shape Node Chunk : "nSHP"
int32 : node id
DICT : node attributes
int32 : num of models (must be 1)
// for each model
{
int32 : model id
DICT : model attributes : reserved
}xN
=================================
(4) Material Chunk : "MATL"
int32 : material id
DICT : material properties
(_type : str) _diffuse, _metal, _glass, _emit
(_weight : float) range 0 ~ 1
(_rough : float)
(_spec : float)
(_ior : float)
(_att : float)
(_flux : float)
(_plastic)
=================================
(5) Layer Chunk : "LAYR"
int32 : layer id
DICT : layer atrribute
(_name : string)
(_hidden : 0/1)
int32 : reserved id, must be -1