Home       About Me       Contact       Downloads       Part 33    Part 35   

Part 34: Beyond Cubes

September 25, 2011

Fig 1: Minecraft plants
Nearly everything in Minecraft is a cube, but there are other types - plants and torches, for example.

Up to now, I've been handling different shapes in my code. There were cubes, half-high cubes (slabs), columns (used for railings) and spheres (used for torches). Anything else, including cube styles I hadn't gotten around to, was rendered with a large white and blue "B" texture. When I put together the Minecraft viewer in Part 32, this left a lot out of some Minecraft landscapes.

I needed to put some other types, like stairs, or the very short bricks used for snow, into the code. There are a lot of these, and I want to render them efficiently. This includes checking to see if I can eliminate obscured sides. But I didn't want to do that with all the other brick types needed. I didn't even want to draw some of the cubical bricks (like crafting tables, chests or beds) as cubes. I can afford a bit of general graphics for low-frequency bricks and make them look nicer.

My plan was to introduce some simple file format where I could store vertex information for brick types. I would initialize these with hand-generated vertex lists. Later, I could support a real graphics format and take 3D shapes from a graphics editor. I didn't think it was time to do that yet.

The simplest solution would be to imitate Minecraft and just use 2D images for bricks like ladders, mine cart rails, plants, etc. As you can see in Figure 1, a plant is just two crossed rectangles with a plant image on them. Designing quality low-res images is an art though, and I ran out of patience with it.

Fig 2: Google SketchUp design
I downloaded Google SketchUp and tried to create some simple shapes with it. SketchUp supports Collada, which is an XML-based graphics interchange format. In those files, you can see the coordinate data for each vertex in the text. I thought I could just copy that coordinate data into my trivial vertex format and be done.

As it turned out, when I started doing more with SketchUp, the output files became more complex. I finally wrote a parser for Collada (.dae) files that creates my little vertex list format. With some more code in the viewer to draw brick types from these vertex lists, I now have a richer Minecraft viewer. I've spent the week learning how to use SketchUp and doing all the brick types I needed. See Figure 2. The world now looks like Figure 3.

Figure 3: The latest world

Here's a video. The world is from the TwentyMine.com server.

The Demo

For Windows, download McrView Part 34 - Windows.

For Linux, download McrView Part 34 - Linux.

For Mac, download McrView Part 34 - Mac.

The UI is the same as before:

  • WASD for movement. Arrow keys also turn and move.
  • Page up/Page down to change your height. Blank and X also work.
  • + and - to change your speed.

You'll need to edit options.xml and point it at the Minecraft world you want to view. The save files are in different directories for each OS:

  • Windows 7: C:\Users\UserName\AppData\Roaming\.minecraft\saves
  • Windows XP: C:\Users\UserName\Application Data\.minecraft\saves
  • Linux: ~/.minecraft/saves
  • Mac: ~/Library/Application Support/minecraft/saves

If the world directory is "New World", set the option line to world="New World". Then run McrView.

Source code is at McrView Part 34 - Source.

You can also pull it from GitHub at https://github.com/mgoodfel/McrView. You'll need the framework at https://github.com/mgoodfel/mgFramework to build the project.

Creating your own Brick Set

You can edit the bricks used to display the world. Each brick type has from one to six images that are placed on the faces of the cube. These are all in docs/bricks in the demo directory. They are named by the type of brick which uses them. To change the look, the simplest thing is to load one of these images into an editor and change it. For example, you can edit docs/bricks/water.jpg and turn it red. Then you'll get the world as shown in Figure 4.

Figure 4: Seas of Blood

If you create a new image from scratch, it must match the size of the other images, currently all 128 by 128 pixels. You could resize all of the images if for some reason you wanted to do that. The size should be a power of two (16, 32, 64, 128, or 256 would be reasonable). I suppose you could take one of the existing Minecraft texture packs and cut apart the texture atlas image into small images for use in McrView. That would be tedious, but there's no reason it shouldn't work. I haven't tried it.

I use a very old version of the Jpeg library. If you have trouble getting your images to load, turn off progressive encoding for Jpeg. The library also supports GIF files, which I've been using for transparency (alpha), and the non-compressed Windows BMP files.

Transparency

The JPG format doesn't include an alpha plane giving transparency, so I specify transparent images with two files. For example, water is rendered using water.jpg and waterAlpha.gif. When a transparent image is specified it will appear as a pair of names separated by a semicolon: "water.jpg;waterAlpha.gif". An opaque image is just "stone.jpg".

Currently, only glass, diamond, fire and water are transparent, but you can use transparent images on any cube type. Just remember that the more transparency you use, the more sorting the program has to do. Make all the stone transparent and it might slow performance a bit.

To add transparency (or remove it), you need to change where the texture is specified for a brick type. That will be in docs/bricks/mcbricks.xml. That file contains lines like:

<brick code="0200" top="grass_top.jpg" bottom="dirt.jpg" sides="grass_side.jpg" />

The code indicates which brick type is being specified. Don't change that. You may also see a dir attribute which indicates which way a brick is facing. Don't change that either!

The top, bottom and sides specify which image is placed on each side of the "grass" cube. You can also specify all, left and right. Or if you are more mathematically inclined, xmin, xmax, ymin, ymax, zmin, and zmax are valid. Y points up.

If you make one side of a cube transparent, you should make them all transparent. I think it will work with a mix of transparent and opaque sides, but I haven't tried it. It will look strange, since cube faces are drawn one sided. In other words, you won't see the opaque back side of a cube through a transparent face.

Changing File Names

If you get serious about creating a new brick set, you might want to copy the docs/bricks directory to docs/my_bricks or something. In options.xml, change the line

brickSet="docs/bricks/mcbricks.xml"

to point to the correct directory. You could also rename mcbricks.xml to something else here.

In your bricks directory, you can change file names in the <brick> tags to point to your versions, if you want different file names for some reason. These file names are relative to the bricks directory.

Editing Shapes

Fig 5: The Chest.skp file
In the <brick> tag, the attribute shape defaults to "cube". Also supported are "stair", "slab", "cap", and "column". These are implemented by the code directly. Any other value for shape is treated as a file name, relative to the bricks directory.

So for example,

<brick code="3600" shape="chest.xml" mat0="wood_dark.jpg" 
   mat1="wood_light.jpg" mat2="obsidian.jpg" />
specifies the "chest" brick, with shape from chest.xml and three materials, "wood_dark", "wood_light" and "obsidian" (for the handle.)

The simplest thing you could do is change the materials to other texture patterns. That would be no different than editing the cube textures as described above. Transparent is not supported on general shapes.

A harder thing to do is edit the shape itself. These are all created with Google SketchUp. That's a free program and has versions for Windows and MacOS.

The SketchUp (.skp) files for all my brick designs are in McrView Part 34 - Bricks. These were all created with SketchUp version 8. I'm told these will not load under earlier versions of SketchUp.

If you create your own versions, there are some restrictions:

  • All surfaces must be painted with a texture. Solid colors are not supported.

  • No more than six materials, which are specified in the <brick> tag as mat0 to mat5.

  • Fit your shape into a 1 meter cube. Anything smaller than that will be left at the size you specify. Anything larger will be scaled down to a 1 meter cube. This is actually a problem for the ascending mine cart rails, which extend into the next cube above. Email me if you need to edit this brick type.

  • Keep the number of triangles low. There's no hard and fast rule. The larger your design is, and the more common that brick type is, the more triangles have to be loaded into the display. That slows things down and uses more display memory. The brick shapes I've designed are around 300 triangles.

Once you've edited the shape with SketchUp, export it as a Collada (dae) file. Then you need to run my utility to strip out the information I need from the dae file and produce the xml taken by the demo. So open a command/terminal window and type

cd "demo directory"
daestrip "source dir"/chest.dae "bricks dir"/chest.xml
daestrip will attempt to find all the coordinate information in the dae file and copy it to the output xml file. Both are readable text (XML) files if you want to look at them with a text editor.

The daestrip program has only been tried with SketchUp output, not Collada files from other sources. If you have another graphics editor you prefer, give it a try. If your editor supports an option to force all the output to be triangles, use that.

If it still doesn't convert, try importing your dae file into SketchUp. Then after selecting all the objects, use Edit/Components/Explode to break it all into triangles. The "Components" menu item is the last item in the Edit menu and seems to change based on what you have selected. After you've exploded your model, Export it as a DAE and try daestrip on it again.

The whole process of editing these shapes with SketchUp and converting them for my code has been extremely frustrating. By trying to make SketchUp easy for a novice, they've made it really unpredictable. It constantly snaps your points to locations it thinks you want or does other odd things with your input. On top of that, I'm fairly sure that there are extra triangles all over the created models, which is a waste. Simple shapes like the curved rails are coming out as over 1000 triangles. I'm not sure what I can do about it though.

Contributing Your Design

I'm more than happy to include contributions of artwork in the demos. Unlike the software contributions I described last week, I don't see any legal complications.

Email me your submissions, or if they are large, email me a link to them. Include a file "copyright.txt", with your name, address, and the date. List the files you are contributing, then add some variety of Creative Commons license. Any of the licenses can be used, in case you want to restrict your work to non-commercial or "no derivatives" uses (though I'd prefer you didn't.)

I of course reserve the right not to accept what you've done... :-) I won't accept something without a copyright notice.

Thanks to Alan Hauck for the first submission - a dandelion shape.

Home       About Me       Contact       Downloads       Part 33    Part 35   

blog comments powered by Disqus