-
Notifications
You must be signed in to change notification settings - Fork 236
Support importing/exporting Voxlap format (.vxl and .kv6) #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is the second time someone request the kv6 files support, so I guess I will have a look at it. Do you have any resources on the file format? |
As Ace of Spades is not open source, I looked in OpenSpades source code. You can also look the KV6Importer and KV6Exporter of VoxelShop. If you want more information about the KV6 file format (maybe some documentation), you can ask to the OpenSpades maintainer. He answers quickly. |
Thanks, I will have a look at that. |
Only loading for the moment. |
Nice ! If reading/modifying Ace of Spades/OpenSpades maps is easy and efficient, so you just made the new map editor ! Actually, mapping for those games is done using Voxed (proprietary, old, hard to use and only available on Windows) or in-game (not really easy as you can only move using the game physics). |
I will try to fix those issues. Also I think the navigation with large models has to be improved, zooming is particularly bad for the moment. |
You are right about navigation in large models. But I think it will be another issue ticket. I'm surprised that modifying large models does not require more resources than currently ! VoxelShop (which I used to modify OpenSpades models until now) does not accept large models. Nice work! |
Thanks, one of the goal for goxel is to support unbounded voxel models, so I made sure to optimize for this case, even though the interface is not very good in that regard. |
I made a comparison between Terravox and Goxel. Terravox was made by the author of OpenSpades to make terrain height-maps. So, it handles VXL format natively (while writing this sentence, I think it's also a good reference about VXL format handling). Supposing that the axes have the same orientation in both softwares and that, obviously, Terravox correctly handles the VXL file format, we can see that, in Goxel:
Concerning the Z axis, Terravox handles it as the Ace of Spades/OpenSpades games do it: |
I fixed the orientation and clipping bug. For the axis, for the moment prefer to stay with goxel default (Z up), though it might make sense to support different referential from a setting in the future. |
I just added support for saving as vxl. It's totally untested, so there might be bugs or corrupted files. |
I'll close this issue not that we have basic support. If there are specific bugs with voxlap export it will be better to open a new issue for each problem. |
Why are .vxl maps not saved properly? I'm new to Goxel, started using it mainly to create maps for AoS. The problem is the following: when I import a working map in the Goxel, adjust the dimensions and export it back into a new .vxl, I get a file with size completely different from the original one (see the screenshot below). Moreover, the resulting map isn't working on the server. The server simply doesn't let me in, throwing an error. How did @damienflament manage to use Goxel to create .vxl maps? Is there something I don't know? |
Moreover Terravox cannot open this map too. Very disappointing |
Hello @OverwhelmingFire. Yes the voxlap support is only as good as it gets, since I never used AoS. Can you give a bit more information? What error does the server give? Can you attach a test image that I can try? |
I created another .vxl map to explain in details (I have already deleted the first one...). It's very simple and is completely filled with blocks (512x512x64) despite just one small area in the middle with a single layer of blocks (which by the game is interpreted as water). Then I opened it in Goxel, went to the Image tab and resized the "canvas": When I saved it under a different name, and it's seen that the size of the map become 4.5 KB. I opened both files in a hex editor to compare the structure, and it definitely differs, though I cannot understand how exactly since I don't know the structure of .vxl files. This is a screenshot of how it looks like on the server (I'm staying at the edge of the central "pit": This is a screenshot of the server logs when I'm trying to enter the Goxel map version: Here I attach the maps: |
Sorry, I miss-mentioned you with @damienflament. It's very late in my country, and the attention decreases in night |
Has anyone ever gotten this to work with OpenSpades? Would be really nice to use Goxel as a level editor for it. |
Hi, I've checked the hexdumps of the .vxl files in the attachment above. This is the one that works (saved by Terravox):
And the one which doesn't (saved by Goxel):
Considering the differences I'm pretty certain even though they are both called '.vxl', these two files are not the same file format (assuming both files are storing the same voxel image, which they should). Check out:
I think the main problem here is, there are no magic bytes to identify the format, and it looks like there's no header which could store the dimensions either. So different tools can (and they do) save completely different files by the same extension. BTW, according to this, the .kv6 format for example has such magic (0x6c78764b) and header, so trying to use the KV6Importer or KV6Exporter for these format obviously won't work either. I could fix this in Goxel using vxl.cpp in Terravox, but I'd suggest to use other format in OpenShades instead, something that has magic bytes, proper dimensions and saved correctly by Goxel in the first place (.kv6 maybe? Or .vox?). And I'm also certain OpenShades' developers are more willing to accept PRs than guillaumechereau (who didn't do anything about this for more than 5 years), so you have much better chances there. Or just keep using Terravox, it looks like a FOSS Qt app to me, should have no issues. Cheers, |
Taking a closer look at Terravox's source, its .vxl format only supports 512 x 512 x 64 sized "canvas", nothing else is valid. This could be very well the reason for the incompatibility. Cheers, |
There is this C library what might be possible to include in Goxel for .vxl read and write support support: Also exporting .kv6 files would be very useful for making OpenSpades models. |
Turns out this has been done already: xtreme8000@71efe67 |
@poVoq: libvxl does not respect the original 512 x 512 x 64 limitations (it saves arbitrary volumes and has some heuristic to detect dimensions on load). Digging deeper, one thing is certain, the example C code in the original Ace of Spades map spec (the same code that Goxel uses) doesn't work at all and is buggy as hell. It saves incorrect lengths, often overflows, and sometimes it does not store any color data after the lengths packet header (probably this was the reason for the client crash). I've tried to fix the example code in the spec, and it is almost perfect now, here's a diff of Terravox saved map.vxl from above loaded and saved with Goxel and compared with the original:
As you can see, there's only one difference in one of the packet lengths at offset ca. 2.2M ( There were several problems:
TODO: figure out why there's a garbage at the end diff --git a/src/formats/vxl.c b/src/formats/vxl.c
index c2a3ba7a..1b863182 100644
--- a/src/formats/vxl.c
+++ b/src/formats/vxl.c
@@ -1,6 +1,7 @@
/* Goxel 3D voxels editor
*
* copyright (c) 2016 Guillaume Chereau <[email protected]>
+ * copyright (c) 2022 vxl export fixes (still not perfect) bzt <bztsrc@gitlab>
*
* Goxel is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
@@ -90,8 +91,8 @@ static int vxl_import(image_t *image, const char *path)
color = (uint32_t*)(v + 4);
for (z = top_color_start; z <= top_color_end; z++) {
- CHECK(z >= 0 && z < d);
- swap_color(*color++, cube[AT(x, y, z)]);
+ if(z >= 0 && z < d)
+ swap_color(*color++, cube[AT(x, y, z)]);
}
len_bottom = top_color_end - top_color_start + 1;
@@ -132,9 +133,11 @@ static int vxl_import(image_t *image, const char *path)
static int is_surface(int x, int y, int z, uint8_t map[512][512][64])
{
if (map[x][y][z]==0) return 0;
+/*
if (x == 0 || x == 511) return 1;
if (y == 0 || y == 511) return 1;
if (z == 0 || z == 63) return 1;
+*/
if (x > 0 && map[x-1][y][z]==0) return 1;
if (x+1 < 512 && map[x+1][y][z]==0) return 1;
if (y > 0 && map[x][y-1][z]==0) return 1;
@@ -215,7 +218,7 @@ void write_map(const char *filename,
bottom_colors_end = k;
// now we're ready to write a span
- top_colors_len = top_colors_end - top_colors_start;
+ top_colors_len = top_colors_end - top_colors_start + 1;
bottom_colors_len = bottom_colors_end - bottom_colors_start;
colors = top_colors_len + bottom_colors_len;
@@ -223,10 +226,10 @@ void write_map(const char *filename,
if (k == MAP_Z)
fputc(0,f); // last span
else
- fputc(colors+1, f);
+ fputc(colors, f);
fputc(top_colors_start, f);
- fputc(top_colors_end-1, f);
+ fputc(top_colors_end, f);
fputc(air_start, f);
for (z=0; z < top_colors_len; ++z)
@@ -244,23 +247,26 @@ static int export_as_vxl(const image_t *image, const char *path)
uint8_t (*map)[512][512][64];
uint32_t (*color)[512][512][64];
const mesh_t *mesh = goxel_get_layers_mesh(image);
- mesh_iterator_t iter = {0};
uint8_t c[4];
- int x, y, z, pos[3];
+ int x, y, z, pos[3], bbox[2][3];
assert(path);
+ if(!mesh_get_bbox(mesh, bbox, true))
+ return -1;
+
map = calloc(1, sizeof(*map));
color = calloc(1, sizeof(*color));
- for (z = 0; z < 64; z++)
- for (y = 0; y < 512; y++)
- for (x = 0; x < 512; x++) {
- pos[0] = 256 - x;
- pos[1] = y - 256;
- pos[2] = 31 - z;
- mesh_get_at(mesh, &iter, pos, c);
- if (c[3] <= 127) continue;
- (*map)[x][y][z] = 1;
- memcpy(&((*color)[x][y][z]), c, 4);
+
+ mesh_iterator_t it = mesh_get_iterator(mesh, MESH_ITER_SKIP_EMPTY);
+ while(mesh_iter(&it, pos)) {
+ mesh_get_at(mesh, &it, pos, c);
+ x = bbox[1][0] - 1 - pos[0];
+ y = pos[1] - bbox[0][1];
+ z = bbox[1][2] - 1 - pos[2];
+ if(x >= 0 && x < 512 && y >= 0 && y < 512 && z >= 0 && z < 64 && c[3] > 0) {
+ (*map)[x][y][z] = 1;
+ memcpy(&((*color)[x][y][z]), c, 4);
+ }
}
write_map(path, *map, *color);
free(map); Cheers, |
Hi, I've added a little patch to the libvxl Goxel version too, so no matter which one @guillaumechereau chooses to be merged, OpenSpades compatibility guaranteed. :-) The map.vxl (from above) loaded and saved with this libvxl Goxel has the same size, but it looks like there's a little hiccup with the alpha channel (I haven't changed anything in libvxl, just used fixed dimensions). I don't know if this matters or not.
Cheers, Ps: it was a lot easier to add fixed sized maps with libvxl than to figure out why does the original AoS example code add extra bytes to the file... |
Closing this because I think this should work now. Feel free to reopen if needed. |
It should be great to allow importing/exporting files used by the games Ace of Spades/OpenSpades (which use the Voxlap engine).
The map files (*.vxl) might be too large for editing in Goxel (they are actually describing a volume of 512x512x64 voxels).
But the models files (*.kv6) are already editable with VoxelShop. Supporting this format in Goxel should be great !
The text was updated successfully, but these errors were encountered: