Can't rotate each mesh on animation update - three.js

I am quite new to Three.js and have been experimenting to get familiar with it.
I am making this exercise where I add to the scene 35 icosahedrons. I would like for each one of them to rotate when calling requestAnimationFrame.
I thought that by looping into each group children element (which is each mesh) and adding value to x and y rotation I could make the meshes rotate. Why is not so? Any help is very appreciated. Thank you.
This my approach:
var camera, scene, renderer;
var geometry, material, mesh;
var edgesGeometry, edgesMaterial, edges;
var group;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init()
animate()
function init() {
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1500;
scene = new THREE.Scene();
group = new THREE.Group();
for ( var i = 0; i < 35; i ++ ) {
var randomSize = Math.floor( Math.random() * (150 - 20) + 20 )
geometry = new THREE.IcosahedronGeometry( randomSize, 1 );
material = new THREE.MeshBasicMaterial({ color: 0x000000 });
mesh = new THREE.Mesh( geometry, material );
mesh.position.x = Math.random() * 2000 - 1000;
mesh.position.y = Math.random() * 2000 - 1000;
mesh.position.z = Math.random() * 2000 - 1000;
mesh.rotation.x = Math.random() * 2 * Math.PI;
mesh.rotation.y = Math.random() * 2 * Math.PI;
edgesGeometry = new THREE.EdgesGeometry( mesh.geometry )
edgesMaterial = new THREE.LineBasicMaterial( { color: 0x63E260, linewidth: 2 } )
edges = new THREE.LineSegments( edgesGeometry, edgesMaterial )
mesh.add( edges )
mesh.matrixAutoUpdate = false;
mesh.updateMatrix();
group.add( mesh );
}
scene.add( group );
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX ) * 0.25;
mouseY = ( event.clientY - windowHalfY ) * 0.25;
}
function animate() {
requestAnimationFrame( animate );
for ( var i = 0; i < group.children.length; i ++ ) {
group.children[i].rotation.x += 0.001;
group.children[i].rotation.y += 0.001;
}
render();
}
function render() {
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 );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.js"></script>

To expand on #prisoner849's comment:
When three.js renders a scene, it parses the entire scene looking for renderable items (visible, within the view frustum, etc.). Part of that process involves multiplying out the transformation matrices to populate the world matrix (matrixWorld) of each renderable item is up-to-date. As you can imagine, this can potentially be a process hog, so you also have the ability to turn off that auto-update.
It looks like you understand that, because your line of code: mesh.matrixAutoUpdate = false; does exactly that, then you follow it up by manually updating the mesh's matrix. This is mostly correct, but you also need to do this for each frame.
For a simple/shallow scene like yours, #prisoner849's approach is correct--just let three.js auto-update the matrices by removing the lines mentioned. But if your scene is more complex, and you want finer control over it, you'll need to exert that control for each frame you want to render.
In the example below, I took your original code and made it so that only every second icosahedron rotates. This is accomplished by collecting them into an array, and then only updating the matrices for objects in that array. (Also note I turned off matrix auto-updating for the entire scene, rather than individual objects.)
var camera, scene, renderer;
var geometry, material, mesh;
var edgesGeometry, edgesMaterial, edges;
var group;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var updatableObjects = [];
init()
animate()
function init() {
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1500;
scene = new THREE.Scene();
scene.autoUpdateMatrix = false; // turn off automatic matrix computation
group = new THREE.Group();
for (var i = 0; i < 35; i++) {
var randomSize = Math.floor(Math.random() * (150 - 20) + 20)
geometry = new THREE.IcosahedronGeometry(randomSize, 1);
material = new THREE.MeshBasicMaterial({
color: 0x000000
});
mesh = new THREE.Mesh(geometry, material);
mesh.position.x = Math.random() * 2000 - 1000;
mesh.position.y = Math.random() * 2000 - 1000;
mesh.position.z = Math.random() * 2000 - 1000;
mesh.rotation.x = Math.random() * 2 * Math.PI;
mesh.rotation.y = Math.random() * 2 * Math.PI;
edgesGeometry = new THREE.EdgesGeometry(mesh.geometry)
edgesMaterial = new THREE.LineBasicMaterial({
color: 0x63E260,
linewidth: 2
})
edges = new THREE.LineSegments(edgesGeometry, edgesMaterial)
mesh.add(edges)
if (i % 2) {
updatableObjects.push(mesh);
}
group.add(mesh);
}
scene.add(group);
//
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//
document.addEventListener('mousemove', onDocumentMouseMove, false);
//
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) * 0.25;
mouseY = (event.clientY - windowHalfY) * 0.25;
}
function updateMeshes(mesh) {
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
mesh.updateMatrix();
}
function animate() {
requestAnimationFrame(animate);
updatableObjects.forEach(updateMeshes);
render();
}
function render() {
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);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.js"></script>

Related

Threejs / Raycast doesn't compute intersection with my cube

Here is my js files. It works. When I click on the cube, it goes inside raycast function, but doesn't enter the for loop and console.log( intersects[ 0 ] ) gives undefined
let camera, scene, renderer;
let mesh, mesh_green;
let raycaster, mouse = { x : 0, y : 0 };
init();
function init() {
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 40;
scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( { color: "red" } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
mesh.position.set( 0, 10, 0 );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
raycaster = new THREE.Raycaster();
renderer.domElement.addEventListener( 'click', raycast, false );
function raycast ( e ) {
mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;
console.log( "raycast" , e.clientX, mouse.x, window.innerWidth);
raycaster.setFromCamera( mouse, camera );
const intersects = raycaster.intersectObjects( scene.children );
for ( let i = 0; i < intersects.length; i++ ) {
console.log( intersects[ i ] );
}
}
It seems your code works by using a latest version of three.js. I've just refactored/simplified it a bit.
let camera, scene, renderer;
let mesh;
let raycaster, pointer = new THREE.Vector2();
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 40;
scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({
color: "red"
});
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 10, 0);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
raycaster = new THREE.Raycaster();
renderer.domElement.addEventListener('pointerdown', raycast);
}
function raycast(e) {
pointer.x = (e.clientX / window.innerWidth) * 2 - 1;
pointer.y = -(e.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(pointer, camera);
const intersects = raycaster.intersectObject(scene);
for (let i = 0; i < intersects.length; i++) {
console.log(intersects[i]);
}
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.140.2/build/three.min.js"></script>

AxisHelper not showing colored

I'm trying to add an AxisHelper to my three.js project. I added it like this:
axes = new THREE.AxisHelper(100);
scene.add(axes);
It gets added, but it isn't colored It's solid white, and therefore hard to see. How can I make it the regular colors?
JSFiddle
var container;
var camera, scene, axis, renderer;
init();
animate();
function init() {
container = document.getElementById('container');
// Camera
camera = new THREE.OrthographicCamera(window.innerWidth / -2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / -2, -500, 1000);
camera.position.x = 200;
camera.position.y = 100;
camera.position.z = 200;
// Scene
scene = new THREE.Scene();
// Axis
axes = new THREE.AxisHelper(100);
scene.add(axes);
// Grid
var size = 500,
step = 50;
var geometry = new THREE.Geometry();
for (var i = -size; i <= size; i += step) {
geometry.vertices.push(new THREE.Vector3(-size, 0, i));
geometry.vertices.push(new THREE.Vector3(size, 0, i));
geometry.vertices.push(new THREE.Vector3(i, 0, -size));
geometry.vertices.push(new THREE.Vector3(i, 0, size));
}
var material = new THREE.LineBasicMaterial({
color: 0x000000,
opacity: 0.2
});
var line = new THREE.LineSegments(geometry, material);
scene.add(line);
// Cubes
var geometry = new THREE.BoxGeometry(50, 50, 50);
var material = new THREE.MeshLambertMaterial({
color: 0xffffff,
overdraw: 0.5
});
var cube = new THREE.Mesh(geometry, material);
cube.scale.y = 1;
cube.position.x = 0;
scene.add(cube);
// Lights
var ambientLight = new THREE.AmbientLight(Math.random() * 0x10);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight(Math.random() * 0xffffff);
directionalLight.position.x = Math.random() - 0.5;
directionalLight.position.y = Math.random() - 0.5;
directionalLight.position.z = Math.random() - 0.5;
directionalLight.position.normalize();
scene.add(directionalLight);
var directionalLight = new THREE.DirectionalLight(Math.random() * 0xffffff);
directionalLight.position.x = Math.random() - 0.5;
directionalLight.position.y = Math.random() - 0.5;
directionalLight.position.z = Math.random() - 0.5;
directionalLight.position.normalize();
scene.add(directionalLight);
// Render
renderer = new THREE.CanvasRenderer();
renderer.setClearColor(0xf0f0f0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
// Events
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.left = window.innerWidth / -2;
camera.right = window.innerWidth / 2;
camera.top = window.innerHeight / 2;
camera.bottom = window.innerHeight / -2;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
var timer = Date.now() * 0.0001;
camera.position.x = Math.cos(timer) * 200;
camera.position.z = Math.sin(timer) * 200;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
<div id="container"></div>
<script src="https://rawgit.com/mrdoob/three.js/master/build/three.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/renderers/Projector.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/renderers/CanvasRenderer.js"></script>
You can get CanvasRenderer to properly render the colored axes of AxisHelper like so:
var axes = new THREE.AxisHelper( 100 );
axes.geometry = new THREE.Geometry().fromBufferGeometry( axes.geometry );
scene.add( axes );
CanvasRenderer has a bug, and does not properly render vertex colors when the geometry is BufferGeometry. The above is a work-around.
three.js r.82

three.js, tween camera and mousemove event

I'm trying my hands on three.js
I am moving the camera using a tween, and it works quite good.
At the end of the animation, however, the camera jumps back to its initial position.
I found out that the mousemove event was causing that behavior.
How can i fix this problem and keep both the tween movement and the mouse move?
I have constructed my three.js based on this example;
Mousemove declared inside render function
function render() {
camera.position.x += ( mouseX - camera.position.x ) * 0.04;
camera.position.y += ( - mouseY - camera.position.y ) * 0.04;
camera.lookAt( scene.position );
TWEEN.update();
renderer.render( scene, camera );
}
Tween movement
function setupTween (position, target, duration) {
TWEEN.removeAll();
new TWEEN.Tween (position)
.to (target, duration)
.easing (TWEEN.Easing.Quadratic.InOut)
.onUpdate (
function() {
// copy incoming position into camera position
camera.position.copy (position);
})
.start();
};
tween function source
UPDATE
Complete working code:
<script>
var container,
i,
camera,
scene,
renderer,
particles,
geometry,
materials = [],
color,
sprite,
size,
mouseX = 0,
mouseY = 0,
isTweening,
windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2;
// +++++ three.js +++++
// +++++ +++++ +++++ +++++ +++++
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.5, 2000 );
camera.position.set (0,0,1900);
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0x000000, 0.0005 );
geometry = new THREE.Geometry();
var textureLoader = new THREE.TextureLoader();
for ( i = 0; i < 1000; i ++ ) {
var vertex = new THREE.Vector3();
vertex.x = Math.random() * 2000 - 1000;
vertex.y = Math.random() * 2000 - 1000;
vertex.z = Math.random() * 2000 - 1000;
geometry.vertices.push( vertex );
}
sprite = textureLoader.load( "circle.png" );
color = [0.90, 0.05, 0.8];
size = 8.5;
materials = new THREE.PointsMaterial( { size: size, map: sprite, blending: THREE.AdditiveBlending, depthTest: false, transparent : false } );
materials.color.setHSL( color[0], color[1], color[2] );
particles = new THREE.Points( geometry, materials );
scene.add( particles );
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
}
function animate() {
requestAnimationFrame( animate );
render();
}
function startTween() {
isTweening = false;
var target = new THREE.Vector3(getRandomNumber(), getRandomNumber(), getRandomNumber());
new TWEEN.Tween (camera.position.clone())
.to (target, 1000)
.easing (TWEEN.Easing.Quadratic.InOut)
.onUpdate( function() {
camera.position.copy(this);
})
.onStart ( function() {
isTweening = true;
})
.onComplete ( function() {
isTweening = false;
})
.start();
}
function getRandomNumber() {
// get a number between -1000 and -500 and 500 and 1000
return ( Math.random() * 500 + 500 ) * ( Math.random() < 0.5 ? -1 : 1 );
}
function render() {
if(!isTweening && (mouseX || mouseY)) {
// more a generic approach, not just transforming x and y (maybe it needs to be improved a bit)
var upVector = camera.up.clone().transformDirection(camera.matrix);
var forwardVector = new THREE.Vector3().subVectors(scene.position, camera.position).normalize();
var rightVector = new THREE.Vector3().crossVectors(forwardVector, upVector);
camera.translateOnAxis(rightVector, mouseX);
camera.translateOnAxis(upVector, -mouseY);
mouseX = mouseY = 0;
}
camera.lookAt( scene.position );
TWEEN.update();
renderer.render( scene, camera );
}
init();
animate();
setTimeout(function(){
startTween();
},2500);
</script>
I think, you should only update the position by the mousemove event, when it's not tweening. So you need to check if its currently tweening or not.
var isTweening = false;
new TWEEN.Tween (camera.position)
.to (target, duration)
.easing (TWEEN.Easing.Quadratic.InOut)
.onStart ( function() {
isTweening = true;
})
.onComplete ( function() {
isTweening = false;
})
.start();
// in your render loop
function render() {
if (!isTweening) {
camera.position.x += ( mouseX - camera.position.x ) * 0.04;
camera.position.y += ( - mouseY - camera.position.y ) * 0.04;
}
camera.lookAt( scene.position );
TWEEN.update();
renderer.render( scene, camera );
}
You don't need to set an onUpdate function and copy the new position to camera.position. You can just pass over camera.position to the tween and it will work.
EDIT:
I didn't see the link to example. Now, I know which kind of navigation is used (which is actually used in a lot of three.js examples). It's not the mousemove event that is causing your problem, it's this kind of calculating the new camera position (camera.position.x += ( mouseX - camera.position.x ) * 0.04;). So, I changed the code of the example a bit, especially the navigation. Here are the important parts:
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
function onDocumentMouseMove( event ) {
mouseX = (event.movementX * 0.5) || event.mozMovementX || event.webkitMovementX || 0;
mouseY = (event.movementY * 0.5) || event.mozMovementY || event.webkitMovementY || 0;
}
function render() {
if(!isTweening && (mouseX || mouseY)) {
// more a generic approach, not just transforming x and y (maybe it needs to be improved a bit)
var upVector = camera.up.clone().transformDirection(camera.matrix);
var forwardVector = new THREE.Vector3().subVectors(scene.position, camera.position).normalize();
var rightVector = new THREE.Vector3().crossVectors(forwardVector, upVector);
camera.translateOnAxis(rightVector, mouseX);
camera.translateOnAxis(upVector, -mouseY);
mouseX = mouseY = 0;
}
camera.lookAt( scene.position );
TWEEN.update();
}
function startTween() {
isTweening = false;
var target = new THREE.Vector3(getRandomNumber(), getRandomNumber(), getRandomNumber());
new TWEEN.Tween (camera.position.clone())
.to (target, 1000)
.easing (TWEEN.Easing.Quadratic.InOut)
.onUpdate( function() {
camera.position.copy(this);
})
.onStart ( function() {
isTweening = true;
})
.onComplete ( function() {
isTweening = false;
})
.start();
}
function getRandomNumber() {
// get a number between -1000 and -500 and 500 and 1000
return ( Math.random() * 500 + 500 ) * ( Math.random() < 0.5 ? -1 : 1 );
}
And you are right about TWEEN.onUpdate: you need to copy the new values to camera.position. My earlier approach do also work, but then all of the functionality of THREE.Vector3 gets lost. I didn't realize that until now.

Three.js Cannot find Obj

I am using the file from three.js and used the OBJloader and render with canvas. Except that I cannot find the object even when I scale the object by 1000 and set the camera to 2. The code is as below.
<script src="../mrdoob/build/three.min.js"></script>
<script src="../mrdoob/examples/js/loaders/OBJLoader.js"></script>
<script src="../mrdoob/examples/js/renderers/CanvasRenderer.js"></script>
<script src="../mrdoob/examples/js/renderers/Projector.js"></script>
<script>
var container;
var camera, scene, renderer;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
//camera.position.z = 100;
camera.position.z = 2;
// scene
scene = new THREE.Scene();
var ambient = new THREE.AmbientLight(0x101030);
scene.add(ambient);
var directionalLight = new THREE.DirectionalLight(0xffeedd);
directionalLight.position.set(0, 0, 1);
scene.add(directionalLight);
// texture
var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
var texture = new THREE.Texture();
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) {
alert(xhr);
};
alert("hi");
var loader = new THREE.ImageLoader(manager);
loader.load('../mrdoob/examples/textures/UV_Grid_Sm.jpg', function (image) {
texture.image = image;
texture.needsUpdate = true;
});
// model
alert("hi2");
var loader = new THREE.OBJLoader();
loader.load('../mrdoob/examples/obj/male02/male02.obj', function (object) {
object.scale = new THREE.Vector3(1000, 1000, 1000);
alert(object.position.y);
scene.add(object);
});
//
alert("hi3");
renderer = new THREE.CanvasRenderer();
renderer.setClearColor(0xf0f0f0);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener('mousemove', onDocumentMouseMove, false);
//
window.addEventListener('resize', onWindowResize, false);
alert("hi4");
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * .05;
camera.position.y += (-mouseY - camera.position.y) * .05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
</script>
I did an alert on the object and the position turns out to be zero, so I am not sure if the object is correctly loaded. If someone can tell me how to look for the object would be good.
It may cause if the camera located inside your object, then it always see the back faces of your object and ignore it.
Please provide jsfiddle live example.

Problems with the texture using MTLLoader of three.js

I'm using the MTLloader of the three.js library and I don't know why but the texture is not load. The mesh becomes completely white.
However, if I use the OBJ file provided by the examples of the three.js library, the object is loaded with its texture correctly.
Any idea?
I post the code:
function loadObj(urlObj, urlObjMtl, urlHairCompl){
var container, stats;
var camera, scene, renderer;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 100;
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 2.0;
controls.zoomSpeed = 4;
controls.panSpeed = 2;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = false;
controls.dynamicDampingFactor = 0.3;
// scene
scene = new THREE.Scene();
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0, 1 ).normalize();
scene.add( directionalLight );
// model
var loader = new THREE.OBJMTLLoader();
if (urlObj !== null){
loader.load( urlObj, urlObjMtl, function ( object ) {
object.position.y = 0;
object.position.z = -10;
scene.add( object );
} );
}
var display = document.getElementById('display') ;
renderer = new THREE.WebGLRenderer( { canvas: display } );
// window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
}
function animate() {
//requestAnimationFrame( animate );
//render();
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y += ( - mouseY - camera.position.y ) * .05;
camera.lookAt( scene.position );
renderer.render( scene, camera );
}
}
Thanks a lot
Open in txt editor your .obj file and search for string reference -nan inside of it.
Replace the -nan value with 0.000000. Sometimes the .obj file get -nan when exported and than mapping textures fails in three.js.
Example:
vn -nan -nan -nan" should be "vn 0.000000 0.000000 0.000000
That was my case. With -nan it will load with OBJLoader, but when added the .mtl [OBJMTLLoader] it was failing. So fix for me was replacing the -nan with 0.000000.

Resources