Extended OBJ format with skeletal animation info

Hi all,

I am the head of physics research at nvidia and for prototyping I have used the obj file format a lot because it is so simple. One big drawback is that it cannot store skeletal animation info. For that you have to use FBX for instance. I wrote code to read that in the past but you have to import the FBX library and it is quite cumbersome to use it.

Now I have a suggestion to extend OBJ in a very simple way to support animation info. I have written a Blender exporter and an example to read it back in already.

Here is my suggestion. I wonder whether it would make sense to add that to the official OBJ exporter of Blender. The extension looks like this:

Definition of the skeleton

b [bone name]
bp [parent bone nr + 1, 0 = no parent]
bb [16 floats for 4x4 bind pose]

Skinning info

vl [vertex number + 1] [bone number] [weight] [bone number] [weight] …

Animations

a [name]
af rot.x rot.y rot.z rot.w [pos.x pos.y pos.z] [scale.x scale.y scale.z]

af defines a transformation per bone per frame so there are num bones x num frames such entries. Since those are most often just rotations (quaternions) the pos and scale info can be ombitted to reduce file size

What do you guys think?

Here is an actual example:

b root
bp 0
bb 0.062615 0.000199 -0.147239 -0.000562 0.000591 0.159998 0.000467 0.700159 0.147238 -0.000727 0.062613 -0.007725 0.000000 0.000000 0.000000 1.000000

b clavicle
bp 1
bb 0.007516 -0.158770 -0.018321 -0.000049 0.159789 0.007846 -0.002440 1.113234 0.003319 -0.018182 0.158929 -0.009602 0.000000 0.000000 0.000000 1.000000

b humerus
bp 2
bb 0.013231 -0.159246 -0.008105 -0.213310 0.000666 -0.008078 0.159795 1.123772 -0.159451 -0.013248 -0.000005 -0.034025 0.000000 0.000000 0.000000 1.000000

b radius
bp 3
bb -0.015432 -0.159234 0.002522 -0.492860 0.000245 0.002510 0.159980 1.109591 -0.159254 0.015434 0.000002 -0.057281 0.000000 0.000000 0.000000 1.000000


vl 3582 2 0.048444 1 0.951556
vl 3583 2 0.055316 1 0.944684
vl 3584 2 0.048894 1 0.951106
vl 3585 2 0.040274 1 0.959726

a armMotion

110 frames

frame 1

af 0.000000 0.000000 0.000000 1.000000
af 0.000000 0.000000 0.000000 1.000000
af 0.000000 0.000000 0.000000 1.000000
af 0.000000 0.000000 0.000000 1.000000

frame 2

af 0.000000 0.000000 0.000000 1.000000
af 0.000000 0.000000 0.000000 1.000000
af 0.000001 0.016234 0.000258 0.992926
af 0.000000 0.000000 0.000000 1.000000

frame 3

Hi, I’d rather not extend the OBJ format since this means there is pressure to support these extended settings for importing - giving extra maintenance overhead.
It also means we need to communicate through the exporters GUI that some options are OBJ incompatible.

Instead you could, define a new format with some differences to simplify parsing and implementation.

eg:

  • define a fixed encoding, eg: utf-8
  • define floating point representation
    (some OBJ’s contain1.#QNAN / nan, inf, which is a hassle to reliably parse).
  • define what a valid face is
    (can it use the same vertices multiple times? - can it loop back on it’s self to define holes?)
  • verts must be defined before faces that use them.
  • objects/groups faces can’t share vertices.
  • no multi-line support (don’t think its really that handy?).
  • simple material specification (lots more could be written on this, for the purpose of a simple format - I would keep material spec simple too).
  • optional extra - a binary version of the file, with a reference implementation of a converter, maybe json version too - which should be fairly trivial to implement.

… there are probably a few missing from this list, if someone were to do this it would be worth further investigation.

If this were done, many existing OBJ’s would fit this new format too. The importer could be relatively simple to write and maintain because it would not need to account for corner cases which aren’t an advantage to support in practice.

.obj does support materials through external .mat file, why not extending using same schema, adding eg a .skl beside and then reuse and extend .obj importer-exporter to read-write .skl when present ?

I like the .skl idea, since it won’t break any code already ‘out there’ for dealing with the .obj format (lets be honest most 3d programmers have written some .obj related code at-least once in their lifetime) and i’m not so sure many of them will deal too well when they encounter into new attributes.