Page 1 of 2

3D model format used by BabylonJS?

Posted: Mon Aug 01, 2016 3:16 pm
by GordenF
First of all, hi!
As some of you have probably noticed, Microsoft now offers customized Xbox One controllers on their 'Xbox Design Lab' page: https://xboxdesignlab.xbox.com/en-US/customize
As you can see, there's a pretty live 3D preview of the selected colors on that page as well, a kinda high-quality one even.
Sadly, the meshes consituting the controller model are compressed and/or encrypted, then stored in a proprietary format only used by BabylonJS (http://www.babylonjs.com).
Has anyone worked with this before? And are there other, better ways of ripping models from WebGL pages? I have tried the WebGL Inspector plugin for Chrome, but it kept crashing, so I got rid of it again.

FWIW, I put all the important files in a ZIP archive available here. They are weirdly numbered, but they should all be there.

Re: 3D model format used by BabylonJS?

Posted: Mon Aug 01, 2016 9:19 pm
by Acewell
controller.64_Front_Case.64_Front_Case.babylonbinarymeshdata :D
controller.64_Front_Case.64_Front_Case.babylonbinarymeshdata.png
the only file info is in the 20 byte footer
0x140124 - number of vertices
0x14012c - number of faces

to find the UV start address, multiply the number of vertices by 8 then
go to the face indices start address and go backward that amount

i think this thread will get more attention in the "3D/2D models" section :)

Re: 3D model format used by BabylonJS?

Posted: Tue Aug 02, 2016 3:34 am
by GordenF
Thanks, that's already super helpful!
That hex2obj tool looks promising, but I can't get it to work for the life of me. Never having worked with model files in-depth before, the tutorial goes right over my head.
Instead, I've started writing a Python script to help me understand what's going on, but I ran into some problems.

Let's take that controller.64(...).babylonbinarymeshdata file.
Assuming that there are 27635 vertices right at the start of the file, vertex data should start at 0x0 and go to 0x50f64.
(vertex count = 27635, times 4 because they're floats = 110540, times 3 because they're 3D vertices = 331620 == 0x50f64)

hex2obj even displays the last few floats on the left side, which confirms to me that I got everything concerning the vertices:
Image

Compare that with the last three floats my script gave me:

Code: Select all

-4.110263347625732, 0.6286904811859131, 2.081153631210327
Now, there are 0x50f64 other bytes that fill the space between the vertex data and what seems to be the UV data. What are those bytes?
I'm gonna go out on a limb here and guess that those are the normals...?
Right after that comes the UV data and after that the face indices.

Is all of that really needed when constructing an .obj file from scratch? hex2obj doesn't seem to mind, given the complete absence of the word "normals" in its UI.

It's very probable that the above is complete nonsense, but I feel confident, considering I've never done this before.

Thanks again for helping a beginner out. :)

Re: 3D model format used by BabylonJS?

Posted: Tue Aug 02, 2016 3:56 am
by Acewell
nice, it looks like you're picking it up quickly! :D
yeah those unused bytes here are likely the normals but Hex2obj doesn't deal with
normals so we just skip that data and fix any messed up normals in your favorite 3d software. :)

Re: 3D model format used by BabylonJS?

Posted: Tue Aug 02, 2016 4:50 am
by GordenF
I mean, I am a programmer, so it was only a matter of time :p

Still, I can't figure out how the UVs are stored. They seem to be 4 byte floats, but I'm unsure on how many there are.
According to hex2obj, they start at 0xa1ec8 and end at 0xbd638. Then what's the data between 0xbd638 and 0xd7e60, where the indices are?
It seems those are floats as well, because my script will happily read up to 0xd7e60 and treat the data as (correct-looking, ie. not hilariously out-of-bounds) floats without a hitch.
They even look like another set of UVs, what with every float being in the range of 0.0-1.0, but I have no idea what to do with them.

Edit: Even if those other floats aren't needed, like the normals, I still don't know how to calculate the length of the UV data block.
Currently I'm just doing

Code: Select all

file_length - texcoord_data_start - FOOTER_LENGTH - index_count * 4
where index_count is the number of indices. Obviously, this isn't good enough. Can you come up with a better way by chance? :)

Edit 2: Actually, I've been misinterpreting hex2obj's output. The UV data doesn't end at 0xbd638, but at 0xbd650. Hmm.

Edit 3: Same thing with the indices. There are 27635 indices in that file, but hex2obj only counts up to 14066. Where does it get its data from?

Re: 3D model format used by BabylonJS?

Posted: Tue Aug 02, 2016 7:31 am
by Acewell
the size of the UV block is vertices * 8

the UV block starts at 0xa1ec8 and ends at 0xd7e5f


all data is accounted for unless i'm really bad at math :D

vertex block
27635 * 12 = 331620
+
normals block
27635 * 12 = 331620
+
UV block
27635 * 8 = 221080
+
face indices
106671 * 4 = 426684
+
footer
20 bytes
_____________
1311024 bytes

Re: 3D model format used by BabylonJS?

Posted: Tue Aug 02, 2016 2:13 pm
by GordenF
Oh. Guess hex2obj was psyching me out.
There's only one thing remaining then, and that's getting all this data into a format that's easy to work with.
My primitive obj exporter has some weird issues though.
Here's my code so far: https://gist.github.com/SamusAranX/6342 ... 9b1422f1f1

If I just let my script write out everything, the resulting model looks like this:
Image
Before that, I wrote everything into the obj file, but accidentally commented out the first vertex.
Weirdly enough, the model looked fine then (if you ignore that long, misplaced polygon and the fact the the normals seem to be hecked up)
Image
Also, it seems that OS X's obj parser is a lot more lenient than Blender's. Blender won't even load these abominations. :D

I'm pretty sure that the issue is that I don't really understand the OBJ format, and with hex2obj's mesh exporter constantly failing on me, I have nothing to compare my result to.
Could you help me with that again? :)

Re: 3D model format used by BabylonJS?

Posted: Tue Aug 02, 2016 3:34 pm
by Gh0stBlade
Topic moved as requested :)

Re: 3D model format used by BabylonJS?

Posted: Tue Aug 02, 2016 5:20 pm
by shakotay2
GordenF wrote:and with hex2obj's mesh exporter constantly failing on me,
I don't see where the problem should be - File/SaveAs mesh results in an obj file (controller.64_Front_Case.64_Front_Case_0.obj) which can be imported into blender for example:
controller_64_Front.JPG

Re: 3D model format used by BabylonJS?

Posted: Tue Aug 02, 2016 5:49 pm
by GordenF
I always get the message that MSVCR100.dll is missing when hitting the appropriate buttons.
I have installed every VC++ redistribution imaginable, but apparently, that isn't enough.

Re: 3D model format used by BabylonJS?

Posted: Tue Aug 02, 2016 10:34 pm
by Acewell
i made a Noesis python script to open your babylonbinarymeshdata model samples :D
fmt_BabylonJS.zip
it works with all of them, but controller.48_R_Thumsticktop.48_R_Thumsticktop.babylonbinarymeshdata
was a special case and had a 40 byte footer so i added a condition just for that one so all could be opened [bruce]

edit
anyone know how to flip the UV data in Noesis python?
i need to flip it on U to get it lined up with the textures :oops:

Re: 3D model format used by BabylonJS?

Posted: Wed Aug 03, 2016 1:55 pm
by GordenF
I thank you for your efforts, and while I'd love to use your script, my Windows 10 installation just nuked itself after this Anniversary Update. So much for that, I guess.
Though, while Windows was busy self-destructing, I went through the BabylonJS GitHub repos on my phone and found a C# program made to convert "regular" models into the babylonbinarymeshdata format.
Interestingly enough, that 20 byte "footer" actually consists of 5 ints of submesh information and can appear multiple times (as it does in that 48_whatever file) if there are multiple submeshes!
Also, I took a closer look at the controller.binary.babylon file that I previously ignored (because it looked like a bunch of scene setup gibberish to me), and lo and behold, it actually contains a bunch of useful information.
Major derp on my part :ninja:
Every object in that JSON file has a key called "_binaryInfo" that contains the offsets and lengths of every important data block. Formatted for readability, here's 48_R_Thumsticktop's _binaryInfo:

Code: Select all

"_binaryInfo": {
  "subMeshesAttrDesc": {
    "offset": 456032,
    "dataType": 0,
    "count": 2,
    "stride": 5
  },
  "uvsAttrDesc": {
    "offset": 198600,
    "dataType": 1,
    "count": 16550,
    "stride": 2
  },
  "indicesAttrDesc": {
    "offset": 264800,
    "dataType": 0,
    "count": 47808,
    "stride": 1
  },
  "normalsAttrDesc": {
    "offset": 99300,
    "dataType": 1,
    "count": 24825,
    "stride": 3
  },
  "positionsAttrDesc": {
    "offset": 0,
    "dataType": 1,
    "count": 24825,
    "stride": 3
  }
}
I'm not sure how that submesh business is supposed to work, but using all this to parse the regular models should be easy enough.

Re: 3D model format used by BabylonJS?

Posted: Wed Aug 03, 2016 6:34 pm
by Karpati
A subMesh is defined by the following JSON:

{
"materialIndex": int,
"verticesStart": int,
"verticesCount": int,
"indexStart": int,
"indexCount": int
}

Re: 3D model format used by BabylonJS?

Posted: Wed Aug 03, 2016 8:23 pm
by Karpati
GordenF,

The line of a face command contains the enumerations of the points in the face, as 1-based indices into the list of points, in the order they occurred in the file. For example, the following describes a simple triangle:

# Simple Wavefront file
v 0.0 0.0 0.0
v 0.0 1.0 0.0
v 1.0 0.0 0.0
f 1 2 3

Re: 3D model format used by BabylonJS?

Posted: Thu Aug 04, 2016 10:19 am
by GordenF
I have pretty much given up on my script. (:
I'll probably come back to it in a week or so to clean it up, but right now it's a mess.
It would probably be easier to just wade through the thousands of files on the BabylonJS repo and copy their importer.
Anyway,

@AceWell: Finally got around to setting up a Windows VM. Your script worked flawlessly, thanks. :)
Image

@Karpati: If I remember correctly, the number of vertices and indices is different in each model.
How would I handle that?