2020-09-12 13:10:05 -07:00
|
|
|
#include "vox_loader.h"
|
2021-07-31 10:48:47 -07:00
|
|
|
#include "../meshers/cubes/voxel_color_palette.h"
|
2020-09-14 11:33:02 -07:00
|
|
|
#include "../storage/voxel_buffer.h"
|
2021-07-31 10:48:47 -07:00
|
|
|
#include "vox_data.h"
|
2020-09-12 13:10:05 -07:00
|
|
|
|
2021-09-25 20:14:50 -07:00
|
|
|
Error VoxelVoxLoader::load_from_file(String fpath, Ref<VoxelBuffer> p_voxels, Ref<VoxelColorPalette> palette) {
|
|
|
|
ERR_FAIL_COND_V(p_voxels.is_null(), ERR_INVALID_PARAMETER);
|
|
|
|
VoxelBufferInternal &voxels = p_voxels->get_buffer();
|
2020-09-12 13:10:05 -07:00
|
|
|
|
2021-07-31 10:48:47 -07:00
|
|
|
vox::Data data;
|
|
|
|
Error load_err = data.load_from_file(fpath);
|
|
|
|
ERR_FAIL_COND_V(load_err != OK, load_err);
|
2020-09-12 13:10:05 -07:00
|
|
|
|
2021-07-31 10:48:47 -07:00
|
|
|
const vox::Model &model = data.get_model(0);
|
2020-09-12 13:10:05 -07:00
|
|
|
|
2021-09-25 20:14:50 -07:00
|
|
|
const VoxelBufferInternal::ChannelId channel = VoxelBufferInternal::CHANNEL_COLOR;
|
2021-07-31 10:48:47 -07:00
|
|
|
Span<const Color8> src_palette = to_span_const(data.get_palette());
|
2021-09-25 20:14:50 -07:00
|
|
|
const VoxelBufferInternal::Depth depth = voxels.get_channel_depth(VoxelBufferInternal::CHANNEL_COLOR);
|
2020-09-12 13:10:05 -07:00
|
|
|
|
2021-05-31 08:48:49 -07:00
|
|
|
Span<uint8_t> dst_raw;
|
2021-09-25 20:14:50 -07:00
|
|
|
voxels.create(model.size);
|
|
|
|
voxels.decompress_channel(channel);
|
|
|
|
CRASH_COND(!voxels.get_channel_raw(channel, dst_raw));
|
2020-09-12 13:10:05 -07:00
|
|
|
|
2021-07-31 10:48:47 -07:00
|
|
|
if (palette.is_valid()) {
|
2020-09-12 18:17:11 -07:00
|
|
|
for (size_t i = 0; i < src_palette.size(); ++i) {
|
|
|
|
palette->set_color8(i, src_palette[i]);
|
|
|
|
}
|
2020-09-12 13:10:05 -07:00
|
|
|
|
2020-09-12 18:17:11 -07:00
|
|
|
switch (depth) {
|
2021-09-25 20:14:50 -07:00
|
|
|
case VoxelBufferInternal::DEPTH_8_BIT: {
|
2021-07-31 10:48:47 -07:00
|
|
|
memcpy(dst_raw.data(), model.color_indexes.data(), model.color_indexes.size());
|
2020-09-12 18:17:11 -07:00
|
|
|
} break;
|
|
|
|
|
2021-09-25 20:14:50 -07:00
|
|
|
case VoxelBufferInternal::DEPTH_16_BIT: {
|
2021-05-31 08:48:49 -07:00
|
|
|
Span<uint16_t> dst = dst_raw.reinterpret_cast_to<uint16_t>();
|
2020-09-12 18:17:11 -07:00
|
|
|
for (size_t i = 0; i < dst.size(); ++i) {
|
2021-07-31 10:48:47 -07:00
|
|
|
dst[i] = model.color_indexes[i];
|
2020-09-12 18:17:11 -07:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Unsupported depth");
|
|
|
|
break;
|
|
|
|
}
|
2020-09-12 13:10:05 -07:00
|
|
|
|
2020-09-12 18:17:11 -07:00
|
|
|
} else {
|
|
|
|
switch (depth) {
|
2021-09-25 20:14:50 -07:00
|
|
|
case VoxelBufferInternal::DEPTH_8_BIT: {
|
2020-09-12 18:17:11 -07:00
|
|
|
for (size_t i = 0; i < dst_raw.size(); ++i) {
|
2021-07-31 10:48:47 -07:00
|
|
|
const uint8_t ci = model.color_indexes[i];
|
2020-09-12 18:17:11 -07:00
|
|
|
dst_raw[i] = src_palette[ci].to_u8();
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2021-09-25 20:14:50 -07:00
|
|
|
case VoxelBufferInternal::DEPTH_16_BIT: {
|
2021-05-31 08:48:49 -07:00
|
|
|
Span<uint16_t> dst = dst_raw.reinterpret_cast_to<uint16_t>();
|
2020-09-12 18:17:11 -07:00
|
|
|
for (size_t i = 0; i < dst.size(); ++i) {
|
2021-07-31 10:48:47 -07:00
|
|
|
const uint8_t ci = model.color_indexes[i];
|
2020-09-12 18:17:11 -07:00
|
|
|
dst[i] = src_palette[ci].to_u16();
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Unsupported depth");
|
|
|
|
break;
|
|
|
|
}
|
2020-09-12 13:10:05 -07:00
|
|
|
}
|
|
|
|
|
2021-07-31 10:48:47 -07:00
|
|
|
return load_err;
|
2020-09-12 13:10:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void VoxelVoxLoader::_bind_methods() {
|
|
|
|
ClassDB::bind_method(D_METHOD("load_from_file", "fpath", "voxels"), &VoxelVoxLoader::load_from_file);
|
|
|
|
}
|