Blender + ManuelBastioniLAB to UE4 workflow

I’ve recently struggled more than usual to get this to work, so I’ll store it for later reference.
My sources are this great Youtube video and this post on the Unreal Engine forums.

Initial Setup

First thing to do is to correct a “feature” in Blender, the FBX export plugin adds a root on top of our armature root. That could create problems when exporting to UE4.

Python script and where to modify it

Under Blender/2.78/scripts/addons/io_scene_fbx/ edit the file named export_fbx_bin.py. You need to find the following section.

elif ob_obj.type == 'EMPTY' or ob_obj.type == 'ARMATURE':
empty_key = data_empties[ob_obj]
connections.append((b"OO", get_fbx_uuid_from_key(empty_key), ob_obj.fbx_uuid, None))

And comment it like so

#elif ob_obj.type == 'EMPTY' or ob_obj.type == 'ARMATURE':
#empty_key = data_empties[ob_obj]
#connections.append((b"OO", get_fbx_uuid_from_key(empty_key), ob_obj.fbx_uuid, None))

Then, download Manuel Bastioni’s plugin from here, unzip it under Blender/2.78/scripts/addons/ and activate the plugin under File|User Preferences|Add-ons|, also make sure to save your settings so you won’t have to do this step again.

Blender Addon Settings

Creating a new character

On a fresh Blender file, delete the cube and set the scene units to centimeter (Metric and 0.01 unit scale).

Then, click on the ManuelBastioniLAB tab, select a preset of your liking and click on Init Character.

Configure the character as your will, the only setting that is important here is inside the Pose Tools section, where you should select the t-pose.

However, before finalizing, you need to delete the modifiers except for the armature (DO NOT APPLY ANY OF THEM).

Make sure it looks more or less like this.

Now we can click on finalize. I like to clean things up as well, and delete all cameras and lamps.

The issue that needs to be corrected now is that our character is too small, measuring only a few centimeters, so we need to scale it by 100 or so. Select everything and hit S then type 100 and press Enter. You can adjust to a correct zoom level with the Home key.

This scaling needs to be applied to the object, otherwise we will have bone weight issues in UE4. You do this by pressing Ctrl+A and selecting Apply Rotation and Scale.

We are now ready to export our character to an FBX formatted file. These are the export settings that work for me, but YMMV.

Under UE4, these are the import settings that work for me. Using this process I don’t get any errors.

Open up the newly created skeleton. There is a section called Retarget Manager where you need to select the Humanoid Rig and make sure you assign each node to its corresponding bone in your skeleton. You should do this for your source and your target skeletons. Also, make sure everything is saved.

Now, find the element that you want to retarget, right click on it and select Retarget Anim Assets|Duplicate Anim Assets and Retarget.

Fill the menu as you prefer, making sure you select your target skeleton (the one we just imported) and placing the files under our desired folder. Once everything is ready hit Retarget.

Wacom Intuos 5 M configuration script for Linux Mint

Introduction

As an indie developer that goes solo, I have a drawing tablet which I mostly use to draw textures. The one I have is very good and from a reputable brand, it’s a Wacom Intuos 5 M tablet.
intuos5Med

Unfortunately this hardware device doesn’t have official support for Linux. There are, however, community maintained drivers, but it can be a little bit difficult to make them work properly. Linux Mint 17.3 (or rather, Cinnamon) comes bundled with a tablet configuration tool. Unfortunately it doesn’t seem to work properly for me.

The device sports 8 button for shortcuts, and a wheel with 4 different functions which can be used to zoom in or out, rotate left and right or increase and decrease the brush’s size. It also comes with a pen that has 2 buttons, a tip for drawing and another one that acts as an eraser. Both tips have pressure sensitivity.

Now the pen works great, both tips and the pressure I apply are registered properly. What doesn’t work is the buttons and wheel on the pad. I want to be able to achieve the following :

  • For the eight buttons
    • Button 1 : Help Button (press F1)
    • Button 2 : Save (press Ctrl + S)
    • Button 3 : Redo (press Ctrl + Shift + Z)
    • Button 4 : Undo (press Ctrl + Z)
    • Button 5 : Add a new layer (Press Insert)
    • Button 6 : Cut (press Ctrl + X)
    • Button 7 : Copy (press Ctrl + C)
    • Button 8 : Paste (press Ctrl + V)
  • For the wheel
    • The central button has to switch between the different modes, the LED has to swap when pressed and a visual CUE has to appear on-screen when the mode changes
    • The four different modes are
      • Zoom In/out (Ctrl + + and Ctrl + -)
      • Increase/Decrease Brush Size ( [ and ] )
      • Rotate Left/Right ( Ctrl + [ and Ctrl + ])
      • Change Layer (PageUp and PageDown)

xev and xsetwacom

I use a spanish keyboard, so some of the keys I require need of a modifier key, like Control or AltGr. As an example, in order to get [ I need to hold AltGr while pressing the key.

teclatESP

In order to find out the name the X server gives to those keys I can use xev which is a tool that displays all X events, and amongst them, input events. I simply fire up the program in a terminal and I press the buttons that I need to check.

$ xev -event keyboard
Outer window is 0x4c00001, inner window is 0x4c00002

KeymapNotify event, serial 24, synthetic NO, window 0x0,
keys: 0 0 0 0 16 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

KeyRelease event, serial 25, synthetic NO, window 0x4c00001,
root 0x2eb, subw 0x0, time 14632163, (-721,140), root:(141,594),
state 0x10, keycode 36 (keysym 0xff0d, Return), same_screen YES,
" XLookupString gives 1 bytes: (0d) "
XFilterEvent returns: False

KeyPress event, serial 28, synthetic NO, window 0x4c00001,
root 0x2eb, subw 0x0, time 14635907, (-122,416), root:(740,870),
state 0x10, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
XKeysymToKeycode returns keycode: 92
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False

KeyRelease event, serial 28, synthetic NO, window 0x4c00001,
root 0x2eb, subw 0x0, time 14636051, (-122,416), root:(740,870),
state 0x90, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
XKeysymToKeycode returns keycode: 92
XLookupString gives 0 bytes:
XFilterEvent returns: False

So that modifier key is known as ISO_Level3_Shift.

Now, xsetwacom is the tool that is used to configure your tablet. We can check if the device is recognized by our machine by simply running.

$ xsetwacom --list devices
Wacom Intuos5 M Pen stylus id: 11 type: STYLUS
Wacom Intuos5 M Pad pad id: 12 type: PAD
Wacom Intuos5 M Pen eraser id: 17 type: ERASER
Wacom Intuos5 M Pen cursor id: 18 type: CURSOR

I have here four devices, but here I’m only interested on the second one, my pad which is called Wacom Intuos5 M Pad pad. We can also get a full list of parameters that can be defined with this tool, but I’ll only be using three of them : Button (a button press), AbsWheelUp (the wheel scrool counter-clockwise) and AbsWheelDown (the wheel scrool clockwise). Buttons are numbered 1 to 3 then 8 to 13, I don’t know why this order is used. Button 1 is my wheel modifier. So in order to have my Button 2 perform a Paste the following command would be used.

$ xsetwacom set "$DEVICE" Button 2 "key +Ctrl C -Ctrl"

The key description can be interpreted as “press and hold control, then press C, then release Control”.

LED change and intensity

The LED can be swapped and its intensity can be modified. This is achieved with two files :

  • status_led0_select swaps the LED, it goes from 0 to 3
  • status0_luminance swaps the intensity, goes from 0 to 255

Both files are under /sys/bus/hid/devices/*/wacom_led

Of course, these files are read-only for any user other than root, so we either have to change this in /etc/rc.local or we’ll have to be elevate our rights everytime we need to change it with sudo or something similar.

Editing /etc/rc.local

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/bin/chmod 666 /sys/bus/usb/devices/*/wacom_led/status_led0_select
/bin/chmod 666 /sys/bus/usb/devices/*/wacom_led/status0_luminance
exit 0

And in case we have never used rc.local before we need to give it execution rights. These changes will be effective after a reboot.

$ sudo chmod +x /etc/rc.local

The script

I have adapted a script I found online to automate the whole process. This script is heavily based off this post on Ubuntu Forums.

#!/bin/bash

## Touch ring toggle script
##
## Bind Button 1 (button center of touch ring) to the script.
##
## To allow script to select mode status LEDs edit rc.local to change root
## only permissions on the sysfs status_led0_select file:
## gksudo gedit /etc/rc.local
## Add the following comment and command (before 'exit 0'):
## # Change permissions on status_led0_select file so being root isn't
## # required to switch Wacom touch ring mode status LEDs.
## /bin/chmod 666 /sys/bus/usb/devices/*/wacom_led/status_led0_select
##
## Intuos - status_led0_select file = the left (only) ring status LEDs.
## Cintiq - status_led1_select = the left ring; status_led0_select =
## the right ring status LEDs. Same for the touchstrips.
##
## For mode state notification use:
## sudo apt-get install libnotify-bin
## Otherwise comment (#) out the notify-send lines. If libnotify-bin
## installed see 'man notify-send' for details.

# check if mode_state file exists, if not create it and set to 0
if [ ! -f /tmp/mode_state ]; then
echo 0 > /tmp/mode_state
fi

# read mode state value from temporary file
MODE=`cat /tmp/mode_state`

# select touch ring mode status LED for current mode state
LED_FILE=`find -H /sys/bus/hid/devices/* |grep status_led0_select`
if [ ! -w "$LED_FILE" ]
then
gksudo chmod 666 "$LED_FILE"
fi

LED_INTENSITY=`find -H /sys/bus/hid/devices/* |grep status0_luminance`
if [ ! -w "$LED_INTENSITY" ]
then
gksudo chmod 666 "$LED_INTENSITY"
fi

echo $MODE > $LED_FILE
echo 255 > $LED_INTENSITY

# for DEVICE use the pad "device name" from 'xinput list'
DEVICE="Wacom Intuos5 M Pad pad"

xsetwacom set "$DEVICE" Button 1 "key Ctrl shift Alt w"
xsetwacom set "$DEVICE" Button 2 "key F1"
xsetwacom set "$DEVICE" Button 3 "key Ctrl s"
xsetwacom set "$DEVICE" Button 8 "key Ctrl shift z"
xsetwacom set "$DEVICE" Button 9 "key Ctrl z"
xsetwacom set "$DEVICE" Button 9 "key Ctrl z"
xsetwacom set "$DEVICE" Button 10 "key Insert"
xsetwacom set "$DEVICE" Button 11 "key Ctrl x"
xsetwacom set "$DEVICE" Button 12 "key Ctrl c"
xsetwacom set "$DEVICE" Button 13 "key Ctrl v"

# set touch ring function option and notification for the 4 toggled modes
if [ "$MODE" == 0 ]; then
xsetwacom set "$DEVICE" AbsWheelUp "key Ctrl -" # zoom in
xsetwacom set "$DEVICE" AbsWheelDown "key Ctrl +" # zoom out
notify-send -t 1500 "Mode 1: Zoom In/Out"
elif [ "$MODE" == 1 ]; then
xsetwacom set "$DEVICE" AbsWheelUp "Key +ISO_Level3_Shift dead_grave -ISO_Level3_Shift" # increase brush radius (must be mapped in GIMP)
xsetwacom set "$DEVICE" AbsWheelDown "Key +ISO_Level3_Shift plus -ISO_Level3_Shift" # decrease brush radius (must be mapped in GIMP)
notify-send -t 1500 "Mode 2: Increase or decrease brush size"
elif [ "$MODE" == 2 ]; then
xsetwacom set "$DEVICE" AbsWheelUp "Key Ctrl +ISO_Level3_Shift dead_grave -ISO_Level3_Shift" # rotate right
xsetwacom set "$DEVICE" AbsWheelDown "Key Ctrl +ISO_Level3_Shift plus -ISO_Level3_Shift" # rotate left
notify-send -t 1500 "Mode 3: Rotate Left/Right"
elif [ "$MODE" == 3 ]; then
xsetwacom set "$DEVICE" AbsWheelUp "key PgUp" # select previous layer
xsetwacom set "$DEVICE" AbsWheelDown "key PgDn" # select next layer
notify-send -t 1500 "Mode 4: Select previous or next layer"
fi

# toggle button increment counter
MODE=$((MODE += 1))

# set next mode state
if (( "$MODE" > 3 )); then # roll over to 0, only 4 mode states available
echo 0 > /tmp/mode_state
else
echo $MODE > /tmp/mode_state
fi

When the button 1 (the wheel button) is pressed, the key combination Ctrl+Shift+Alt+W is pressed. I have mapped this key combination to the execution of the script itself, so in order to initialise my configuration I can either set this script to run on XInit or by doing that key combination. Every time it’s pressed the wheel mode is swapped, and a little notification appears.

A new beginning

Looks like I am going to have some time to do my own thing, finally. Maybe it is a good time to retake some old forgotten projects. For a very long time, I’ve wanted to make videogames. Not just as a hobby, but as a profession. I’m a huge fan of indie games as you can see from my Steam library here. Now with SteamOS and smatphone games it seems like there’s a lot of changes in the videogame industry. You don’t need to have a team of 100+ people working together to create the next hit game, it just seems like game development is going back to its roots, where people created little gems, on their own, with a lot of talent and tons of imagination.

Limbo
Limbo, one of the best games I’ve ever played

Now, I’m a hardcore techie, so I’m not going to be using any popular engines like Unity or Ogre. I did contribute to Leadwerks being ported to Linux on Kickstarter, but I don’t think I’ll be using it.

I don’t intend on reinventing the wheel though, so I will be using a great number of open source libraries. This is a list of technologies that I might probably be using :

  • C/C++
  • Lua, for scripting purposes
  • Simple DirectMedia Layer (SDL), by the great icculus, the cross-platform equivalent of DirectX, handles images, audio, net, …
  • OpenGL, the cross-platform of Direct3D
  • OpenAL, the audio equivalent to OpenGL
  • Assimp, the Asset Import Library, a library used to import 3D models, bones and animations
  • Audacity, audio editor
  • zlib, probably, for compression purposes
  • Boost, because it just rocks
  • LMMS, to produce music. I’m actually going to give this a shot! Needless to say, I have no idea what i’m doing.
  • Blender, 3D model creation
  • Makehuman, quick and easy character creation
  • Git, version control
  • CMake, the most flexible build system I can think of
  • Valgrind, the analysis tools that have taught me so much about programming
  • GCC/GDB the GNU compiler and debugger

Other than this, I will give a shot to LLVM, as I keep hearing more and more about it, but I’ve never actually tried it. And I have no idea what I could use for creating sound effects.

Eventually, I might write a second part to this post, where I will aacknowledge how wrong I was about many choices I make here. There is one thing I know for sure though, and it’s that, at the very least, I will get more knowledge from this experience.

darktable, a photo workflow software for Linux users

As I’m a Linux user I was looking for a decent substitute for Adobe Lightroom. I recently discovered a viable alternative called darktable. I decided to give it a try, as, even if I managed to work with the excellent UFRaw, it took me way too long to get things done, as the user interface wasn’t really suitable for fast workflow.

Darktable seems to be a project that has been going on for two years now, but I have to admit I had never heard of it until recently. I only found out about it because I looked for an alternative to Lightroom in The Linux Alternative Project, and so I decided to give it a go.

My first impressions were excellent, the interface is very similar to LightRoom’s and the program is agile even on an underpowered computer. The program seems to use libraw, meaning it instantly supports RAW formats from an overwhelming number of manufacturers.

After some hours spent editing, I’ve discovered a few weak points with it though; the interface can be a bit difficult to understand at first, and it would be particularly uncomfortable to navigate using a touchpad. Some of the extra tools are difficult to find and are not properly documented, but I still have to admire the effort put into documenting most features, something where most open source programs lag behind.

I’m hoping that, as this program keeps getting better and better, it won’t be long until it comes included in all major Linux distro repositories. It is, in my opinion, crucial to make it more easily available for it to get the attention it deserves.

Darktable