Zylann / godot_voxel

Voxel module for Godot Engine
MIT License
2.7k stars 251 forks source link

Trouble using VoxelVoxLoader #246

Open brodcoli opened 3 years ago

brodcoli commented 3 years ago

Hello, I'm wanting to load MagicaVoxel .vox models into a VoxelTerrain

I noticed there is VoxelVoxLoader and this looks like what I need, but I'm unsure how to get the voxel buffer and color palette from a VoxelTerrain to pass into load_from_file I looked through the docs, but I can't figure out how to retrieve this data from a VoxelTerrain

How do I load .vox models with VoxelVoxLoader?

Zylann commented 3 years ago

That class only lets you load a .vox into a VoxelBuffer, at the moment it isn't integrated to the terrain system.

You can obtain a mesh from it using code like this:

extends Node

const _materials = [
    preload("./opaque_color_material.tres"),
    preload("./transparent_color_material.tres")
]

onready var _mesh_instance : MeshInstance = $MeshInstance
var _mesher = VoxelMesherCubes.new()

func _ready():
    _generate()

func _generate():
    var voxels = VoxelBuffer.new()
    voxels.set_channel_depth(VoxelBuffer.CHANNEL_COLOR, VoxelBuffer.DEPTH_8_BIT)
    var palette = VoxelColorPalette.new()

    var loader = VoxelVoxLoader.new()
    var err = loader.load_from_file("res://local_tests/vox/monu1.vox", voxels, palette)
    if err != OK:
        push_error(str("Error: ", err))
        return

    _mesher.palette = palette
    _mesher.color_mode = VoxelMesherCubes.COLOR_MESHER_PALETTE

    var padded_voxels = VoxelBuffer.new()
    padded_voxels.create(
        voxels.get_size().x + 2, 
        voxels.get_size().y + 2, 
        voxels.get_size().z + 2)
    padded_voxels.set_channel_depth(
        VoxelBuffer.CHANNEL_COLOR, voxels.get_channel_depth(VoxelBuffer.CHANNEL_COLOR))
    padded_voxels.copy_channel_from_area(
        voxels, Vector3(), voxels.get_size(), Vector3(1, 1, 1), VoxelBuffer.CHANNEL_COLOR)

    var mesh = _mesher.build_mesh(padded_voxels, _materials)

    _mesh_instance.mesh = mesh

You might also be able to paste the buffer into a VoxelTerrain using VoxelTool.paste() but I never tested doing that yet. Also this isn't optimized for very large .vox files (256x256x256 for example).

brodcoli commented 3 years ago

Oh I see now, thanks for the example and for the idea I'll try out pasting the buffer to a VoxelTerrain, but obtaining a mesh directly from a .vox file is also very useful, thank you very much!