This is a little modified version of "three.js webgl cameras." (got from examples)
I have created a wrapper div for the future canvas and a 'three_webgl' instance.
(I create an instance for a new three_webgl, which is the original function instanced as an object).
As you can see there are two buttons one to create the instance and the animation and the other to stop the animation and delete the instance.
I have a 'stop' control inside the animate loop.
Also I have increased the number of points for the pointcloud (100 000) to measure the memory spent.
The problem I have is that delete works fine but I leave 10 000 KB 'lost'
You can play with create-start / stop- delete and you can see how the memory grows and grows.
My question is how to delete the three environment and data correctly. The goal is to avoid memory leaks.
I'm using the dev branch dated on 12 / 05, chrome 34.0 and Windows XP.
This is the code. (Maybe it is neccesary to change the tree paths for three and stats.)
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - cameras</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #808080;
font-family:Monospace;
font-size:13px;
text-align:center;
background-color: #000;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px; width: 100%;
padding: 5px;
z-index: 100;
}
a {
color: #0080ff;
}
b { color: lightgreen }
#stats { position: absolute; top:0; left: 0 }
#stats #fps { background: transparent !important }
#stats #fps #fpsText { color: #777 !important }
#stats #fps #fpsGraph { display: none }
#apDiv1 {
position: absolute;
width: 652px;
height: 376px;
z-index: 101;
left: 54px;
top: 95px;
border: 1px solid white;
}
#apDiv2 {
position: absolute;
width: 655px;
height: 80px;
z-index: 102;
left: 53px;
top: 490px;
border: 1px red solid;
}
#apDiv3 {
position: absolute;
width: 200px;
height: 34px;
z-index: 103;
left: 54px;
top: 52px;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">three.js - cameras<br/>
<b>O</b> orthographic <b>P</b> perspective
</div>
<div id="apDiv1"></div>
<div id="apDiv2"></div>
<div id="apDiv3">
<input type="submit" name="b1" id="b1" value="crete-start" onClick="new_webgl()">
<input type="submit" name="b2" id="b2" value="stop-delete" onClick="del_webgl()">
</div>
<script src="tree/build/three.js"></script>
<script src="tree/examples/js/libs/stats.min.js"></script>
<script>
var webgl_true;
try
{ var canvas = document.createElement( 'canvas' );
webgl_true = !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); }
catch( e ) { webgl_true= false; }
THE_DIV2 = document.getElementById("apDiv2");
THE_DIV2.innerHTML = "Webgl detector : "+webgl_true;
</script>
<script>
var webgl;
var renderer;
var del_renderer = false;
new_webgl = function () { webgl = new three_webgl(); }
var del_webgl = function () { del_renderer = true;
THE_DIV.parentNode.removeChild(THE_DIV);
webgl = null;
// THE_DIV.appendChild( renderer.domElement );
}
three_webgl = function () {
del_renderer = false;
THE_DIV = document.createElement( 'div' );
THE_DIV.style.height="100%";
document.getElementById("apDiv1").appendChild(THE_DIV);
var SCREEN_WIDTH = THE_DIV.clientWidth;
var SCREEN_HEIGHT = THE_DIV.clientHeight;
var container, stats;
var camera, scene, mesh;
var cameraRig, activeCamera, activeHelper;
var cameraPerspective, cameraOrtho;
var cameraPerspectiveHelper, cameraOrthoHelper;
init();
animate();
function init () {
//container = document.createElement( 'div' );
//document.body.appendChild( container );
scene = new THREE.Scene();
//
camera = new THREE.PerspectiveCamera( 50, 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
camera.position.z = 2500;
cameraPerspective = new THREE.PerspectiveCamera( 50, 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT, 150, 1000 );
cameraPerspectiveHelper = new THREE.CameraHelper( cameraPerspective );
scene.add( cameraPerspectiveHelper );
//
cameraOrtho = new THREE.OrthographicCamera( 0.5 * SCREEN_WIDTH / - 2, 0.5 * SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_HEIGHT / - 2, 150, 1000 );
cameraOrthoHelper = new THREE.CameraHelper( cameraOrtho );
scene.add( cameraOrthoHelper );
//
activeCamera = cameraPerspective;
activeHelper = cameraPerspectiveHelper;
// counteract different front orientation of cameras vs rig
cameraOrtho.rotation.y = Math.PI;
cameraPerspective.rotation.y = Math.PI;
cameraRig = new THREE.Object3D();
cameraRig.add( cameraPerspective );
cameraRig.add( cameraOrtho );
scene.add( cameraRig );
//
mesh = new THREE.Mesh( new THREE.SphereGeometry( 100, 16, 8 ), new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } ) );
scene.add( mesh );
var mesh2 = new THREE.Mesh( new THREE.SphereGeometry( 50, 16, 8 ), new THREE.MeshBasicMaterial( { color: 0x00ff00, wireframe: true } ) );
mesh2.position.y = 150;
mesh.add( mesh2 );
var mesh3 = new THREE.Mesh( new THREE.SphereGeometry( 5, 16, 8 ), new THREE.MeshBasicMaterial( { color: 0x0000ff, wireframe: true } ) );
mesh3.position.z = 150;
cameraRig.add( mesh3 );
//
var geometry = new THREE.Geometry();
for ( var i = 0; i < 100000; i ++ ) {
var vertex = new THREE.Vector3();
vertex.x = THREE.Math.randFloatSpread( 2000 );
vertex.y = THREE.Math.randFloatSpread( 2000 );
vertex.z = THREE.Math.randFloatSpread( 2000 );
geometry.vertices.push( vertex );
}
var particles = new THREE.PointCloud( geometry, new THREE.PointCloudMaterial( { color: 0x888888 } ) );
scene.add( particles );
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
renderer.domElement.style.position = "relative";
THE_DIV.appendChild( renderer.domElement );
renderer.autoClear = false;
//
stats = new Stats();
THE_DIV2.appendChild( stats.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
document.addEventListener( 'keydown', onKeyDown, false );
}
//
function onKeyDown ( event ) {
switch( event.keyCode ) {
case 79: /*O*/
activeCamera = cameraOrtho;
activeHelper = cameraOrthoHelper;
break;
case 80: /*P*/
activeCamera = cameraPerspective;
activeHelper = cameraPerspectiveHelper;
break;
}
};
//
function onWindowResize( event ) {
SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
camera.aspect = 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
cameraPerspective.aspect = 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT;
cameraPerspective.updateProjectionMatrix();
cameraOrtho.left = - 0.5 * SCREEN_WIDTH / 2;
cameraOrtho.right = 0.5 * SCREEN_WIDTH / 2;
cameraOrtho.top = SCREEN_HEIGHT / 2;
cameraOrtho.bottom = - SCREEN_HEIGHT / 2;
cameraOrtho.updateProjectionMatrix();
}
//
function animate() {
if (!(del_renderer))
{ requestAnimationFrame( animate );
render();
}
stats.update();
if (del_renderer) {renderer=null;}
}
function render() {
var r = Date.now() * 0.0005;
mesh.position.x = 700 * Math.cos( r );
mesh.position.z = 700 * Math.sin( r );
mesh.position.y = 700 * Math.sin( r );
mesh.children[ 0 ].position.x = 70 * Math.cos( 2 * r );
mesh.children[ 0 ].position.z = 70 * Math.sin( r );
if ( activeCamera === cameraPerspective ) {
cameraPerspective.fov = 35 + 30 * Math.sin( 0.5 * r );
cameraPerspective.far = mesh.position.length();
cameraPerspective.updateProjectionMatrix();
cameraPerspectiveHelper.update();
cameraPerspectiveHelper.visible = true;
cameraOrthoHelper.visible = false;
} else {
cameraOrtho.far = mesh.position.length();
cameraOrtho.updateProjectionMatrix();
cameraOrthoHelper.update();
cameraOrthoHelper.visible = true;
cameraPerspectiveHelper.visible = false;
}
cameraRig.lookAt( mesh.position );
renderer.clear();
activeHelper.visible = false;
renderer.setViewport( 0, 0, SCREEN_WIDTH/2, SCREEN_HEIGHT );
renderer.render( scene, activeCamera );
activeHelper.visible = true;
renderer.setViewport( SCREEN_WIDTH/2, 0, SCREEN_WIDTH/2, SCREEN_HEIGHT );
renderer.render( scene, camera );
}
}
</script>
</body>
</html>
Related
I am trying to display my ply modifying three.js webgl_loader_ply example, but it is not showing anything. I can see the object when I open the ply with MeshLab. I have tried to zoom out, change the camera angle, disable the shadowedlight to no avail. Any more tips?
Below is the edited webgl_loader_ply.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - PLY</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
a { color: skyblue }
.button { background:#999; color:#eee; padding:0.2em 0.5em; cursor:pointer }
.highlight { background:orange; color:#fff; }
span {
display: inline-block;
width: 60px;
float: left;
text-align: center;
}
</style>
</head>
<body>
<div id="info">
three.js -
PLY loader test by Wei Meng. Image from John Burkardt
</div>
<script src="../build/three.js"></script>
<script src="js/loaders/PLYLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, cameraTarget, scene, renderer;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 15 );
camera.position.set( 3, 0.15, 3 );
cameraTarget = new THREE.Vector3( 0, -0.1, 0 );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x72645b );
scene.fog = new THREE.Fog( 0x72645b, 2, 15 );
// Ground
var plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 40, 40 ),
new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
);
plane.rotation.x = -Math.PI/2;
plane.position.y = -0.5;
scene.add( plane );
plane.receiveShadow = true;
// PLY file
var loader = new THREE.PLYLoader();
loader.load( './models/ply/binary/foot.ply', function ( geometry ) {
geometry.computeVertexNormals();
var material = new THREE.MeshStandardMaterial( { color: 0x0055ff, flatShading: true } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 0.2;
mesh.position.z = 0.3;
mesh.rotation.x = - Math.PI / 2;
mesh.scale.multiplyScalar( 0.001 );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
} );
// Lights
scene.add( new THREE.HemisphereLight( 0x443333, 0x111122 ) );
addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
addShadowedLight( 0.5, 1, -1, 0xffaa00, 1 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMap.enabled = true;
renderer.shadowMap.renderReverseSided = false;
container.appendChild( renderer.domElement );
// stats
stats = new Stats();
container.appendChild( stats.dom );
// resize
window.addEventListener( 'resize', onWindowResize, false );
}
function addShadowedLight( x, y, z, color, intensity ) {
var directionalLight = new THREE.DirectionalLight( color, intensity );
directionalLight.position.set( x, y, z );
scene.add( directionalLight );
directionalLight.castShadow = true;
var d = 1;
directionalLight.shadow.camera.left = -d;
directionalLight.shadow.camera.right = d;
directionalLight.shadow.camera.top = d;
directionalLight.shadow.camera.bottom = -d;
directionalLight.shadow.camera.near = 1;
directionalLight.shadow.camera.far = 4;
directionalLight.shadow.mapSize.width = 1024;
directionalLight.shadow.mapSize.height = 1024;
directionalLight.shadow.bias = -0.005;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
var timer = Date.now() * 0.0005;
camera.position.x = Math.sin( timer ) * 2.5;
camera.position.z = Math.cos( timer ) * 2.5;
camera.lookAt( cameraTarget );
renderer.render( scene, camera );
}
</script>
</body>
</html>
You will see it if you comment out the lines
mesh.rotation.x = - Math.PI / 2;
mesh.scale.multiplyScalar( 0.001 );
I have written the following code to get the shadow of the stanford dragon on a plane. But I am not getting it. I have enabled shadow by object and plane to receive shadow. My code is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
</style>
</head>
<body>
<script src="http://mrdoob.github.com/three.js/build/three.min.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/shaders/CopyShader.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/shaders/SSAOShader.js"></script>
<script type="text/javascript" src="http://mrdoob.github.com/three.js/examples/js/shaders/ConvolutionShader.js"></script>
<script type="text/javascript" src="http://mrdoob.github.com/three.js/examples/js/shaders/FXAAShader.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/postprocessing/EffectComposer.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/postprocessing/RenderPass.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/postprocessing/MaskPass.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/postprocessing/ShaderPass.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/loaders/DDSLoader.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/loaders/MTLLoader.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/loaders/OBJMTLLoader.js"></script>
<script type="text/javascript" src="http://mrdoob.github.com/three.js/examples/js/postprocessing/BloomPass.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/Detector.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/libs/stats.min.js"></script>
<script>
if ( window.innerWidth === 0 ) { window.innerWidth = parent.innerWidth; window.innerHeight = parent.innerHeight; }
var camera, scene, renderer;
var group;
var depthMaterial, depthTarget, composer;
var object;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor(new THREE.Color(0x000000,0.1));
renderer.shadowMapType = THREE.PCFSoftShadowMap;
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
document.body.appendChild( renderer.domElement );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
//camera.position.x = 100;
camera.position.y = 100;
camera.position.z = 100;
// scene
scene = new THREE.Scene();
var planeGeometry = new THREE.PlaneGeometry(150,150);
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xaaaaaa});
var plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.receiveShadow = true;
plane.rotation.x=-0.5*Math.PI;
plane.position.x=0;
plane.position.y=0;
plane.position.z=0;
// add the plane to the scene
scene.add(plane);
var ambient = new THREE.AmbientLight( 0xffffff );
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0, 1 ).normalize();
scene.add( directionalLight );
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( -80, 60, -10 );
spotLight.shadowMapWidth =2048;
spotLight.shadowMapHeight = 2048;
spotLight.castShadow = true;
spotLight.shadowMapEnabled = true;
scene.add( spotLight );
//Camera
// model
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 ) {
};
THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
var loader = new THREE.OBJMTLLoader();
loader.load( 'dragon.obj', 'dragon.mtl', function ( object ) {
object.position.y = 0;
object.position.x = 0;
object.position.z = 10;
object.castShadow=true;
object.receiveShadow= true;
object.scale.set(4,4,4);
scene.add( object );
}, onProgress, onError );
//
var depthShader = THREE.ShaderLib[ "normal" ];
var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
depthMaterial.blending = THREE.NoBlending;
// postprocessing
composer = new THREE.EffectComposer( renderer );
composer.addPass( new THREE.RenderPass( scene, camera ));
depthTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat } );
var effect = new THREE.ShaderPass( THREE.SSAOShader );
effect.uniforms[ 'tDepth' ].value = depthTarget;
effect.uniforms[ 'size' ].value.set( window.innerWidth, window.innerHeight );
effect.uniforms[ 'cameraNear' ].value = camera.near;
effect.uniforms[ 'cameraFar' ].value = camera.far;
effect.uniforms[ 'aoClamp' ].value = 0.9;
effect.uniforms[ 'onlyAO' ].value=0;
effect.renderToScreen = true;
composer.addPass( effect );
camera.lookAt( scene.position );
}
function animate() {
requestAnimationFrame( animate );
scene.overrideMaterial = depthMaterial;
renderer.render( scene, camera, depthTarget );
scene.overrideMaterial = null;
composer.render();
}
</script>
</body>
</html>
Please help me in finding out in what I have done wrongly. I am comparatively new to JavaScript also.
Another thing I wanted to add to the information above is that it works only with firefox and not chrome.
Thanks in advance.
I'm using three.js and have now a scene with a floor and a car as json loaded. Everything fine but the car is just black and not with the texture from blender. Is there any possibility to export it directly with textures from blender or add the textures afterwards ?
Here's the code I use :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>three.js - pointerlock controls</title>
<style>
html, body {
width: 100%;
height: 100%;
}
body {
background-color: #eeeeee;
margin: 0;
overflow: hidden;
font-family: arial;
}
#blocker {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
}
#instructions {
width: 100%;
height: 100%;
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack: center;
-webkit-box-align: center;
-moz-box-align: center;
box-align: center;
color: #ffffff;
text-align: center;
cursor: pointer;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/controls/PointerLockControls.js"></script>
<div id="blocker">
<div id="instructions">
<span style="font-size:40px">Click to move</span>
<br />
(WASD or Arrow Keys = Move, SPACE = Jump, MOUSE = Look around)
</div>
</div>
<script>
var camera, scene, renderer;
var geometry, material, mesh;
var loader;
var mesh2;
var loadModel;
var controls,time = Date.now();
var objects = [];
var ray;
var blocker = document.getElementById( 'blocker' );
var instructions = document.getElementById( 'instructions' );
// http://www.html5rocks.com/en/tutorials/pointerlock/intro/
var havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
if ( havePointerLock ) {
var element = document.body;
var pointerlockchange = function ( event ) {
if ( document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element ) {
controls.enabled = true;
blocker.style.display = 'none';
} else {
controls.enabled = false;
blocker.style.display = '-webkit-box';
blocker.style.display = '-moz-box';
blocker.style.display = 'box';
instructions.style.display = '';
}
}
var pointerlockerror = function ( event ) {
instructions.style.display = '';
}
// Hook pointer lock state change events
document.addEventListener( 'pointerlockchange', pointerlockchange, false );
document.addEventListener( 'mozpointerlockchange', pointerlockchange, false );
document.addEventListener( 'webkitpointerlockchange', pointerlockchange, false );
document.addEventListener( 'pointerlockerror', pointerlockerror, false );
document.addEventListener( 'mozpointerlockerror', pointerlockerror, false );
document.addEventListener( 'webkitpointerlockerror', pointerlockerror, false );
instructions.addEventListener( 'click', function ( event ) {
instructions.style.display = 'none';
// Ask the browser to lock the pointer
element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;
if ( /Firefox/i.test( navigator.userAgent ) ) {
var fullscreenchange = function ( event ) {
if ( document.fullscreenElement === element || document.mozFullscreenElement === element || document.mozFullScreenElement === element ) {
document.removeEventListener( 'fullscreenchange', fullscreenchange );
document.removeEventListener( 'mozfullscreenchange', fullscreenchange );
element.requestPointerLock();
}
}
document.addEventListener( 'fullscreenchange', fullscreenchange, false );
document.addEventListener( 'mozfullscreenchange', fullscreenchange, false );
element.requestFullscreen = element.requestFullscreen || element.mozRequestFullscreen || element.mozRequestFullScreen || element.webkitRequestFullscreen;
element.requestFullscreen();
} else {
element.requestPointerLock();
}
}, false );
} else {
instructions.innerHTML = 'Your browser doesn\'t seem to support Pointer Lock API';
}
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xffffff, 0, 750 );
var light = new THREE.DirectionalLight( 0xffffff, 1.5 );
light.position.set( 1, 1, 1 );
scene.add( light );
var light = new THREE.DirectionalLight( 0xffffff, 0.75 );
light.position.set( -1, - 0.5, -1 );
scene.add( light );
controls = new THREE.PointerLockControls( camera );
scene.add( controls.getObject() );
ray = new THREE.Raycaster();
ray.ray.direction.set( 0, -1, 0 );
// floor
geometry = new THREE.PlaneGeometry( 2000, 2000, 100, 100 );
geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
for ( var i = 0, l = geometry.vertices.length; i < l; i ++ ) {
var vertex = geometry.vertices[ i ];
vertex.x += Math.random() * 20 - 10;
vertex.y += Math.random() * 2;
vertex.z += Math.random() * 20 - 10;
}
for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) {
var face = geometry.faces[ i ];
face.vertexColors[ 0 ] = new THREE.Color().setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 1 ] = new THREE.Color().setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 2 ] = new THREE.Color().setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 3 ] = new THREE.Color().setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
}
material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
// objects
loader = new THREE.JSONLoader( );
loadModel = function(geometry)
{
mesh2 = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'textures/metal.jpg', new THREE.SphericalReflectionMapping() ) } ) );
mesh2.scale.set(0.1, 0.1, 0.1);
mesh2.position.set(0, 1, 0);
mesh2.rotation.set(29.85, 3.14, 2);
scene.add( mesh2 );
};
loader.load('blender.js/auto.js', loadModel );
//
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
//
controls.isOnObject( false );
ray.ray.origin.copy( controls.getObject().position );
ray.ray.origin.y -= 10;
var intersections = ray.intersectObjects( objects );
if ( intersections.length > 0 ) {
var distance = intersections[ 0 ].distance;
if ( distance > 0 && distance < 10 ) {
controls.isOnObject( true );
}
}
controls.update( Date.now() - time );
renderer.render( scene, camera );
time = Date.now();
}
</script>
</body>
</html>
The part with //objects is where I load the car I already tried to add some example texture which doesn't work as well. The best would be when I can simply import the textures in blender together with the model.
Tutorial how to export from blender: here
Load object with texture:
var loader = new THREE.JSONLoader();
loader.load( "obj.js", function(geometry, materials) {
var material = new THREE.MeshFaceMaterial(materials);
mesh = new THREE.Mesh(geometry, materials);
scene.add(mesh)
});
Add texture separately:
var loader = new THREE.JSONLoader();
loader.load( "obj.js", function(geometry) {
var texture = THREE.ImageUtils.loadTexture(textureUrl);
var material = new THREE.MeshLambertMaterial({map: texture});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh)
});
I haven't been able to get my blender exported mesh to animate. Not even the included buffalo one that I can clearly see animated in the example. (which I've been trying to reproduce to no avail.
Here's the code, I suspect it's a really simple missing thing, but I have no idea. I doubt it's a blender issue since I haven't even been able to animate the included meshes.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - blender</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
a { color: red }
#stats { position: absolute; top:0; left: 0 }
#stats #fps { background: transparent !important }
#stats #fps #fpsText { color: #aaa !important }
#stats #fps #fpsGraph { display: none }
</style>
</head>
<body>
<div id="info">
025 Valgany
</div>
<script src="/js/three.min.js"></script>
<script src="/js/Detector.js"></script>
<script src="/js/libs/stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var modelBB={"min":new THREE.Vector3(),"max":new THREE.Vector3() };
var crewon, animation;
var container, stats;
var camera, scene, renderer, objects;
var particleLight, pointLight;
var skin;
var clock = new THREE.Clock();
init();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 10000 );
camera.position.set( 2, 4, 5 );
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0x00FF00, 0.035 );
var loader = new THREE.JSONLoader(true);
loader.load("buffalo.js", function(geometry, materials) {
geometry.computeBoundingBox();
var faceMaterial = new THREE.MeshFaceMaterial( materials );
faceMaterial.skinning = true;
THREE.AnimationHandler.add( geometry.animation );
crewon = new THREE.SkinnedMesh(geometry,faceMaterial, false);
modelBB=geometry.boundingBox;
crewon.position.set(0,0,0);
scene.add(crewon);
renderer.render(scene, camera);
animation = new THREE.Animation( crewon, geometry.animation.name );
animation.play( true, 0.5 );
});
// Lights
scene.add( new THREE.AmbientLight( 0xcccccc ) );
pointLight = new THREE.PointLight( 0xffffff, 1, 30 );
pointLight.position.set( 5, 0, 0 );
scene.add( pointLight );
// Renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
// Stats
stats = new Stats();
container.appendChild( stats.domElement );
// Events
window.addEventListener( 'resize', onWindowResize, false );
animate();
}
function onWindowResize( event ) {
renderer.setSize( window.innerWidth, window.innerHeight );
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame( animate, renderer.domElement );
var delta = clock.getDelta();
THREE.AnimationHandler.update( delta );
render();
stats.update();
}
function render() {
if ( crewon ){
crewon.rotation.y+=0.01;
}
if( typeof animation != 'undefined' && animation!=null){
animation.update(0.1);
}
if( typeof modelBB != 'undefined' && modelBB!=null){
camera.position.x = 0;
camera.position.y = (modelBB.max.y-modelBB.min.y)/2;
camera.position.z = (modelBB.max.z-modelBB.min.z)*2;
camera.lookAt( new THREE.Vector3(
0,
(modelBB.max.y-modelBB.min.y)/2,
0) );
}
renderer.render( scene, camera );
}
</script>
</body>
</html>
The problem may be here:
var faceMaterial = new THREE.MeshFaceMaterial( materials );
faceMaterial.skinning = true;
The meshFaceMaterial is just like a container of other materials - it isn't itself a real material. Try iterating over its collection of materials:
var materials = faceMaterial.materials;
for (var i = 0,length = materials.length; i < length; i++) {
var material = materials[i];
material.skinning = true;
}
I'm using the OBJLoader to load a large 3D model (described in a .obj file) but it loads the whole file as a single Object3D object. Using scene.add(object) it adds the whole object to the scene.
I need to pick the selected mesh and change some of its properties, but when I add mouse function and use Ray.intersectObjects try to get the selected mesh it never works. I can not find where I made mistakes.
Would love some help with trying to get this working. Thanks!
It confused me for couples of days. The following is all my codeļ¼
<!doctype html>
<html lang="en">
<head>
<title>three.js webgl - loaders - OBJ loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
</style>
</head>
<body>
<div id="info">
three.js - OBJLoader test
</div>
<script src="../build/Three.js"></script>
<script src="js/loaders/OBJLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="js/Stats.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var _mouse = { x: 0, y: 0 },
objects = [],
_projector = new THREE.Projector();
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 100;
scene.add( camera );
var ambient = new THREE.AmbientLight( 0x101030 );
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0, 1 ).normalize();
scene.add( directionalLight );
var texture = THREE.ImageUtils.loadTexture( 'textures/ash_uvgrid01.jpg' );
var loader = new THREE.OBJLoader();
loader.load( "obj/male02/male02.obj", function ( object ) {
for ( var i = 0, l = object.children.length; i < l; i ++ ) {
object.children[ i ].material.map = texture;
}
object.position.y = - 80;
object.position.z = - 160;
scene.add( object );
objects.push( object );
} );
// RENDERER
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
// find intersections
_mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
_mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
var vector = new THREE.Vector3( _mouse.x, _mouse.y, 1 );
var ray = _projector.pickingRay( vector, camera );
var intersects = ray.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
alert("selected!");
_SELECTED_DOWN = true;
}
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
</html>
ray.intersectObjects() is not recursive. You need to pass a list of the objects you want to test.