Hello guys, I am a new user but would like to suggest the use of FileReader API (http://blog.teamtreehouse.com/reading-files-using-the-html5-filereader-api) to upload files (OBJ, STL...) in Three.js loaders.
FileReader API enable the user to upload files locally too. I inserted this script in my STLLoader.js
THREE.STLLoader.prototype.load2 = function(files, callback) {
var scope = this;
var file = files.files[0];
var reader = new FileReader();
reader.onload = function(event) {
if (event.target.readyState === 2 || event.target.status === 0) {
var geometry = scope.parse(event.target.result || event.target.responseText);
scope.dispatchEvent({type: 'load', content: geometry});
if (callback)
callback(geometry);
} else {
scope.dispatchEvent({type: 'error', message: 'Couldn\'t load URL [' + url + ']', response: event.target.readyState});
}
};
reader.readAsArrayBuffer(file);
};
How come it can load local files?
Imagine that you need to load a STL file but you don't have the localhost server. FileReader API allows the user do this and XMLHttpRequest() does not support.
Example
HTML:
<input type="file" class="filestyle" data-icon="false" id="stl" onchange="start(this)" >
JS
function start(file){
init();
loadSTL(file)
animate();
}
function loadSTL(file){
loader = new THREE.STLLoader();
loader.addEventListener('load', function(event) {
var geometry = event.content
var material = new THREE.MeshPhongMaterial({ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200});
var mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
});
loader.load2(file);
}
STLLoader.js
THREE.STLLoader.prototype.load2 = function(files, callback) {
var scope = this;
var file = files.files[0];
var reader = new FileReader();
reader.onload = function(event) {
if (event.target.readyState === 2 || event.target.status === 0) {
var geometry = scope.parse(event.target.result || event.target.responseText);
scope.dispatchEvent({type: 'load', content: geometry});
if (callback)
callback(geometry);
} else {
scope.dispatchEvent({type: 'error', message: 'Couldn\'t load URL [' + url + ']', response: event.target.readyState});
}
};
reader.readAsArrayBuffer(file);
};
If you want to know more about File Reader API, look:
http://blog.teamtreehouse.com/reading-files-using-the-html5-filereader-api
Has this feature been added to ThreeJS collada loader?
Why not add it as separate component, since the same code cannload any file format? User loads the file in a Blob, generates URL, and pass it to Loader instance.
Possibly even read magic number from the Blob file, and initiate the correct Loader.
mrdoob, how come you closed this? Is the suggestion about using FileReader already implemented in ThreeJS?
I don't think this needs to be added to the loaders. I think this can be done in the application layer and pass it to the loaders instead.
I do a similar thing in the editor:
https://github.com/mrdoob/three.js/blob/dev/editor/js/Loader.js#L17-L421
Thanks mrdoob. Thanks to your reply I realized your Editor is a great framework for me to build on. I'm trying to convert our Energy3D project (http://energy.concord.org/energy3d/) from java to javascript.
One questions though: when I make a change in the scene, I have to move the scene with mouse to force Editor to render the new scene. How can I render the updated scene via code?
One questions though: when I make a change in the scene, I have to move the scene with mouse to force Editor to render the new scene. How can I render the updated scene via code?
Keep studying the code 馃槈
Studied the code :) Looks like the code I'm looking for is in Viewport.js:
Viewport.render()
But unfortunately the above method is declared private. Do I need to make it public? Or is there a better way?
Found it. I can simply call this:
editor.signals.sceneGraphChanged.dispatch();
I only wish "editor" was singleton so I could call Editor.getInstance() instead of declaring editor as a global variable.
Found it. I can simply call this:
editor.signals.sceneGraphChanged.dispatch();
馃憤
I only wish "editor" was singleton so I could call Editor.getInstance() instead of declaring editor as a global variable.
Some day...
Most helpful comment
Imagine that you need to load a STL file but you don't have the localhost server. FileReader API allows the user do this and XMLHttpRequest() does not support.
Example
HTML:
JS
STLLoader.js
If you want to know more about File Reader API, look:
http://blog.teamtreehouse.com/reading-files-using-the-html5-filereader-api