I just learned about the THREE.js and am fascinated with it's abilities. I am no where advanced enough to write my own code so I have been browsing around trying to find an example to do exactly what I need or close to but so far with no avail :(
What I am working with is some code that moves an object by using the mouse. The X axis works prefectly but the Y axis rotates around the object instead of tilts it left and right.
My current code :
var container, stats;
var camera, scene, renderer;
var group, text, plane;
var targetRotationX = 0;
var targetRotationOnMouseDownX = 0;
var targetRotationY = 0;
var targetRotationOnMouseDownY = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var mouseY = 0;
var mouseYOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var finalRotationY
var center
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(100, window.innerWidth / window.innerHeight, 0.1, 10000 );
camera.position.z = 1000;
camera.eulerOrder = "YXZ"
scene = new THREE.Scene();
// lights
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );
light = new THREE.DirectionalLight( 0x002288 );
light.position.set( -1, -1, -1 );
scene.add( light );
light = new THREE.AmbientLight( 0x222222 );
scene.add( light );
var geometry = new THREE.BoxGeometry(1400, 100, 700, 10, 10, 10);
var material = new THREE.MeshBasicMaterial({color: 0xfffff, wireframe: true});
var cube = new THREE.Mesh(geometry, material);
//cube.position.set( center.x, center.y, center.z );
//cube.geometry.applyMatrix(new THREE.Matrix4().makeTranslation( -center.x, -center.y, -center.z ) );
renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
group = new THREE.Object3D();
group.add(cube)
scene.add(group);
// renderer
//stats = new Stats();
//stats.domElement.style.position = 'absolute';
//stats.domElement.style.top = '0px';
//container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
//for debuging stats
interval = setInterval( debugInfo, 50 );
}
function modelLoadedCallback(geometry) {
mesh = new THREE.Mesh( geometry, material );
group.add(mesh);
scene.add( group );
}
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 onDocumentMouseDown( event ) {
event.preventDefault();
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
mouseXOnMouseDown = event.clientX - windowHalfX;
targetRotationOnMouseDownX = targetRotationX;
mouseYOnMouseDown = event.clientY - windowHalfY;
targetRotationOnMouseDownY = targetRotationY;
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
targetRotationY = targetRotationOnMouseDownY + (mouseY - mouseYOnMouseDown) * 0.02;
targetRotationX = targetRotationOnMouseDownX + (mouseX - mouseXOnMouseDown) * 0.02;
}
function onDocumentMouseUp( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentMouseOut( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentTouchStart( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
targetRotationOnMouseDownX = targetRotationX;
mouseYOnMouseDown = event.touches[ 0 ].pageY - windowHalfY;
targetRotationOnMouseDownY = targetRotationY;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
targetRotationX = targetRotationOnMouseDownX + ( mouseX - mouseXOnMouseDown ) * 0.05;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
targetRotationY = targetRotationOnMouseDownY + (mouseY - mouseYOnMouseDown) * 0.05;
}
}
//
function animate() {
requestAnimationFrame( animate );
render();
//stats.update();
}
function render() {
//horizontal rotation
group.rotation.y += ( targetRotationX - group.rotation.y ) * 0.1;
finalRotationY = (targetRotationY - group.rotation.x);
if (group.rotation.x <= 1 && group.rotation.x >= -1) {
group.rotation.x += finalRotationY * 0.1;
}
if (group.rotation.x > 1) {
group.rotation.x = 1
}
else if (group.rotation.x < -1) {
group.rotation.x = -1
}
renderer.render( scene, camera );
}
function debugInfo()
{
//$('#debug').html("mouseX : " + mouseX + " mouseY : " + mouseY + "</br>")
}
<style>canvas { width: 100%; height: 100% }</style>
<script src="http://threejs.org/build/three.min.js"></script>
<div id="container"></div>
What I was hoping to do is when the mouse is clicked and moving either left or right, the box will tilt towards the mouse and keep the same "X" rotation unless the mouse is moving up or down as well. Right now, the camera seems to rotate around the object instead of tilt in the corresponding direction.
Any ideas?
micnil was right and I had to change the rotation order to "ZYX". Now off to learning how to join my 2 scripts together.
Related
This is the code I'm using -
var camera, scene, renderer;
var Container = document.getElementById('container');
var imageFile = Container.getAttribute('data');
var isUserInteracting = false,
onMouseDownMouseX = 0, onMouseDownMouseY = 0,
lon = 0, onMouseDownLon = 0,
lat = 0, onMouseDownLat = 0,
phi = 0, theta = 0;
init();
animate();
function closeModal() {
}
function init() {
var container, mesh;
container = document.getElementById( 'gallery-modal' );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1100 );
camera.target = new THREE.Vector3( 0, 0, 0 );
scene = new THREE.Scene();
var geometry = new THREE.SphereGeometry( 500, 60, 40 );
geometry.scale( - 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( {
map: new THREE.TextureLoader().load( imageFile )
} );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
//renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setSize( window.innerWidth, 500);
container.appendChild( renderer.domElement );
// Controls to move the image
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'wheel', onDocumentMouseWheel, false );
document.addEventListener( 'dragover', function ( event ) {
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
}, false );
document.addEventListener( 'dragenter', function ( event ) {
document.body.style.opacity = 0.5;
}, false );
document.addEventListener( 'dragleave', function ( event ) {
document.body.style.opacity = 1;
}, false );
var galleryDOM = document.getElementById('gallery');
var modal = document.getElementById('gallery-modal');
galleryDOM.addEventListener('click', function(e) {
if(e.target.localName == 'img') {
//console.log(e.target.src);
modal.style.display = "block";
var reader = new FileReader();
reader.addEventListener('load', function(e) {
material.map.image.src = e.target.result;
material.map.needsUpdate = true;
}, false);
}
});
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = 'none';
}
}
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();
isUserInteracting = true;
onPointerDownPointerX = event.clientX;
onPointerDownPointerY = event.clientY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
function onDocumentMouseMove( event ) {
if ( isUserInteracting === true ) {
lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
}
}
function onDocumentMouseUp( event ) {
isUserInteracting = false;
}
function onDocumentMouseWheel( event ) {
camera.fov += event.deltaY * 0.05;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame( animate );
update();
}
function update() {
if ( isUserInteracting === false ) {
lon += 0.1;
}
lat = Math.max( - 85, Math.min( 85, lat ) );
phi = THREE.Math.degToRad( 90 - lat );
theta = THREE.Math.degToRad( lon );
camera.target.x = 500 * Math.sin( phi ) * Math.cos( theta );
camera.target.y = 500 * Math.cos( phi );
camera.target.z = 500 * Math.sin( phi ) * Math.sin( theta );
camera.lookAt( camera.target );
/*
// distortion
camera.position.copy( camera.target ).negate();
*/
renderer.render( scene, camera );
}
UPDATE** I'm no longer recieving an error, but this also isn't changing the texture image?
I've add my entire code. I'm trying to create a gallery effect, click a placeholder image, modal opens with 360 image, but I need to it switch 360 images based on the placeholder clicked.
I have a simple three.js graphics, and I tried to use the answers in this and this question to make the created plot zoomable by the mouse wheel. By using the mouse wheel I would like to zoom in to the graphics or to zoom out.
Here is the complete code: pastebin link
However, when turning the mouse wheel nothing happens, and I do not get an error message. Maybe I am missing something?
DEMO
var container, camera, scene, renderer, colors;
var selected = 0;
var selectedObject;
var objects = [];
// DOM element...
container = document.createElement('div');
document.body.appendChild(container);
// Camera...
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 0, 150);
// Scene...
scene = new THREE.Scene();
scene.add(camera);
// Renderer...
renderer = new THREE.WebGLRenderer({
clearAlpha: 1
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff, 1);
document.body.appendChild(renderer.domElement);
// Scatter plot...
scatterPlot = new THREE.Object3D();
scene.add(scatterPlot);
// Plot some random points...
circle = new THREE.CircleGeometry(1, 20);
colors = [];
var max = 50;
var min = -50;
for (var i = 0; i < 10; i++) {
var object = new THREE.Mesh( circle.clone(), new THREE.MeshBasicMaterial( { color: new THREE.Color('black'), opacity: 0.5 } ) );
object.position.x = Math.random() * (max - min) + min;
object.position.y = Math.random() * (max - min) + min;
object.position.z = 0;
scene.add( object );
objects.push( object );
}
animate();
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
function onDocumentMouseDown( event ) {
event.preventDefault();
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( objects );
if ( intersects.length > 0 ) {
//intersects[ 0 ].object.material.color.set('red');
//intersects[ 0 ].object.geometry.scale(1.1,1.1,1.1);
if (selected === 0) {
selected = 1;
selectedObject = intersects[ 0 ].object;
selectedObject.material.color.set('red');
console.log(selectedObject.position.x);
} else {
selected = 0;
var geometry = new THREE.Geometry();
geometry.vertices.push(intersects[ 0 ].object.position);
geometry.vertices.push(selectedObject.position);
var line = new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: 0x0000ff }));
scene.add(line);
selectedObject.material.color.set('black');
}
}
}
function onWindowResize() {
camera.left = window.innerWidth / - 2;
camera.right = window.innerWidth / 2;
camera.top = window.innerHeight / 2;
camera.bottom = window.innerHeight / - 2;
camera.aspect = window.innerWidth / window.innerHeight;
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseWheel( event ) {
var fovMAX = 160;
var fovMIN = 1;
camera.fov -= event.wheelDeltaY * 0.05;
camera.fov = Math.max( Math.min( camera.fov, fovMAX ), fovMIN );
camera.projectionMatrix = new THREE.Matrix4().makePerspective(camera.fov, window.innerWidth / window.innerHeight, camera.near, camera.far);
}
body { margin: 0; }
canvas { width: 100%; height: 100% }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/54/three.js"></script>
In your code add event listener
document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
document.addEventListener( 'mousewheel', (event) => {
camera.position.z +=event.deltaY/500;
});
The mousewheel event is supported only in Webkit browsers.
For cross-browser compaitibility use the wheel event.
I'm setting up a texture on a mesh in three.js:
var container, stats;
var camera, scene, projector, raycaster, renderer;
var mouse = new THREE.Vector2(), INTERSECTED;
onMouseDownMouseX = 0, onMouseDownMouseY = 0,
lon = 0, onMouseDownLon = 0,
lat = 0, onMouseDownLat = 0,
phi = 0, theta = 0,
target = new THREE.Vector3();
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 1, 1000 );
scene = new THREE.Scene();
texture = THREE.ImageUtils.loadTexture( "textures/DIVE_IMMO_00000.jpg");
var background = new THREE.MeshBasicMaterial({map: texture});
var sphere = new THREE.Mesh( new THREE.SphereGeometry( 500, 60, 40 ), background );
sphere.scale.x = -1;
scene.add( sphere );
//projector = new THREE.Projector();
//raycaster = new THREE.Raycaster();
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
document.addEventListener( 'DOMMouseScroll', onDocumentMouseWheel, false);
//
window.addEventListener( 'resize', onWindowResize, false );
}
Next, i want to change the texture on this mesh using a button. I've try :
function newTexture() {
sphere.material.texture = THREE.ImageUtils.loadTexture( "textures/DIVE_IMMO_00004.jpg");
sphere.material.texture.needsUpdate = true;
}
also:
texture2 = THREE.ImageUtils.loadTexture( "textures/DIVE_IMMO_00004.jpg"); and
function newTexture() {
background = new THREE.MeshBasicMaterial({map: texture2});
}
but it doesn't work, and i really don't understand why.
Sorry for this noob question ^^
UPDATE: FULL CODE PAGE
var container, stats;
var camera, scene, projector, raycaster, renderer;
var mouse = new THREE.Vector2(), INTERSECTED;
onMouseDownMouseX = 0, onMouseDownMouseY = 0,
lon = 0, onMouseDownLon = 0,
lat = 0, onMouseDownLat = 0,
phi = 0, theta = 0,
target = new THREE.Vector3();
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 1, 1000 );
scene = new THREE.Scene();
//textures
texture = THREE.ImageUtils.loadTexture( "textures/DIVE_IMMO_00000.jpg");
texture_salon= THREE.ImageUtils.loadTexture( 'textures/btn_salon.png');
//materials
var background = new THREE.MeshBasicMaterial({map: texture});
var mat_salon = new THREE.MeshBasicMaterial( { map: texture_salon } )
mat_salon.transparent = true;
mat_salon.map.needsUpdate = true;
mat_salon.depthTest = false;
//Objects
var sphere = new THREE.Mesh( new THREE.SphereGeometry( 500, 60, 40 ), background );
sphere.scale.x = -1;
scene.add( sphere );
var plane_salon = new THREE.Mesh( new THREE.PlaneGeometry( 80, 60 ), mat_salon );
plane_salon.position.set( -280, 0, 100 );
plane_salon.lookAt( camera.position );
plane_salon.id = 01;
scene.add( plane_salon );
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
document.addEventListener( 'DOMMouseScroll', onDocumentMouseWheel, false);
//
window.addEventListener( 'resize', onWindowResize, false );
}
function newTexture() {
sphere.material.map = THREE.ImageUtils.loadTexture( "textures/DIVE_IMMO_00004.jpg");
sphere.material.map.needsUpdate = true;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
onPointerDownPointerX = event.clientX;
onPointerDownPointerY = event.clientY;
onPointerDownLon = lon;
onPointerDownLat = lat;
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
var projector = new THREE.Projector();
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( scene.children,true );
if ( intersects.length > 0 ) {
SELECTED = intersects[0].object;
if (SELECTED.id == 01){
$('#plan').css('display', '');
$('#Menu-plan').css('height', '285px');
RotToKitchen();
}
}
}
function onDocumentMouseMove( event ) {
lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
}
function onDocumentMouseUp( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
}
function onDocumentMouseWheel( event ) {
if ( event.wheelDeltaY ) {fov -= event.wheelDeltaY * 0.05;} // WebKit
else if ( event.wheelDelta ) {fov -= event.wheelDelta * 0.05;} // Opera / Explorer 9
else if ( event.detail ) {fov += event.detail * 1.0;} // Firefox
}
function animate() {
requestAnimationFrame( animate );
render();
}
function RotToKitchen() {
var id = requestAnimationFrame( RotToKitchen );
if (lon < 90) {lon +=0.85;}
else if (lon > 91) {lon -=0.85;}
else cancelAnimationFrame( id );
render();
}
function render() {
lat = Math.max( - 85, Math.min( 85, lat ) );
phi = THREE.Math.degToRad( 90 - lat );
theta = THREE.Math.degToRad( lon );
target.x = 0 * Math.sin( phi ) * Math.cos( theta );
target.y = 0 * Math.cos( phi );
target.z = 0 * Math.sin( phi ) * Math.sin( theta );
camera.position.x = 100 * Math.sin( phi ) * Math.cos( theta );
camera.position.y = 100 * Math.cos( phi );
camera.position.z = 100 * Math.sin( phi ) * Math.sin( theta );
camera.lookAt( target );
renderer.render( scene, camera );
}
One issue I notice is that you do sphere.material.texture = ... while it should be sphere.material.map = ...
And sphere.material.texture.needsUpdate should be sphere.material.map.needsUpdate = true;
I think it is better to update the existing texture:
texture = THREE.ImageUtils.loadTexture( "textures/DIVE_IMMO_00000.jpg");
update it:
texture.image = ( "textures/DIVE_IMMO_00004.jpg" );
texture.needsUpdate = true;
Not sure how it works with preloading the image etc...
Arrggh, I really need some help, going nuts. I have a three.js HTML5 page with three objects (1)cube, (2)cylinder and (3) an imported OBJ mesh.
Everything works fine until I try to rotate the mesh (guitar), then nothing renders. I can rotate and position it fine before adding to the scene, but if I try to rotate it within the render function everything goes black.
Can anyone tell me what I am doing wrong? Code is attached below.
thanks
<script src="../build/three.min.js"></script>
<script src="js/loaders/DDSLoader.js"></script>
<script src="js/loaders/MTLLoader.js"></script>
<script src="js/loaders/OBJMTLLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var targetRotation = 0;
var targetRotationOnMouseDown = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var container, stats;
var camera, scene, renderer;
var guitar,button1,cube;
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( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 640;
// scene
scene = new THREE.Scene();
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0, 1 ).normalize();
scene.add( directionalLight );
// model
THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
var loader = new THREE.OBJMTLLoader();
loader.load( 'obj/male02/guitarOBJ.obj', 'obj/male02/male02_dds.mtl', function ( guitar ) {
guitar.rotation.x = 1.57;
scene.add( guitar );
} );
var geometry = new THREE.CylinderGeometry( 5, 5, 50, 32 );
var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
button1 = new THREE.Mesh( geometry, material );
button1.rotation.y = 1;
button1.rotation.z = 0.75;
scene.add( button1 );
var geometry = new THREE.BoxGeometry( 100, 100, 100 );
for ( var i = 0; i < geometry.faces.length; i += 2 ) {
var hex = Math.random() * 0xffffff;
geometry.faces[ i ].color.setHex( hex );
geometry.faces[ i + 1 ].color.setHex( hex );
}
var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );
cube = new THREE.Mesh( geometry, material );
cube.position.y = 150;
scene.add( cube );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
/////////document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mousedown', onDocumentMouseDown, 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 ) / 2;
///mouseY = ( event.clientY - windowHalfY ) / 2;
///}
function onDocumentMouseDown( event ) {
event.preventDefault();
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
mouseXOnMouseDown = event.clientX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
}
function onDocumentMouseUp( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentMouseOut( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentTouchStart( event ) {
if ( event.touches.length === 1 ) {
event.preventDefault();
mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length === 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
}
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
guitar.rotation.y = button1.rotation.y = cube.rotation.y += ( targetRotation - cube.rotation.y ) * 0.05;
camera.lookAt( scene.position );
renderer.render( scene, camera );
}
</script>
Check this fiddle here. It is done exactly like how you did it.
Maybe the if clause makes a difference? Maybe you should not try rotating something before the mesh is properly loaded?
if(mesh){
mesh.rotation.y += 0.02;
}
Otherwise I would try simplifying the code to isolate the issue. Could be something else bothering you.
I've created a scene with textured and meshed cylinder and a grid with line and vertices of three.js. The cylinder has a spinning effect by dragging mouse left or right.
<!DOCTYPE html>
<html lang="en">
<head>
<title>3d Model using HTML5 and three.js</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="three.min.js" type="text/javascript"></script>
<script src="Stats.js" type="text/javascript"></script>
<script src="Detector.js" type="text/javascript"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, scene, renderer, light, projector;
var particleMaterial;
var cylinder, line, geometry, geometry1;
var targetRotation = 0;
var targetRotationOnMouseDown = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var objects = [];
var radious = 1600, theta = 45, onMouseDownTheta = 45, phi = 60, onMouseDownPhi = 60, isShiftDown = false;
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 = 'Drag to spin the cylinder<br/>Objective: By spining left, cylinder should go into the surface and by spining right it should come out.';
container.appendChild( info );
// camera
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.y = 200;
camera.position.z = 800;
// scene
scene = new THREE.Scene();
// light
scene.add( new THREE.AmbientLight( 0x404040 ) );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 1, 0 );
scene.add( light );
// texture
var materials = [];
for ( var i = 0; i < 6; i ++ ) {
materials.push( new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ) );
}//alert(materials.length);
// Grid
geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
for ( var i = 0; i <= 20; i ++ ) {
line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
line.position.z = ( i * 50 ) - 500;
scene.add( line );
line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
line.position.x = ( i * 50 ) - 500;
line.rotation.y = 90 * Math.PI / 180;
scene.add( line );
}
// cylinder
geometry1 = new THREE.CylinderGeometry(100, 100, 300, 16, 4, false);
cylinder = new THREE.Mesh(geometry1 ,new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ));
//cylinder.position.x = 100;
cylinder.position.y = -50;
//cylinder.overdraw = true;
scene.add(cylinder);
alert(geometry1.faces.length);
objects.push(cylinder);
// projector
projector = new THREE.Projector();
// renderer
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
// stats
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.left = window.innerWidth / - 2;
camera.right = window.innerWidth / 2;
camera.top = window.innerHeight / 2;
camera.bottom = window.innerHeight / - 2;
camera.aspect = window.innerWidth / window.innerHeight;
//camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
mouseXOnMouseDown = event.clientX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
}
function onDocumentMouseUp( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentMouseOut( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentTouchStart( event ) {
if ( event.touches.length === 1 ) {
event.preventDefault();
mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length === 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
}
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
cylinder.rotation.y += ( targetRotation - cylinder.rotation.y ) * 0.05;
renderer.render( scene, camera );
}
</script>
</body>
</html>
How do I know which face of cylinder is selected by clicking on a face of it ?
You have to shoot a virtual ray from your viewpoint to the cube. You can then read out the face or faceIndex from the intersected object.
function onDocumentMouseDown( event ) {
event.preventDefault();
// position of mouse + screen calc
var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
projector.unprojectVector( vector, camera );
// create a ray from the camera thru the vector
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
// array of intersecting object (front to back)
var intersects = ray.intersectObjects( objects );
// are we hitting something?
if ( intersects.length > 0 ) {
// first intersection should be the object (Mesh,...)
console.log(intersects[0].object);
// gimme face as THREE.Face3/4 object
console.log(intersects[0].face);
// tell me face index (int)
console.log(intersects[0].faceIndex);
// lets change color of the intersected object for fun
intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );
}
}
Also check out the canvas_interactive_cubes example