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
Related
I'm trying to create a three.js scene with a cubemap panorama background and a few .obj files with .mtl textures placed in the scene. However, I'm receiving this WebGL error that I can't figure out the source of:
THbindTexture: textures can not be used with multiple targets
Does anyone know what could possibly be going wrong? Here is the relevant code:
var camera, cubeCamera, scene, object, renderer;
var cube, sphere, torus;
var fov = 70,
isUserInteracting = false,
onMouseDownMouseX = 0, onMouseDownMouseY = 0,
lon = 0, onMouseDownLon = 0,
lat = 0, onMouseDownLat = 0,
phi = 0, theta = 0;
var skyLoader = new THREE.TextureLoader();
skyLoader.load( 'pano.jpg', function ( texture ) {
texture.mapping = THREE.UVMapping;
init( texture );
animate();
} );
function init( texture ) {
camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
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 );
var mesh = new THREE.Mesh( new THREE.SphereGeometry( 500, 60, 40 ), new THREE.MeshBasicMaterial( { map: texture } ) );
mesh.scale.x = -1;
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
cubeCamera = new THREE.CubeCamera( 1, 1000, 256 );
scene.add( cubeCamera );
document.body.appendChild( renderer.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
document.addEventListener( 'MozMousePixelScroll', onDocumentMouseWheel, false);
window.addEventListener( 'resize', onWindowResized, false );
onWindowResized( null );
var loader = new THREE.OBJLoader();
loader.load( 'nsa_sanantonio.obj', function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material.envMap = texture;
// add any other properties you want here. check the docs.
}
} );
scene.add( object );
} );
}
function onWindowResized( event ) {
renderer.setSize( window.innerWidth, window.innerHeight );
camera.projectionMatrix.makePerspective( fov, window.innerWidth / window.innerHeight, 1, 1100 );
}
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 );
}
function onDocumentMouseMove( event ) {
lon = ( event.clientX - onPointerDownPointerX ) * 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 ) {
// WebKit
if ( event.wheelDeltaY ) {
fov -= event.wheelDeltaY * 0.05;
// Opera / Explorer 9
} else if ( event.wheelDelta ) {
fov -= event.wheelDelta * 0.05;
// Firefox
} else if ( event.detail ) {
fov += event.detail * 1.0;
}
camera.projectionMatrix.makePerspective( fov, window.innerWidth / window.innerHeight, 1, 1100 );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var time = Date.now();
lon += .15;
lat = Math.max( - 85, Math.min( 85, lat ) );
phi = THREE.Math.degToRad( 90 - lat );
theta = THREE.Math.degToRad( lon );
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( scene.position );
cubeCamera.updateCubeMap( renderer, scene );
renderer.render( scene, camera );
}
I don't understand how two textures are being applied at once.
I got the Objloader code from here.
But it also doesn't work with the normal obj/stl loader. I have a demo on my website at http://www.zakziebell.com/nsa (you'll see that my model is black)
bindTexture: textures can not be used with multiple targets
means you're trying to use the same texture in 2 different ways, once as a 2D texture and again as a cubemap. A texture can only be one thing or the other not both.
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.
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 modified an example from Three.js library and I tried to add click event on objects.
After a lot of attempts... I'm still not capable to listening for clicks.
This code produces convex forms.
There is my code:
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, scene, renderer;
var objects = [];
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.y = 400;
scene = new THREE.Scene();
var light, object, object2, materials;
scene.add( new THREE.AmbientLight( 0x404040 ) );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 1, 0 );
scene.add( light );
var map = THREE.ImageUtils.loadTexture( 'textures/ash_uvgrid01.jpg' );
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 16;
materials = [
new THREE.MeshLambertMaterial( { ambient: 0xbbbbbb, map: map } ),
new THREE.MeshBasicMaterial( { color: 0x242424, wireframe: true, transparent: false, opacity: 0.1 } )
];
// random convex
points = [];
for ( var i = 0; i < 15; i ++ ) {
points.push( randomPointInSphere( 50 ) );
}
object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
object.position.set( -250, 0, 200 );
scene.add( object );
objects.push( object );
object.callback = function() { console.log('blabla');}
renderer = new THREE.WebGLRenderer( { antialias: true } );
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 );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function randomPointInSphere( radius ) {
return new THREE.Vector3(
( Math.random() - 0.5 ) * 1 * radius,
( Math.random() - 0.5 ) * 1 * radius,
( Math.random() - 0.5 ) * 1 * radius
);
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
var timer = Date.now() * 0.0001;
camera.position.x = Math.cos( timer ) * 800;
camera.position.z = Math.sin( timer ) * 800;
camera.lookAt( scene.position );
for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
var object = scene.children[ i ];
object.rotation.x = timer * 5;
object.rotation.y = timer * 2.5;
}
renderer.render( scene, camera );
}
function addMeteor()
{
var map = THREE.ImageUtils.loadTexture( 'textures/ash_uvgrid01.jpg' );
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 16;
var materials = [
new THREE.MeshLambertMaterial( { ambient: 0xbbbbbb, map: map } ),
new THREE.MeshBasicMaterial( { color: 0x242424, wireframe: true, transparent: false, opacity: 0.1 } )
];
objects.push( materials );
var object3;
var points3 = [];
for ( var i = 0; i < 10; i ++ ) {
points3.push( randomPointInSphere( 50 ) );
}
object3 = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points3 ), materials );
object3.position.set( -50, Math.floor((Math.random()*window.innerWidth)), Math.floor((Math.random()* window.innerHeight)) );
scene.add( object3 );
objects.push( object3 );
}
projector = new THREE.Projector();
// listeners
document.addEventListener( 'mousedown', onDocumentMouseDown, false)
// keyboard handler
function onDocumentMouseDown( event ) {
event.preventDefault();
console.log('blabla');
var vector = new THREE.Vector3(
( event.clientX / window.innerWidth ) * 2 - 1,
- ( event.clientY / window.innerHeight ) * 2 + 1,
0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
console.log(objects);
var intersects = ray.intersectObjects( objects );
console.log(intersects);
if ( intersects.length > 0 ) {
intersects[0].object.callback();
console.log('blabla');
}
}
renderer.render( scene, camera );
I was supposed to push Mesh into Objects array, but which one?
THREE.SceneUtils.createMultiMaterialObject() creates an object with two child meshes.
So, you need to set the recursive flag to true when calling Raycaster.intersectObjects().
var intersects = ray.intersectObjects( objects, true );
three.js r.62