Closed wizardgsz closed 5 years ago
Hmm, very good point, I hadn't realised this case. In the current framework, what you've laid out seems pretty reasonable.
In the case that the vox has less frames than the frame number provided, we could unpack every XYZI
we see, into voxel_data
. Then if we reach end of frames we know that the last one we saw was the last frame. Then we move that data over to voxels
.
That would, in effect, make load_frame = min(load_frame, total_frames)
, which is how the upper voxel bound is currently handled.
Are separate XYZI chunks always separate frames? I worry with the scene graph stuff from the extension, and with layers that might not be the case.
I have to further investigate about new file format (i.e. Transform Node, Group Node, Shape Node and Layer Chunks), but old files have always a pair of SIZE+XYZI for each "frame" (SIZE can be skipped of course).
So, SIZE+XYZI identifies a single frame.
Should I make a pull request or have you time to "fix" it in the next days? At least for old file format I mean...
load_frame
, or whatever you prefer, is a new Integer property in [0, +inf] defined in
class ImportVOX(bpy.types.Operator, ImportHelper):
load_frame: IntProperty(name="Frame Number To Load", default=0, min=0)
The XYZI
parser could be:
# MagicaVoxels frames are 0-based
current_frame = 0
while True:
...
elif name == 'XYZI':
# voxel data
if current_frame <= load_frame:
voxels.clear()
num_voxels, = struct.unpack('<i', vox.read(4))
for voxel in range(num_voxels):
voxel_data = struct.unpack('<4B', vox.read(4))
voxels.append(voxel_data)
else:
print("Skipping voxels in frame #{}".format(current_frame))
vox.read(s_self)
current_frame = current_frame + 1
Btw, should we keep track of changes and versioning in bl_info
and "change log" in the script?
Sorry, I forgot to modify the function call (new param load_frame=0
):
def import_vox(path, *, voxel_spacing=1, voxel_size=1,
load_frame=0, use_bounds=False, start_voxel=None, end_voxel=None,
use_palette=True, gamma_correct=True, gamma_value=2.2, use_shadeless=False):
In 0.98 it seems we have load_frame in [0, 29] (max 30 frames), but in release note I read:
0.98 - 10/22/2016
Frame-Based Animation Supports up to 24 frames animation
And about latest release 0.99, no more frame animations:
Limitations: will be improved in future version
- Not stable
- Export: can only export single models, cannot export models with offsets and names
- Render: no voxel shapes
- Animation: no frame based animation
Pushed commit a543e8f to incorporate these changes.
num_models
from PACK
chunk is used to clamp the value of load_frame
, makes the implementation very clean.
Have updated bl_info
to include a version, have made this version 2.1, and have tagged appropriately.
A lack of frame support in MV0.99 is annoying, but at least that resolves the question of how it and the new scene graph interact: they don't.
Shorlty: I think we should load the first (or a specific) frame instead of loading all of them (see
SIZE
andXYZI
for old file format).See also on YouTube: Magicavoxel Frame Based Animation - Tutorial
We are drawing all voxels, all frames now (deer.vox): first frame to the left (355 voxels) vs all frames (1415 voxels).
Here we can look for a "specific" frame voxels:
For example:
About error handling: