Var undefined when I use a loader in three.js - javascript

//Script loader
<script src="js/jquery.min.js"></script>
<script src="js/three.min.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/ColladaLoader.js" type="text/javascript"></script>
<script>
var loader = new THREE.ColladaLoader();
loader.load( 'texture/bigcube_hetre.dae', function ( collada ) {
window.cubeBigHetre = collada.scene;
var skin = collada.skins[ 0 ];
cubeBigHetre.position.set(0, 0, 0);
cubeBigHetre.scale.set(1, 1, 1);
});
var container;
var camera, scene, renderer;
var plane, cube;
var cubeExport;
init();
render();
function init() {
container = document.createElement( 'div' );
container.setAttribute("id", "container");
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( 0xf0f0f0 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 0, 2000 );
camera.lookAt( new THREE.Vector3() );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.damping = 0.2;
controls.addEventListener( 'change', render );
scene = new THREE.Scene();
// 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, i, 0 ) );
geometry.vertices.push( new THREE.Vector3( size, i, 0 ) );
geometry.vertices.push( new THREE.Vector3( i, - size, 0 ) );
geometry.vertices.push( new THREE.Vector3( i, size, 0 ) );
}
var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2, transparent: true } );
var line = new THREE.Line( geometry, material, THREE.LinePieces );
scene.add( line );
//
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
var geometry = new THREE.PlaneBufferGeometry( 1000, 1000 );
plane = new THREE.Mesh( geometry );
plane.visible = false;
scene.add( plane );
// Lights
var ambientLight = new THREE.AmbientLight( 0x606060 );
scene.add( ambientLight );
var directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.set( 1, 0.75, 0.5 ).normalize();
scene.add( directionalLight );
alert(cubeBigHetre);//Uncaught ReferenceError: cubeBigBrun is not defined
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function render() {
renderer.render( scene, camera );
}
</script>
Here is the code, and the problem comes from alert(cubeBigHetre);
It's working in Firefox and Internet Explorer but not with others. The error is : Uncaught ReferenceError: cubeBigBrun is not defined but not in firefox !
Cordialy Alexander

There is a race in your code:
loader.load(..., function)
will call the function when the resource becomes available. So when you call your init() function, the resource may be loaded, the loader callback called and your variable initialized, or the resource may be still downloading, the callback not yet called and your variable still not initialized. This code works by chance in IE and Firefox. Probably you are testing locally and/or experiencing minor differences in Javascript engines across the browsers.
You should move code that depends on the resource to be loaded from the init() function to the loader callback.

Thank you, I think you are true but i can't move it in the loader so I should add a setTimeout().

Related

My model doesn't display it's texture with ThreeJS

I have downloaded the following model from TF3DM : http://tf3dm.com/3d-model/sprite-bottle-91563.html
And i'm trying to display it in a scene with threeJS.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 10, 10, 10 );
scene.add( light );
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
var mtlLoader = new THREE.MTLLoader();
// mtlLoader.setBaseUrl( '' );
mtlLoader.setPath( './' );
var url = "SpriteBottle.mtl";
mtlLoader.load( url, function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( './' );
objLoader.load( 'SpriteBottle.obj', function ( object ) {
object.position.y = - 95;
scene.add( object );
}, function() {}, function() {} );
});
camera.position.z = 5;
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
With this code, nothing appears but the cube. I sometimes manage to display the bottle but the texture is not set.
EDIT: I have also tried to convert the obj file to JSON using the python script, and then applied the texture on it, it displays but not at the right spot.
What am i doing wrong ?

Three.js Object3D division and custom coloring

I want to ask for some help with my project of temperature change on model. I'm using OBJLoader to load my model exported from autoCAD,
and I need to show temperature change on it by color change. I'm stuck on point, how to divide loaded object to smaller regions,
maybe set them some id and than set that region the particular color.
I will be grateful for any help or advice.
By now, I have this:
<body>
<div id="info">
three.js - Temperature model
</div>
<script src="../three.js-lib/build/three.min.js"></script>
<script src="../three.js-lib/examples/js/loaders/OBJLoader.js"></script>
<script src="../three.js-lib/examples/js/Detector.js"></script>
<script src="../three.js-lib/examples/js/controls/OrbitControls.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var camera, scene, renderer;
var container;
init();
function init() {
container = document.getElementById("container");
scene = new THREE.Scene();
scene.add( new THREE.AmbientLight( 0x999999 ) );
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 500 );
camera.up.set( 0, 0, 10 );
camera.position.set( 0, -150, 95 );
camera.add( new THREE.PointLight( 0xffffff, 0.8 ) );
scene.add( camera );
var grid = new THREE.GridHelper( 200, 10.0 );
grid.setColors( 0xffffff, 0x555555 );
grid.rotateOnAxis( new THREE.Vector3( 1, 0, 0 ), 90 * ( Math.PI/180 ) );
scene.add( grid );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( 0x999999 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//loader
loadModel();
var controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render );
controls.target.set( 0, 1.2, 2 );
controls.update();
window.addEventListener( 'resize', onWindowResize, false );
}
function loadModel() {
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 manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
var loader = new THREE.OBJLoader(manager);
loader.load('temperature/suciastka.obj', function (object) {
object.traverse(function (child){
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshPhongMaterial({color: 0x451E0C, vertexColors: THREE.VertexColors});
}
})
scene.add(object);
render();
}, onProgress, onError);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
function render() {
renderer.render( scene, camera );
}
</script>

Problems making a tween on Three.js

I am making my first steps learning JavaScript and playing with Three.js.
I made a reflection cube with a tween animation and i would like to make this tween runs everytime that I reload my site without clicking.
I have two days trying to make it and cant. Can you tell me which is the problem with my code please? I tryied to verify it in the JavaScript console in Chrome and it didnt say anything. If you can help would be amazing because i am doing my best and it's something really hard.
Here is my code with some comments i made:
<script>
// set up the first variables scene, the camera, etc, etc
var container;
var camera, scene, renderer;
var raycaster;
var mouse;
init();
animate();
function init() {
// My scene is a div inside the html
container = document.createElement( 'div' );
document.body.appendChild( container );
//Set up the camera and make an scene
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.target = new THREE.Vector3( 0, 50, 0 );
camera.position.y = 300;
camera.position.z = 500;
scene = new THREE.Scene();
//environment map
var imgAr = [
'sources/cube_sides/0.jpg',
'sources/cube_sides/02.jpg',
'sources/cube_sides/03.jpg',
'sources/cube_sides/04.jpg',
'sources/cube_sides/05.jpg',
'sources/cube_sides/06.jpg',
'sources/cube_sides/07.jpg',
'sources/cube_sides/08.jpg',
'sources/cube_sides/09.jpg',
'sources/cube_sides/010.jpg',
'sources/cube_sides/011.jpg',
'sources/cube_sides/012.jpg',
'sources/cube_sides/013.jpg',
'sources/cube_sides/014.jpg',
'sources/cube_sides/015.jpg',
'sources/cube_sides/016.jpg',
'sources/cube_sides/017.jpg',
'sources/cube_sides/018.jpg'
];
var urls = imgAr.sort(function(){return .6 - Math.random()}).slice(0,6);
var reflectionCube = THREE.ImageUtils.loadTextureCube( urls, THREE.CubeReflectionMapping );
//load the model
var loader = new THREE.BinaryLoader();
loader.load( "sources/obj/mmlogo/mm_logo.js", function ( geometry ) {
var material = new THREE.MeshPhongMaterial( {
color: 0x515151,
morphTargets: true,
overdraw: 0.5,
envMap: reflectionCube,
combine: THREE.AddOperation,
reflectivity: 1,
shininess: 0,
side: THREE.DoubleSide,
} );
//assign a mesh to the geometry
mesh = new THREE.Mesh( geometry, material );
mesh.scale.set( 120, 120, 120 );
mesh.position.y = 50;
mesh.position.x = 0;
mesh.position.z = 700;
mesh.rotation.y = 10;
mesh.rotation.x = 10;
scene.add( mesh );
//mixer = new THREE.AnimationMixer( mesh );
//var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'gallop', geometry.morphTargets, 30 );
//mixer.addAction( new THREE.AnimationAction( clip ).warpToDuration( 1 ) );
} );
//set up the Raycaster
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
//set up the renderer
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xffffff );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild(renderer.domElement);
document.addEventListener( 'load', onDocumentLoad, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentLoad( event ) {
event.preventDefault();
var intersects = raycaster.intersectObjects( scene.children );
new TWEEN.Tween( intersects[ 0 ].object.position ).to( {
x: 0,
y: 50,
z: 70 }, 20000 )
.easing( TWEEN.Easing.Sinusoidal.In).start();
new TWEEN.Tween( intersects[ 0 ].object.rotation ).to( {
x: 0,
y: 0,
z: 0 }, 20000 )
.easing( TWEEN.Easing.Sinusoidal.In).start();
}
function animate() {
requestAnimationFrame( animate );
render();
}
var radius = 600;
var theta = 0;
function render() {
TWEEN.update();
theta += 0;
camera.position.y = radius * Math.sin( THREE.Math.degToRad( theta ) );
camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) );
camera.lookAt( camera.target );
renderer.render( scene, camera );
}
</script>

Cannot read property 'uniform' of undef when rendering mesh with multiple materials

I have exported a 3d model from blender to a three.js file. It has 2 materials applied to different portions of it. It has a lot of vertices and uv coords so i wont post the code here. I can see that it indeed has 2 materials though, so im pretty sure my error is in my three.js code. It does have 0 bones, morph targets, and colors though. I dont know if those are important for my application or not, so my error might be there.
Here is what I have so far:
var camera, scene1, scene2, raycaster, renderer, staticMesh , loader;
var highlighted, standard;
var mouse = new THREE.Vector2(), INTERSECTED;
init();
animate();
function init() {
standard = new THREE.MeshLambertMaterial( { color: 0x9999ff } );
highlighted = new THREE.MeshLambertMaterial( { color: 0xff0000 } )
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 15;
scene1 = new THREE.Scene();
scene2 = new THREE.Scene();
loader = new THREE.JSONLoader();
loader.load( "abs.json", function( geometry ) {
var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: 0x9999ff } ) );
//mesh.scale.set( 10, 10, 10 );
mesh.position.y = -6;
mesh.position.x = 0;
scene2.add( mesh );
} );
loader.load( "bodyTest.json", function(geometry, material) {
material[0] = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: 0x9999ff } ) );
material[1] = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: 0x9999ff } ) );
var materials = new THREE.MeshFaceMaterial(material);
staticMesh = new THREE.Mesh( geometry, materials );
scene1.add( staticMesh );
} );
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(-1, -1, -1).normalize();
scene1.add(directionalLight);
directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene1.add(directionalLight);
directionalLight = new THREE.DirectionalLight(0xffffff, .5);
directionalLight.position.set(1, 0, 0).normalize();
scene1.add(directionalLight);
directionalLight = new THREE.DirectionalLight(0xffffff, .5);
directionalLight.position.set(-1, 0, 0).normalize();
scene1.add(directionalLight);
raycaster = new THREE.Raycaster();
renderer = new THREE.WebGLRenderer({ antialiasing: true});
renderer.setClearColor( 0xffffff );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
document.body.appendChild( renderer.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
function animate() {
requestAnimationFrame( animate );
scene1.rotation.y += 0.007;
scene2.rotation.y += 0.007;
/*
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 ).unproject( camera );
raycaster.set( camera.position, vector.sub( camera.position ).normalize() );
var intersects = raycaster.intersectObjects( scene2.children );
if ( intersects.length > 0 ) {
if ( INTERSECTED != intersects[ 0 ].object ) {
if(staticMesh) staticMesh.material.materials[1] = staticMesh.currentMat;
INTERSECTED = intersects[ 0 ].object;
staticMesh.currentMat = staticMesh.material.materials[1]
staticMesh.material.materials[1] = highlighted;
}
} else {
if(staticMesh) staticMesh.material.materials[1] = staticMesh.currentMat;
INTERSECTED = null;
}
*/
renderer.render( scene2, camera );
renderer.render( scene1, camera );
}
As you can see I already commented out portions that I thought the error might be coming from. I have also tried running it with renderer.render( scene1, camera ); commented out and it had no errors.
I don't fully understand how this fixed it, but I found this in a different example and it ended up working. standard is a lambert material i have defined prior.
loader.load( "bodyTest.json", function(geometry) {
var material = [];
material.push( standard );
material.push( standard );
var materials = new THREE.MeshFaceMaterial(material);
staticMesh = new THREE.Mesh( geometry, materials );
scene1.add( staticMesh );
} );
I'd still appreciate an explanation if someone knows what my problem was.

Issue with custom geometry and face normal

I'm quite new to ThreeJS and I have a small issue (probably wrong usage). I'm trying to create a custom geometry and define the faces normals by myself.
I create one normal in one direction and the other one in the opposite direction, as my Mesh is not 2 sided I expect to see only one of the face, however I can see both of them... Any Idea of what I'm doing wrong ?
Thanks!
<body>
<script src="../build/Three.js"></script>
<script src="js/Stats.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
container = document.createElement( 'div' );
document.body.appendChild( container );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.up.x = 0;
camera.up.y = 0;
camera.up.z = 1;
camera.position.x = 300;
camera.position.y = -1000;
camera.position.z = 1000;
camera.lookAt(new THREE.Vector3(300, 250, 0));
scene.add( camera );
var light, geometry, material;
scene.add( new THREE.AmbientLight( 0x404040 ) );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 1, 0 );
scene.add( light );
material = new THREE.MeshBasicMaterial( { color: 0xFFFF00, wireframe: false, transparent: false, opacity: 1 } );
geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0,0,0));
geometry.vertices.push(new THREE.Vector3(600,0,0));
geometry.vertices.push(new THREE.Vector3(0,-500,0));
geometry.vertices.push(new THREE.Vector3(600,-500,0));
var face;
face = new THREE.Face3(0,2,1);
face.normal.set(0,0,-1);
geometry.faces.push(face);
face = new THREE.Face3(2,3,1);
face.normal.set(0,0,1);
geometry.faces.push(face);
geometry.computeCentroids();
//geometry.computeFaceNormals();
//geometry.computeTangents();
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
renderer.render( scene, camera );
</script>
</body>
WebGLRenderer uses the vertex order in which you created the face for defining the orientation instead of the normal. Try doing this:
face = new THREE.Face3(2,1,3);

Categories