onLoad event in Three.js - javascript

I am making my first steps in JavaScript and playing with Three.js too. I am trying to make an event to activate a Tween each time that I reload my site.
I have a week trying to make it but I didn't get it. I already watched some tutorials but it still doesn't working. This is the code I made:
document.addEventListener( 'load', onDocumentLoad, false );
function onDocumentLoad( event ) {
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( scene.children );
new TWEEN.Tween( intersects[ 0 ].object.position ).to( {
x: 0,
y: 0,
z: 1500 }, 50000 )
.easing( TWEEN.Easing.Sinusoidal.In).start();
new TWEEN.Tween( intersects[ 0 ].object.rotation ).to( {
x: Math.random() * 2 * Math.PI,
y: Math.random() * 2 * Math.PI,
z: Math.random() * 2 * Math.PI }, 30000 )
.easing( TWEEN.Easing.Sinusoidal.In).start();
//setTimeout('window.open(\'http://www.lemonde.fr/\',"_self")', 38000);
}
I knwow that maybe it is a stupid question but I am learning for my own. So please help me if you can, this is an important project for me.
and this is the complete code if it can helps:
<script>
var container;
var camera, scene, renderer;
var raycaster;
var mouse;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.target = new THREE.Vector3( 0, 50, 0 );
camera.position.y = 300;
camera.position.z = 500;
scene = new THREE.Scene();
//environment map
//JavaScript does not know the number of images on your server side. You need to count and pass a number of the last image from server with PHP in example.
var numberOfImages = 46, images = [];
for (var i = 1; i <= numberOfImages; i++) {
images.push('sources/instagram2/image' + i + ".jpg");
}
var urls = images.sort(function(){return .6 - Math.random()}).slice(0,6);
var reflectionSphere = THREE.ImageUtils.loadTextureCube( urls, THREE.SphereReflectionMapping );
//loading the model
var loader = new THREE.BinaryLoader();
loader.load( "sources/obj/mmlogo/mm_logo.js", function ( geometry ) {
var material = new THREE.MeshPhongMaterial( {
color: 0x515151,
morphTargets: true,
overdraw: 0.5,
envMap: reflectionSphere,
combine: THREE.AddOperation,
reflectivity: 1,
shininess: 0,
side: THREE.DoubleSide,
} );
//assign a mesh to the geometry
mesh = new THREE.Mesh( geometry, material );
mesh.scale.set( 120, 120, 120 );
mesh.position.y = 50;
scene.add( mesh );
mixer = new THREE.AnimationMixer( mesh );
var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'gallop', geometry.morphTargets, 30 );
mixer.addAction( new THREE.AnimationAction( clip ).warpToDuration( 1 ) );
} );
//
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setClearColor(0xfffff, 0);
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild(renderer.domElement);
document.addEventListener( 'load', onDocumentLoad, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentTouchStart( event ) {
event.preventDefault();
event.clientX = event.touches[0].clientX;
event.clientY = event.touches[0].clientY;
onDocumentMouseDown( event );
}
function onDocumentLoad( event ) {
event.preventDefault();
mouse.x = ( event.clientX / renderer.domElement.width ) * 2 - 1;
mouse.y = - ( event.clientY / renderer.domElement.height ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( scene.children );
new TWEEN.Tween( intersects[ 0 ].object.position ).to( {
x: 0,
y: 0,
z: 1500 }, 50000 )
.easing( TWEEN.Easing.Sinusoidal.In).start();
new TWEEN.Tween( intersects[ 0 ].object.rotation ).to( {
x: Math.random() * 2 * Math.PI,
y: Math.random() * 2 * Math.PI,
z: Math.random() * 2 * Math.PI }, 30000 )
.easing( TWEEN.Easing.Sinusoidal.In).start();
//setTimeout('window.open(\'http://www.lemonde.fr/\',"_self")', 38000);
}
function animate() {
requestAnimationFrame( animate );
render();
}
var radius = 600;
var theta = 0;
function render() {
TWEEN.update();
theta += 0;
camera.position.x = radius * Math.sin( THREE.Math.degToRad( theta ) );
camera.position.y = radius * Math.sin( THREE.Math.degToRad( theta ) );
camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) );
camera.lookAt( camera.target );
renderer.render( scene, camera );
}
</script>

Related

Three js 360 video camera controls api

I am using this demo:
https://threejs.org/examples/?q=video#webgl_video_panorama_equirectangular
with the following code:
let camera, scene, renderer;
let isUserInteracting = false,
lon = 0, lat = 0,
phi = 0, theta = 0,
onPointerDownPointerX = 0,
onPointerDownPointerY = 0,
onPointerDownLon = 0,
onPointerDownLat = 0;
const distance = 50;
init();
animate();
function init() {
const container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1100 );
scene = new THREE.Scene();
const geometry = new THREE.SphereGeometry( 500, 60, 40 );
// invert the geometry on the x-axis so that all of the faces point inward
geometry.scale( - 1, 1, 1 );
const video = document.getElementById( 'video' );
video.play();
const texture = new THREE.VideoTexture( video );
const material = new THREE.MeshBasicMaterial( { map: texture } );
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
document.addEventListener( 'pointerdown', onPointerDown );
document.addEventListener( 'pointermove', onPointerMove );
document.addEventListener( 'pointerup', onPointerUp );
//
window.addEventListener( 'resize', onWindowResize );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onPointerDown( event ) {
isUserInteracting = true;
onPointerDownPointerX = event.clientX;
onPointerDownPointerY = event.clientY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
function onPointerMove( event ) {
if ( isUserInteracting === true ) {
lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
lat = ( onPointerDownPointerY - event.clientY ) * 0.1 + onPointerDownLat;
}
}
function onPointerUp() {
isUserInteracting = false;
}
function animate() {
requestAnimationFrame( animate );
update();
}
function update() {
lat = Math.max( - 85, Math.min( 85, lat ) );
phi = THREE.MathUtils.degToRad( 90 - lat );
theta = THREE.MathUtils.degToRad( lon );
camera.position.x = distance * Math.sin( phi ) * Math.cos( theta );
camera.position.y = distance * Math.cos( phi );
camera.position.z = distance * Math.sin( phi ) * Math.sin( theta );
camera.lookAt( 0, 0, 0 );
renderer.render( scene, camera );
}
Is there an api for the THREE.PerspectiveCamera so you can manually call zoom in / out, move left / right inside the scene ..etc?
Is this possible?
There is indeed an API for the Three.PerspectiveCamera, including a method to call to zoom in/out the camera.
https://threejs.org/docs/#api/en/cameras/PerspectiveCamera.zoom
If you wish to move the camera around the scene, you can update the position of the camera through updating its position attribute. This can be done by either updating each of its three coordinates individually, or using the 'set' method to pass in a Vector3 for its position. Below is the documentation to Object3D, which camera inherits from.
https://threejs.org/docs/#api/en/core/Object3D.position
Be wary though that script is already updating its position during its 'update' function, so you will need to possibly change those lines directly, depending on what you want to do.
Hopefully this helps!

How to position sprites in Three.js?

I'm currently using PointCloud to generate a particle system but within that I would like one single sprite that floats in the position of my indication. When I tried using this three.js example: http://threejs.org/examples/#webgl_sprites I found that the Orthographic Camera limited my ability to still zoom about.
var container, stats;
var camera, scene, renderer, particles, geometry, materials =[], i, h, color, sprite, size;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 2, 2000 );
camera.position.z = 1000;
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0x000000, 0.001 );
geometry = new THREE.Geometry();
sprite = THREE.ImageUtils.loadTexture( "disc.png" );
for ( i = 0; i < 5000; i ++ ) {
var vertex = new THREE.Vector3();
vertex.x = 2000 * Math.random() - 1000;
vertex.y = 2000 * Math.random() - 1000;
vertex.z = 2000 * Math.random() - 1000;
geometry.vertices.push( vertex );
}
// size = Math.random() * 10;
material = new THREE.PointCloudMaterial( { size: 5, sizeAttenuation: false, map: sprite, alphaTest: 0.5, transparent: true } );
particles = new THREE.PointCloud( geometry, material );
scene.add( particles );
var map2 = THREE.ImageUtils.loadTexture( "astronaut.png" );
var material2 = new THREE.SpriteMaterial( { map: map2, color: 0xffffff, fog: true } );
var sprite2 = new THREE.Sprite( material2 );
sprite2.position.x = 0;
sprite2.position.y = 0;
sprite2.position.z = 498;
scene.add( sprite2 );
//
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
//
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
}
function onDocumentTouchStart( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var time = Date.now() * 0.00005;
camera.position.x += ( mouseX - camera.position.x ) * 0.05;
camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );
h = ( 360 * ( 1.0 + time ) % 360 ) / 360;
renderer.render( scene, camera );
}
My attempt at solving it was:
var map2 = THREE.ImageUtils.loadTexture( "astronaut.png" );
var material2 = new THREE.SpriteMaterial( { map: map2, color: 0xffffff, fog: true } );
var sprite2 = new THREE.Sprite( material2 );
sprite2.position.x = 0;
sprite2.position.y = 0;
sprite2.position.z = 498;
scene.add( sprite2 );
Right now the sprite is in the center of the screen when I first load but instantly disappears when I begin to move the camera. Ideally, I would like the astronaut.png sprite to move with the other particles but if this is difficult, having him always fixed to the center of the screen would work fine as well.
Resolved this on my own. I created a second THREE.Geometry and THREE.Vector3 an positioned it with vertices.
geometry2 = new THREE.Geometry();
var vertex2 = new THREE.Vector3(0, 0, -50);
geometry2.vertices.push( vertex2 );
var material2 = new THREE.PointCloudMaterial( { size: 100, sizeAttenuation: false, map: map2, alphaTest: 0.5, transparent: true } );
particles2 = new THREE.PointCloud( geometry2, material2 );
scene.add( particles2 );
It seems to me that your values for mouse position would be way too high for camera positions. OpenGL works on the (-1,1) (1,1) (1,-1) (-1,-1) bounding rectangle as a unit. Pixels for your cursor position are in screen pixels like 350,720 etc.
When you increment by the half distance, your numbers are still too large. So here you have to divide by your width/height:
camera.position.x += ( mouseX / window.innerWidth- camera.position.x ) * 0.05;
camera.position.y += ( - mouseY /window.innerHeight- camera.position.y ) * 0.05;
assuming your GL portal is the same size as the window.

Clickable Three JS Convex Objects (once clicked reveals image)

I adjusted an example from the three js website.
I'm looking for making the small floating objects have a click event.
The click event would trigger an image or video revealed on the larger convex shape in the center
Concept + Images
http://kevinwitkowski.tumblr.com/post/109592122645/workshop-update
Working Sample
Here is my current code.
var container;
var camera, scene, renderer;
var mesh;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
// array of functions for the rendering loop
var onRenderFcts= [];
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0xd6e3e8, 0.0030 );
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.z = 0;
controls = new THREE.OrbitControls(camera)
var light, object, materials;
light = new THREE.DirectionalLight( 0xe8dbd6 );
light.position.set( -50, -80, -10 );
scene.add( light );
light = new THREE.DirectionalLight( 0xd6dae8 );
light.position.set( 20, 120, 1 );
scene.add( light );
light = new THREE.DirectionalLight( 0xd6e8e4 );
light.position.set( 0, 1, 30 );
scene.add( light );
var map = THREE.ImageUtils.loadTexture( 'textures/1.jpeg' );
map.wrapS = map.wrapT =
THREE.RepeatWrapping;
map.anisotropy = 16;
var materials = [
new THREE.MeshLambertMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors } )
//new THREE.MeshBasicMaterial( { color: 0x00000, shading: THREE.FlatShading, wireframe: true, transparent: false, opacity: 0.5} )
];
// random convex 1
points = [];
for ( var i = 0; i < 30; i ++ ) {
points.push( randomPointInSphere( 50 ) );
}
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
object.position.set( 0, 0, 0);
scene.add( object );
// random convex 2
points = [];
for ( var i = 0; i < 30; i ++ ) {
points.push( randomPointInSphere( 15 ) );
}
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
object.position.set( 15, 50, -60 );
scene.add( object );
// random convex 3
points = [];
for ( var i = 0; i < 30; i ++ ) {
points.push( randomPointInSphere( 15 ) );
}
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
object.position.set( 30, 10, 80 );
scene.add( object );
// random convex 4
points = [];
for ( var i = 0; i < 30; i ++ ) {
points.push( randomPointInSphere( 8 ) );
}
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
object.position.set( -80, -50, 20 );
scene.add( object );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( 0xf5f5f5 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize, true );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
}
//
function randomPointInSphere( radius ) {
return new THREE.Vector3(
( Math.random() - 0.5 ) * 1 * radius,
( Math.random() - 0.5 ) * 2 * radius,
( Math.random() - 0.5 ) * 2 * radius
);
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var timer = Date.now() * 0.00005;
camera.position.x = Math.cos( timer ) * 300;
camera.position.z = Math.sin( timer ) * 300;
camera.lookAt( scene.position );
for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
var object = scene.children[ i ];
object.rotation.x = timer * 1;
object.rotation.y = timer * 3;
}
// handle window resize
window.addEventListener('resize', function(){
renderer.setSize( window.innerWidth, window.innerHeight )
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
}, true)
renderer.render( scene, camera );
}
var lastTimeMsec= null
requestAnimationFrame(function animate(nowMsec){
// keep looping
requestAnimationFrame( animate );
// measure time
lastTimeMsec = lastTimeMsec || nowMsec-1000/60
var deltaMsec = Math.min(200, nowMsec - lastTimeMsec)
lastTimeMsec = nowMsec
// call each update function
onRenderFcts.forEach(function(onRenderFct){
onRenderFct(deltaMsec/1000, nowMsec/1000)
})
})
The normal way of doing this is using a THREE.Raycaster and THREE.Projector to cast a ray from the camera through space, then finding if an object intersects with this ray.
See this example: http://soledadpenades.com/articles/three-js-tutorials/object-picking/
Thankfully, others have implemented libraries such as ObjectControls: https://github.com/cabbibo/ObjectControls
This allows you to directly attach hover or select events to meshes and it will just work.
CreateMultiMaterialObject method creates an object3D, so when you click, it is necessary to specify the second parameter (recursion) = true:
var intersects = raycaster.intersectObjects( objects, true );
if ( intersects.length > 0 ) {
intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );
}

Vertex and Vector3 are not interchangeable in three.js

Starting on three.js revision 48 I made vertices connected by lines. It works fine but when updating to revision 65 from 48 I get an error message saying that Vertix is deprecated and should be replaced by Vector3. However, when I replace it with Vector3, Vector2 or Vector4 it behaves differently – the lines won't connect to the vertices anymore. I also get some strange rendering problems on the edges when the canvas is the width of the viewport.
var container = document.getElementById('container');
var camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,1,10000);
var distance = 1000;
camera.position.z = distance;
var scene = new THREE.Scene();
scene.add(camera);
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
camera.lookAt(new THREE.Vector3(0,0,0));
var geometry = new THREE.Geometry();
for ( var i = 0; i < 50; i ++ ) {
particle = new THREE.Particle( new THREE.ParticleCanvasMaterial( {
color: Math.random() * 0x808080 + 0x808080, //0x0000000,
opacity: 1,//0.1,
program: function ( context ) {
context.beginPath();
context.arc( 0, 0, 1, 0, Math.PI * 2, true );
context.closePath();
context.fill();
}
} ) );
particle.position.x = Math.random() * 2000 - 1000;
particle.position.y = Math.random() * 2000 - 1000;
particle.position.z = Math.random() * 2000 - 1000;
particle.scale.x = particle.scale.y = Math.random() * 12 + 5;
scene.add( particle );
geometry.vertices.push( new THREE.Vertex( particle.position ) );
}
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.05 } ) );
scene.add( line );
renderer.render( scene, camera );
document.addEventListener( 'mousemove', onMouseMove, false );
function onMouseMove(event){
mouseX = (event.clientX - window.innerWidth/2) / window.innerWidth/2;
mouseY = (event.clientY - window.innerHeight/2) / window.innerHeight/2;
camera.position.x = Math.sin(mouseX * Math.PI) * distance;
camera.position.y = - Math.sin(mouseY * Math.PI) * distance;
camera.lookAt(new THREE.Vector3(0,0,0));
renderer.render( scene, camera );
}
Try replacing the Vertex at line 42 with Vector3: http://jsfiddle.net/kz94z/
Try changing this line:
geometry.vertices.push( new THREE.Vertex( particle.position ) );
to this:
geometry.vertices.push( particle.position );

How can I make my text labels face the camera at all times? Perhaps using sprites?

I'm looking at two examples, one is canvas interactive objects and the other is mouse tooltip. I tried combining the two to generate text labels on each individual cube and here's what I have so far.
However, the text moves with the rotating cubes and the text appears backwards or sideways at times.
How can I make the text fixed in a sprite like in the mouse tooltip (http://stemkoski.github.io/Three.js/Mouse-Tooltip.html) example? I tried to incorporate the sprite but I kept getting errors. I'm not sure how to do it. Could you explain how I can go by it?
Thanks.
Here's my code so far:
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - interactive - cubes</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: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script src="js/stats.min.js"></script>
<script>
var container, stats;
var camera, scene, projector, renderer;
var projector, mouse = { x: 0, y: 0 }, INTERSECTED;
var particleMaterial;
var currentLabel = null;
var objects = [];
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = 'three.js - clickable objects';
container.appendChild( info );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 300, 500 );
scene = new THREE.Scene();
var geometry = new THREE.CubeGeometry( 100, 100, 100 );
for ( var i = 0; i < 10; i ++ ) {
var object = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) );
object.position.x = Math.random() * 800 - 400;
object.position.y = Math.random() * 800 - 400;
object.position.z = Math.random() * 800 - 400;
object.scale.x = Math.random() * 2 + 1;
object.scale.y = Math.random() * 2 + 1;
object.scale.z = Math.random() * 2 + 1;
object.rotation.x = Math.random() * 2 * Math.PI;
object.rotation.y = Math.random() * 2 * Math.PI;
object.rotation.z = Math.random() * 2 * Math.PI;
object.label = "Object " + i;
scene.add( object );
objects.push( object );
}
var PI2 = Math.PI * 2;
particleMaterial = new THREE.ParticleCanvasMaterial( {
color: 0x000000,
program: function ( context ) {
context.beginPath();
context.arc( 0, 0, 1, 0, PI2, true );
context.closePath();
context.fill();
}
} );
projector = new THREE.Projector();
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
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 raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
var intersects = raycaster.intersectObjects( objects );
if ( intersects.length > 0 ) {
if ( intersects[ 0 ].object != INTERSECTED )
{
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED ) {
INTERSECTED.material.color.setHex( INTERSECTED.currentHex ); }
// store reference to closest object as current intersection object
INTERSECTED = intersects[ 0 ].object;
// store color of closest object (for later restoration)
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
// set a new color for closest object
INTERSECTED.material.color.setHex( 0xffff00 );
var canvas1 = document.createElement('canvas');
var context1 = canvas1.getContext('2d');
context1.font = "Bold 40px Arial";
context1.fillStyle = "rgba(255,0,0,0.95)";
context1.fillText(INTERSECTED.label, 0, 50);
// canvas contents will be used for a texture
var texture1 = new THREE.Texture(canvas1)
texture1.needsUpdate = true;
var material1 = new THREE.MeshBasicMaterial( {map: texture1, side:THREE.DoubleSide } );
material1.transparent = true;
var mesh1 = new THREE.Mesh(
new THREE.PlaneGeometry(canvas1.width, canvas1.height),
material1
);
mesh1.position = intersects[0].point;
if (currentLabel)
scene.remove(currentLabel);
scene.add( mesh1 );
currentLabel = mesh1;
}
else // there are no intersections
{
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED ) {
console.log("hello");
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
}
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
mesh1 = null;
mesh1.position = intersects[0].point;
scene.add( mesh1 );
}
//var particle = new THREE.Particle( particleMaterial );
//particle.position = intersects[ 0 ].point;
//particle.scale.x = particle.scale.y = 8;
//scene.add( particle );
}
/*
// Parse all the faces
for ( var i in intersects ) {
intersects[ i ].face.material[ 0 ].color.setHex( Math.random() * 0xffffff | 0x80000000 );
}
*/
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
var radius = 600;
var theta = 0;
function render() {
theta += 0.1;
camera.position.x = radius * Math.sin( THREE.Math.degToRad( theta ) );
camera.position.y = radius * Math.sin( THREE.Math.degToRad( theta ) );
camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) );
camera.lookAt( scene.position );
renderer.render( scene, camera );
}
</script>
</body>
Billboarding is easy. All you have to do, in your case, is add this inside your render loop:
if ( currentLabel ) currentLabel.lookAt( camera.position );

Categories

Resources