Osm2city.py textures

From FlightGear wiki
Revision as of 07:39, 18 March 2015 by Radi (talk | contribs) (updated texture atlas restrictions)
Jump to navigation Jump to search

This article describes how you can prepare and register your own textures for use with osm2city.py. It assumes you already have a texture image file. If not, see Howto:Create_textures_from_photos.

Introduction

To texture a facade or a roof, you need

  • two image files: the texture itself and a lightmap
  • the texture's dimensions in meters
  • locations in pixels at which osm2city.py may cut the texture to fit it to a given facade geometry, e.g. to apply a photo of a 15-storey building to a 12 storey model without shrinking it.
  • 'provides' and 'requires' tags, e.g., a texture could require a black roof, while providing a commercial facade.

Osm2city uses a texture atlas to improve performance. But that places some restrictions:

  1. textures can only wrap around in zero or one direction.
  2. textures that don't wrap around must come in 2^n sizes (32, 64, 128px ...)
  3. textures that wrap around in one direction will be resized to (currently hardcoded) 256 px in that direction

texGUI.py

The script texGUI.py eases calibration and finding the cut locations. Run the GUI and supply your texture file:

texGUI.py facade.png
texGUI: Calibrating a texture's width using an aircon as a reference object. Note the red line.
texGUI: Added horizontal and vertical cut locations.

It is generally a good idea to use descriptive names, such as "facade_industrial_old_white.png", but for this example we simply use "facade.png".

  1. Calibrate the image width/height. Find a feature in the image whose dimensions you know or can estimate. For example, simple windows are typically about 0.8 m wide. Here, we're using the aircon's width, estimated 0.82 m. Left drag to select that horizontal feature, then enter its length. Right drag for a vertical feature. You need only one of them. If both are given, both are used (e.g. if your image is stretched in one direction).
  2. Mark locations at which osm2city.py may cut the texture. Use left and right mouse buttons. Shift+click removes the last marker.
  3. Once you're satisfied, click "dump and quit". This writes calibration/cut data to a file "facade_24x19m.py". Note that texGUI added "_24x19m" to the texture file name (the original file is still in place), since you're likely to have more than one texture for an industrial facade.

Texture metadata

Now edit facade_24x19m.py:

facades.append(Texture('tex.src/facade_24x19m.png',
    23.8, [364, 742, 1086], h_can_repeat=True,
    18.5, [295, 565, 842], v_can_repeat=False,
    v_align_bottom = True,
    requires=[],
    provides=[]))

Usually you need to change very little here.

  • You can set the texture to wrap around in at most one direction using h_can_repeat or v_can_repeat
  • If v_align_bottom is True, osm2city.py will align the bottom part of the texture with the ground and cut away the top part if neccessary. Otherwise, it will align the top part with the roof and cut away the bottom.

For reference, we now descibe the format in a bit more detail. You might want to skip to the next section.

First line is the path to our texture. Second line says the texture

  • is 23.8m wide
  • can be cut at u = 364, 742, and 1068 px, where u is the horizontal coordinate. The last value 1086 also gives the width in px. Note that the .ac file uses normalized coordinates (0 ... 1). Internally, osm2city.py divides all coordinates by the last value. Therefore, when preparing the textures, you can work with the highest resolution possible and register those numbers, then just downscale the texture for actual flightgear use. Once the next generation of graphics cards arrives you just replace the textures with higher resolution ones without touching the cut locations.
  • the texture can repeat in horizontal direction.

The third line gives the same information for the vertical direction:

  • 18.5m height
  • can cut at 295, 565, 842 px,
  • the texture cannot repeat in vertical direction

Texture compatibility

The fourth and fifth line state compatibility with other textures. TexGUI.py just creates an empty template here. A useful example could look like this:

    requires=['roof:color:black'],
    provides=['shape:industrial','age:old','compat:roof-flat','compat:roof-gable']))

This facade texture requires a black roof. It provides an old-aged, industrial facade, and is compatible with both flat and gable roofs. TODO: describe details on our requires/provides mechanism.

Lightmap

A lightmap is required for every texture, havinghas the same file name with a postfix "_LM". So for our example this would be "facade_24x19m_LM.png"

Osm2city uses

  • red channel for window lights
  • green channel for ambient street lights shining onto facade
  • blue and alpha unused

TODO describe add_streetlight.py

Install texture and lightmap

  • copy texture and lightmap to tex.src/
  • add the snippet from "facade_24x19m.py" to textures/catalog.py

If you're adding a roof, name your texture "roof_something.png" and append it to the list of roofs (instead of facades)

roofs.append(Texture('tex.src/roof_something.png',

See roof examples starting around line 400.Note that also roofs need a lightmap. They no longer need a LM.

Finally, run

osm2city.py -A

to re-create the texture atlas. If there are no errors, your texture is registered and will be used next time you run osm2city.py. If your texture is GPL compatible, please consider sending it (along with the meta data) to one of the osm2city.py devs to have it included in the official distribution.