I use THREE.OBJLoader for import model obj I use code from https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_obj.html#L75 and i insert THREE.GeometryUtils.center for move model tothe original
var loader = new THREE.OBJLoader();
loader.addEventListener( 'load', function ( event ) {
var object = event.content;
for ( var i = 0, l = object.children.length; i < l; i ++ ) {
object.children[ i ].material.map = texture;
}
object.position.y = - 80;
scene.add( object );
});
THREE.GeometryUtils.center(object);
loader.load( 'obj/001939.obj');
I show error in firefox is"a.computeBoundingBox() is not function".Idon't know why show it's error. Iuse firfox version 17.0.1
Related
I am trying to render an object with UV maps and updating the texture with a loaded image thru Three JS. My problem is, I'm having artifacts on the rendered result. Why does this happen?
Notes:
Object is from a gltf file
I used blender for creating the model
I used KhronosGroup's blender gltf exporter for exporting the model
Image texture is 3239x2745 big
Here's my code
var inside_image = load_image("texture/inside.jpg");
var outside_image = load_image("texture/outside.jpg");
var textures = [];
Promise.all([inside_image, outside_image]).then((images)=>{
console.log('image', images);
for (var i in images) {
var canvas = document.createElement('canvas');
var compositeTexture = new THREE.Texture(canvas);
compositeTexture.wrapS = compositeTexture.wrapT = THREE.RepeatWrapping;
compositeTexture.repeat.y = -1;
var ctx = canvas.getContext('2d');
canvas.width = images[i].width;
canvas.height = images[i].height;
ctx.globalCompositeOperation = 'source-over';
ctx.fillRect(0,0,0,0);
ctx.drawImage(images[i], 0, 0, images[i].width, images[i].height);
compositeTexture.needsUpdate = true;
textures.push(compositeTexture);
}
loader.load(
'http://local.webgl.com/model.gltf',
function ( gltf ) {
console.log('gltf', gltf);
gltf.scene.traverse( function ( child ) {
if ( child.isMesh ) {
if (child.material.name == "Inside") {
child.material.map = textures[0];
} else {
child.material.map = textures[1];
}
console.log('child', child);
}
});
scene.add(gltf.scene);
// mixer = new THREE.AnimationMixer(gltf.scene);
// animations = gltf.animations;
},
// called when loading is in progresses
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened', error );
}
);
});
I'm using the following code to load OBJ objects, but in order to load the resulted group on a global variable, I pre-define the variable as 'null' which raises Type-error messages in Firefox console. I tried defining it as THREE.Group, THREE.Mesh, etc to no avail -those are causing the code to not execute.
How can I have the same functionality without those annoying error messages?
//this is causing Type-error messages in FF dev tools
var femModel = null;
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round(percentComplete,2)+ '% downloaded');//<<<<
}
if (percentComplete = 100){
waitmodeltoload();//<<<<<<
}
};
var onError = function ( xhr ) { };
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( 'female02/' );
mtlLoader.setMaterialOptions({ side:THREE.DoubleSide });
// the code in question:
mtlLoader.load( 'female02.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'female02/' );
objLoader.load( 'female02.obj', function ( object ) {
femModel = object;
}, onProgress, onError );
});
var waitid;
function waitmodeltoload(){
if (!femModel){
clearTimeout(waitid);
waitid = setTimeout(setupmodel, 100);
}
setupmodel();//<<<<<
}
function setupmodel(){
var intersects=null;
femModel.traverse( function ( child ) { // <<<<<<<<
if ( child instanceof THREE.Mesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
} );
femModel.position.set( 0, -90, 0 );
sceneR2S.add( femModel );
}
OK, that was simpler than I thought, it was a logical error of mine, I overlooked that the code was trying to access femModel before it was available:
So instead of:
var waitid;
function waitmodeltoload(){
if (!femModel){
clearTimeout(waitid);
waitid = setTimeout(setupmodel, 100);
}
setupmodel();
}
It should be:
var waitid;
function waitmodeltoload(){
if (!femModel){
clearTimeout(waitid);
waitid = setTimeout(setupmodel, 100);
}else{
setupmodel();
}
}
In the first case setupmodel() was called even if the model wasn't loaded.
An "else" was all that was needed -no more red-alert Type-error messages.
i'm trying to load my .obj & MTL file into threejs and apply simple wall collision using raycaster. The scene has walls and other objects.
Used pointer control example
the loading and texturing are in place
problem is when using raycaster it throws an error "cannot read property visible of undefined" I guess my referencing is bad.
i used scene.children for passing objects in raycaster
here is the code for ray caster and obj loader. please let me know where im going wrong
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl( 'neavik/' );
mtlLoader.setPath( 'neavik/' );
mtlLoader.load( 'room.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'neavik/' );
objLoader.load( 'room.obj', function ( object ) {
object.position.y = - 5;
object.scale.x=object.scale.y=object.scale.z=0.05
object.traverse( function( child ) { if ( child instanceof THREE.Mesh ) {
if (child.material.name == "Interior_wall") {
child.material = innerwall;
child.castShadow = true;
child.receiveShadow = true;
}
if (child.material.name == "Loby") {
child.material = innerwall1;
child.castShadow = true;
child.receiveShadow = true;
}
if (child.material.name == "TV_Black_Plastic") {
child.material = Black;
child.castShadow = true;
child.receiveShadow = true;
}});
object.name = "object";
scene.add( object );
});
} );
//Raycast
var rayCaster = new THREE.Raycaster(controls.getObject().position, cameraDirection);
var intersects = rayCaster.intersectObject(scene.children, true); //getting error on this line
$("#status").html("camera direction x: " + cameraDirection.x + " , z: " + cameraDirection.z);
// rest of the code
I had the same error and in my case the reason was that the object to be intersected was not existing yet or found at time of intersection.
Therefore I added a kind of null check to prevent this error message:
if (typeof scene != "undefined")
I'm having issues trying to load dds textures with SceneLoader.
I'm currently using version 69 of three.js. I have tried modifying the SceneLoader to use THREE.DDSLoader but my page stalls and produce no errors.
Modification:
var isCompressed = fullUrl.toLowerCase().endsWith(".dds"); // had to add prototype endsWith
//console.warn(isCompressed);
if ( isCompressed) {
var loader = new THREE.DDSLoader();
console.log(fullUrl);
var texture = loader.load(fullUrl);
}
else{
var loader = THREE.Loader.Handlers.get( fullUrl );
if ( loader !== null ) {
texture = loader.load( fullUrl, textureCallback );
} else {
texture = new THREE.Texture();
loader = new THREE.ImageLoader();
( function ( texture ) {
loader.load( fullUrl, function ( image ) {
texture.image = image;
texture.needsUpdate = true;
textureCallback();
} );
} )( texture )
}
}
Nevermind, I figured it out.
I needed to replace var texture = loader.load(fullUrl) with texture = loader.load( fullUrl, textureCallback );
Am I able to add progress event listener to THREE.OBJMTLLoader?
I've tried this but it didn't work...
var callbackProgress = function( progress, result ) {}
var loader = new THREE.OBJMTLLoader();
loader.callbackProgress = callbackProgress;
loader.load(...);
Unless the signature has changed this should work :
loader = new THREE.OBJMTLLoader();
loader.load
(
'thefile.obj',
'thefile.mtl',
function ( object )
{
// onload ...
scene.add( object );
animate();
},
function ( progress, result )
{
console.log (100 * progress.loaded / progress.total);
}
);