1

I am working on the cube example from three.js (webgl_interactive_cubes_gpu.html). I realized that events goes to the entire html page. I mean i can rotate, zoom in or zoom out, even if the mouse pointer is not inside the scene..

I google a little bit and found some answers (Allow mouse control of three.js scene only when mouse is over canvas) but they do not work for me..Below is my code...

        var container, stats;
        var camera, controls, scene, renderer;
        var pickingData = [], pickingTexture, pickingScene;
        var objects = [];
        var highlightBox;

        var mouse = new THREE.Vector2();
        var offset = new THREE.Vector3( 10, 10, 10 );

        init();
        animate();

        function init() {

            container = document.getElementById( "container" );

            camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000 );
            camera.position.z = 1000;
            //camera.translateZ( -500 );

            controls = new THREE.TrackballControls(camera);
            controls.rotateSpeed = 1.0;
            controls.zoomSpeed = 4;
            controls.panSpeed = 0.8;
            controls.noZoom = false;
            controls.noPan = false;
            controls.staticMoving = true;
            controls.dynamicDampingFactor = 0.3;


            scene = new THREE.Scene();

            pickingScene = new THREE.Scene();
            pickingTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight );
            pickingTexture.minFilter = THREE.LinearFilter;
            pickingTexture.generateMipmaps = false;

            scene.add( new THREE.AmbientLight( 0x555555 ));

            var light = new THREE.SpotLight( 0xffffff, 1.5 );
            light.position.set( 0, 500, 2000 );
            scene.add( light );

            var geometry = new THREE.Geometry(),
            pickingGeometry = new THREE.Geometry(),
            pickingMaterial = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ),
            defaultMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading,      vertexColors: THREE.VertexColors} );

            function applyVertexColors( g, c ) {

                g.faces.forEach( function( f ) {

                    var n = ( f instanceof THREE.Face3 ) ? 3 : 4;

                    for( var j = 0; j < n; j ++ ) {

                        f.vertexColors[ j ] = c;

                    }

                } );

            }

            var geom = new THREE.BoxGeometry(0.005, 0.005, 0.005 );
            var color = new THREE.Color();

            var matrix = new THREE.Matrix4();
            var quaternion = new THREE.Quaternion();

            var coord="219_163_189;130_173_179;161_113_231;
            var splitCoord=coord.split(";");

            var coordColr="0_255_255;255_255_0;0_0_255;0_255_0;255_255_0;
            var splitCoordColor=coordColr.split(";");

            for ( var i = 0; i < splitCoord.length; i++ ) {

                var position = new THREE.Vector3();
                var xyz=splitCoord[i].split("_");
                var col=splitCoordColor[i].split("_");

                position.x = xyz[0];
                position.y = xyz[1];
                position.z = xyz[2];

                var rotation = new THREE.Euler();
                rotation.x = 0
                rotation.y = 0;
                rotation.z = 0;

                var scale = new THREE.Vector3();
                scale.x = 200 + 100;
                scale.y = 200 + 100;
                scale.z = 200 + 100;

                quaternion.setFromEuler(rotation, false );
                matrix.compose( position, quaternion, scale);

                col[0]=col[0]/255;
                col[1]=col[1]/255;                  
                col[2]=col[2]/255;

                applyVertexColors(geom, color.setRGB(col[0], col[1], col[2]));
                geometry.merge(geom, matrix);

                // give the geom's vertices a color corresponding to the "id"
                applyVertexColors( geom, color.setHex( i ) );

                pickingGeometry.merge( geom, matrix );

                pickingData[ i ] = {

                    position: position,
                    rotation: rotation,
                    scale: scale

                };

            }

            var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
            scene.add(drawnObject);

            pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) );

            highlightBox = new THREE.Mesh(
                new THREE.BoxGeometry( 0.01, 0.01, 0.01 ),
                new THREE.MeshLambertMaterial( { color: 0xffff00 }
            ) );
            scene.add( highlightBox );

            renderer = new THREE.WebGLRenderer( );
            //renderer.setClearColor( 0xffffff );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize(800, 800);
            renderer.sortObjects = false;
            container.appendChild(renderer.domElement);

            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            container.appendChild( stats.domElement );

            //renderer.domElement.addEventListener('mousemove', onMouseMove );

        }


        function onMouseMove( e ) {
            mouse.x = e.clientX;
            mouse.y = e.clientY;
        }

        function animate() {

            requestAnimationFrame( animate );
            render();
            stats.update();
        }

        function pick() {


            //render the picking scene off-screen
            renderer.render( pickingScene, camera, pickingTexture );

            //create buffer for reading single pixel
            var pixelBuffer = new Uint8Array( 4 );

            //read the pixel under the mouse from the texture
            renderer.readRenderTargetPixels(pickingTexture, mouse.x, pickingTexture.height - mouse.y, 1, 1, pixelBuffer);

            //interpret the pixel as an ID

            var id = ( pixelBuffer[0] << 16 ) | ( pixelBuffer[1] << 8 ) | ( pixelBuffer[2] );
            var data = pickingData[ id ];

            if (data) {

                //move our highlightBox so that it surrounds the picked object
                if ( data.position && data.rotation && data.scale ){

                    highlightBox.position.copy( data.position );
                    highlightBox.rotation.copy( data.rotation );
                    highlightBox.scale.copy( data.scale ).add( offset );
                    highlightBox.visible = true;
                }

            } else {

                highlightBox.visible = false;
            }

        }

        function render() {

            controls.update();
            pick();
            renderer.render( scene, camera );

        }

any help is greatly appreciated.. Thanks

Community
  • 1
  • 1
user1275607
  • 99
  • 1
  • 10

1 Answers1

2

You can pass in the canvas as an argument to the TrackballsControls constructor.

var controls = new THREE.TrackballControls(camera, renderer.domElement);

That should solve the problem.

EDIT: included a working example,

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, 400 / 300, 1, 1000);

var renderer = new THREE.WebGLRenderer();
renderer.setSize(400, 300);
document.body.appendChild(renderer.domElement);

var controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 4;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;


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

camera.position.z = 5;

var render = function() {
  requestAnimationFrame(render);
  controls.update();
  cube.rotation.x += 0.1;
  cube.rotation.y += 0.1;

  renderer.render(scene, camera);
};

render();

could not get your code to run at all so..

WestLangley
  • 102,557
  • 10
  • 276
  • 276
micnil
  • 4,705
  • 2
  • 28
  • 39
  • micnil Thanks for your reply..I already tried it but didn't work for me. It just do not allow any movement thereafter (no zoom, no drag). – user1275607 Apr 11 '15 at 15:00
  • @user1275607, updates with a working example. tried to get dependecies to be hidden, but could not figure it out... the code snippet above is the relevant one anyways. Thats the best i can do, if ou cant figure it out from that then i dont know, sorry! – micnil Apr 11 '15 at 15:45