Three.js load multiple separated objects / JSONLoader - javascript

is it possible to load a scene (e.g. two different cubes) exported from blender to json and identify them?
I need to distinguish between them e.g. to make one rotating and the other moving.
Thank you in advance!
Denv
edit+++
Thank you for your answer!
So if I load two cubes in one JSON file:
loader.load("untitled1.js", function(geometry, materials) {
mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial(materials));
mesh.scale.set( 10, 10, 10 );
mesh.position.y = 0;
mesh.position.x = 0;
scene.add( mesh );
});
How can I move first cube?
mesh.getObjectById(0).position.x = 15;
Doesn't seems to work.
Thank you!

Yes, it is possible to load an entire scene from a json file exported from Blender!
I achieved that with the following process: (Using three.js r80)
First you have to name your different objects in Blender like in the following image Outliner.
Then you can export the file using Three.js json exporter add-on for Blender, but taking care of marking the Scene checkbox like in the following:
Using this option your json file now contains all the meshes on the Blender's Outliner, as you can verify using any text editor. It doesn't matter if the meshes were selected or not.
It is important to know that the root (or parent) object isn't a Geometry anymore. It is labeled with the Object type by now. To access the children objects (of Mesh type) you can use the getObjectByName method on the root object like in the following code:
jsonloader.load( "obj/Books.json", function ( loadedObj ) {
var surface = loadedObj.getObjectByName("Surface");
var outline = loadedObj.getObjectByName("Outline");
var mask = loadedObj.getObjectByName("Mask");
// Watch the objects properties on console:
console.log(loadedObj);
console.log(surface);
console.log(outline);
console.log(mask);
} );
If we check the browser's console, we can see the proper objects assigned. And from now, you can manipulate the children objects independently (move, rotate, change materials, etc.)

Each object loaded has an associated .id. So you can use the Object3D.getObjectById() to find it and apply transforms on it.

Related

Adding Physics to OBJ Model in ThreeJS

I am trying to use PhysiJS with ThreeJS. I have an OBJ model that I exported from Blender. When I load it with OBJLoader, I see that it is a BufferGeometry. I also notice that it is missing a vertices property, which is what PhysiJS looks for.
My ThreeJS version is r101. I would appreciate any suggestions. If there is a more suitable library, I am open to that too. I am also happy to provide any clarifications.
If you need to convert your BufferGeometry to Geometry, you can simply use the .fromBufferGeometry() method.
// Called when your obj finishes loading
onLoadComplete(obj) {
var geom = new THREE.Geometry();
geom.fromBufferGeometry(obj);
// Now you'll have access to vertices
console.log(geom.vertices);
}

How can I smooth my polygons in a Three.js scene?

I've this model here in Three.js:
Unsmoothed part of the model
I used a plug-in from the Unity asset store, to export the model into a JSON file, then imported in my three.js application. The problem is that the plugin doesn't export the smoothing groups, so the quality of the model doesn't look so good.
Is there any way to smooth everything with three.js?
You can use the THREE.SubdivisionModifier and use it like this:
var modifier = new THREE.SubdivisionModifier(divisions);
// Apply the modifier to your geometry NOT MESH.
modifier.modify( geometry );
Actually it's not included in Three.js build, so you have to import it.
You can get it here
UPDATE 1
Basically you JSON file gets loaded as an Object3d, which is like a container. It's structured like this:
Object3D
children (arrays containing your meshes (the number can change based on the model in your scene))
Mesh (containing data about your geometry, which is what you need to modify).
So in order to modify the "geometry" you need to access it like so:
modifier.modify( mesh.children[0].children[0].geometry );
You'll need to apply a modifier to every model in your scene, so:
modifier.modify( mesh.children[0].children[0].geometry );
modifier.modify( mesh.children[0].children[1].geometry );
modifier.modify( mesh.children[0].children[2].geometry );
depending on the number of models you have.
It's like you have to open a container and inside you find a smaller container, then another one and so on, until you access geometry data. Hope it is clear enough :)

three.js - is it possible to change an loaded .obj object faces' texture dynamically?

Currently I have a task that would like to show an .obj object on the web
,and the texture of the .obj file should varies through different user input (clicking several
buttons), so I look into three.js.
After finding for solutions in stackoverflow some time, I found that there are some solutions about changing the object texture in a whole, but cannot find out solutions for particularly of a single face (For example, if the obj is a cube, then just change the texture of the front face). I would need to do that since the texture of different faces in the obj is different
Is is possible to change an loaded .obj object's texture for one face only dynamically? If yes, what would be the trick?
===========================
Updated:
Now my .obj object is a cubeman like the game Minecraft player character (reference image if you do not know what it is: http://static1.wikia.nocookie.net/cb20130604003021/p/protagonist/images/5/52/Minecraft-steve_12.png)
I have import the .obj file from the OBJLoader that comes with the three.js example:
var loader = new THREE.OBJLoader();
loader.load( 'test.obj', function ( object ) {
object.position.x = 0;
object.position.y = 0;
scene.add( object );
} );
I would like to the know the way that can change different faces' texture of the object, as like to change the cloth / face skin of the character. The texture are required to be changed independently since the texture of cloth and face can be change independently.

Three.js loading exported blender model

I did a simple 3d model in blender and exported it to .obj file. Now I am loading it using three.js and I want objects that have string 'clickable' in its name to move on Y axis on click.
You can look at it here: http://three.parkz.cz/shop.html
The problem is that the informations parsed from names of objects (which I set in blender) are not corresponding to the right objects.
Loading and parsing:
var loader = new THREE.OBJMTLLoader();
loader.addEventListener('load', function(event) {
object = event.content;
object.name = 'CustomObjects';
for(var i = 0; i < object.children.length; i++) {
//console.log(object.children[i]);
var properties = object.children[i].name.split('_');
if(properties[1] == 'clickable') {
object.children[i].clickable = true;
} else object.children[i].clickable = false;
}
object.rotation.x = 0.5;
object.rotation.y = 0.5;
scene.add(object);
});
loader.load('shop.obj', 'shop.mtl');
For example that two cubes in the center (called '005_kiosek' and '010_kiosek2') are not supposed to be clickable but they are! You can open console and after click on it you can see that they are named wrongly '004_clickable' and '009_clickable'!
Here is my blender file: http://three.parkz.cz/shop.blend
Is it problem on javascript side or blender exports it wrong?
Thank you in advance!
Martin
P.S: Does anybody know why aren't that simple meshes (green and blue) rendered well?
The green and blue mesh are not rendered correctly because, under the current implementation, the obj loader only accepts triangles as faces. As those meshes use polygons, they are not rendered correctly.
As for the names I would try to verify that what I put in the blender file, comes out correct. So when you load the model, just print the name and its clickable attribute, to see if all is correct instead for taking it for granted.

Multiple .obj Models in THREE.js and detecting clicked objects

I have been following along this example to load .obj Model using three.js. Since I needed more than one model to load so I tried this
loader.addEventListener( 'load', function ( event ) {
var object = event.content;
object.position.y = - 80;
scene.add( object );
});
loader.load( 'obj/model1.obj' );
loader.load( 'obj/model2.obj' );
First: I don't know whether this is the right approach or not since I searched but didn't find any tutorial loading more than one .obj models.
Second: I want to be able to click different models on the screen. I tried this which doest not seem to work for me. Any suggestions on this?
This example shows you a pattern for loading multiple models:
http://mrdoob.github.com/three.js/examples/webgl_loader_json_objconverter.html
Regarding detecting clicked objects, depending on your model, you may need to set the recursive flag to true:
ray.intersectObjects( objects, true );
Well, since you haven't provide enough code to fully explain you question I will guess that for the second part you have to make sure you put the objects in an array of objects such as:
var objects = [];
after initializing the objects you do:
objects.push( object );
now you have an array where you can check for objects intersected after implementing the THREE.Ray.

Categories

Resources