Extending THREE.BinaryLoader? #1942

patrickkidd opened this Issue May 18, 2012 · 8 comments

3 participants


How would you suggest I extend THREE.BinaryLoader? I'd like to augment it by adding support for morph targets after the current loading code.

Would it be possible to add createBinModel() and parseMetaData() to THREE.BinaryLoader (and change the call from THREE.BinaryLoader.prototype.createBinModel( xhr.response, callback, texturePath, json.materials ); to this.createBinModel( xhr.response, callback, texturePath, json.materials ); ) so we could override them as necessary in a subclass, or maybe add THREE.BrinaryLoader.init_extra_data( data, start )?



@alteredq So for now I edited BinaryLoader.js to call BinaryLoader.init_extra_data which can be overridden in a subclass. I also edited exporters/obj/convert_obj_to_three.py to take JSON input and produce binary output and include morph targets & morph normals, although so far have only tested it with smooth tris.

Are you at all interested in this? If so would it help if I reorganized it at all? If you are not interested in the binary morph targets then can we at least make it possible to extend THREE.BinaryLoader?

--- a/src/loaders/BinaryLoader.js
+++ b/src/loaders/BinaryLoader.js
@@ -38,7 +38,7 @@ THREE.BinaryLoader.prototype.load = function( url, callback, texturePath, binary
 THREE.BinaryLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, binaryPath, callbackProgress ) {

    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {

        if ( xhr.readyState == 4 ) {
@@ -71,6 +71,7 @@ THREE.BinaryLoader.prototype.loadAjaxBuffers = function ( json, callback, binary
        url = binaryPath + "/" + json.buffers;

    var length = 0;
+   var context = this;

    xhr.onreadystatechange = function () {

@@ -78,7 +79,7 @@ THREE.BinaryLoader.prototype.loadAjaxBuffers = function ( json, callback, binary

            if ( xhr.status == 200 || xhr.status == 0 ) {

-               THREE.BinaryLoader.prototype.createBinModel( xhr.response, callback, texturePath, json.materials );
+               context.createBinModel( xhr.response, callback, texturePath, json.materials );

            } else {

@@ -116,8 +117,13 @@ THREE.BinaryLoader.prototype.loadAjaxBuffers = function ( json, callback, binary

 // Binary AJAX parser

+THREE.BinaryLoader.prototype.init_extra_data = function ( data, start, geometry ) { }
 THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texturePath, materials ) {

+    var context = this;
    var Model = function ( texturePath ) {

        var scope = this,
@@ -179,6 +185,8 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture
        start_quad_flat_uv  = start_quad_smooth   + len_quad_smooth    + handlePadding( md.nquad_smooth * 2 );
        start_quad_smooth_uv= start_quad_flat_uv  + len_quad_flat_uv   + handlePadding( md.nquad_flat_uv * 2 );

+       start_extra_data    = start_quad_smooth_uv  + len_quad_smooth_uv   + handlePadding( md.nquad_smooth_uv * 2 );
        // have to first process faces with uvs
        // so that face and uv indices match

@@ -195,6 +203,8 @@ THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texture

        init_quads_flat( start_quad_flat );
        init_quads_smooth( start_quad_smooth );
+       context.init_extra_data( data, start_extra_data, this )



It's kinda hard to see what's going on here.

The most usual way how to deal with changes here on GitHub is simply to make commits to your clone (single branch per feature is the cleanest way) and then we can see everything in context.

GitHub has nice interface to show both "big picture" overview of how branches from multiple clones relate to each other and also you can then drill down to see individual per-file differences for each commit (when you click on dots):



I went through the changes and I'm bit lost here, why is there JSON parser in OBJ converter? How is your pipeline?

So far OBJ converter was used like this: one or more OBJs were read as input and these were then used to generate either ascii or binary model.

For ascii output, if there were multiple OBJs, vertices were extracted and added as morph frames.

For binary output, only single OBJ could be used to generate static model.

So for adding morph normals to binary format generated by OBJ converter I would expect something similar - reuse internal Python data structures generated by parsing OBJs to create binary data directly (instead of going via JSON).

Now if you wanted to have ascii => binary formats converter, this would be probably better handled as a separate tool.

Though maybe it would make a sense to spin out some functions out of OBJ converter into a separate Python module(s) so the code could be reused (and not just here, other three.js pipelines with Python could benefit from this as well).


I'm not sure how to solve this in some nice way, maybe @mrdoob would have some ideas?

Summary for @mrdoob:

It seems we came at the point where it could be beneficial to have a Python module for dealing with three.js models, some common methods that could be used in different asset pipelines and tools (mainly for parsing of models and for generation of models).

Now the question is how to structure this.

For now, every tool stands completely on its own, which is kinda neat because you don't know where they will end up (e.g. for Blender tools to work, they go into own Blender folders).

But it's also bad as there is a lot of code replication (so for example you are not guaranteed JSON handling is exactly the same everywhere).

If we had a separate Python module (let's say three.py), then this would need to be either copied to each tools folder (and then we could simply do import three) or we would need to centralize somehow this module so all tools could share the same file.

Which could be for example achieved by installing this module into Python. But even this wouldn't still solve everything, as for example Blender has its own Python installation, independent of system's Python installation. Also it would complicate the process, installing is worse then just copying files.

Bah, I'm lost here, it's messy :S


Sorry for the delayed response...

On unix-based systems you could just use symlinks to solve this. The problem here is Windows. Even if it's sounds like a pain, I think the simplest solution for this case would be copying the three.py lib by hand...

@mrdoob mrdoob closed this Feb 15, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment