Question

I'm trying to set up a website that runs in a single WebGL element. I'm trying to get it to tell when the mouse is over an object. I'm using a couple of planes with a with transparent textures on them as links, but it won't pick up on any intersections at all. It does absolutely nothing. I've even added a cube and used the same code as the interactive cubes example (http://mrdoob.github.com/three.js/examples/webgl_interactive_cubes.html) and it does absolutely nothing. No changing the color, absolutely nothing. I've gone through and tried about 8 different examples online having to do with this and not a single one has worked for me.

Here is my code:

    <meta charset="utf-8">

    <style type="text/css">
        body {
            margin: 0px;
            overflow: hidden;
            background: #000000;
        }
        div {
            margin: 0px;
        }
    </style>

    </head>
    <div>
        <script src="http://www.html5canvastutorials.com/libraries/Three.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
        <script type="text/javascript">

            //Variable Declarations
            var camera, scene, renderer, aspect, projector;
            var INTERSECTED;
            var mouseX = 0, mouseY = 0;

            init();

            //Method Declarations
            function init() {
                aspect = window.innerWidth / window.innerHeight;
                //aspect = 1.25;
                //Sets the camera variable to a new Perspective Camera with a field of view of 45 degrees, an aspect ratio
                //of the window width divided by the window height, the near culling distance of 1 and the far culling distance of 2000
                camera = new THREE.PerspectiveCamera(45, aspect, 1, 2000);

                //Sets the height of the camera to 400
                camera.position.z = 700;

                //Sets a variable "lookat" to a new 3d vector with a position of 0, 0, 0, 
                //or the center of the scene/center of the menu plane
                var lookat = new THREE.Vector3(0, 0, 0);

                //Uses a function built in to every camera object to make it look at a given coordinate
                camera.lookAt(lookat);

                //Makes a new scene object to add everything to
                scene = new THREE.Scene();

                //Adds the camera object to the scene
                scene.add(camera);

                //Sets the renderer varialbe to a new WebGL renderer object
                //Change "WebGLRenderer" to "CanvasRenderer" to use canvas renderer instead
                renderer = new THREE.WebGLRenderer({antialias:true});
                //renderer.sortObjects = false;

                //Sets the size of the renderer object to the size of the browser's window
                //renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.setSize(window.innerWidth, window.innerHeight);

                //Adds an event listener to the webpage that "listens" for mouse movements and when the mouse does move, it runs the 
                //"onMouseMove" function
                document.addEventListener('mousemove', onMouseMove, false);

                //Force canvas to stay proportional to window size
                window.addEventListener('resize', onWindowResize, false);

                document.addEventListener('mousedown', onDocumentMouseDown, false);

                //Sets the update frequency of the webpage in milliseconds
                setInterval(update, 1000/60);


                //Makes a variable "texture" and sets it to the returned value of the method "loadTexture" 
                //supplied by the THREE.js library
                var texture = THREE.ImageUtils.loadTexture('imgs/backgrounds.png');

                //Makes a variable "geometry" and sets it to a "PlaneGeometry" object with a width of 645 and a height of 300
                var geometry = new THREE.PlaneGeometry(645, 300);

                //Makes a variable "material" and sets it to a "MeshBasicMaterial" object with it's map set to
                //the "texture" object, it also makes it transparent
                var material = new THREE.MeshBasicMaterial({map: texture, transparent: true});

                //Makes a variable "plane" and sets it to a "Mesh" object with its geometry set to the "geometry" object
                //and it's material set to the "material" object
                var plane = new THREE.Mesh(geometry, material);


                //Background Texture
                var backgroundTexture = THREE.ImageUtils.loadTexture('imgs/gears.png');
                var backgroundGeo = new THREE.PlaneGeometry(3500, 2500);
                var backgroundMat = new THREE.MeshBasicMaterial({map: backgroundTexture});
                var backgroundPlane = new THREE.Mesh(backgroundGeo, backgroundMat);
                backgroundPlane.position.z = -1000;
                backgroundPlane.overdraw = true;


                //Home Button
                //Makes a "homeTexture" variable and sets it to the returned value of the makeTextTexture function when 
                //the text passed in is set to "Home", the width is set to 300, height of 150, font set to 80pt Arial, 
                //fillStyle set to white, textAlign set to center, textBaseLine set to middle, and the color of the 
                //background set to red = 0, green = 0, blue = 0 and alpha = 0
                var homeTexture = makeTextTexture("Home", 300, 150, '80pt Arial', 'white', "center", "middle", "rgba(0,0,0,0)");
                var homeGeom = new THREE.PlaneGeometry(50, 25);
                var homeMaterial = new THREE.MeshBasicMaterial({map: homeTexture, transparent: true});
                var homeTest = new THREE.Mesh(homeGeom, homeMaterial);
                homeTest.position.x -= 270;
                homeTest.position.y += 120;
                homeTest.position.z = 40;
                homeTest.castShadow = true;

                //Gallery Button
                var galleryTexture = makeTextTexture("Gallery", 340, 150, '80pt Arial', 'white', "center", "middle", "rgba(0,0,0,0)");
                var galleryGeom = new THREE.PlaneGeometry(50, 25);
                var galleryMaterial = new THREE.MeshBasicMaterial({map: galleryTexture, transparent: true});
                var galleryTest = new THREE.Mesh(galleryGeom, galleryMaterial);
                galleryTest.position.x -= 270; 
                galleryTest.position.y += 90;
                galleryTest.position.z = 40;
                galleryTest.castShadow = true;


                //The Team Button
                var theTeamTexture = makeTextTexture("Company", 510, 150, '80pt Arial', 'white', "center", "middle", "rgba(0,0,0,0)");
                var theTeamGeom = new THREE.PlaneGeometry(80, 25);
                var theTeamMaterial = new THREE.MeshBasicMaterial({map: theTeamTexture, transparent: true});
                var theTeamTest = new THREE.Mesh(theTeamGeom, theTeamMaterial);
                theTeamTest.position.x -= 260; 
                theTeamTest.position.y += 60;
                theTeamTest.position.z = 40;
                theTeamTest.castShadow = true;

                projector = new THREE.Projector();

                var cubeGeom = new THREE.CubeGeometry(20, 20, 20);
                var cubeMat = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
                var cubeMesh = new THREE.Mesh(cubeGeom, cubeMat);
                cubeMesh.position.z = 15;

                //scene.add(cubeMesh);

                //Adds all of the previously created objects to the scene
                scene.add(plane);
                scene.add(backgroundPlane);
                scene.add(homeTest);
                scene.add(theTeamTest);
                scene.add(galleryTest);

                //Adds the renderer to the webpage
                document.body.appendChild(renderer.domElement);
            }

            function update() {
                camera.position.x = (mouseX - (window.innerWidth / 2)) * 0.1;

                camera.position.y = -((mouseY - (window.innerHeight / 2)) * 0.15);
                camera.lookAt(new THREE.Vector3(0, 0, 0));

                render();
            }

            function render() {
                renderer.render(scene, camera);
            }

            function onMouseMove(event) {
                mouseX = event.clientX;
                mouseY = event.clientY;
            }

            function onDocumentMouseDown(event) {
                event.preventDefault();

                var vector = new THREE.Vector3(
                    ( event.clientX / window.innerWidth ) * 2 - 1,
                  - ( event.clientY / window.innerHeight ) * 2 + 1,
                    0.5
                );
                projector.unprojectVector( vector, camera );

                var ray = new THREE.Ray( camera.position, 
                                         vector.subSelf( camera.position ).normalize() );

                var intersects = ray.intersectObjects( objects );

                if ( intersects.length > 0 ) {

                    intersects[ 0 ].object.materials[ 0 ].color.setHex( Math.random() * 0xffffff );
                }

            }

            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            }

            function makeTextTexture(text, width, height, font, fillStyle, textAlign, textBaseline, backgroundColor)
            {
                //Makes a new canvas element
                var bitmap = document.createElement('canvas');

                //Gets its 2d css element
                var g = bitmap.getContext('2d');

                //Sets it's width and height
                bitmap.width = width;
                bitmap.height = height;

                //Takes "g", it's 2d css context and set's all of the following
                g.font = font;

                g.fillStyle = backgroundColor;
                g.fillRect(0, 0, width, height);

                g.textAlign = "center";
                g.textBaseline = "middle";
                g.fillStyle = fillStyle;
                g.fillText(text, width / 2, height / 2);

                //Rendered the contents of the canvas to a texture and then returns it
                var texture = new THREE.Texture(bitmap);
                texture.needsUpdate = true;

                return texture;
            }


        </script>
    </div>
</html>

Thanks to anyone that can help out. I wish I could figure out what's going on myself, it seems like I'm using StackOverflow to answer my questions way too much.

Was it helpful?

Solution

You have not declared the variable objects. Do this:

var objects = [];

Then populate it:

objects.push( plane );
objects.push( backgroundPlane );

Now, this line will work:

var intersects = ray.intersectObjects( objects );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top