0
votes

I'm using three.js and I have put together a mesh (.obj), a material (.mtl) and a couple of textures into a single JSON object.

The mesh and material come from Blender's wavefront obj export.

The JSON (truncated):

{
    "data": {
        "type": "b64obj",
        "material": "--Long base64-encoded Material data--",
        "mesh": "--Long base64-encoded Mesh data--",
        "textures": {
            "texture.jpg": "base64-encoded image",
            "anothertexture.jpg": "base64-encoded image",
        }
    }
}

Here is the routine that loads it (without the base64-decoding part):

var mtlLoader = new THREE.MTLLoader();
var materials = mtlLoader.parse(data.material);
materials.preload();

var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
var object = objLoader.parse(data.mesh);
renderObj(object); //start using it inside the application once it is there

The .mtl refers to image files and the MTLLoader would expect them on hard drive. How do I tell to use the object with the textures inside instead?

1

1 Answers

2
votes

Brace yourself, this is going to get hacky. You need to monkeypatch MTLLoader and intercept requests for those URLs, replacing them with your Data URIs.

var json = JSON.parse(myJSON);

var _loadTexture = THREE.MTLLoader.MaterialCreator.prototype.loadTexture;

THREE.MTLLoader.MaterialCreator.prototype.loadTexture = function ( url, mapping, onLoad, onProgress, onError ) {

  url = json.data.textures[ url ] || url;
  return _loadTexture( url, mapping, onLoad, onProgress, onError );

};

I've proposed a less hacky way of doing this — I use it to support drag-and-drop — but am not sure whether it's common enough to be officially supported.