THREE JS Raycaster - javascript

How to select only a specific object by clicking the mouse in THREE JS
Now the function is executed by clicking on any point, although the condition states the name mesh
var cubeGeometry = new THREE.BoxGeometry(100, 100, 100);
var cubeMaterial = new THREE.MeshLambertMaterial({color: 0x9370DB});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.y = 50;
cube.name = "cube";
scene.add(cube);
const sizeBox = 30;
const geo = new THREE.BoxGeometry(sizeBox, sizeBox, sizeBox);
const mat = new THREE.MeshPhongMaterial({
side: THREE.DoubleSide,
});
const earth = new THREE.Mesh(geo, mat);
earth.position.set(-300, sizeBox/2, 10);
scene.add(earth);
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onMouseClick( event ) {
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
const intersects = raycaster.intersectObjects( scene.children );
console.log(intersects);
for ( var i = 0; i < intersects.length; i++ ) {
console.log(intersects[ i ].name)
if(intersects[ i ].name = 'cube') {
gsap.to(camera.position, {z: 100, duration: 10})
}
}
}
window.addEventListener( 'click', onMouseClick, false );

if (intersects[ i ].name = 'cube') {
gsap.to(camera.position, {z: 100, duration: 10})
}
You're not testing anything in that "if" statement. It should be "===" instead of "=".

Related

Three.js how to delete controls and zoom in

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!

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.

Three js clickable Img in Scene

i have a 360 degree scene where i place some imgs (sprits) on. I'd like to make this imgs clickable, so that I receive a function if i click on it.
My Code:
var map = new THREE.TextureLoader().load( "arrow-poi.png" );
var material = new THREE.SpriteMaterial( { map: map, color: 0xffffff, fog: true } );
var sprite = new THREE.Sprite( material );
var geometry = new THREE.PlaneGeometry(6,6);
sprite.material.side = THREE.DoubleSide,
sprite.position.x= 40,
sprite.position.y= -6,
sprite.position.z= 10,
sprite.scale.set(6,6,1),
sprite.name="arrow",
sprite.directto=r,
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector3( 0, 1, 0 );
projector = new THREE.Projector();
clickableObjects = [];
clickableObjects.push(sprite, sprite1);
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( clickableObjects );
if ( intersects.length > 0) {
intersects[0].object.onClick();
}
}
sprite1.onClick = function(){console.log('Clicked');}
I've been looking for something like that, and after some research, I found that the last THREE.js version has new features in the Raycasting. So i'm using this function for detecting the clicks on sprites, and it's working.
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
function clickOnSprite(event){
console.log("CLICK! " + event.clientX + ", " + event.clientY);
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( iconsSprites );
intersects.forEach(function(element){
console.log("Intersection: " + element.object.id);
});
}

Three.js Dom event ( linkify.js)

I can't make it work. on the console, it says that the click event work,
but i cant link the sphere with an url.
Iam using last version of three.js
here is my code : `
// once everything is loaded, we run our Three.js stuff.
$(function () {
var geometry, material, mesha;
var clock = new THREE.Clock();
var raycaster;
var stats = initStats();
// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render and set the size
var webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0x000, 1.0));
webGLRenderer.setSize(window.innerWidth, window.innerHeight);
webGLRenderer.shadowMapEnabled = true;
// position and point the camera to the center of the scene
camera.position.x = 100;
camera.position.y = 10;
camera.position.z = 1000;
camera.lookAt(new THREE.Vector3(0, 0, 0));
var camControls = new THREE.FirstPersonControls(camera);
camControls.lookSpeed = 0.4;
camControls.movementSpeed = 30;
camControls.noFly = true;
camControls.lookVertical = true;
camControls.constrainVertical = false;
camControls.verticalMin = 0.0;
camControls.verticalMax = 1.0;
camControls.lon = -150;
camControls.lat = 120;
var ambientLight = new THREE.AmbientLight(0x383838);
scene.add(ambientLight);
// add spotlight for the shadows
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(100, 140, 130);
spotLight.intensity = 10;
scene.add(spotLight);
// add the output of the renderer to the html element
$("#WebGL-output").append(webGLRenderer.domElement);
// call the render function
var step = 0;
// setup the control gui
var controls = new function () {
// we need the first child, since it's a multimaterial
}
var domEvents = new THREEx.DomEvents(camera, webGLRenderer.domElement)
//////////////////////////////////////////////////////////////////////////////////
// add an object and make it move //
//////////////////////////////////////////////////////////////////////////////////
var geometry = new THREE.SphereGeometry( 100.5 )
var material = new THREE.MeshNormalMaterial()
var mesh = new THREE.Mesh( geometry, material )
scene.add( mesh )
//////////////////////////////////////////////////////////////////////////////////
// linkify our cube //
//////////////////////////////////////////////////////////////////////////////////
var url = 'http://jeromeetienne.github.io/threex/'
THREEx.Linkify(domEvents, mesh, url)
domEvents.addEventListener(mesh, 'click', function(event){
console.log('you clicked on mesh', mesh)
}, false)
var gui = new dat.GUI();
var mesh;
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round(percentComplete, 2) + '% downloaded' );
}
};
var onError = function ( xhr ) { };
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl( '../assets/models/door/' );
mtlLoader.setPath( '../assets/models/door/' );
mtlLoader.load( 'door.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( '../assets/models/door/' );
objLoader.load( 'door.obj', function ( object ) {
object.position.y = -1;
object.scale.x = 2;
object.scale.y = 2;
object.scale.z = 2;
scene.add( object );
}, onProgress, onError );
});
// floor
geometry = new THREE.PlaneGeometry( 2000, 2000, 100, 100 );
geometry.rotateX( - Math.PI / 2 );
for ( var i = 0, l = geometry.vertices.length; i < l; i ++ ) {
var vertex = geometry.vertices[ i ];
vertex.x += Math.random() * 20 - 10;
vertex.y += Math.random() * 3;
vertex.z += Math.random() * 20 - 10;
}
for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) {
var face = geometry.faces[ i ];
face.vertexColors[ 0 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 1 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 10.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 2 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
}
material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
function setCamControls() {
}
render();
function setRandomColors(object, scale) {
var children = object.children;
if (children && children.length > 0) {
children.forEach(function (e) {
setRandomColors(e, scale)
});
} else {
// no children assume contains a mesh
if (object instanceof THREE.Mesh) {
object.material.color = new THREE.Color(scale(Math.random()).hex());
if (object.material.name.indexOf("building") == 0) {
object.material.emissive = new THREE.Color(0x444444);
object.material.transparent = true;
object.material.opacity = 0.8;
}
}
}
}
function render() {
stats.update();
var delta = clock.getDelta();
if (mesh) {
// mesh.rotation.y+=0.006;
}
camControls.update(delta);
webGLRenderer.clear();
// render using requestAnimationFrame
requestAnimationFrame(render);
webGLRenderer.render(scene, camera)
}
function initStats() {
var stats = new Stats();
stats.setMode(0); // 0: fps, 1: ms
// Align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
$("#Stats-output").append(stats.domElement);
return stats;
}
});
can somebody help ? have you an idea?
Iam quite a newbie...
Solution:
Get the latest version of DomEvents (https://github.com/jeromeetienne/threex.domevents) which has been updated to r74 right now.
Explaination:
This one took me some time to figure out, lets see whats going on:
THREEx.DomEvents is internally using the THREE.Raycaster to detect when the mouse is pointing on meshes. ThreeJS changed lately the behavior of the raycaster to not intersect with invisible meshes anymore (source). Yeah well I dont care, my click event is fireing you say?
Lets have a look at Linkyfy:
THREEx.Linkify = function(domEvents, mesh, url, withBoundingBox){
withBoundingBox = withBoundingBox !== undefined ? withBoundingBox : true
// create the boundingBox if needed
if( withBoundingBox ){
var boundingBox = new THREE.Mesh(new THREE.CubeGeometry(1,1,1), new THREE.MeshBasicMaterial({
wireframe : true
}))
boundingBox.visible = false
boundingBox.scale.copy(size)
mesh.add(boundingBox)
}
// ...
The fourth parameter withBoundingBox is evaluating to true if you dont supply it. Linkify is then creating a "bounding box mesh" which is invisible and wrapping around your mesh you want to linkify. The raycaster does not trigger an intersection anymore and there you have it. To allow the raycaster to detect an intersection although the boundingBox-object is invisible, set only the meshs materials visibility to false and not the mesh:
boundingBox.material.visible = false

Rotate the mergeometry object at its center in Three.js

I am struggling to find the way to rotate the object at its center. At the moment i am able to rotate the scene, but when i do the rotation, the object goes away from the user. I look into the some the already asked questions in the same line on the forum, but couldn't able to get it work. Below is the part of the html/three.js file i am using /attached you will find the complete working example.Any help is greatly appreciated
<script src="../build/three.min.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var container, stats;
var camera, controls, scene, renderer;
var pickingData = [], pickingTexture, pickingScene;
var objects = [];
var highlightBox;
var splitCoord;
var avStdProp;
var mouse = new THREE.Vector2();
var offset = new THREE.Vector3( 10, 10, 10 );
var geom = new THREE.BoxGeometry(0.005, 0.005, 0.005 );
geom.colorsNeedUpdate = true;
init();
animate();
function init() {
container = document.getElementById( "container" );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.x=250;
camera.position.y=300;
camera.position.z=400;
renderer = new THREE.WebGLRenderer( { antialias: true } );
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(800, 800);
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 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;92_103_176;169_193_180;161_165_187;262_163_166;198_143_155;161_189_155;125_121_107";
splitCoord=coord.split(";");
var coordColr="0_255_255;255_255_0;0_0_255;0_255_0;255_255_0;0_255_0;0_0_255;0_255_255;255_255_0;210_210_45";
var splitCoordColor=coordColr.split(";");
var avgStd="1_0;3_0;0_0;2_0;3_0;2_0;0_0;1_0;3_0;3_0.35";
avStdProp=avgStd.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 );
// give the geom's vertices a random color, to be displayed
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.009, 0.009, 0.009 ),
new THREE.MeshLambertMaterial( { color: 0xffffff }
) );
scene.add( highlightBox );
//renderer.setClearColor( 0xffffff );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(800,800);
renderer.sortObjects = false;
container.appendChild( renderer.domElement );
renderer.domElement.addEventListener( 'mousemove', onMouseMove );
}
//
function onMouseMove( e ) {
mouse.x = e.clientX;
mouse.y = e.clientY;
}
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+window.pageXOffset, pickingTexture.height - (mouse.y+window.pageYOffset), 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 && controls.enabled){
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 animate() {
requestAnimationFrame( animate );
render();
//stats.update();
}
function render() {
controls.update();
pick();
renderer.render(scene, camera);
}
any help?
You can set your objects geometry to center, so the center of the mesh will then be at position (0,0,0) and it wont "move away" while rotating.
Do it like this:
geometry.center();
var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
scene.add( drawnObject );
Update
Because you want to use picking in an unusual way by saving your geometrys coordinates into an array, centering the geometry doesnt help you. Your question was "Rotate the mergeometry object at its center", but it seems like you want to rotate the camera around your geometrys center.
Calculate the bounding sphere of your geometry and set the controls target to its position:
drawnObject.geometry.computeBoundingSphere();
controls.target = drawnObject.geometry.boundingSphere.center;

Categories

Resources