How to store Model loaded by ColladaLoader in Three.js? - three.js

Since the Three.js migration (r68 -> r69) the ColladaLoader returns a Scene instead of an Object3D. How can I get the loaded Object3D now? I want store the loaded Object in a var to use it everytime.
var newpos = Cube.position;
var oLoader = new THREE.ColladaLoader();
oLoader.load('models/logo.dae',
function(collada)
{
var object = collada.scene;
var skin = collada.skins[0];
object.rotation.x = -Math.PI / 2;
object.rotation.z = Math.PI / 2;
object.position.x = newpos.x;
object.position.y = newpos.y+1.85;
object.position.z = newpos.z;
object.scale.set(0.75, 0.75, 0.75);
object.updateMatrix();
scene.add(object);
},
function ( xhr ) {
// console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
}
);

The ColladaLoader returns a scene because the loaded Model is'nt created as a 3DObject. The ColladaLoader creates a new scene added to your scene including the loaded .dae-Model. (Now it returns a group) That's because not every Model is just one Object. Check the childs of the dae.scene that you loaded, it helps a lot.

Related

three.js create a mesh from a gltf objections

I have rendered a gltf object in three.js, but the issue is I don't think it contains a mesh. I want to use a ray caster to move the object with an on click event handler. I have all the code in place to do this, but it doesn't register when I click.
Code to load the object:
var loader = new THREE.GLTFLoader();
loader.load(
// resource URL
'./vitra_eames_plastic_chair/scene.gltf',
// called when the resource is loaded
function ( object ) {
object.animations; // Array<THREE.AnimationClip>
object.scene; // THREE.Scene
object.scenes; // Array<THREE.Scene>
object.cameras; // Array<THREE.Camera>
object.asset; // Object
var object = new THREE.Mesh(gltf.asset, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff }));
object.scene.position.x = -75;
object.scene.position.y = -75;
object.scene.position.z = -75;
object.scene.rotation.x = 50;
object.scene.rotation.y = 50;
object.scene.rotation.z = 50;
object.scene.scale.x = .5;
object.scene.scale.y = .5;
object.scene.scale.z = .5;
object.scene.castShadow = true;
object.scene.receiveShadow = true;
boxScene.add(object.scene);
objects.push(object.scene);
},
// called while loading is progressing
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened' );
}
);
I also have this code, which generates boxes. Here, the event handler works, but obviously the object were loaded differently. Any advice would be greatly appreciated.
var geometry = new THREE.BoxGeometry(1, 1, 1);
for (var i = 0; i < 50; i++) {
var object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff }));
object.position.x = Math.random() * 50 - 25;
object.position.y = Math.random() * 10 + 1;
object.position.z = Math.random() * 50 - 25;
object.rotation.x = Math.random() * 2 * Math.PI;
object.rotation.y = Math.random() * 2 * Math.PI;
object.rotation.z = Math.random() * 2 * Math.PI;
object.scale.x = Math.random() * 3 + 1;
object.scale.y = Math.random() * 3 + 1;
object.scale.z = Math.random() * 3 + 1;
object.castShadow = true;
object.receiveShadow = true;
boxScene.add(object);
objects.push(object);
}
I think you have to change your onLoad() callback of GLTFLoader.load() to fix the problem. You are creating a mesh with object.asset which is not correct. Instead, you can add object.scene directly to your scene graph. So in most cases the callback can simply be like this:
var loader = new THREE.GLTFLoader();
loader.load( function( gltf ) {
scene.add( gltf.scene );
) };
Check out the source code of the following example to see this approach in action.
https://threejs.org/examples/webgl_loader_gltf.html

Three.JS Model exported from editor, bump map not rendering

I have a model with a bump map. It displays great in the three.js editor, but when I export the scene and load it into a scene, the model displays without the bump map. It's puzzling because the envMap and specularMap are loading just fine, but no bump map. Any ideas?
The exported json is here: https://www.dropbox.com/sh/xj8plnceoce1gwh/AABWChVTw6TW2hPXr5a3t9Tpa/Backpack_3_scene.json?dl=0
Here is my code for loading the exported json:
// scene
scene = new THREE.Scene();
// model
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round(percentComplete, 2) + '% downloaded' );
}
};
var onError = function ( xhr ) {
};
var loader = new THREE.ObjectLoader();
loader.load(model_json, function(json_scene) {
scene.add(json_scene);
render();
}, onProgress, onError);
In your json model file the bumpScale is set to 0.04. THat is very small to have any effect. You probably need to scale it up.

Determine the object that was clicked in three.js

I wish to detect when an object has been clicked. I am generating a page from the three.js editor. It is a brilliant environment.
Following the advice from this post (https://mandemeskel.wordpress.com/2013/08/19/mouse-events-raycasting-with-three-js/) I ended up with the following code. I have placed a comment where I am having a problem.
function mousedown( event ) {
var scene = this.parent;
var projector = new THREE.Projector();
var mouse_vector = new THREE.Vector3(),
mouse = { x: 0, y: 0, z: 1 },
ray = new THREE.Raycaster( new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,0) ),
intersects = [];
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
mouse_vector.set( mouse.x, mouse.y, mouse.z );
// How do I get the camera?
projector.unprojectVector( mouse_vector, camera );
var direction = mouse_vector.sub( camera.position ).normalize();
ray.set( camera.position, direction );
var object = scene.getObjectByProperty( 'uuid', this.uuid, true );
intersects = ray.intersectObject( object );
if( intersects.length ) {
alert( "hit" );
event.preventDefault();
}
}
I have temporarily fixed the problem by modifying app.js in the published page. By moving the camera variable to be global I got around it, but it is obviously a fudge. Is there any way to access the camera generated by the editor without modifying app.js?
var camera;
var APP = {
Player: function () {
....
The awesome mrdoob has modified the editor to include a getCamera() call
https://github.com/mrdoob/three.js/issues/7510#issuecomment-153059247
The default camera can now be accessed by
var camera = player.getCamera();

Three.js mouse picking, 3D model with OBJMTLLoader

i started programing with Three.js. Now i have a problem, when i load an Object with the OBJMTLLoader i dont get any access to change the position of the object with mouseMove. I have pushed the obects into the objects array but it doesnt work. If anybody could help or knowes a good tutorial would be really fine. I hope the structure how i wrote the question is clear....its the first time i´m using stacko.
These are my variables and the function i try to change the objects:
var mouse = new THREE.Vector2();
var raycaster = new THREE.Raycaster();
var objects = [];
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera(mouse,camera);
intersects = raycaster.intersectObjects(objects);
if (intersects.length> 0) {
intersects[0].object.position.set(5, 5 ,5);
}
}
Here i load the object with the OBJMTLLoader....this works:)
var loader = new THREE.OBJMTLLoader();
loader.load('models/sofa4.obj', 'models/sofa4.mtl', function(object) {
// console.log(object);
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.shininess = 0;
// console.log(child.material);
}
});
object.position.z = 2;
object.position.y = -5.95;
object.scale.set(0.05,0.05,0.05);
scene.add(object);
objects.push(object);
});

In Haxe, how can I load the json model I exported from Blender?

I have recently started to play around with Haxe and Three.js. How do I load a 3D object using JSONLoader. I’m very new to the Haxe way of doing things and haven’t wrapped my head around the whole extern thing.
I’m making use of this lib to simplify things:
https://github.com/rjanicek/three.js-haXe
Most of the Three.js Classes are abstracted in the lib except for JSONLoader or any loader for that matter. How can I load the json model I exported from Blender in Haxe?
It seems like I was using the wrong lib :)
This is a better abstraction:
https://github.com/labe-me/haxe-three.js
To load a 3D model, you’ll go about it this way:
package co.za.anber;
import js.three.Three;
import js.Lib;
class Main
{
static private var scene:Scene;
static function main()
{
//Get the dimensions of the scene
var w = Lib.window.innerWidth;
var h = Lib.window.innerHeight;
scene = new Scene();
//add some light
var pointLight = new PointLight(0xffffff, 1, 0);
pointLight.position.set(10, 50, 130);
scene.add(pointLight);
//add a camera
var camera = new PerspectiveCamera(70, w/h, 1, 1000);
camera.position.z = 500;
scene.add(camera);
//setup renderer in the document
var renderer = new WebGLRenderer(null);
renderer.setSize(w, h);
Lib.document.body.appendChild(renderer.domElement);
//Load the Blender exported Mesh.
//This is where we load the Mesh and setup the onload handler. This was the part I wasn't so sure about.
var loader:JSONLoader = new JSONLoader(true);
//I don't like in-line functions. You need to make the returning function into a Dynamic type.
var callbackModel:Dynamic = function( geometry:Dynamic ){createScene(geometry); };
loader.load("Suzanne.js", callbackModel);
//Listen for mouse move. In-line function from somewhere else.
var mouseX = 0, mouseY = 0;
untyped Lib.document.addEventListener('mousemove', function(event){
mouseX = (event.clientX - Lib.window.innerWidth/2);
mouseY = (event.clientY - Lib.window.innerHeight/2);
}, false);
//Render the scene #60 frames per second. Inline function from somewhere else.
var timer = new haxe.Timer(Math.round(1000/60));
timer.run = function(){
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
}
/**
* Onload complete handler. Here we can add our Mesh.
* #param geometry
*/
static function createScene( geometry:Dynamic):Void{
var mesh:Mesh = new Mesh( geometry, new MeshLambertMaterial( { color: 0x00FF00 } ) );
//We scale it up to be visible!
mesh.scale.set( 150.15, 150.5, 150.5 );
scene.add( mesh );
}
}
Hope this help someone.
Look at this, it should help you.

Resources