How to remove or hide loaded stl in three.js - three.js

How remove of hide loaded.load three.js according to the condition for example id the door condition = 0, if will load the flame.stl and reverse
function checkDoorStatus(isDoorOpen, prevIsDoorOpen){
if ( isDoorOpen == 1)
{
var loader = new THREE.STLLoader();
loader.load( 'model/panic.stl', function ( geometry ) {
var material = new THREE.MeshPhongMaterial( { color: 0xa80306, specular: 0x111111, shininess: 200 } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0.145, -0.3, -0.29);
mesh.rotation.set( 0 , 0, Math.PI / 2 );
mesh.scale.set( 0.05, 0.05, 0.05);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
} );
//console.log("Panic 1");
}
else if (isDoorOpen == 0)
{
var loader = new THREE.STLLoader();
loader.load( 'model/flame.stl', function ( geometry ) {
var material = new THREE.MeshPhongMaterial( { color: 0xa80306, specular: 0x111111, shininess: 200 } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0.145, -0.3, -0.29);
mesh.rotation.set( 0 , 0, Math.PI / 2 );
mesh.scale.set( 0.05, 0.05, 0.05);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
} );
//console.log("Panic 0");
}
}

According to my understanding, you want to show only one mesh at a time based on some condition. If that is the case, one possible solution is give a name to your mesh before adding to the scene and remove the old door based on its name before adding the new one. For example
mesh.name = "openDoor";
scene.remove(scene.getObjectByName("closedDoor"));
scene.add( mesh )
Hope it helps.

Related

Ray does not accurately determine the intersection

I want to find point of intersection curve and line. Created raycast, but it doesn't work well. The point of the ray is far from the actual intersection.
Webgl 1, threejs 0.109
var sartPoint = new THREE.Vector3( -30, -50, 0 );
var endPoint = new THREE.Vector3( 50, 80, 0 );
var geometry = new THREE.Geometry();
geometry.vertices.push(sartPoint);
geometry.vertices.push(endPoint);
var materialTmp = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 5 } );
var itemTmp = new THREE.Line( geometry, materialTmp );
_this.add( itemTmp, 'lines' );
scene.updateMatrixWorld()
var curve = new THREE.EllipseCurve(
0, 0, // ax, aY
10, 10, // xRadius, yRadius
0, 2 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
);
var points = curve.getPoints( 10 );
var geometry = new THREE.BufferGeometry().setFromPoints( points );
var material = new THREE.LineBasicMaterial( { color : 0xff00ff } );
var ellipse = new THREE.Line( geometry, material );
scene.add( ellipse );
var raycaster = new THREE.Raycaster(sartPoint, endPoint.clone().normalize());
var intersects = raycaster.intersectObject( ellipse );
console.log(intersects);
if(intersects.length > 0){
// FIRST dot of intersect
var dotGeometry2 = new THREE.Geometry();
dotGeometry2.vertices.push(intersects[0].point);
var dotMaterial2 = new THREE.PointsMaterial( { size: 5, color: 0x00ff00 } );
var dot2 = new THREE.Points( dotGeometry2, dotMaterial2 );
_this.add( dot2, 'points' );
}
The second argument to the Raycaster constructor is a direction vector. Instead of:
endPoint.clone().normalize()
I think you want:
endPoint.clone().sub(startPoint).normalize()
It is work if
curve.getPoints( 10 );
When
curve.getPoints( 100 );
That doesn't work.

Applying postprocessing steps for specific objects

Based on this example i try to create a scene where several objects get the bloom, and other objects dont.
The white cube in the middle is supposed to be just white (without the bloom)
I'm confused on how to get the result that i want. I tried for example adding a 2nd scene with the white cube but it seems i cant get the order right. Maybe my approch with different scenes is wrong?
Whats the "best" way to achieve this behaviour? I always end up just seeing one scene, just the white cube or the 4 colored ones. (example below shows everything atm)
myFiddle: https://jsfiddle.net/qwertasyx/8qw3ys4z/16/
var scene,scene2,camera, controls, pointLight, stats;
var composer, renderer, mixer;
var params = {
exposure: 1,
bloomStrength: 1.5,
bloomThreshold: 0,
bloomRadius: 0
};
var objects = [];
var clock = new THREE.Clock();
var container = document.getElementById( 'container' );
stats = new Stats();
//container.appendChild( stats.dom );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.toneMapping = THREE.ReinhardToneMapping;
container.appendChild( renderer.domElement );
scene = new THREE.Scene();
//scene2 = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 100 );
camera.position.set( 2.5,2.5, 10 );
scene.add( camera );
// scene2.add( camera );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.maxPolarAngle = Math.PI * 0.5;
controls.minDistance = 1;
controls.maxDistance = 10;
controls.target.set(2.5,2.5,0)
controls.update()
// scene.add( new THREE.AmbientLight( 0x404040 ) );
pointLight = new THREE.PointLight( 0xffffff, 1 );
// camera.add( pointLight );
var renderScene = new THREE.RenderPass( scene, camera );
//var renderScene2 = new THREE.RenderPass( scene2, camera );
var bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 );
bloomPass.renderToScreen = true;
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
composer = new THREE.EffectComposer( renderer );
composer.setSize( window.innerWidth, window.innerHeight );
composer.addPass( renderScene );
composer.addPass( bloomPass );
//composer.addPass( renderScene2 );
//objects
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
var cube = new THREE.Mesh( geometry, material );
cube.vrz = 0.01;
cube.position.x += 5
scene.add( cube );
objects.push(cube)
var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
var cube = new THREE.Mesh( geometry, material );
cube.vrz = 0.01;
cube.position.x += 5
cube.position.y += 5
scene.add( cube );
objects.push(cube)
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
cube.vrz = 0.01;
cube.position.y += 5
scene.add( cube );
objects.push(cube)
var material = new THREE.MeshBasicMaterial( { color: 0x0000ff } );
var cube = new THREE.Mesh( geometry, material );
cube.vrz = 0.01;
scene.add( cube );
objects.push(cube)
// cube thats supposed to be not bloomy
var material = new THREE.MeshBasicMaterial( { color: 0xffffff } );
var cube = new THREE.Mesh( geometry, material );
cube.vrz = 0.01;
cube.position.y += 2.5
cube.position.x += 2.5
scene.add( cube );
objects.push(cube)
var gui = new dat.GUI();
gui.add( params, 'exposure', 0.1, 2 ).onChange( function ( value ) {
renderer.toneMappingExposure = Math.pow( value, 4.0 );
} );
gui.add( params, 'bloomThreshold', 0.0, 1.0 ).onChange( function ( value ) {
bloomPass.threshold = Number( value );
} );
gui.add( params, 'bloomStrength', 0.0, 3.0 ).onChange( function ( value ) {
bloomPass.strength = Number( value );
} );
gui.add( params, 'bloomRadius', 0.0, 1.0 ).step( 0.01 ).onChange( function ( value ) {
bloomPass.radius = Number( value );
} );
window.onresize = function () {
var width = window.innerWidth;
var height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize( width, height );
composer.setSize( width, height );
};
function animate() {
requestAnimationFrame( animate );
objects.forEach(function(obj){
obj.rotation.z += obj.vrz;
});
stats.update();
composer.render();
}
animate();
I had a similar problem once. An example from this comment helped me.
Note that in that example there are 2 scenes and 2 composers (the final composer gets output of the previous composer as its input)
ppoFinal.blendPass.uniforms.tAdd.value = ppoRGB.composer.renderTarget2.texture;
and render() is called on both composers.
ppoRGB.composer.render();
ppoFinal.composer.render();
This pattern allows you to apply postprocessing effects selectively and it works well. The problem is the scalability of the method and probably performance. Because when you want to apply another object with yet different effect, you need to introduce 3rd scene and 3rd composer. For my little project in the past I ended up with 4 scenes and 4 composers...

Shadow on pure white

I'm trying to create a pure white scene where the only hint of depth is by moving a spotLight around with your mouse. I like the effect I have now but I was wondering how I could get the entire field (now gray) to be pure white, while keeping the shadow.
If I turn ambient light up I lose the shadow.
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 50, 0 );
var controls = new OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render );
controls.minDistance = 20;
controls.maxDistance = 500;
controls.enablePan = false;
var ambient = new THREE.AmbientLight( 0xffffff, .7 );
scene.add( ambient );
spotLight = new THREE.SpotLight( 0xffffff, 1 );
spotLight.position.set( 0, 10, 0 );
spotLight.target.position.set( 0, 0, 0 );
spotLight.angle = 1.05;
spotLight.penumbra = 0.05;
spotLight.decay = 1;
spotLight.distance = 200;
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.camera.near = 10;
spotLight.shadow.camera.far = 200;
scene.add( spotLight );
lightHelper = new THREE.SpotLightHelper( spotLight );
// scene.add( lightHelper );
shadowCameraHelper = new THREE.CameraHelper( spotLight.shadow.camera );
// scene.add( shadowCameraHelper );
// scene.add( new THREE.AxisHelper( 10 ) );
var material = new THREE.MeshPhongMaterial( { color: 0xffffff, dithering: true } );
var geometry = new THREE.BoxGeometry( 2000, 1, 2000 );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, - 1, 0 );
mesh.receiveShadow = true;
scene.add( mesh );
var material = new THREE.MeshPhongMaterial( { color: 0xffffff, dithering: true } );
geometry = new THREE.BoxGeometry( 3, 1, 2 );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, 0, 0 );
mesh.castShadow = true;
scene.add( mesh );

Draw 3D object axes threejs

How can i draw object axes. I am refering at the mesh local axes and not the world axes. I know that using:
function drawlines(){
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3( 100, 0, 0 ),
new THREE.Vector3( 0, 0, 0 )
);
var line = new THREE.Line( geometry, material );
scene.add( line );
var material = new THREE.LineBasicMaterial({
color: 0x00ff00
});
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3( 0, 100, 0 ),
new THREE.Vector3( 0, 0, 0 )
);
var line = new THREE.Line( geometry, material );
scene.add( line );
var material = new THREE.LineBasicMaterial({
color: 0xff0000
});
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3( 0, 0, 100 ),
new THREE.Vector3( 0, 0, 0 )
);
var line = new THREE.Line( geometry, material );
scene.add( line );
}
draws lines at XYZ respectively. What i need is to draw the XYZ axis of the model. How can i do that. I load the model with this code
var loader = new THREE.JSONLoader();
loader.load( "https://threejs.org/examples/models/animated/horse.js", function ( geometry ) {
var material = new THREE.MeshLambertMaterial( {
vertexColors: THREE.FaceColors,
morphTargets: true,
overdraw: 0.5
} );
mesh = new THREE.Mesh( geometry, material );
mesh.scale.set( 1.5, 1.5, 1.5 );
scene.add( mesh );
mixer = new THREE.AnimationMixer( mesh );
var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'gallop', geometry.morphTargets, 30 );
mixer.clipAction( clip ).setDuration( 1 ).play();
} );
If I get you correctly, you can use THREE.AxisHelper(). Just create an instance of it and then add it to your model.
jsfiddle example.
var camera, scene, renderer, controls;
var sphere, cube;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 5, 1.5).setLength(100);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
//renderer.setClearColor(0xcccccc);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var plane = new THREE.GridHelper(100, 10);
scene.add(plane);
sphere = new THREE.Mesh(new THREE.SphereGeometry(10, 16, 8), new THREE.MeshBasicMaterial({color: "red", wireframe: true}));
sphere.position.set(-20, 0, 0);
cube = new THREE.Mesh(new THREE.BoxGeometry(10, 10, 10), new THREE.MeshBasicMaterial({color: "green", wireframe: true}));
cube.position.set(20, 0, 0);
var worldAxis = new THREE.AxesHelper(20);
scene.add(worldAxis);
scene.add(sphere);
scene.add(cube);
var sphereAxis = new THREE.AxesHelper(20);
sphere.add(sphereAxis);
var cubeAxis = new THREE.AxesHelper(20);
cube.add(cubeAxis);
}
var delta;
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}

Weird square on scene with SSAO shader

I'm running following code (jsfiddle: http://jsfiddle.net/sx9p7/ ) :
var scene, camera, renderer, composer;
var l1, l2, hemiLight;
var effectSSAO;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer( { antialias: false, alpha: false } );
renderer.shadowMapEnabled = true;
renderer.setClearColor( 0xd8e7ff );
renderer.setSize( 800,600);
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, 800 / 600, 1, 10000 );
camera.position.set(-200,100,-60);
camera.lookAt(new THREE.Vector3(0,0,0));
var container = document.createElement( 'div' );
document.body.appendChild( container );
composer = new THREE.EffectComposer( renderer );
composer.addPass( new THREE.RenderPass( scene, camera ) );
effectSSAO = new THREE.ShaderPass( THREE.SSAOShader );
effectSSAO.renderToScreen = true;
composer.addPass( effectSSAO );
hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.4 );
hemiLight.position.set( 0, 300, 0 );
scene.add( hemiLight );
l1 = new THREE.DirectionalLight( 0xffffff, 0.3);
l1.position.set( 100, 100, 0 );
l1.castShadow = true;
scene.add(l1);
l2 = new THREE.DirectionalLight( 0xffffff, 0.3);
l2.position.set( -100, 100, 0 );
l2.castShadow = true;
scene.add(l2);
var plane = new THREE.Mesh( new THREE.PlaneGeometry( 200, 200), new THREE.MeshLambertMaterial({ }) );
plane.receiveShadow = true;
plane.castShadow = true;
plane.rotation.x = - 90 * Math.PI / 180;
plane.position.set(0,0,0);
scene.add( plane );
var cube = new THREE.Mesh(new THREE.CubeGeometry(50, 50, 50), new THREE.MeshPhongMaterial( { color: 0xaaaaaa, ambient: 0xbbbbbb, specular: 0xcccccc, perPixel: true, vertexColors: THREE.FaceColors } ));
cube.receiveShadow = true;
cube.castShadow = true;
scene.add(cube);
}
function animate() {
requestAnimationFrame( animate );
composer.render();
}
and i have a problem with SSAO shader. I did try many parameters, codes, examples but still i can't remove that square which is in the middle of scene ( which sometime look like correct SSAO effect but in wrong position ??? )
If i will remove one directional light fragment is gone - but still no SSAO effect and shadows are still super very low resolution.
Well, 2 directional lights are strange anyway, just leave it at 1 for the moment.
Concerning the SSAO, see the shader and its numerous parameters. you would need to adjust those according to your scene. example:
effectSSAO .uniforms[ 'tDepth' ].value = depthTarget;
effectSSAO .uniforms[ 'size' ].value.set( width, height );
effectSSAO .uniforms[ 'cameraNear' ].value = 0.1;
effectSSAO .uniforms[ 'cameraFar' ].value = 1000;
As you see above, you also need more than just a few parameter tweaks.
The Three.SSAO shader expects a previously rendered depth pass to work properly.
See here for more help:
How to use the three.js SSAO shader?

Resources