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

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 ?

Related

Three.js duplicates objects shape but uses new color with ColladaLoader and STLLoader

I need to load collada and STL models stored in files to the same scene. I do this with three.js framework with a standard ColladaLoader() and STLLoader() like in the linked examples.
The first object appears correctly, but the second repeats its shape in the color of the second object.
I don't understand why. Where can be the problem?
UPD
var sloader = new STLLoader();
sloader.load( 'models/m1.stl', function ( geometry ) {
var meshMaterial = new THREE.MeshPhongMaterial( { color: 0xAAAAAA, specular: 0x111111, shininess: 200 } );
if ( geometry.hasColors ) {
meshMaterial = new THREE.MeshPhongMaterial( { opacity: geometry.alpha, vertexColors: THREE.VertexColors } );
}
var mesh = new THREE.Mesh( geometry, meshMaterial );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
});
var tmploader = new ColladaLoader();
tmploader.load('models/m2.dae',
function (geometry) {
var robot = geometry.scene;
var meshMaterial = new THREE.MeshPhongMaterial();
robot.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = meshMaterial;
}
});
//robot = new THREE.Mesh( geometry, meshMaterial );
scene.add(robot);
});
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 2000 );
camera.position.set( -10, 10, -10);
camera.lookAt( 0, 3, 0 );
scene = new THREE.Scene();
// lights
var light = new THREE.AmbientLight( 0x404040, 1.0 ); // soft white light
scene.add( light );
var directionalLight = new THREE.DirectionalLight( 0xffffff, 1.0 );
directionalLight.position.set( 1, 1, -1 ).normalize();
scene.add( directionalLight );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

Loading PLY files without faces - Three.js

I'm working on a Web Service which main funcionality resolves around displaying binary .ply files. To open and visualize the point cloud I'm using PLYLoader from Three.js. I used it to present example files from the internet and it worked. But when I'm trying to attach my .ply file it doesn't. I'm using Three.js because I need my display to be optimal, my files are at least 70mb.
Example .ply file here:
https://onedrive.live.com/redir?resid=7DDB287362EDFD5A!761&authkey=!AOHxkZk-6etH--0&ithint=file%2cply
I noticed that the .ply files that i have are a bit different from .ply files i displayed before. In my files there are no faces only points.
So basically my question is "Is it possible to display point cloud using Three.js? or should I use other library? If this is possible can someone help me with configuring my code to work properly?
Here it is my script in which I'm supporting .ply files:
var cameraControls;
var container = document.getElementById("three");
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, container.offsetWidth / container.offsetHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( container.offsetWidth, container.offsetHeight );
document.getElementById("three").appendChild( renderer.domElement );
cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
cameraControls.target.set( 0, 0, 0 );
cameraControls.addEventListener( 'change', render );
var geometry = new THREE.BoxGeometry( 3, 3, 3 );
var material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
var loader = new THREE.PLYLoader();
loader.load( 'resources/cube.ply', function ( geometry ) {
geometry.computeFaceNormals();
var material = new THREE.MeshStandardMaterial( { color: 0x0055ff } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 0.25;
mesh.rotation.x = - Math.PI / 2;
mesh.scale.multiplyScalar( 1 );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
} );
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
directionalLight.position.set( 0, 1, 0 );
scene.add( directionalLight );
camera.position.z = 5;
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
}
render();
Use THREE.MeshNormalMaterial. It loads the textures with MeshNormalMaterial for some odd reason
Use PointMaterials and Points
const loader = new PLYLoader();
loader.load('00000012.ply', function (geometry) {
var material = new THREE.PointsMaterial( { size: 0.005 } );
material.vertexColors = true //if has colors
var mesh = new THREE.Points(geometry, material)
scene.add(mesh)
} );

Var undefined when I use a loader in three.js

//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().

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.

Three.js Cube with different texture on each face. How to hide edges / vertices

I am trying to create a Cube in Three.js with a different image as texture on each face of the cube.
How can I hide the edges/vertices of the mesh?
Code:
var container, camera, scene, renderer, cube;
init();
animate();
function init(){
container = document.getElementById('container');
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.y = 150;
camera.position.z = 500;
scene.add( camera );
var materials = [];
for ( var i = 0; i < 6; i ++ ) {
materials.push( new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/' + i + '.png') } ) );
}
cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200, 5,5,5, materials ), new THREE.MeshFaceMaterial() );
cube.position.y = 150;
scene.add( cube );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight);
container.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render(){
cube.rotation.y += 0.005;
renderer.render( scene, camera );
}
change:
for ( var i = 0; i < 6; i ++ ) {
materials.push( new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/' + i + '.jpg') } ) );
}
to:
for ( var i = 0; i < 6; i ++ ) {
materials.push( new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/' + i + '.jpg'), overdraw: true } ) );
}
change the line:
cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200, 5,5,5, materials ), new THREE.MeshFaceMaterial() );
to:
cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200, 1,1,1, materials ), new THREE.MeshFaceMaterial() );
Try using another renderer. Change this line:
renderer = new THREE.CanvasRenderer();
to this one:
renderer = new THREE.WebGLRenderer();

Categories