error
infos

How to load 3d model from different domain and display it with Three.js

Go to author's homepage | Go back to author's blog


The problem

For one of my Three.js projects i needed loading a 3d model(.js) + texture from different domain than the domain hosting the app itself. Everything i tryed with "THREE.JSONLoader" failed :-/ ...


The solution (1/2) : THREE.CrossDomainJSONLoader

... So i ended up  writing my own loader: "THREE.CrossDomainJSONLoader". Here is the code: (it's a bit dirty, but it works)

/**
 * 
 * Hack to load cross domain models, generated by obj_to_threejs converter from here
 * https://github.com/mrdoob/three.js/blob/master/utils/exporters/convert_obj_three.py
 * without changing generated models's code...
 * ...generates js files are supposed to run inside a worker, but workers dont support
 * cross domain scripts (yet??) :'( ...
 * 
 * Usage is EXACTLY the same as THREE.JSONLoader
 * 
 */
THREE.CrossDomainJSONLoader = function ( showStatus ) {

    THREE.JSONLoader.call( this, showStatus );

};

THREE.CrossDomainJSONLoader.prototype = new THREE.JSONLoader();
THREE.CrossDomainJSONLoader.prototype.constructor = THREE.CrossDomainJSONLoader;
THREE.CrossDomainJSONLoader.prototype.supr = THREE.JSONLoader.prototype;

THREE.CrossDomainJSONLoader.prototype.load = function ( parameters ) {

    var scope = this,
    	url = parameters.model,
		callback = parameters.callback, 
		texture_path = parameters.texture_path ? parameters.texture_path : this.extractUrlbase( url );
        
	this.onLoadStart();
    
    function _eval(src)
    {
        postMessage = function(model){};
        close = function(){};
        eval(src);
        return model;
    }
    
    var req = new XMLHttpRequest();
    req.open('GET', url, true);
    req.withCredentials = true;
    req.onreadystatechange = function (aEvt)
    {
        if (req.readyState == 4)
        {
            if(req.status == 200)
            {
                var tmp = _eval(req.responseText);
                scope.createModel(tmp, callback, texture_path);
                scope.onLoadComplete();
            }
            else
                console.log("ERROR loading model");
        }
    };
    req.send(null);
};





The solution (2/2) :  Access-Control-Allow-Credentials + Access-Control-Allow-Origin

On the server side, you will need to add 2 extra HTTP headers while serving files. Here is a simple php script i used for that:
Note that you can download all assets here: zip. This works for an app hosted here, on html5snippet.net, but to make it work with an app hosted somewhere else, simply replace "http://echo.html5snippet.net" by your own domain ;-)


<?php

header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Allow-Origin: http://echo.html5snippet.net');


if (isset($_GET['file']))
{
    switch($_GET['file'])
	{
		case 'texture.jpg':
			header('Content-Type: image/jpg');
			die (file_get_contents("texture.jpg"));
		break;
		
		case 'model.js':
			die (file_get_contents("model.js"));
		break;
	}
}


The problem (bis) : Browser Compatibility & Three.js version

Expect this hack to work only in latest versions of modern browsers. You'll also need to use the latest three.js release (r43 or r44). (Note that three.js version available on html5snippet has been updated )
       chrome:
           +chrome 14
           +chrome 16(canary)
           ?maybe it was working before chrome 14, not sure. BTW how can i downgrade chrome version ?
  
       firefox:
           +firefox 8.0a2 (aurora)
           -Before ff8, we have a "Security Error: code 1000"
  
       safari:
           -This link says webgl works in safari 5.1 (https://discussions.apple.com/thread/3300585?start=0&tstart=0)
            but, i can't find "Enable WebGL", so i think that it only works on Safari-Mac, not Safari-Windows release.
            ...If someone tested this on Safari-Mac 5.1, plz tell if that worked ;-)...
  
       IE:
           -NOTHING about supporting WebGL.... **** *** microsoft. Why do you hate web developers so much? :-/ 


The demo:



Comments (1)
You have to be logged in to be able to write comments.
jamad
Woa. Availability of 3d model + texture from different domain is super.
I definitely will try your loader to display the textured model next time.
Thanks for your great works.

I checked this post on Mac Safari 5.1.
The model was not visible on it, unfortunately...