Three.js keeps displaying the same geometry - javascript

I have a simple Three.js code that works properly in Three.js v68 but it displays 2 cubes instead of a cube and a sphere in Three.js v71. If I draw the sphere first it will draw two spheres.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 5;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var CubeGeometry = new THREE.BoxGeometry( 1, 1, 1 );
var CubeMaterial = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( CubeGeometry, CubeMaterial );
scene.add( cube );
var spheregeometry = new THREE.SphereGeometry(1, 16, 16);
var spherematerial = new THREE.MeshBasicMaterial({ color: 0x00ff00});
var sphere = new THREE.Mesh(spheregeometry, spherematerial);
sphere.position.set(-2.0, 0, 0);
scene.add(sphere);
renderer.render(scene, camera);

Related

Changing the location of an object on the canvas, using three js

I need to place a number of objects on the canvas, using three js. I'm getting stuck at the point of trying to change the location of the objects. My code is as below:
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 geometry = new THREE.BoxGeometry( 2, 1, 1 );
//geometry.position.x = 1;
//geometry.position.y = 1;
//geometry.position.z = 1;
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
//scene.children[1].position.set(0, 0, 0);
var cube = new THREE.Mesh(geometry, material);
scene.add( cube );
camera.position.z = 5;
renderer.render( scene, camera );
I've commented out the two different ways I tried to achieve this (both failed). Can anyone suggest a solution?
You have to set position to a mesh, not a geometry:
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh(geometry, material);
cube.position.set(1, 1, 1);
scene.add( cube );

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 );

How to change thickness of three.js cyclinder

If I have a basic hollow cyclinder made using three.js like in the JSFiddle how can I change the thickness of the walls?
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 95, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry = new THREE.CylinderGeometry( 2, 2, 5, 360, 1, true );
var material = new THREE.MeshNormalMaterial( { color: 0x00ff00, side: THREE.DoubleSide } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.y = 5;
camera.position.z = 5;
camera.lookAt(0,0,0);
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
animate();
JSFiddle example
No, you have to subtract another cylinder from a cylinder. The one you subtract from it is the inner diameter of the cylinder.
So I changed your code to this:
var outerGeometry = new THREE.CylinderGeometry(2, 2, 5, 360, 1);
var innerGeometry = new THREE.CylinderGeometry(1.5, 1.5, 5, 360, 1);
var material = new THREE.MeshNormalMaterial({
color: 0x00ff00,
side: THREE.DoubleSide
});
var outerCylinder = new ThreeBSP(outerGeometry);
var innerCylinder = new ThreeBSP(innerGeometry);
var hollowedCylinder = innerCylinder.union(outerCylinder);
scene.add(hollowedCylinder.toMesh(material));
Here is the fiddle:
http://jsfiddle.net/gerdonabbink/tephoLr1/133/
As you can see the inner cylinder is 1.5, change this to 1 for example to make the thickness 1.

ThreeJS texture problems

I have a basic scene in threejs that loads a .stl file, it loads normally, but it automatically changes color and I also want it to have its original color What do I have to do to fix it?
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 60, window.innerWidth/window.innerHeight, 1, 500 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.center = new THREE.Vector3();
// var geometry = new THREE.BoxGeometry( 3, 1, 1 );
// var material = new THREE.MeshBasicMaterial( { color: 'skyblue' } );
// var cube = new THREE.Mesh( geometry, material );
// scene.add( cube );
var loader = new THREE.STLLoader();
loader.load( 'js/novo/undefined.stl', function ( geometry ) {
console.log(geometry);
var mesh = new THREE.Mesh(geometry);
mesh.scale.set( 0.1, 0.1, 0.1 );
// mesh.rotation.set( - Math.PI / 2, Math.PI / 2, 0 );
// mesh.scale.set( 0.3, 0.3, 0.3 );
// mesh.receiveShadow = true;
scene.add( mesh );
});
camera.position.z = 300;
var animate = function () {
requestAnimationFrame( animate );
renderer.render(scene, camera);
};
animate();
How should be:
How are you doing:
You are not applying a material to your Mesh.
var mesh = new THREE.Mesh(geometry);
When a mesh is created, if you do not specify a material, a random colored BasicMaterial is applied which can be seen if you look at the THREE.Mesh source.
function Mesh( geometry, material ) {
Object3D.call( this );
this.type = 'Mesh';
this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );
this.drawMode = TrianglesDrawMode;
this.updateMorphTargets();
}
So, to fix your problem, create some sort of material, and send it to the Mesh constructor as the second parameter.
eg.
// create a red material.
var myMaterial = new THREE.MeshBasicMaterial({color: 0xff0000})
// create mesh with red material applied
var mesh = new THREE.Mesh(geometry, myMaterial);
you can find here how to change color or texture for your loader
var loader = new THREE.STLLoader();
loader.load('./FA-FF/FA.STL', function (geometry) {
/* different texture */
var material = new THREE.MeshPhongMaterial({ map: THREE.ImageUtils.loadTexture('img/wood.jpg') });
/* for different color */
var material = new THREE.MeshPhongMaterial({ color: 0xAAAAAA, specular: 0x111111, shininess: 200 });
var mesh = new THREE.Mesh(geometry, material);
mesh.name = "first";
mesh.position.set(-1, 1, 0);
mesh.rotation.set(1.5707963267948963, -8.326672684688674, -1.570796326794894);
mesh.scale.set(0.005, 0.005, 0.005);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
});

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