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