Three.js how to delete controls and zoom in - javascript

How can I solve the following issues?
1- I would like to delete controls panel on top right (behind stoke but still there). This is the page https://lovespeechgalaxy.xyz/love-galaxy/insert/navigate.php
2- I would like to zoom-in (maybe moving the camera?) a little bit and then increase the words that you are looking as a background on this page https://lovespeechgalaxy.xyz/love-galaxy/insert/navigate.php
How can achieve this and which parameter on my code should I change?
My code
import * as THREE from '../../build/three.module.js';
import Stats from '../../jsm/libs/stats.module.js';
import { GUI } from '../../jsm/libs/dat.gui.module.js';
let camera, scene, renderer, stats, material, material2, material3, material4, material5, material6, material7;
let mouseX = 0, mouseY = 0;
let windowHalfX = window.innerWidth / 2;
let windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 2, 2000 );
camera.position.z = 1000;
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0x0000020, 0.001 );
const geometry = new THREE.BufferGeometry();
const geometry2 = new THREE.BufferGeometry();
const geometry3 = new THREE.BufferGeometry();
const geometry4 = new THREE.BufferGeometry();
const geometry5 = new THREE.BufferGeometry();
const geometry6 = new THREE.BufferGeometry();
const geometry7 = new THREE.BufferGeometry();
const vertices = [];
const vertices2 = [];
const vertices3 = [];
const vertices4 = [];
const vertices5 = [];
const vertices6 = [];
const vertices7 = [];
const sprite = new THREE.TextureLoader().load( '../../words/hate-words/fuckyou.png' );
const sprite2 = new THREE.TextureLoader().load( '../../words/hate-words/bastard.png' );
const sprite3 = new THREE.TextureLoader().load( '../../words/hate-words/idiot.png' );
const sprite4 = new THREE.TextureLoader().load( '../../words/hate-words/bitch.png' );
const sprite5 = new THREE.TextureLoader().load( '../../words/hate-words/nigger.png' );
const sprite6 = new THREE.TextureLoader().load( '../../words/hate-words/faggot.png' );
const sprite7= new THREE.TextureLoader().load( '../../words/hate-words/handicapped.png' );
for ( let i = 0; i < 10000; i ++ ) {
const x = 4000 * Math.random() - 1000;
const y = 2000 * Math.random() - 1000;
const z = 2000 * Math.random() - 1000;
vertices.push( x, y, z );
}
for ( let i = 0; i < 10000; i ++ ) {
const x = 4000 * Math.random() - 1000;
const y = 2000 * Math.random() - 1000;
const z = 2000 * Math.random() - 1000;
vertices2.push( x, y, z );
}
for ( let i = 0; i < 10000; i ++ ) {
const x = 4000 * Math.random() - 1000;
const y = 2000 * Math.random() - 1000;
const z = 2000 * Math.random() - 1000;
vertices3.push( x, y, z );
}
for ( let i = 0; i < 10000; i ++ ) {
const x = 4000 * Math.random() - 1000;
const y = 2000 * Math.random() - 1000;
const z = 2000 * Math.random() - 1000;
vertices4.push( x, y, z );
}
for ( let i = 0; i < 10000; i ++ ) {
const x = 4000 * Math.random() - 1000;
const y = 2000 * Math.random() - 1000;
const z = 2000 * Math.random() - 1000;
vertices5.push( x, y, z );
}
for ( let i = 0; i < 10000; i ++ ) {
const x = 4000 * Math.random() - 1000;
const y = 2000 * Math.random() - 1000;
const z = 2000 * Math.random() - 1000;
vertices6.push( x, y, z );
}
for ( let i = 0; i < 10000; i ++ ) {
const x = 4000 * Math.random() - 1000;
const y = 2000 * Math.random() - 1000;
const z = 2000 * Math.random() - 1000;
vertices7.push( x, y, z );
}
geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
geometry2.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices2, 3 ) );
geometry3.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices3, 3 ) );
geometry4.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices4, 3 ) );
geometry5.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices5, 3 ) );
geometry6.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices6, 3 ) );
geometry7.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices7, 3 ) );
material = new THREE.PointsMaterial( { size: 35, sizeAttenuation: true, map: sprite, alphaTest: 0.5, transparent: true } );
material2 = new THREE.PointsMaterial( { size: 35, sizeAttenuation: true, map: sprite2, alphaTest: 0.5, transparent: true } );
material3 = new THREE.PointsMaterial( { size: 35, sizeAttenuation: true, map: sprite3, alphaTest: 0.5, transparent: true } );
material4 = new THREE.PointsMaterial( { size: 35, sizeAttenuation: true, map: sprite4, alphaTest: 0.5, transparent: true } );
material5 = new THREE.PointsMaterial( { size: 35, sizeAttenuation: true, map: sprite5, alphaTest: 0.5, transparent: true } );
material6 = new THREE.PointsMaterial( { size: 35, sizeAttenuation: true, map: sprite6, alphaTest: 0.5, transparent: true } );
material7 = new THREE.PointsMaterial( { size: 35, sizeAttenuation: true, map: sprite7, alphaTest: 0.5, transparent: true } );
const particles = new THREE.Points( geometry, material );
scene.add( particles );
const particles2 = new THREE.Points( geometry2, material2 );
scene.add( particles2 );
const particles3 = new THREE.Points( geometry3, material3 );
scene.add( particles3 );
const particles4 = new THREE.Points( geometry4, material4 );
scene.add( particles4 );
const particles5 = new THREE.Points( geometry5, material5 );
scene.add( particles5 );
const particles6 = new THREE.Points( geometry6, material6 );
scene.add( particles6 );
const particles7 = new THREE.Points( geometry7, material7 );
scene.add( particles7 );
//
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.setClearColor( 0x000000);
//
//
const gui = new GUI();
gui.add( material, 'sizeAttenuation' ).onChange( function (){
material.needsUpdate = true;
} );
gui.close();
//
document.body.style.touchAction = 'none';
document.body.addEventListener( 'pointermove', onPointerMove );
//
window.addEventListener( 'resize', onWindowResize );
}
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 onPointerMove( event ) {
if ( event.isPrimary === false ) return;
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
const time = Date.now() * 0.00000000005;
camera.position.x += ( mouseX - camera.position.x ) * 0.05;
camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );
const h = ( 360 * ( 1.0 + time ) % 360 ) / 360;
renderer.render( scene, camera );
}
</script>

Okay so I can offer a partial solution as of now;
I'm not sure what you mean, please be more descriptive.
You camera is currently controlled by the position of the mouse on the page.
function onPointerMove( event ) {
if ( event.isPrimary === false ) return;
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
}
This code here processes the move even and caches the x/y position
When your scene is rendered here
function render() {
// Scene camera position is altered based on cusor position giving 'control' effect
camera.position.x += ( mouseX - camera.position.x ) * 0.05;
camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
..........
renderer.render( scene, camera );
}
If you want add zooming you can do super easily! PerspectiveCamera has built in support for zooming: https://threejs.org/docs/#api/en/cameras/PerspectiveCamera.zoom
Simply listen for mouse wheel changes (on even pinches for mobile) and adjust the camera's zoom on render!
Mousewheel event in modern browsers
Alternatively; You may just scratch all that code and use one of Threejs built-in controls libs like OrbitControls or FlyControls
https://threejs.org/docs/?q=controls#examples/en/controls/FlyControls
https://threejs.org/docs/?q=controls#examples/en/controls/OrbitControls
EDIT:
Replying to comment:
If you want to make the words bigger globally simply change the size attribute in your material
material2 = new THREE.PointsMaterial( { size: 35, sizeAttenuation: true, map: sprite2, alphaTest: 0.5, transparent: true } );
https://threejs.org/docs/?q=points#api/en/materials/PointsMaterial
Threejs has some really good documentation, consider reading through there and familiarizing yourself with what common parameters do!
Additionally if you did add zooming to the camera you will be able to shift through the depth of the words which I think would look nice, but depending on what you're going for its up to you.
If my replies have helped you please consider marking my answer as "accepted" - Good luck!

Related

How to give each point its own color in ThreeJS

I am using ThreeJS to create a point cloud. I would like to givee each point in the cloud a specific color based on its location. How can I assign a specific color to each vertice in the geometry and change the color of the vertice whenever necessary?
geometry = new THREE.Geometry();
for (i = 0; i < particleCount; i++) {
var vertex = new THREE.Vector3();
vertex.x = Math.random() * 2000 - 1000;
vertex.y = Math.random() * 2000 - 1000;
vertex.z = Math.random() * 2000 - 1000;
geometry.vertices.push(vertex);
}
colors = [0xff0000, 0x0000FF, 0x00FF00, 0x000000]
size = 0.5
material = new THREE.PointsMaterial({
size: size,
color: colors[0]
});
particles = new THREE.Points(geometry, material);
scene.add(particles);
Starting with r125, THREE.Geometry is deprecated and no part of the core anymore. It is highly recommended to work with THREE.BufferGeometry.
You can apply a color per vertex by adding an additional buffer attribute holding vertex colors. You also have to set the material property vertexColors to true.
let camera, scene, renderer;
let points;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 5, 3500 );
camera.position.z = 2750;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x050505 );
scene.fog = new THREE.Fog( 0x050505, 2000, 3500 );
//
const particles = 500000;
const geometry = new THREE.BufferGeometry();
const positions = [];
const colors = [];
const color = new THREE.Color();
const n = 1000, n2 = n / 2; // particles spread in the cube
for ( let i = 0; i < particles; i ++ ) {
// positions
const x = Math.random() * n - n2;
const y = Math.random() * n - n2;
const z = Math.random() * n - n2;
positions.push( x, y, z );
// colors
const vx = ( x / n ) + 0.5;
const vy = ( y / n ) + 0.5;
const vz = ( z / n ) + 0.5;
color.setRGB( vx, vy, vz );
colors.push( color.r, color.g, color.b );
}
geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
//
const material = new THREE.PointsMaterial( { size: 15, vertexColors: true } );
points = new THREE.Points( geometry, material );
scene.add( points );
//
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
const time = Date.now() * 0.001;
points.rotation.x = time * 0.25;
points.rotation.y = time * 0.5;
renderer.render( scene, camera );
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/build/three.js"></script>

Runaway raycasting when it should only respond on click

I've created a script to add a new plane to a scene every time I click on an existing plane - the detection uses a raycaster. However, instead of waiting for a click, the script uncontrollably adds more and more planes to the scene with no clicks at all. What have I missed?
Thanks!
var container, renderer, scene, camera;
var container = document.body;
var frustumSize = 1000;
var width, height;
var numRows = 4;
var numCols = 7;
var spacingSize = 300;
var raycaster;
var mouse;
var savedColor;
function init() {
width = window.innerWidth;
height = window.innerHeight;
container = document.createElement( 'div' );
document.body.appendChild( container );
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor(0x000000);
scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
camera = new THREE.OrthographicCamera( frustumSize * aspect / - 2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, 0, 2000 );
// camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 0, 2000 );
camera.updateProjectionMatrix();
// set up grid of colored planes
var startXPos = -((spacingSize*(numCols-1))/2);
var startYPos = -((spacingSize*(numRows-1))/2);
for ( var i = 0; i < numCols; i++ ) {
var x = startXPos + (i*spacingSize);
for ( var j = 0; j < numRows; j++ ) {
var y = startYPos + (j*spacingSize);
var z = -10 + (j * -1.0001);
var geometry = new THREE.PlaneGeometry( 50, 50 );
var material = new THREE.MeshBasicMaterial( {color: new THREE.Color( Math.random(), Math.random(), Math.random() ), side: THREE.DoubleSide} );
var plane = new THREE.Mesh( geometry, material );
plane.position.set( x, y, z );
scene.add(plane);
}
}
savedColor = null;
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
document.addEventListener( 'click', onDocumentClick, false );
var axesHelper = new THREE.AxesHelper( 100 );
scene.add( axesHelper );
container.appendChild( renderer.domElement );
scene.updateMatrixWorld();
render();
}
function render() {
// update the picking ray with the camera and mouse position
raycaster.setFromCamera( mouse, camera );
// calculate objects intersecting the picking ray
var intersects = raycaster.intersectObjects( scene.children );
// calculate objects intersecting the picking ray
if ( intersects.length > 0 ) {
// console.log("yo!");
for ( var i = 0; i < intersects.length; i++ ) {
var geometry = new THREE.PlaneGeometry( 60, 60 );
var material = new THREE.MeshBasicMaterial( {color: new THREE.Color( 0xffff00 ), side: THREE.DoubleSide} );
var plane = new THREE.Mesh( geometry, material );
plane.position.set( getRandomBetween(-300,300), getRandomBetween(-300,300), -20 );
scene.add(plane);
// console.log("hey!");
scene.updateMatrixWorld();
}
}
renderer.render( scene, camera );
requestAnimationFrame( render );
}
function getRandomBetween( min, max ) {
return Math.random() * (max - min) + min;
}
function onDocumentClick( event ) {
event.preventDefault();
// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components
// console.log("Oi!");
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/106/three.js"></script>
It's because the initial position of mouse is (0, 0), which intersects with the AxesHelper.
change the inital position of mouse or remove AxesHelper or change the intersecting target to a specific group should resolve this.

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

Categories

Resources