Three JS OBJloader - obj not importing properly - javascript

i'm trying to import an obj with OBJLoader but it isn't importing properly
The obj is like this -
Obj img
And it's importing this -
Obj in three js
What happens is that the whole obj isn't importing well.
What can i do about it ?
The code that i'm doing is
var objLoader = new THREE.OBJLoader();
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setTexturePath("obj2/");
mtlLoader.setPath( "obj2/" );
mtlLoader.load( "Mules/Base_10.mtl", function( materials ) {
materials.preload();
objLoader.setMaterials( materials );
objLoader.load( 'obj2/Mules/Base_10.obj', function ( object ) {
object.traverse( function ( child )
{
if ( child instanceof THREE.Mesh )
{
meshes.push(child);
}
});
var object = meshes[meshes.length-1];
object.position.y = -0.05;
object.position.x = 0;
object.position.z = 0;
object.name = "salto";
scene.add(object);
}, onProgress, onError );
});
Thank you.

The problem is:
object.traverse(...);
var object = meshes[meshes.length-1]; //<-- you overriding the object, with the last mesh.
object.position.y = -0.05;
object.position.x = 0;
object.position.z = 0;
object.name = "salto";
scene.add(object); //<-- than you add the object to your scene.
do not override the object. Also you don't need to traverse through the objects, as you will add the whole thing to your scene. and you do nothing with your meshes anyway :)
so try this:
object.position.y = -0.05;
object.position.x = 0;
object.position.z = 0;
object.name = "salto";
scene.add(object);

Related

Three.js animation mixer not playing?

Ok I have an fbx successfully loaded into Three.js exported from blender with all animation boxes checked. Ive tried all export settings from blender so that's not it.
This is how I bring the model in, and I am able to accurately determine whether the fbx has animations or not:
var geoFromScene = new THREE.Geometry();
var FBXLoader = require('three-fbx-loader');
var loader = new FBXLoader();
loader.load(string, function ( object ) {
object.traverse( function ( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
geoFromScene = (new THREE.Geometry()).fromBufferGeometry(child.geometry);
}
} );
var theModel = new THREE.Mesh();
theModel.geometry = geoFromScene;
theModel.material = material;
theModel.position.set(5,5,-8);
//theModel.rotation.set(new THREE.Vector3( 0, MATH.pi/2, 0));
theModel.scale.set(0.1, 0.1, 0.1);
localThis.scene.add(theModel);
localThis.mixer = new THREE.AnimationMixer(theModel);
if(theModel.animations[0])
{
var action = localThis.mixer.clipAction(theModel.animations[0]);
action.play();
} else {
console.log("No animations");
}
} );
In update (which does work, because I can print the animation.time):
this.mixer.update(this.clock.getDelta());
And yet the model is just static. Whats wrong here?
UPDATE:
code from example copy pasted-
var geoFromScene = new THREE.Geometry();
var FBXLoader = require('three-fbx-loader');
var loader = new FBXLoader();
loader.load( string, function ( object ) {
localThis.mixer = new THREE.AnimationMixer( object );
var action = localThis.mixer.clipAction( object.animations[ 0 ] );
action.play();
object.traverse( function ( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
} );
object.position.set(5,5,-8)
object.scale.set(0.1, 0.1, 0.1);
localThis.scene.add( object );
} );
in animate-
this.mixer.update(this.clock.getDelta());
All I get is the model armature it seems -
New approach:
var FBXLoader = require('wge-three-fbx-loader'); //https://www.npmjs.com/package/wge-three-fbx-loader
var loader = new FBXLoader();
loader.load( string, function ( object ) {

How to use multiple texture use in `OBJLoader` three.js?

How to multiple textures material use in Three.js?.Here three textures using and one 3D sofa.obj format file. I tried a lot of time. Below my code. What do I mistake in my code?
var loader = new THREE.OBJLoader();
var textureLoader = new THREE.TextureLoader();
threeDTexture = new THREE.ImageUtils.loadTexture( 'models/Sofa/Texturses/paradis_beige.jpg' );
threeDTexture2 = new THREE.ImageUtils.loadTexture( 'models/Sofa/Texturses/1.jpg' );
threeDTexture3 = new THREE.ImageUtils.loadTexture( 'models/Sofa/Texturses/2.jpg' );
loader.load('models/Sofa/sofa.obj', function (object) {
var geo = object.children[0].geometry;
var mats = [threeDTexture, threeDTexture2,threeDTexture3];
objct = new THREE.Mesh(geo, mats);
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = objct;
}
});
object.position.x = posX;
object.position.y = 0;
object.position.z = posZ;
var size = new THREE.Box3().setFromObject(object).getSize();
object.scale.set(width/size.x, height/size.y, depth/size.z);
scene1.add(object);
console.log(object);
console.log(size);
console.log(width/size.x, height/size.y, depth/size.z);
},
function ( xhr ) {
returnValue = ( xhr.loaded / xhr.total * 100 ) + '% loaded';
console.log(returnValue);
},
function ( error ) {
console.log( 'An error happened' );
}
);
break
first, the textureLoader declared on line-2 is not in use;
second, belowing mats is not an Material Array, you should new MeshBasicMaterial(...) to wrap a texture, see the document here.
var mats = [threeDTexture, threeDTexture2,threeDTexture3];
objct = new THREE.Mesh(geo, mats); // Mesh will not accept this mats param!

OBJLoader and MTLLoader aren't rendering png/texture in ThreeJS

I imported the 3D model that contains .obj .mtl and bunch of jpeg and pngs
trying to load the model with /images like this
But, I'm getting is only a black model like his
I wonder what I have missed as I followed the guidelines for using the two loaders.
here is my code.
//loader
var MTTLoader = new THREE.MTLLoader();
MTTLoader.setPath( '/assets/HotAirBalloonIridesium/' );
MTTLoader.load('Air_Balloon.mtl',(materials) => {
console.log(materials);
materials.preload()
var objLoader = new THREE.OBJLoader();
objLoader.load('/assets/HotAirBalloonIridesium/Air_Balloon.obj', (object) => {
console.log(materials)
objLoader.setMaterials(materials)
scene.add(object);
})
})
I wonder what i'm missing as my asset folder contains all the model files
try loading obj using
var loader = new THREE.OBJLoader( manager );
loader.load( 's_v1.obj', function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh )
{
// child.material.map = texture2;
// child.material.specularMap=texture;
// child.material.map=texture;
}
} );
// object.position.x = - 60;
// object.rotation.x = 0; //20* Math.PI / 180;
// object.rotation.z = 0;//20* Math.PI / 180;
object.scale.x = 80;
object.scale.y = 80;
object.scale.z = 80;
obj = object
scene.add( obj );
animate(obj);
} );
okay quick update, there was nothing wrong with the loader but I was using the wrong lighting as Phong Material needed
var hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.50);
var dirLight = new THREE.DirectionalLight(0xffffff, 0.50);
to be apparent.
You must call "setMaterials" before load obj.
//loader
var MTTLoader = new THREE.MTLLoader();
MTTLoader.setPath( '/assets/HotAirBalloonIridesium/' );
MTTLoader.load('Air_Balloon.mtl',(materials) => {
console.log(materials);
materials.preload()
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials); // "setMaterials" must before "load"
objLoader.load('/assets/HotAirBalloonIridesium/Air_Balloon.obj', (object) => {
console.log(materials)
scene.add(object);
})
})

three.js how to map a texture on mtl,obj file

i'm trying to map a png file on mtl,obj file
Before mapping
but after mapping, the mtl texture just disappear.
After mapping
what should I do ?
I'm not good at English. If you can't understand my question, please leave a comment.
this is my code :
var onProgress = function(xhr) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
};
var onError = function(xhr) {};
THREE.Loader.Handlers.add(/\.dds$/i, new THREE.DDSLoader());
var loader = new THREE.ImageLoader();
loader.load("../img/ang.png", function(image) {
texture.minFilter = THREE.LinearFilter;
texture.image = image;
texture.wrapS = THREE.ClampToEdgeWrapping;
texture.wrapT = THREE.ClampToEdgeWrapping;
texture.offset.set(-3, -9.5);
texture.repeat.set(13, 13);
texture.needsUpdate = true;
},onProgress,onError);
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath('../models/');
mtlLoader.load('nag-green.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('../models/');
objLoader.load('nag-green.obj', function(object) {
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.map = texture;
}
});
object.name = "object";
object.position.y = 0;
scene.add(object);
}, onProgress, onError);
});
what I want to do is to map 'ang.png' file over that t-shirts like this
what i want
Thank you for your answer Radio, I tried that way but this is not what i want to do.
give a name to material and map
You've applied the same 'ang.png' texture to all child meshes. I think you need a conditional in the traverse function to apply the texture only to the part of the mesh that needs the texture.
The mtl should have applied a name to the material when it first loaded. For example, here I am pretending the material name is "torso". Your exporter from the original 3d editor will have given it some other name. In any case, you should be able to query the name in the conditional:
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
if(child.material != undefined){
if(child.material.name=="torso"){
child.material.map = texture;
}
}
}
});

three.js - get object name with mouse click

I had loaded 3 external model with the name into my scene using json loader and now i want to get the name of the model/object by clicking it.
Below is the that i had used to load the model
var object_material = new THREE.MeshBasicMaterial({
color: 0xd6d6d6,
side: THREE.DoubleSide
});
var loader = new THREE.JSONLoader();
loader.load("models/"+file,
function(geometry, object_material)
{
var object = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(object_material));
model = new THREE.Object3D();
model.id=file;
model.name='sample'+file;
model.userData.id='sampledata'+file;
model.add(object);
model.position.set(obj_x,obj_y,obj_z);
model.mirroredLoop = true;
model.castShadow = true;
model.receiveShadow = true;
scene.add(model);
}
);
Below is my mouse down function
function onMouseDown(event) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var pLocal = new THREE.Vector3(0, 0, -1);
var pWorld = pLocal.applyMatrix4(camera.matrixWorld);
var ray = new THREE.Raycaster(pWorld, vector.sub(pWorld).normalize());
// Get meshes from all objects
var getMeshes = function(children) {
var meshes = [];
for (var i = 0; i < children.length; i++)
{
if (children[i].children.length > 0) {
meshes = meshes.concat(getMeshes(children[i].children));
} else if (children[i] instanceof THREE.Mesh) {
meshes.push(children[i]);
}
}
return meshes;
};
function attributeValues(o)
{
var out = [];
for (var key in o) {
if (!o.hasOwnProperty(key))
continue;
out.push(o[key]);
}
return out;
}
var objects = attributeValues(this.o3dByEntityId);
var meshes = getMeshes(objects);
var intersects = ray.intersectObjects(meshes);
raycaster.set( camera.position, vector.sub( camera.position ).normalize() );
var intersects = raycaster.intersectObjects( scene.children );
console.log(scene);
// this console displays all the objects under children - THREE.Object3D - name as name: "sample513.js"
if ( intersects.length > 0 )
{
// but for the clickedObject - the length is > 0 and name is empty
var clickedObject = intersects[0].object;
console.log(clickedObject.parent.userData.id); // return as undefined
if ( INTERSECTED != intersects[ 0 ].object )
{
INTERSECTED= intersects[ 0 ].object;
name = INTERSECTED.name;
}
} else {
console.log('intersects.length is 0');
}
}
Even-though i had provided the model name in the userData , i am not able to retrieve it . can any one guide me how to retrieve the name of the object when it is clicked
Try to make through this example. Look at messages in the console.
<script src="js/controls/EventsControls.js"></script>
EventsControls = new EventsControls( camera, renderer.domElement );
EventsControls.attachEvent( 'onclick', function() {
console.log( 'this.focused.name: ' + this.focused.name );
});
// if use drag and drop
EventsControls.attachEvent( 'dragAndDrop', function () {
this.container.style.cursor = 'move';
this.focused.position.y = this.previous.y;
});
EventsControls.attachEvent( 'mouseOut', function () {
this.container.style.cursor = 'auto';
});
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load( "models/Tux.js", addModelToScene );
function addModelToScene( geometry, materials ) {
var material = new THREE.MeshFaceMaterial( materials );
model = new THREE.Mesh( geometry, material );
model.scale.set( 10, 10, 10 ); model.name = 'Tux';
model.rotation.x = -Math.PI/2;
model.position.set( 175, 45, 125 );
scene.add( model );
EventsControls.attach( model );
}
The parent of the clickedObject is probably undefined. Perhaps you can console log the clickedObject and see which path you need to access the id.

Categories