How to use EdgesHelper on imported Collada model in three.js - javascript

I'm trying to use EdgesHelper on loaded Collada model in three.js and having problems with:
applying edges to the whole model geometry,
misalignment and scale differences between the Collada model
and generated edges.
http://codepen.io/znak/pen/raqBLM?editors=001
var controls, scene, camera, renderer;
var light;
var dae, daeGeometry, daeMaterial, daeMesh, daeEdges;
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load( 'http://www.lenart.pl/assets/codepen/FestoolClamp2.dae', function ( collada ) {
dae = collada.scene;
daeMaterial = new THREE.MeshBasicMaterial( { color: 0xaaaaaa } );
collada.scene.traverse( function ( child ) {
if ( child.material ) child.material = daeMaterial;
if ( child.geometry ) {
daeMesh = new THREE.Mesh( child.geometry, daeMaterial );
daeEdges = new THREE.EdgesHelper( daeMesh, 0x444444 );
}
} );
dae.updateMatrix();
init();
render();
} );
function init() {
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 150, -350 );
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', render );
light = new THREE.DirectionalLight( 0xffffff, .75 );
light.position.set( 0, 1, -2 );
scene.add( light );
dae.add( daeEdges );
scene.add( dae );
dae.scale.x = dae.scale.y = dae.scale.z = 10;
renderer = new THREE.WebGLRenderer( { alpha: true, antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
animate();
}
function animate() {
requestAnimationFrame( animate );
dae.rotation.y += 0.002;
controls.update();
render();
}
function render() {
renderer.render( scene, camera );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
Any help would be appreciated.

Traverse the scene objects and add edges using EdgesHelper in the loader callback:
object3D.traverse(function(o){ if (o.type === "Mesh") {
var m = new THREE.EdgesHelper(o, 0x0);
m.matrixAutoUpdate = true;
m.matrix = o.matrix;
o.add(m);
} });
You should see outline on your imported dae models. I'm using this in one of my projects.

Related

Rotate object with rotated parent in world space?

I'm using this function to rotate object Y axis in world space:
function rotateWorldYAxis( obj, angle ) {
quat.setFromAxisAngle( new THREE.Vector3(0,1,0), angle );
obj.quaternion.multiplyQuaternions(quat,obj.quaternion);
obj.updateMatrixWorld();
}
But it doesn't work with the object has rotated parent.
Here is example Fiddle:
Correct behavior when parent not rotated:
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var container, stats;
var camera, scene, controls;
var renderer;
var quat = new THREE.Quaternion();
var axis = new THREE.Vector3();
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
// CAMERA
camera = new THREE.PerspectiveCamera( 30, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
camera.position.set( 0, 0, 500 );
scene = new THREE.Scene();
scene.add( new THREE.AmbientLight( 0xaaaaaa ) );
var light = new THREE.PointLight( 0xffffff );
light.position.set(100,100,100);
scene.add( light );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
renderer.domElement.style.position = "relative";
container.appendChild( renderer.domElement );
//____________________________//
cube = new THREE.Mesh(
new THREE.CubeGeometry(50,100,50),
new THREE.MeshPhongMaterial()
);
cube.rotation.set(Math.PI/3, 0, 0);
cubeParent = new THREE.Object3D();
cubeParent.rotation.set(0,0,0) //Not rotated parent
cubeParent.add(cube)
scene.add(cubeParent)
//____________________________//
var grid = new THREE.Mesh(
new THREE.PlaneGeometry(200, 200, 10, 10),
new THREE.MeshBasicMaterial({wireframe: true})
)
grid.position.y = -100
grid.rotation.x = Math.PI/2
scene.add(grid);
window.addEventListener( 'resize', onWindowResize, false );
}
function rotateWorldYAxis( obj, angle ) {
quat.setFromAxisAngle( new THREE.Vector3(0,1,0), angle );
obj.quaternion.multiplyQuaternions(quat,obj.quaternion);
obj.updateMatrixWorld();
}
function animate() {
requestAnimationFrame( animate );
render();
rotateWorldYAxis(cube, 0.01)
}
function render() {
renderer.render( scene, camera );
}
function onWindowResize( event ) {
SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
}
<script src="https://threejs.org/build/three.js"></script>
<p style="position: fixed;z-index:1;top:0;text-align:center;color: #fff">This is correct behavior</p>
Wrong behavior when parent is rotated:
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var container, stats;
var camera, scene, controls;
var renderer;
var quat = new THREE.Quaternion();
var axis = new THREE.Vector3();
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
// CAMERA
camera = new THREE.PerspectiveCamera( 30, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
camera.position.set( 0, 0, 500 );
scene = new THREE.Scene();
scene.add( new THREE.AmbientLight( 0xaaaaaa ) );
var light = new THREE.PointLight( 0xffffff );
light.position.set(100,100,100);
scene.add( light );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
renderer.domElement.style.position = "relative";
container.appendChild( renderer.domElement );
//____________________________//
cube = new THREE.Mesh(
new THREE.CubeGeometry(50,100,50),
new THREE.MeshPhongMaterial()
);
cube.rotation.set(Math.PI/3, 0, 0);
cubeParent = new THREE.Object3D();
cubeParent.rotation.set(1,0,0) //Rotated parent
cubeParent.add(cube)
scene.add(cubeParent)
//____________________________//
var grid = new THREE.Mesh(
new THREE.PlaneGeometry(200, 200, 10, 10),
new THREE.MeshBasicMaterial({wireframe: true})
)
grid.position.y = -100
grid.rotation.x = Math.PI/2
scene.add(grid);
window.addEventListener( 'resize', onWindowResize, false );
}
function rotateWorldYAxis( obj, angle ) {
quat.setFromAxisAngle( new THREE.Vector3(0,1,0), angle );
obj.quaternion.multiplyQuaternions(quat,obj.quaternion);
obj.updateMatrixWorld();
}
function animate() {
requestAnimationFrame( animate );
render();
rotateWorldYAxis(cube, 0.01)
}
function render() {
renderer.render( scene, camera );
}
function onWindowResize( event ) {
SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
}
<script src="https://threejs.org/build/three.js"></script>
<p style="position: fixed;z-index:1;top:0;text-align:center;color: #fff">Parent rotate cause this wrong behavior, this cube need to rotates on Y world axis</p>
Any help is appreciated! Thank you!

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>

Three.js OBJloader with OrbitControls

I need to do very simple 3d model viewer with rotation and so on..
I have simple code, everything works fine, but when I add these two rows with OrbitControls then there'S only blank page:
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', render );
Whole code:
<body>
<script src="js/OrbitControls.js"></script>
<script src="js/three.min.js"></script>
<script src="js/OBJLoader.js"></script>
<div id="ahoj" style="width:1000px; height:700px">
</div>
<script>
var container;
var camera, controls, scene, renderer;
var mouseX = 0, mouseY = 0;
var windowHalfX = 1000 / 2;
var windowHalfY = 700 / 2;
init();
animate();
function init() {
container = document.getElementById('ahoj');
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 75, 1000 / 700, 1, 2000 );
camera.position.z = 200;
// scene
scene = new THREE.Scene();
var ambient = new THREE.AmbientLight( 0x000 );
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 ) {
};
var loader = new THREE.ImageLoader( manager );
loader.load( 'textures/mapa1.png', function ( image ) {
texture.image = image;
texture.needsUpdate = true;
} );
// model
var loader = new THREE.OBJLoader( manager );
loader.load( 'obj/Immortal.obj', function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
//child.material.map = texture;
}
} );
object.scale.set(3,3,3);
object.position.y = 0;
object.position.z = 0;
object.position.x = 0;
scene.add( object );
}, onProgress, onError );
//
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
//controls = new THREE.OrbitControls( camera );
//controls.addEventListener( 'change', render );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( 1000, 700 );
container.appendChild( renderer.domElement )
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = 1000 / 2;
windowHalfY = 700 / 2;
camera.aspect = 1000 / 700;
camera.updateProjectionMatrix();
renderer.setSize( 1000, 700 );
}
function animate() {
render();
requestAnimationFrame( animate );
controls.update();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
Any idea where is the problem?
I tried some few tutorials, but no one helped me..
You need to include three.min.js first:
<script src="js/three.min.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/OBJLoader.js"></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.

Three.js - VRML Loader

I'm trying to use the Three.js with VRML (WRL) models. What I am wondering is that the model is loaded with variations of colors (colored). How can I load the model in solid color as the original file?
My example is: http://dev.logicarts.com.br/semapro/projeto-3d/teste-1.html
The code:
<div id="info">
three.js -
vrml format loader test -
<!--model from VRML 2.0 Tutorial,-->
</div>
<script src="js/three.min.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/VRMLLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="js/stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer;
var cross;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.01, 1e10 );
camera.position.z = 6;
controls = new THREE.OrbitControls( camera );
controls.rotateSpeed = 5.0;
controls.zoomSpeed = 5;
controls.noZoom = false;
controls.noPan = false;
scene = new THREE.Scene();
scene.add( camera );
// light
var dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( 200, 200, 1000 ).normalize();
camera.add( dirLight );
camera.add( dirLight.target );
var loader = new THREE.VRMLLoader();
loader.addEventListener( 'load', function ( event ) {
scene.add(event.content);
} );
loader.load( "3d/conjunto-carcaca.wrl" );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setSize( window.innerWidth, window.innerHeight );
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
stats.update();
}
</script>
If you add this code under the scene.add(event.content); statement, all the objects in your scene will turn red.
scene.traverse (function (object)
{
if (object instanceof THREE.Mesh) {
object.material.color.setHex( 0xff0000 );
}
});

Categories