Hi all.
Most 3D models here are stored in blender format, and the programmer who want to use them has to know how to read them. The file format is not easy to understand, so I'm starting a thread here to discuss about it.
For the moment, I'm interested in reading v 2.49 files such as http://opengameart.org/content/zombie-0
The basic way to parse a blend file is given here : http://www.atmind.nl/blender/mystery_ot_blend.html
All data structures are given here : http://www.atmind.nl/blender/blender-sdna-249.html
So far, I can load vertices and skeleton. I think I could find how to read animations. I will update my post later and upload a python script to explain this.
But I definitely can't find where rigging information is stored : if someone has a hint or link, please post them (my few tries googling didn't gave me anything). What I'm looking for is for each vertex the list of bones (and weights) it is linked to.
Another question : is there some people here who would find usefull to create a simple 3D file format ? (or reuse an existing one if it has the good specs). The goal would be to have light 3D files to spead up their loading, for instance for webgl games.
Regards.
Here's a random question... Have you tried pulling apart the blender source code and finding the functions that load a .blend file and parse it into usable data? That may be easier than rewriting it from scratch, depending on how tightly the code is integrated with the program.
Creating the data structure and loading data is quite easy : the end of the file tells you how to do this (the DNA1 block). The problem is how to interpret these data structures : they are not documented, nor is the source code :(.
However by searching 'weight' in the source code (readfile.c), I came on the MeshDeformModifierData structure. I'll look later into this.
EDIT : It seems the data is in the following structures : MDeformWeight and MDeformVert. I still don't find how these weights are linked to the bones, perhaps with the flag int ?
Correct me if I'm wrong, but I thought .blend files weren't typically used directly by games. My understanding was that they're more like GIMP's xcf, where it's a working format that, when done, gets exported to a more easily usable format. From GIMP you export a png or jpg, from Blender you export obj or collada or something. These formats are probably easier to import into games. But, of course, .blend files get uploaded here because that way they can be modified or exported to any other format through Blender.
Games uses binary format for speed and I believe a lot of game have their own binary format. I have tried the collada exporter of blender a year ago. The result was so poor that it didn't come into my mind to retry it :P. I have a java ms3d parser, but blender do not export to this format. Obj does not handle rigging and animations.
As I haven't any loader for the moment, I prefer looking into blender file format instead of convert .blend in another format I will have to look at. But if you know a light binary format that handle animations and rigging, and that is exportable from blender, let me know, I don't want to reinvent the wheel.
Oh and I think I found how to link weights vertices and bones (the def_nr int should target a bone).
No idea how much use it will be for you, but you might have a look at Glest's Blender export script: http://titusgames.de/news.html#blenderscript
Discussion of the model format is here: http://glest.org/glest_board/index.php?topic=713
Sadly, it doesn't store bones. I think it just knows where each vertex is in each frame, but I could be wrong.
Thanks for the link johndh. You're right, Glest doesn't use skeletal animation. I guess it is to lower CPU load while animating hundreds or thousands of units, at the expense of more memory used in the graphic card.
The export script is interesting, I'll have a look at Blender's python API.
I fully agree with Tempel, you usually don't use .blend in games. If you use a library, it certainly has an exporter (Cal3D has), you might even just use the Cal3D exporter and file formats, they are OK.
I'd also like to comment on text file formats vs binary file formats. Binary is obviously faster. But, first, my (big) models in text format always loaded faster than an eyeblink, today's processors are monsters! I think it doesn't count anymore nowadays, except maybe if you got to load hundreds of Mo of files at the same time. Text files have also the advantage to being easy to diagnose for problems and being more secure.
Besides that, it seems you really want to go ahead with .blend, so I should say something constructive too :-) Take a look at the Ogre and Irrlicht source code, IIRC they have .blend importers, and skeletal animation!
I don't want to use .blend in game. I want to be able to process a directory containing various .blend files to convert them to a more simple file format.
For the text vs binary, it's because I want to use the model with webGL. Next generations of smartphones will be able to display webGL, however they still have a less powerfull processor than desktop pcs and more importantly, less bandwidth to download the models to display. Because I want a light format, I don't have a lot of information to pick in 3D files, so I was thinking of directly picking them into .blends :).
I 'll take a look at Ogre and Irrlicht source code, thanks for the hint ;).
md5mesh and md5anim are quite "nice" text based and proven file formats. There are Exporters for Blender <2.5 and >=2.5, for MisfitModel 3D (Milkshape-but-open, a GPLed exporter plugin is part of the LinWarrior3d distribution ;) and other modellers. There are serval libraries for loading and a lot of websites describing that format.
There is another similar and derived extensible format IQM (little-endian binary) and IQE (ascii). I prefer formats readable with a candle and a magnifying glass ;) for long-term-source-persistence. IQE can be used as a kind of source to be compiled to IQM. There are several open fps games supporting IQM/IQE but only Blender supports export - export only so far. No libraries so far but there is public domain sample code in the SDK. A drawback is that the sdk does not contain a IQE sample model - only IQM - kind of counter intuitive given that the sdk contains the IQE to IQM compiler.
That's what I found out when I was searching for a suitable fileformat.
Some more considerations regarding size, bandwidth and loading performance:
I've got a rather small model 476 Faces, 296 Vertices, 25 Bones, the binary MisfitModel 3d file is 58KB and the ascii md5mesh is 44KB only. If you compress them into zip files that ratio is even larger 18KB to 11KB. That's because modellers dump down whole state structures - binary game related formats may be smaller. But there is the tendency to save only what's needed in ascii and write down whole structs with binary. And with ascii you can control filesize by controlling precission of numbers (digits) - that would get you a size/quality tradeoff.
Of course there is a difference in loading performance (and overhead for writing a compatible robust parser) but as for the impact: Loading will virtually always consume fixed x% of your processing power the only question is what models your system can handle.
With the right datastructures loading scales linearly. I fully agree to Pompei2: Loading isn't the bottleneck, except if you needed thousands of models but then you'd probably stream the data anyway. And if bandwidth is a problem then compression may help.
http://www.atmind.nl/blender/mystery_ot_blend.html points out: Blender is a moving target and only dumps internal structures down - internal structures change => format changes. Yes, it's better to write an export plugin for blender and maybe blender supports (or eventually will) support commandline converts. And it's probably even easier and faster to 'buy' than to make.
Tartos, if you use http://jsfromhell.com/classes/binary-parser then I'm sure ascii is on par with binary for java/js because that code *parses* IEEE floats 32 bit, *bitwise*.
Just to make black and white things a bit more gray ;)
md5mesh and md5anim are quite "nice" text based and proven file formats. There are Exporters for Blender <2.5 and >=2.5
...
Tartos, if you use http://jsfromhell.com/classes/binary-parser then I'm sure ascii is on par with binary for java/js because that code *parses* IEEE floats 32 bit, *bitwise*.
Ok you convinced me :). I looked at this format and it seems to do the trick. It will save me some time. Thanks for the answers.