RichysHub / MagicaVoxel-VOX-importer

Blender import script for MagicaVoxel .vox format as cube primitives.
MIT License
227 stars 56 forks source link

Extended vox format scene structure is not supported. #10

Open RichysHub opened 5 years ago

RichysHub commented 5 years ago

The extension to the .vox format added several chunks that deal with the layout of the scene.

Namely, these define a scene graph containing grouped content, that then can be part of other groups, or be transformed.

This is not appreciably replicated in the blender import, although it could be.

I believe that in Blender>2.80, this maps nicely to the collections system.

However, I don't believe collection objects themselves can be transformed, so these would be applied through the tree.

example scene graph from the spec.

=================================
(d) Scene Graph

T : Transform Node
G : Group Node
S : Shape Node

     T
     |
     G
    / \
   T   T
   |   |
   G   S
  / \
 T   T
 |   |
 S   S

=================================
wizardgsz commented 5 years ago

A "simple" example:

Immagine

Here it is the VOX file and its structure:

XYZI(0) num_voxels 1398
XYZI(1) num_voxels 389
XYZI(2) num_voxels 0
XYZI(3) num_voxels 0
XYZI(4) num_voxels 0
XYZI(5) num_voxels 3067

nTRN(0):
        child: 1
        layer: -1
nGRP(1):
        child_node_id: 2
        child_node_id: 4
        child_node_id: 6
        child_node_id: 8
        child_node_id: 10
        child_node_id: 12
        _name: 2222
        _t: -41 -1 20
nTRN(2):
        child: 3
        layer: 2
nSHP(3):
        child_node_id: 0
        _name: 333
        _t: 0 0 20
nTRN(4):
        child: 5
        layer: 3
nSHP(5):
        child_node_id: 1
        _t: 0 0 20
nTRN(6):
        child: 7
        layer: 0
nSHP(7):
        child_node_id: 2
        _t: 0 0 20
nTRN(8):
        child: 9
        layer: 4
nSHP(9):
        child_node_id: 3
        _name: 3333
        _t: 0 0 20
nTRN(10):
        child: 11
        layer: 0
nSHP(11):
        child_node_id: 4
        _name: 111
        _t: 39 45 20
nTRN(12):
        child: 13
        layer: 1
nSHP(13):
        child_node_id: 5

That is, in the new "scene" structure, something like:

scene

Summarizing, the most important thing is: for each "model" (or object) we have a pair of SIZE-XYZI chunks to store data. Shape node nSHP is the "final" / leaf node representing a single object (its voxel data and the roto-translations to apply). Actually frames are not supported yet in new format (num of frames must be 1).

p.s. I omitted the info on the layers (nTRN contains layer number) that can be ignored in my opinion (they are just useful to organize your work in the editor).

RichysHub commented 5 years ago

I've been thinking about how to reorganise the importer, such that this structure is easier to manage. Principly that the structure would be parsed into Python objects that resemble the same structure, which then can be manipulated, simplified, and "exported" into the scene.

Along with this I hope to pave the way for a test suite; by having this Python based representation, rather than going straight to the blender scene (which I feel makes testing a whole lot messier).

This would result in a drastic restructuring, but I think should be cleaner, clearer, and more easily extensible. I hope to get some solid ideas into code in the coming days.

wizardgsz commented 5 years ago

A basic group of 2 models (here the VOX):

Scene graph GROUP 2

That is:

XYZI(0) num_voxels 80
XYZI(1) num_voxels 24
nTRN(0):
        child_node_id: 1
        layer: -1
nGRP(1):
        child_node_id: 2
        _t: -12 6 3
nTRN(2):
        child_node_id: 3
        layer: 0
nGRP(3):
        child_node_id: 4
        child_node_id: 6
        _name: child_blu
        _t: -11 10 -1
nTRN(4):
        child_node_id: 5
        layer: 0
nSHP(5):
        child_node_id: 0
        _name: parent_grn
        _t: 12 -9 1
nTRN(6):
        child_node_id: 7
        layer: 0
nSHP(7):
        child_node_id: 1
wizardgsz commented 5 years ago

Two models grouped + a single model in a scene graph (the VOX file):

Scene graph GROUP 3

That is:

XYZI(0) num_voxels 48
XYZI(1) num_voxels 80
XYZI(2) num_voxels 24
nTRN(0):
        child_node_id: 1
        layer: -1
nGRP(1):
        child_node_id: 2
        child_node_id: 4
        _name: alone_red
        _t: 13 -19 4
nTRN(2):
        child_node_id: 3
        layer: 0
nSHP(3):
        child_node_id: 0
        _t: -12 6 3
nTRN(4):
        child_node_id: 5
        layer: 0
nGRP(5):
        child_node_id: 6
        child_node_id: 8
        _name: child_blu
        _t: -11 10 -1
nTRN(6):
        child_node_id: 7
        layer: 0
nSHP(7):
        child_node_id: 1
        _name: parent_grn
        _t: 12 -9 1
nTRN(8):
        child_node_id: 9
        layer: 0
nSHP(9):
        child_node_id: 2