Skip to content
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

Design and Implement vox2schematic tool #99

Closed
acs opened this issue Jun 14, 2020 · 53 comments
Closed

Design and Implement vox2schematic tool #99

acs opened this issue Jun 14, 2020 · 53 comments
Labels
Framework Work in the framework

Comments

@acs
Copy link
Contributor

acs commented Jun 14, 2020

This tool must be used to import voxels and meshes into McThings (schematics format).

https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox.txt
https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox-extension.txt

The primary goal is to import from vox format fo schematic. For that:

@acs
Copy link
Contributor Author

acs commented Jun 14, 2020

Related to this one: #100

@acs acs added the Framework Work in the framework label Jun 14, 2020
@acs
Copy link
Contributor Author

acs commented Jun 14, 2020

Maybe we should extend:

https://gitlab.com/bztsrc/mtsedit/blob/master/docs/batch.md

so it exports Schematic format. And that's all!

Add a

-S: output to Schematic

It is implemented in C language, like GNOME :)

@acs
Copy link
Contributor Author

acs commented Jun 14, 2020

vox has several importers at:

https://github.com/Zarbuz/FileToVox

So the writting of vox files is well covered here.

And probably also the reading if they have good tests. It is implemented in C# and here we have the reader and writer:

https://github.com/Zarbuz/FileToVox/tree/master/SchematicToVoxCore/Vox

In this tool, it seems all the formats are comnverted to Schematics and the Schematics is converted to Vox. In McThings, my guess is that we will use also Schematics format as the common one. Why? Becase it has solid tools to process it (NBTtools) and the format is simple and flexible and complete.

@acs
Copy link
Contributor Author

acs commented Jun 14, 2020

The writing to vox format seems to be pretty easy:

https://gitlab.com/bztsrc/mtsedit/-/commit/80569a64c0c91080699f46fd9a1302b14b1847b2

and it uses the Y, X, Z order as in schematics.

it is writing a header, the data and the palette. If it is so easy to do, probably we can just implement it from scratch and later, create a library with support for reading and writing VOX files like the NBT library.

@acs
Copy link
Contributor Author

acs commented Jun 14, 2020

The process for a guy doing the same for Three.js: https://luciopaiva.com/magicavoxel-threejs-howto/

@acs
Copy link
Contributor Author

acs commented Jun 14, 2020

VOX uses RIFF format, and in Python there is a module built-in for reading this kind of data:

https://docs.python.org/3.8/library/chunk.html

Great!

So we can do a clean job reading and writing VOX files.

@acs
Copy link
Contributor Author

acs commented Jun 14, 2020

So my conclusion is that VOX format is so easy to read and write that:

  • Implement reader and writer for Python using the RIFF Python module. Support both vox formats if possible.
  • The schematic writer is already implemented in McThings, so we just need to read the VOX file, map the voxels color and material to a Minecraft block (using mcpi.block) and save all in schematic format.
    *The parsing will be implemented with objects representing the core concepts:
    • Models
    • Material
    • Palette
    • Scene
    • World

So we have a plan!

@acs acs changed the title Design and Implement mcthings_importer Design and Implement vox2schematic tool Jun 14, 2020
@acs
Copy link
Contributor Author

acs commented Jun 14, 2020

The name of the first library was vox-io. Not bad. I will use voxpy probably.

Screenshot from 2020-06-15 00-40-38

@acs
Copy link
Contributor Author

acs commented Jun 17, 2020

https://github.com/RichysHub/MagicaVoxel-VOX-importer Blender importer for VOX format implemented in Python. A good reference.

And also in https://github.com/jpaver/opengametools they have a reader and writter implemented in C++ based on a vox parser C++ library.

For JS: https://github.com/dgoemans/VoxRenderer

@acs
Copy link
Contributor Author

acs commented Jun 18, 2020

Some experiences supporting the new format:

RichysHub/MagicaVoxel-VOX-importer#6

@acs
Copy link
Contributor Author

acs commented Jun 25, 2020

A very useful command to see the structure of the vox file:

(venv) strings vxs.vox 
VOX 
MAIN
SIZE
XYZI
nTRN
nGRP
nTRN-
-1 -1 2nSHP
LAYR
_name
LAYR
_name
LAYR
_name
LAYR
_name
LAYR
_name
LAYR
_name
LAYR
_name
LAYR
_name
RGBA
MATL
_type
_diffuse
_weight
_rough
_spec
_spec_p
_ior
_att
-0.5
_flux
_ldr
0MATL
....

@acs
Copy link
Contributor Author

acs commented Jun 25, 2020

The proposed reading process for chunks in python lib:

«Usually an IFF-type file consists of one or more chunks. The proposed usage of the Chunk class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end of the file, creating a new instance will fail with an EOFError exception.»

Let's try to follow it! Start a new chunk given the position of the chunk on the file.

A nice example doing just that here: https://www.programcreek.com/python/example/93077/chunk.Chunk

The key is to create Chunk with the file positioned correctly for reading the next chunk. Part of:

https://github.com/pyblish/pyblish-win/blob/master/lib/Python27/Lib/wave.py

And indeed this is a pretty interesing project: https://pyblish.com/ «Pyblish is what enables our artists to focus more on the artistic barrier of raising quality instead of the technical one whilst maintaining a pipeline that raises the bar for both.»

@acs
Copy link
Contributor Author

acs commented Jun 25, 2020

Ok, let's try to describe at high level the format in the current version of the file (vox-extension) using the strings command output.

@acs
Copy link
Contributor Author

acs commented Jun 25, 2020

So if we want to load 1 model and only the cubes, our focus must be the Model Chunk:

5. Chunk id 'SIZE' : model size
-------------------------------------------------------------------------------
# Bytes  | Type       | Value
-------------------------------------------------------------------------------
4        | int        | size x
4        | int        | size y
4        | int        | size z : gravity direction
-------------------------------------------------------------------------------


6. Chunk id 'XYZI' : model voxels
-------------------------------------------------------------------------------
# Bytes  | Type       | Value
-------------------------------------------------------------------------------
4        | int        | numVoxels (N)
4 x N    | int        | (x, y, z, colorIndex) : 1 byte for each component
-------------------------------------------------------------------------------

and the palette

7. Chunk id 'RGBA' : palette
-------------------------------------------------------------------------------
# Bytes  | Type       | Value
-------------------------------------------------------------------------------
4 x 256  | int        | (R, G, B, A) : 1 byte for each component
                      | * <NOTICE>
                      | * color [0-254] are mapped to palette index [1-255], e.g : 
                      | 
                      | for ( int i = 0; i <= 254; i++ ) {
                      |     palette[i + 1] = ReadRGBA(); 
                      | }
-------------------------------------------------------------------------------

@acs
Copy link
Contributor Author

acs commented Jun 25, 2020

In the first iteration the goal is to support the last version of the format, but probably, it is easy to support older formats.

@acs
Copy link
Contributor Author

acs commented Jun 25, 2020

Great, it seems it is going to be easy and clean to support VOX format. The code is taking shape at:

https://github.com/acs/mcthings/blob/99-vox2schematics/mcthings/vox.py

@acs
Copy link
Contributor Author

acs commented Jun 26, 2020

Great, it is a bit tricky to use the chunk python lib to read the vox file, but once I know how to do it, it will be much maintainable having the Chunk concept supported in the logic. 2h aprox to have a first working version.

@acs
Copy link
Contributor Author

acs commented Jun 28, 2020

Ok, now we can read the blocks and the colors from a MagicaVoxel file. Cool! Now it is time to map it to Minecraft. And this is a tough problem because we don't have all colors in Minecraft. Using wool we can replicate partially the colors.

https://www.stuffaboutcode.com/p/minecraft-api-reference.html

Data Values of blocks:
WOOL:
0: White
1: Orange
2: Magenta
3: Light Blue
4: Yellow
5: Lime
6: Pink
7: Grey
8: Light grey
9: Cyan
10: Purple
11: Blue
12: Brown
13: Green
14: Red
15: Black

So we need to map the RGBA colors to this ones. The best thing is to have a Minecraft palette in MagicaVoxel to create the models using them. In this case, let's do a hack:

ee 00 00 is 14.

@acs
Copy link
Contributor Author

acs commented Jun 28, 2020

Ok, here we go:

Screenshot from 2020-06-28 10-16-32

from

Screenshot from 2020-06-28 10-19-11

@acs
Copy link
Contributor Author

acs commented Jun 28, 2020

mv2mc

@acs
Copy link
Contributor Author

acs commented Jun 28, 2020

Colors from 15 to 0:

mc_colors

we need to create a magicavoxel palette with them (we need the hex codes for them).

COLORS = [
        "White",
        "Orange",
        "Magenta",
        "Light Blue",
        "Yellow",
        "Lime",
        "Pink",
        "Grey",
        "Light grey",
        "Cyan",
        "Purple",
        "Blue",
        "Brown",
        "Green",
        "Red",
        "Black"
    ]

https://gaming.stackexchange.com/questions/47212/what-are-the-color-values-for-dyed-wool

• White - FFe4e4e4
• Orange - FFea7e35
• Magenta - FFbe49c9
• Light Blue - FF6387d2
• Yellow - FFc2b51c
• Lime Green - FF39ba2e
• Pink - FFd98199
• Dark Gray - FF414141
• Light Gray - FFa0a7a7
• Cyan - FF267191
• Purple - FF7e34bf
• Blue - FF253193
• Brown - FF56331c
• Green - FF364b18
• Red - FF9e2b27
• Black - FF181414

So our next step is to create a palette in MagicaVoxel with this colors.

@acs
Copy link
Contributor Author

acs commented Jun 28, 2020

But before working at the color detail, let's check all is working with some models in vox format.

One of our goals is to support the loading of:

https://github.com/mikelovesrobots/mmmm

And maybe this is the old version format. The goal is to support it also. So let's work on that.

Let's play with this one wich is 8 (z) x 4 (x) x 11 (y): 332 blocks. alien_engi1a

Screenshot from 2020-06-28 18-05-06

It has 4 colors: blue, black, gray and light gray. So an accurate job could be done!

It is a 6 years old model, and I love to support this old models!!! Let's do it 💯

The old format is simpler:

(venv) strings alien_engi1a.vox 
VOX 
MAIN
SIZE
XYZI
RGBA

To check the correct loading of the palette we can do it in MV. For each palette there are 32 * 8 = 256 colors.

And we can check the colors in MV:

Screenshot from 2020-06-28 21-08-22

To check the full palette:

Screenshot from 2020-06-28 21-01-10

In this palette the first color is (index 1): ffffff . The index 2: ffffcc. index 3: ffff99.

and the last color is index 255 is 111111. The 249 is aaaaaa (256 can not be selected and it is not part of the palette). So the palette goes from 0 to 254 (at least in the old version).

¿Is that the default one? I think so (but in the file, index 1 is 000000, and the colors are in different order: ffff99 is 99ffff.

Let's check that we are reading the palette correctly (I am pretty sure there are no issues with the blocks).

@acs
Copy link
Contributor Author

acs commented Jun 28, 2020

The results are promising.

alien_engi1a_mc

As expected we need to fix the colors. But we are in the right path!

@acs
Copy link
Contributor Author

acs commented Jun 28, 2020

Ok, before putting all focus in the colors transformation, let's try to conversion to Schematic. This is something already available in McThings, so just testing the plumbing.

The goal is to generate the Voxelers logo as a Schematic.

Screenshot from 2020-06-28 23-23-45

Loaded from a Schematic. For some reason we are exporting 24 blocks instead of 6. We need to review it, but it is working in the dev branch for vox support.

Screenshot from 2020-06-28 23-26-55

The problem is "x-axis" that must be 1 and it is 4. I will recheck it.

Screenshot from 2020-06-29 05-29-12

So the problem is the self.position. If we use init_pos and end_pos for schematic extraction, it will work. But why self.position is not init_pos? Let's review.

It is working nicely. Why? Let's take a look to MV:

Screenshot from 2020-06-29 05-41-28

The position of z is +3, x +1 and y +0- So the blocks go from z:0, 2 x:0, 3 y:0,1 (3 x 4 x 2 = 24). So the schematic is perfect. In order to avoid the offset, we need to create in MV without offset.

Screenshot from 2020-06-29 05-50-20

And using this vox model we get in the schematic:

2020-06-29 05:51:12,466 Schematic: Exporting blocks: 6

And we get the right number of blocks (3 empty blocks, and 3 red blocks)

@acs
Copy link
Contributor Author

acs commented Jun 29, 2020

Ok, just pending:

  • Fix the flipped
  • Review the code to refactor if if needed
  • Add tests
    • Number of voxels imported/exported
    • Colors
  • Define a demo plan to show the possibilities of the MV and MC integration
    • use the shaders in MV to create cool regions in MC
    • use the minibots to create a museum with them in MC
  • Implement a command line tool
  • Dissemination of the new feature in the forums

@acs
Copy link
Contributor Author

acs commented Jun 30, 2020

In order to fix the flip issue, the best approach is to implement the flip operation in mcthings: #112

But we have not a flip issue. It is just to look to the wall from the right side (the same side we use in MV).

wool_wall_ok

But, is it the same for the alien robot? No

alien_flip

And we have the same issue when going through vox->obj->binvox->schematic

The problem is that in general x grows in this direction >--->---> but in MC it grows in <----<-----< (and the same for z). So we need to flip.

@acs
Copy link
Contributor Author

acs commented Jun 30, 2020

Much better now with the flip operation implemented.

Screenshot from 2020-06-30 08-33-17

@acs
Copy link
Contributor Author

acs commented Jun 30, 2020

Ok, let's play with colors and then review code, improve tests, prepare demos and implement the command line tool and disseminate.

@acs
Copy link
Contributor Author

acs commented Jun 30, 2020

Let's try to reproduce the alien colors in Minecraft. For doing it:

  • Open the alien vox model
  • Load the Minecraft palette
  • Change colors to one of the 16 from Minecraft palette
  • Save the vox model
  • Import it in McThings and check the results

This is a general workflow to be done each time you want to have valid colors inside Minecraft.

Also, we can add more colors using other blocks in Minecraft:

  • Red Stone
  • Gold
  • Diamond
  • ...

@acs
Copy link
Contributor Author

acs commented Jul 1, 2020

But first, let's check if flip_z is needed also. And let's do it by default when loading VOX data for both use cases. Let's play with the model veh_ambulance.vox:

Screenshot from 2020-07-01 05-15-57

Screenshot from 2020-07-01 05-23-48

@acs
Copy link
Contributor Author

acs commented Jul 1, 2020

Ok, it seems there are no flipping issues in z-axis. Let's try to recreate the ambulance colors.

For doing it, let's use the MC palette y MV.

Screenshot from 2020-07-01 05-27-12

Screenshot from 2020-07-01 05-28-12

To the left the original one, to the right using the MC wool colors:

Screenshot from 2020-07-01 05-37-59

and the result in MC:

Screenshot from 2020-07-01 05-41-24

The dark gray wool is getting red wool for some reason. But the rest of the colors are ok. Bug found: the grey in this region is not the MC one, but the empty one without color!

Screenshot from 2020-07-01 05-54-12

@acs
Copy link
Contributor Author

acs commented Jul 1, 2020

Ok, just pending:

  • Implement the command line tool
  • Add unit testing using the in memory version
  • Create a video doing the ambulance with colors

@acs
Copy link
Contributor Author

acs commented Jul 1, 2020

Command line tool

vox2schematic:

  • Input file to convert
  • Optional output file

In the first version that's all. In new version we can add an optional map from MV colors to MC blocks/wool colors.

The tool will work from memory version of the models, so it must be pretty fast. Test it with the 400 models from Mike.

@acs
Copy link
Contributor Author

acs commented Jul 1, 2020

Goals:

@acs
Copy link
Contributor Author

acs commented Jul 1, 2020

Ok, let's create the tool: vox2schematic. At some point it could be also interesting the schematic2vox, but I think it is less interesting.

@acs
Copy link
Contributor Author

acs commented Jul 1, 2020

Ok, right now we are collecting the data in build_schematic_nbt from the data in the renderer. But this information is available in memory also, because we are using the Minecraft format for the memory schemas. So we need to have at least a method build_schematic_nbt_from_memory that uses the data in memory and that does not try to collect the data from the renderer.

But we are pretty close to have the feature implemented.

@acs
Copy link
Contributor Author

acs commented Jul 2, 2020

Ok, the script is working:

(venv) bin/vox2schematic.py ~/devel/mmmm/vox/obj_house6.vox -o tests/schematics/obj_house6.schematic

It is slow, but increase the performace should be easy to reach a reasonable performance.

Screenshot from 2020-07-02 18-55-42
Screenshot from 2020-07-02 18-55-30

For example, with this house with 78336 blocks, it has not finished yet after 5 minutes. So let's implement the first improvement.

Fixed the performance issue:

(venv) bin/vox2schematic.py ~/devel/mmmm/vox/obj_house6.vox -o tests/schematics/obj_house6.schematic
2020-07-02 19:12:20,855 Vox input file: /home/adelcastillo/devel/mmmm/vox/obj_house6.vox
2020-07-02 19:12:20,855 Schematic output file: tests/schematics/obj_house6.schematic
2020-07-02 19:12:22,006 Schematic: Exporting blocks: 78336
2020-07-02 19:12:22,053 Creating the memory cache with positions
2020-07-02 19:12:22,119 Done memory cache with positions
2020-07-02 19:12:22,552 Schematic export finished in 0.55 secs

and the schematic result is ...

Screenshot from 2020-07-02 19-15-57
Screenshot from 2020-07-02 19-15-25

@acs
Copy link
Contributor Author

acs commented Jul 2, 2020

5 minutes investment colouring the house:

Screenshot from 2020-07-02 19-21-51
Screenshot from 2020-07-02 19-28-38

and the result in Minecraft:

(venv) bin/vox2schematic.py ~/devel/voxels/MagicaVoxel-0.99.5.1-win64/export/obj_house6-mc.vox -o tests/schematics/obj_house6-mc.schematic
....
    voxel_color = self.palette[voxel.color_index]
IndexError: list index out of range

Found a bug. Let's fix it! The format of the file is different, We need to improve our parser. The problem is that for some reason during colouring two models were created. Right now, only one model is supported. Fixed.

And the result house:

Screenshot from 2020-07-03 06-25-34
Screenshot from 2020-07-03 06-24-53

@acs
Copy link
Contributor Author

acs commented Jul 3, 2020

The main issue with this house is that it is for giants. So it is not at the right dimension for MC. So we need to work in MV at a smaller scale so the creations are natural inside the MC world. But this can be done. But it is a new way to create inside MV: for Minecraft. And also, the models are filled, so the house is a thick block.

So this kind of models are not useful in Minecraft to interact with them. So the question is .... is it better to create in MV that inside MC directly? My guess is that yes, but we need to improve the MC blocks can be used inside MV, and there are things that will be done better inside MC.

@acs
Copy link
Contributor Author

acs commented Jul 3, 2020

Ok, so next steps:

  • Add unit testing using the in memory version
  • Release the tool
  • Create a video doing the ambulance with colours
  • Use the MV shaders to create regions and import them into MC

@acs
Copy link
Contributor Author

acs commented Jul 3, 2020

Tool included in 0.51.1 and working.

Next step is to put focus in the tests!!

@acs
Copy link
Contributor Author

acs commented Jul 3, 2020

About the tool, we need to capture the exceptions if the format is not the expected one: only one model for legacy and current format.

@acs
Copy link
Contributor Author

acs commented Jul 3, 2020

Hay muchos conversores de otros formatos a VOX (https://github.com/Eisenwave/voxel-io y otros proyectos), así que todos ellos los podríamos llevar a Minecraft.

@acs
Copy link
Contributor Author

acs commented Jul 3, 2020

More repos with models to test the conversor: https://www.mediafire.com/folder/a0znmricqxlkz/Free_Voxels

@acs
Copy link
Contributor Author

acs commented Jul 3, 2020

Should we add the multi model support? Probably not in the first iteration: it is complex to have useful results with complete scenes ... but it is pretty alignet with McThings. The scene could be broken in schematics and added individually.

@acs
Copy link
Contributor Author

acs commented Jul 3, 2020

Probably if we can not convert a color to the right Minecraft one, it is better to leave the block as a grey one (or stone or a fixed block).

@acs
Copy link
Contributor Author

acs commented Jul 3, 2020

Ok, next steps:

@acs
Copy link
Contributor Author

acs commented Jul 4, 2020

Using an improved version of the automatic coloring based on the above proposal the results are:

Screenshot from 2020-07-04 09-08-18
Screenshot from 2020-07-04 09-11-47
Screenshot from 2020-07-04 09-08-36
Screenshot from 2020-07-04 09-12-00
Screenshot from 2020-07-04 09-12-22

@acs
Copy link
Contributor Author

acs commented Jul 5, 2020

Ok, time to close this ticket! The tool is ready, with doc and tweeter dissemination also done. Let's see the impact.

https://github.com/Voxelers/mcthings/tree/develop/bin

@HelixCreations
Copy link

Hey acs, I was wondering were you able to get it to scale for a 1 to 1 ratio. For instance, seeing the house it was huge, did you get it to scale in MC?

Also, does your tool support each different type of block?

I have been trying to find something that will scale my 3d assets correctly in MC for years.

As I want that one meter in blender or just magic voxel to MC.

Would you know where I could go for something like this? Thanks.

@acs
Copy link
Contributor Author

acs commented Aug 30, 2020

Hi @HelixCreations ,

Hey acs, I was wondering were you able to get it to scale for a 1 to 1 ratio. For instance, seeing the house it was huge, did you get it to scale in MC?

No, I have not found a way to fix the scale. And I think that it is not possible to fix this problem in a general way. In order to create models for MC with MV, you need to work in MC scale in MV.

Also, does your tool support each different type of block?

Each different type of block in MC? No, the goal is to support the designs that can be created in MV. And in MV you have:

  • Blocks
  • Colors
  • Materials

Right now the support is pretty basic. Support the colors using the wood colors in MC. And if you have selected a specific material in MV that exists in MC, use the material to define the block in MC instead of the color (for example, glass material).

I have been trying to find something that will scale my 3d assets correctly in MC for years.

The problem is that blocks in MC are fixed to 1x1x1 meter and you can not change that. So you need to create your models with this limitation in mind. You can not have a better resolution in MC.

As I want that one meter in blender or just magic voxel to MC.

In MV just work with this requirement in mind when you create the models: the voxel are 1x1x1 meter.

In blender, I want to play with remesh but at the end, the problem is the same. You can not work in MC with more
detailed models.

Would you know where I could go for something like this? Thanks.

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Framework Work in the framework
Projects
None yet
Development

No branches or pull requests

2 participants