Jump to content
  • Advertisement
bzt

New 3D model format and single header SDK

Recommended Posts

On 11/5/2019 at 3:20 PM, Sacaldur said:

First of all, you have to think about when it's used in the entire development cycle.

First of all, you should read the repo's main README. It starts by explaining exactly that. Why this format was created, and who is its target audience.

In short, this format aims to be used in engines, it is optimized for fast load times, but also to be a distribution format (you can embed the materials and textures and it is small, therefore saves storage space and network traffic). What it is not, a designer format that can store all aspects of a modeller software, I leave that job to the modeller software's native format (after all, they were developed for that only purpose).

If we want to compare it to 2D images, then this format is not a PSD, it does not store layers, history etc.; it is rather a PNG, which can store all aspects of the resulting product (dimensions, exif data, palette, etc.) with high efficiency and compression. You won't get an undo history by opening a PNG, but you'll get the image properly and entirely, there's no missing data (unlike with existing 3d model formats).

On 11/5/2019 at 3:20 PM, Sacaldur said:

either small size or (what most will prefer nowadays) fast load times

You speak of these if they were exclusive. The point is, they are not. Actually quite the contrary, a smaller file can be loaded faster from disk :-) With this Model 3D format, you can have both (that's why I invented it!).

For example, I've converted a high-resolution model of Bat Mobile which I've downloaded. The original was 22 Megabytes in binary FBX (and textures were separated files), but in M3D that's only 1.6 MBytes (with textures embedded). Obviously it is faster to load and parse 1.6M than 22M. But let's put deflate aside, the plain binary M3D is only 2.4 Mbytes (with textures), 90% smaller than the binary FBX just because it has better data representation and much higher information density. And I haven't spoken about the post-process yet, the FBX variant had to be converted a lot to finally display it, while the M3D version can be sent into a VBO directly (no in-memory conversion or further parsing needed at all).

Another example, in Minetest mobs_dwarves mod, there's a Blitz3D model with animation. It is 151 K. After converting into M3D, it is only 8 K (compressed to 0.05%!!!), and all information is there, nothing is missing, you have all the materials, their names, texture references etc., and you can replay all frames exactly as they were in the original. I can't stress enough how much work I put into this format to be better than any existing format. And it is better :-D

On 11/5/2019 at 3:20 PM, Sacaldur said:

only the engine developers are your target audience.

No. They are definitely targets, sure, but not the only one. This format is capable of storing all aspects of a model within a single file, because I hate that you can't download a complete model in a single file (textures are missing, mtl file is missing etc. which you can only see when you unzip). So it is also designed to be a model distribution format which does not need additional files and zip.

On 11/5/2019 at 3:20 PM, Sacaldur said:

For all of these, a text format is easier to handle

That's why it also has an ASCII variant. However I'd prefer to store the modeller's native format (BLEND for example) if I were in the designer's shoes, instead of any text-based format (those are for interchanging models between software, and not for storing all software-specific options. Hell, you can't even store a bone hierarchy in OBJ. And they are SLOOOW on load).

18 hours ago, Shaarigan said:

It is fast load times in nearly any case

Agreed. It is not pleasant to download 60 Mbytes, open it in a modeller software, wait a minute for the importer, just to find out that materials or texture are missing, named differently, so you can't actually use the model.

Let's not forget smaller files can be downloaded much faster (which is specially important if your game is server-based and you're sending models to the clients).

Because you haven't answered my question about the sprintf, I'll assume everything is fine with it (and you shouldn't use ASCII format in the first place :-) ).

Cheers,
bzt

 

Share this post


Link to post
Share on other sites
Advertisement
6 hours ago, bzt said:

First of all, you should read the repo's main README. It starts by explaining exactly that. Why this format was created, and who is its target audience.

Yes, it states that other formats have certain drawbacks, and that's why this new format was created, but it doesn't explain where it wants to belong. 

 

6 hours ago, bzt said:

You speak of these if they were exclusive.

There's always a tradeoff. You can either optimize for calculation times, or you can optimize for memory usage. Yesm your file format is smaller than others and faster to load, but if someone now wanted to optimize it even further, they could either make changes to the format so the stored data more closely resembles the data structures used by the application, or the data is compressed even further. (Keep in mind that uncompressing and converting data needs time.)

Share this post


Link to post
Share on other sites

Professional engines mostly have an own data compression anyways (or even an own data format that plays well with the compression) and are optimized to streaming the data on demand when it is needed. The question is if developers will use the format in their engines or if it stays a development time exclusive thing.

Then that's my point on this topic, it depends if it finally fits into their workflow and can be exported from Maya oder 3dsMax (because these software is industry standard). I honestly don't see people convert an art software export to the file format, just to convert it to an engine asset

Share this post


Link to post
Share on other sites

Thank you guys for your interest! I have a feeling that you're seriously underestimating how prepared and experienced I am on this topic. But that's okay 🙂

4 hours ago, Sacaldur said:

but it doesn't explain where it wants to belong.

I think it does. Can you suggest a better phrasing that would make it clearer? I'd appreciate that.

4 hours ago, Sacaldur said:

they could either make changes to the format so the stored data more closely resembles the data structures used by the application

NO WAY! That's insane! Can you imagine that Photoshop or Gimp changes the PNG format as they please??? The M3D specification clearly states that the model file must store data related to the model, and only to the model, no application specific modifications allowed in basic data structures. For example, model stored with well-defined orientation (it does not care if your app is +Y up or -Z up, that has nothing to do with the model itself). If you need application specific data, you can have them in additional chunks, which does not interfere with other applications.

4 hours ago, Sacaldur said:

or the data is compressed even further.

Not possible either. I've spent months to study the topic and define the bare minimum information needed to store a model with skeletal animation, there's nothing you can take away without compromising data integrity. On the other hand, you can use a different stream compression algorithm in your engine if you like (or just use the plain binary without stream compression to speed up loading), no-one stops you from doing so. However distributed files are required to use RFC 1951 deflate only, the specification mandates that (and for a good reason).

And about data representation, I've used architecture limited quantities, you can't go below to shrink the model further. I've already introduced a quality setting in the model files, because high-resolution models (over 65556 polygons) may loose some surface details with the best compression (only noticeable if you zoom in to the model closely).

4 hours ago, Sacaldur said:

Keep in mind that uncompressing and converting data needs time.

I'm well aware, thank you. I've made performance measurements. That's why the SDK autodetects if the model is stream compressed, and works without deflate too, and that's why all of the conversions are done in a converter tool during export, so that loading only needs to deal with a simple, well-defined structure. Let me put it this way: I've moved all the complexity from the loader's shoulders away into the exporters.

3 hours ago, Shaarigan said:

Professional engines mostly have an own data compression anyways

And they s*ck. How big their installer is? 1G? 10G? Lempel-Zip-Welsh did a really good job in the 70's which is fast and compact enough. There's a reason why it is still being used 50 years later. Bzip2 or 7z may provide a better compression ratio, but require more resource and are much slower to uncompress. Homemade compressions are ALWAYS worse than LZW, if you want I can give you a mathematical proof of that (as a matter of fact LZW only fails in one case when the occurance distribution of samples to build Huffman-trees is actually the Fibonacci numbers, which is highly unlikely with real-life distribution).

3 hours ago, Shaarigan said:

can be exported from Maya oder 3dsMax (because these software is industry standard)

If you need those, you are welcome to implement them. Blender plugin is provided as a sample and Proof of Concept, and the license is MIT. Open Source rulez 🙂 I'd really like to see you as a contributor to M3D!

3 hours ago, Shaarigan said:

I honestly don't see people convert an art software export to the file format, just to convert it to an engine asset

Professional engines all do this, converting into an engine asset. And all good Open Source engines too. For example the Unity editor imports models in formats that people exported from art software. Orge3D also converts models in art software format into .mesh. Megaglest likewise, but into .g3d. Shall I continue the list? M3D is no different, you can use the m3dconv tool to create .m3d files from .max, .blend, etc. and also from interchange model formats like .fbx, .dae, .ase, .obj, .stl, .ply etc. The only difference is, .m3d is also good for distribution and for your engine, therefore you can omit m3dconv from your build procedure without increasing the complexity of your engine's source. (Note: M3D can be your engine asset format, it was designed that way. If you need to convert a lot to fit its m3d_t in-memory structure into your engine's, then your engine is designed poorly and it will s*ck with VBOs no matter what (like Assimp does). Just stating the obvious).

Cheers,
bzt

Share this post


Link to post
Share on other sites

Just to be clear, by compression I mean two different things:

1. the way how the abstract data is encoded in binary form, which I call data representation. This involves high level things like storing transformation matrices (12 floats min) or position+rotation quaternions (3+4 floats) instead, and also low level things like how many bits are used for a vertex index, how are strings encoded and such.

2. stream compression, which does not care about 1., rather encodes more often used patterns with smaller bit-chunks (typically the LZW algorithm)

The 1. point is specific to the format (and in which M3D is far better than the competition), while the 2. is optional (for that M3D uses standardized RFC 1951 deflate). Making binary representation (1.) smaller speeds up loading time, while using more complex algorithms for 2. to make the model smaller slows down loading time.

Cheers,
bzt

Share this post


Link to post
Share on other sites

Hi,

I've put together a small mobile-friendly webpage for the Model 3D format. I hope this helps to clearify what this format is all about.

https://bztsrc.gitlab.io/model3d/

I've uploaded a handful of M3D models too, so that you can play with them. I took the original models from FOSS games with permissive license, or downloaded them from websites which claimed that the models are free to use. If you find your own model here, let me know so that I can properly attribute you (or remove the model if that's your wish).

Cheers,
bzt

model3d.png

Share this post


Link to post
Share on other sites

Hi,

I'm proudly present that the M3D format is now officially finalized. It has all the features I wanted it to have. List of changes:

The M3D SDK has serious performance improvements, specially on export side. The API hasn't changed, but a few new arrays has been added to m3d_t. Test cases now cover all combinations of binary / ASCII format with bone transformation matrices generation and smooth normal vectors generation.

Support for CAD models have been added. Parameterized shapes, translatable UTF-8 annotations as well as a preview images are now supported.

The m3dconv utility now has its own OBJ parser, which can handle everything that Assimp and tinyobjloader, plus negative indices and free-form definitions too: polylines, Bezier and B-spline curves, Bezier surfaces and NURBS. (Just a side note, tinyobjloader has a C version too, which is almost as fast as this OBJ parser. It is only slower because it uses a float parser implemented in C, while m3dconv uses hardware-optimized, platform specific function from libc (both glib and musl has an Assembly optimized version)).

A dependency-free STEP (ISO-10303-21-4) parser is work in progress. With only 200 SLoC, it can read and tokenize any STEP file I could find; now it only needs a grammar parser (which should not be difficult considering we just need curves and surface definitions, CARTESIAN_POINTs are already converted to floats and indexed properly).

A new feature has been added, the m3dconv utility can now convert any texture format into PNG on-the-fly when creating distribution models (requires libpng and libimagequant).

The m3dview portable viewer has been updated to use VBOs that are compatible with OpenGL 3.3 vertex shaders (although I left the old, pure OpenGL command version too because I think it's code is more readable and more helpful.)

I've done some serious tests and measurements. For this, I've slightly modified the assview.c from asstools so that it exits immediately after the first render cycle. Similar modification was made to m3dview, so that these measurements include everything from model loading, parsing and rendering. Both viewers were linked against GLFW to use the same framework, and both are now building a VBO.

As a test subject, I've chosen SGC Atlantis, with more than 2 million triangles (model can be downloaded from the Model 3D website). The Assimp version parsed a COLLADA file, which had many references to the same parts of the mesh (therefore coordinates had to be transformed in run-time), and was 11 Megabytes in size. The M3D version was bigger, 21 MegaBytes, because it is important in M3D that a simple, only mesh-aware parser should be able to read the entire object, therefore it stores all over 2 million triangles directly (no run-time transformation needed). The COLLADA file had 2117 meshes, while the M3D only 23 material switches.

The results: to load and render the COLLADA file with Assimp, the average was 2.5 secs. The same with the M3D SDK was 1.2 secs. In both cases these results include the VBO generation, which only has to be done once after model loading. BTW that took 0.3 secs for the m3dview, but after all, more than 270 MegaBytes of RAM required for that many polygons, vertices and their attributes (more than 2 million triangles are quite a lot, the model is *very* detailed).

Cheers,
bzt

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!