Making a model for FlyThrough.Space

Ever wanted to make a 3d vehicle model?

What follows is an extremely minimal (and probably very wrong) blender tutorial. I’m mostly posting this so that I do not forget, but I know that there’s an audience out there that just wants to use Blender to do quick modelling tasks, and this is the shortest path I’ve found to achieve that goal. This post explains how to make and texture the model. A subsequent post will explain the aspects that are specific to BabylonJS (and, thus, FlyThroughSpace)

Step 1: Bilateral Symmetry

Most scifi spaceships are bilaterally symmetrical, at least from the outside. I won’t get into for the rationale for this (if nothing else, cars and airplanes count.) And though there are Notable Exceptions, even those generally start from a symmetrical base with variations on each side.

We don’t want to have to recreate every change by hand, so we’re going to set up our blender object to automatically mirror our changes along the X axis.

Switch the “active data to display and edit” tab on the right to Modifiers (Wrench icon)

Now, add a modifier of the type “mirror” by opening the “Add Modifier” dropdown and selecting “Mirror”

One thing I notice here is that it offers up what I think is the equivalent Python code so that you don’t need to do this task in the GUI. A laudable goal.

Now select the following options and don’t hit apply.

Axis: Y, Options: Merge, Clipping, Vertex Groups

What follows is my least favourite step, because I’m 100% sure I’m doing it wrong. Your cube is half-repeated, because it was already symmetrical and repeated along the Y axis. You need to get rid of the real part overlapping with the mirror part. What I do is go to edit mode, set the selection mode to face, and then slide the face out of the mirrored side, then delete it. I encourage finding a more reliable method and leave it as an exercise to the reader.

At the end of this step, you should have half of a cube mirrored to make a full cube.

Half a cube reflected into a full cube

Step 2: Make your spaceship

I won’t claim to be an expert in actually using the modeling tools in Blender. When I first tried my hand at making 3d objects, it was in Lightwave, when your basic tools where Extrude and Slice, so that’s what I usually use to achieve the shapes I’m looking for. There are probably far better tutorials on how to actually model in blender out there, so feel free to consult some of those. I’ll be here, extruding faces and sliding edges around until you’re back.

Not especially spaceship-y yet

Some subdivision and the knife tool go a long way

You can press ‘K’ to select the knife too, drag it around to add vertices and edges in the middle of faces. You can delete troublesome vertices and re-close your mesh by selecting three vertices and hitting ‘F’ for a new face. I won’t pretend to be an especially good modeler. Here are the results:

Step 3: Paint on a texture

Use the circle select in edit mode (faces) to select every face. You’ll need to rotate the model between uses of the select tool to get all of them. Now in “shading/UVs” press “unwrap” and select “Smart UV Project.” Now you can switch your bottom window to “UV Editor” mode and scale it up a bit (icon in the bottom left)

Now make a material for it, set the view mode to texture or material, and load up some random texture to paint on.

ugly tiger looking thing

Well, that wasn’t very good. There used to be a way to just paint a single color and I was going to sort of airbrush it up, but I can’t find it anymore (leave a comment if you know where it is!) If you _must_ work with solid colors, you can texture paint from solid colored textures I guess.

If you haven’t saved your work before, do save it now and do not keep saving it after this step! We’re going to do some destructive editing in order to export for BabylonJS

In Appreciation: Termux

I’ve been playing with Termux quite a bit in the last couple of days. Being able to do development-any development-while standing on the train is an awesome feeling. I think the site undersells what it is-it’s your compiler in your pocket. It’s ssh in your pocket. I’m redoing my website on my phone (the mobile experience is crap at the moment) by editing the sources in vim, then hosting it locally with Python.

Beware of side effects on default arguments

Check out this quick interactive session:

Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def f(y, x={}):
...   print x
...   if y:
...     x['y'] = True
>>> f(False)
>>> f(False, {'x': True})
{'x': True}
>>> f(True, {'x': True})
{'x': True}
>>> f(False)
>>> f(True)
>>> f(False)
{'y': True}
>>> f(True, {'x': True})
{'x': True}
>>> f(False)
{'y': True}

What’s wrong with this picture? Notice that when I call f(True) we assign something to the default argument x. When we call f again, it replaces the default x = {} with the previous value of x!

I suppose the moral of the story here is that in order to avoid side effects, you should not mess with arguments you’re passing in, even if they’re just the default arguments.

Python list comprehensions

If, like me, you learned python and programming at the same time, you may have missed out on advanced features that, while awesome in python, won’t carry over to other languages you’ll “graduate” to using. One of these features is a list comprehension. It lets you in a compact (and readable) way write loops that take a list and return a list, and does not require lambda syntax. They let you write this:

list_squared = []
for x in [1, 2, 3, 4, 5]:
    list_squared.append(x ** 2)

like this:

[x ** 2 for x in [1, 2, 3, 4, 5]]

This really shines when you’re transforming and extracting data – you can also stick an ‘if’ at the end, turning this:

odds_squared = []
for x in [1, 2, 3, 4, 5]:
    if x % 2:
        odds_squared.append(x ** 2)

into this

[x ** 2 for x in [1, 2, 3, 4, 5] if x % 2]

It might not be a huge improvement in amount of code (or LOC, since you’ll want to break complex list comprehensions across multiple lines) but it saves you from potential mistakes, typing ‘append’, and (importantly) having to declare and use another variable name. I consider that a win.

If you found this post exciting, generator expressions will blow your mind.