HOWTO: Blender -> egg, with animation & UV textures

I struggled through trying to figure out the details of getting a model from Blender to Panda. Here is what I worked out.

My setup
Blender 2.36
Ubuntu Linux 5.04
Python 2.4
Panda 1.0.5
DirectX8exporter236 I couldn’t get the default DirectX exporter to export textures. This newer version fixed that problem.

Create a Model
The Blender User guide has a chapter called Your first animation in 30 + 30 minutes which shows you how to model & animate Gus, the gingerbread man. Follow this, except:
don’t do the subdivision surfaces (they aren’t exported)
don’t do materials the way they suggest. Instead, you want to do a UV texture. See Unwrapping Suzanne in the User Guide.

The exporter doesn’t like it if you scale, rotate, or move the model in Object mode. You can check if you’ve done this by clearing any transformations (alt-g, alt-s, and alt-r). Instead, scale/rotate/move the vertices in Edit mode.

Export to .x
You need to export each animation to a separate .x file. I made three animations for Gus:
so I end up with three .x files
For each one, you need to:

Select the animation in the Action editor
Bake it
Set the animation start & end frames (Buttons View -> Scene)

This includes a copy of the mesh in every .x file. That is lame, but I’m not sure what to do about it. It still works, but I’m sure it isn’t very good for efficiency.

Convert to .egg
Blender convention is to name bones with .L and .R at the end, like Arm.L or Foot.R. Some features in Blender depend on these names (paste flipped pose, for example). Additionally, Blender has a habit of naming new objects things like cube.001 and cube.002. x2egg can’t handle . in names, so we have to strip them out.

Finally, Blender seems to have different ideas about which way is up, so we tell x2egg to rotate the model with -TR -90,0,0.

I wrote a python script to do this for me (it doesn’t strip “.001” because I can just rename the objects in Blender):

#!/usr/bin/env python
import sys
import os
import re

xfile  = sys.argv[1]
eggfile = re.sub("\.x$", ".egg", xfile)
if xfile == eggfile: # safety check
    print "Refusing to overwrite source file %s" % xfile

# clean up some blender conventions that x2egg doesn't like
xdata = open(xfile).read()
xdata = re.sub ("\.L", "_L", xdata)
xdata = re.sub ("\.R", "_R", xdata)
fh = open(xfile, "w")

os.system("x2egg %s -o %s -TR -90,0,0 %s" %
    (xfile, eggfile, " ".join(sys.argv[2:])))

View in pview
You should be able to look at the egg files with commands like “pview gus.egg” and “pview gus_walk.egg.”

Load into Panda
You can load the mesh and animations like this:

gus = Actor.Actor("gus", { "idle"  : "gus",
                           "walk"  : "gus_walk",
                           "dance" : "gus_dance" })

This looks extremely good. Thanks a lot for sharing your experience! If now we could just seperate mesh and anims it’d be open source heaven… :slight_smile:

Very precise,Very helpful.Thank you very much for your help.

Yeah. I don’t think it would be very hard to write a script to remove the mesh from the animations, but perhaps someone can think of a better way :slight_smile:

I really appreciate your work doing this.

I think our next step should be to modify x2egg so that it can handle “.” in object names. (Maybe convert them to “_” automatically). Then, we can add a command-line option to x2egg that says “animation channel only.”

These things don’t sound hard, the real work was figuring out what needed to be done. You’ve already done that. Thanks. :slight_smile:

  • Josh

Those would be great modifications :slight_smile: Glad I could help…

Actually, if you could email me an x-file that contains a “.” in place that causes panda to fail, that would help.

I start liking this thread better every minute! :slight_smile:

OK, I have the x-file. I’ll look into it today.

OK, I’ve added support for “.” in identifiers, and I’ve added a command-line option “-anim” to export animation only, and a command line option “-model” to export model only.

I should warn you though - these X-files that blender is producing are invalid X files. The coordinate system is incorrect (directx specifies a y-up coordinate system), and the dots in identifiers are incorrect. You can test the X-file by running it through microsoft DXViewer.EXE (it doesn’t show up). So we now have workarounds for these bugs, but in the long run, somebody should fix the blender exporter.

The new code will be in the next release.


In addition to fixing the output of the Blender exporter, it would be nice if it was easier to use. However, we are up and running now and that’s a start :slight_smile:

Great work, Josh! :slight_smile: So it now accepts any kind of .x input - standards-compliant and “blenderish”?

I must say it bugs me that the Blender exporter produces non-compliant output, not exactly what one would expect from an open source project… I could try to solve it, but due to lack of experience it might take quite a while.

Hey Marc, Zovirl - I just released the new version of panda. It should contain the new x2egg. Give it a try for me, let me know if it works?

If it does work, would you guys consider updating and fleshing out the manual page on blender exporting? The manual is a wiki, the login button is at the bottom of every manual page in the form of a tiny dot (I’m trying to keep the fact that it’s a wiki relatively unknown, except to experienced panda users). Feel free to just dig in. Oh, and there’s a real short style-guide for the manual.

Hey Josh,

Sure thing, I’ll try it this weekend with Blender’s default (plugin) X exporter. That’s the least I can do! :slight_smile:

I also have a coder trying to figure out what’s wrong with that exporter in terms of standards compliance, so maybe the “Blender situation” will soon improve even further.

Just to have my todo-list somewhere I can find it - I will test the following three Blender X-exporters (results will be edited in once I’m done):

The last one I just discovered while looking for test models. It claims to fix the annoying bugs of the former ones, but I’m going to verify it.

Josh, thanks for adding this so quickly :slight_smile:

x2egg seems to handle blender output fine now. The animation-only egg files are so much smaller! Very nice. The only thing I can’t get working is the --model option. When I do that, my program gives this error:

Assertion failed: !is_empty() at line 265 of panda/src/pgraph/nodePath.I
Traceback (most recent call last):
  File "/home/mivey/svn_co/mayfly/", line 308, in ?
    temp.pose("idle", random.uniform(0, 40))
  File "debtmp/usr/share/panda3d/direct/src/actor/", line 1028, in pose
  File "debtmp/usr/share/panda3d/direct/src/actor/", line 1162, in getAnimControls
  File "debtmp/usr/share/panda3d/direct/src/actor/", line 1370, in __bindAnimToPart
AssertionError: !is_empty() at line 265 of panda/src/pgraph/nodePath.I

I did a diff between the model+animation .egg file and the model-only .egg file. In the model-only egg file, a big section at the end was missing:

<Table> {
  <Bundle> mayfly {
    <Table> "<skeleton>" {
# snip...lots of stuff here

any ideas? Need more info?

Ok, so here’s the result of my weekend of Blender practice and pipeline testing:

  • Blender 2.37a’s default DirectX exporter doesn’t work properly - better download one of the two plugin exporters. 2.40 is on the way, though, which is likely to include the updated (now plugin) exporter.
  • Model and UV-mapped textures always turn out well with the alternative exporters (using x2egg), but only the “Mindfloaters” exporter produces valid .x-files that can also be displayed with dxviewer.exe.
  • Armatures give the “Mindfloaters” exporter trouble, exporting failed. I might have done something wrong, though, this has just been my second rigging and animating experiment. Would you mind checking the other exporter with your model, zovirl?
  • Animations and armatures only make it to Panda via non-standards-compliant .x-files. That does work by now, but is unsatisfactory in the long run.

I’ll keep up trying, on Tuesday I should find some more time for that. Zovirl, could you please shortly try the other exporter with your model and animations? I’d really like to get that Blender pipeline documented and fixed for good…


good to see we’re up to the same, even at the same time. :slight_smile: I found something in the x2egg options that could explain the diff:

This program converts DirectX retained-mode (.x) files to egg.  Polygon
meshes, materials, and textures, as well as skeleton animation and
skinning data, are supported.  All animations found in the source .x
file are written together into the same egg file.

  x2egg [opts] input.x output.egg
  x2egg [opts] -o output.egg input.x
  x2egg [opts] input.x >output.egg


  -a name      Specify the name of the animated character to generate.
               This option forces the model to be converted as an
               animatable character, even if animation channels are not
               found in the file.  Without this option, the model is
               converted as a static model (which is usually more
               efficient to load within Panda), unless animation
               channels are present in the .x file.

For the rest the “-model” option worked fine here.

EDIT: Uhm, forget that idea. That’s for rigged, unanimated models only - quite probably not what you tested.

Still working on it, Tuesday wasn’t long enoguh for results - sorry! Will post back later…