How to animate a glb with GTLF loader in THREE.js - javascript

<!DOCTYPE html>
<html>
<head>
<title>____________glTF2_Loader_________</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="three.js"></script>
<script src="GLTFLoader.js"></script>
<script src="OrbitControls.js"></script>
<script>
// Load 3D Scene
var scene = new THREE.Scene();
// Load Camera Perspektive
var camera = new THREE.PerspectiveCamera( 25, window.innerWidth / window.innerHeight, 1, 20000 );
camera.position.set( 1, 1, 20 );
// Load a Renderer
var renderer = new THREE.WebGLRenderer({ alpha: false });
renderer.setClearColor( 0xC5C5C3 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls( camera, renderer.domElement );
//load in camera controls
controls.update();
// Load the Orbitcontroller
// Load Light
var ambientLight = new THREE.AmbientLight( 0xcccccc, 2);
// NOTE: More ambience gives an etherial look. :O
scene.add( ambientLight );
var PointLight = new THREE.PointLight( 0xffffff, 3, 100, 2 );
//color (white), intensity (3 times)
PointLight.position.set( 4, -4, 1 ).normalize();
scene.add( PointLight );
// _____ TODO!!!: FADE INTO SCENE. ___________
// glTf 2.0 Loader
var mixer;
var clock = new THREE.Clock();
var loader = new THREE.GLTFLoader();
let obj;
loader.load( './models/ZOMBIIIL12.glb', function ( gltf ) {
// <<--------- Model Path
mixer = new THREE.AnimationMixer(gltf.scene);
obj = gltf.scene;
var action = mixer.clipAction( gltf.animations[ 0 ] );
console.log( action );
gltf.scene.scale.set( .5, .5, .5 );
gltf.scene.position.x = 0; //Position (x = right+ left-)
gltf.scene.position.y = -5; //Position (y = up+, down-)
gltf.scene.position.Z = 5; //Position (z = front +, back-)
gltf.scene.rotation.y = 90; //rotating on the y axis, + is towards the right, - is towards the left.
obj.rotation.y = camera.rotation.y;
var URll = './texture maps/Material Base Color.png';
var textT = THREE.ImageUtils.loadTexture( URll );
var materiall = new THREE.MeshPhongMaterial({
map : textT,
})
gltf.texture = materiall;
scene.add( gltf.scene );
action.play();
});
function animate() {
renderer.render(scene, camera);
requestAnimationFrame( animate );
}
function render() {
renderer.render( scene, camera );
}
var geometry2 = new THREE.PlaneGeometry( 30, 20, 32 );
var url = './texture maps/GREEN LEAVES.png';
var texture = THREE.ImageUtils.loadTexture( url );
var material2 = new THREE.MeshPhongMaterial({
map : texture,
})
var plane = new THREE.Mesh( geometry2, material2 );
plane.position.z = -1;
scene.add( plane );
/*
var xSpeed = .1;
var zSpeed = .1;
document.addEventListener("keydown", onDocumentKeyDown, false);
//while the document is active, listen for this event called keydown, and run function onDocumentKeyPress
x1 = 0;
function onDocumentKeyDown(event) {
var keyCode = event.which;
if (keyCode == 87) {
//obj.rotation.y += .05;
//rotates the model so that you change where it is facing.
obj.translateZ( .5 );
// camera.rotation.y = obj.rotation.y;
camera.translateZ( .5 );
camera.position.y = obj.position.y - 1.9;
// camera.position.y = obj.position.y - 1.9;
//++++++++++++++++++ WWWWWW KEYYYYYYYY (forward)
} else if (keyCode == 83) {
obj.translateZ( -0.5 );
camera.translateZ( -0.5 );
camera.position.y = obj.position.y - 1.9;
console.log(obj.position.y)
//camera.position.set(obj.position.x, camera.position.y, camera.position.z);
//updates z position by the amount of speed.
// obj.rotation.y = 90;
// camera.rotation = 90;
//camera.translateZ( .1 );
//++++++++++++++++++ SSSSSSS KEYYYYYYYY (back)
} else if (keyCode == 65) {
//obj.rotation.y += 90;
obj.translateX( -.5 );
camera.translateX( -.5 );
camera.position.z = obj.position.z + 20;
//++++++++++++++++++ AAAAAAA KEYYYYYYYY (left)
/// If camera rotation on the y is less than or greater than a certain value, then rotate it on the mouse movement, otherwise, nothing.
} else if (keyCode == 68) {
obj.translateX(.5);
camera.translateX(.5);
camera.position.z = obj.position.z + 20;
//++++++++++++++++++ DDDDDD KEYYYYYYYY (rigtht)
} else if (keyCode == 32) {
obj.position.set(0, 0, 0);
// console.log(obj.position.x);
//space bar
}
//camera.rotation.x += 0.05
};
*/
render();
animate();
</script>
</body>
</html>
above code works to load in the model, however, it does not play the animation when called. I get no errors but it still does not work. The console even logs the action animation that is loaded from the glb model showing that it is there. i tried acting as though it is a json, and using json loader animator functions. I tried using clipaction functions, but they only gave me errors saying that they were either undefined, or just would say that there was an error.

You have to update your animation mixer in your animation loop like so:
var delta = clock.getDelta();
if ( mixer ) mixer.update( delta );
Notice that clock is an instance of THREE.Clock. Create it similar to your camera and scene at the top of your file.
three.js R112

Related

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

How to reflect an object in itself?

Is it possible that an object reflects in itself?
I like to receive a self reflection on a metallic object.
So basicially, the two rings of the mechanism should be reflected in the lower part.
Thank you very much in advance!
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container;
var loader;
var camera, cameraTarget, controls, scene, renderer;
init();
animate();
function init() {
var previewDiv = document.getElementById("preview");
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 15 );
camera.position.set( 3, 0.15, 3 );
cameraTarget = new THREE.Vector3( 0, -0.25, 0 );
controls = new THREE.OrbitControls( camera );
controls.maxPolarAngle = Math.PI / 2.2;
controls.minDistance = 1;
controls.maxDistance = 8;
controls.noPan = false;
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xdae1e6, 2, 15 );
// Ground
var plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 40, 40 ),
new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
);
plane.rotation.x = -Math.PI/2;
plane.position.y = -0.5;
scene.add( plane );
plane.receiveShadow = true;
// feinleinen
var feinleinentexture = THREE.ImageUtils.loadTexture( 'textures/feinleinen.jpg' );
feinleinentexture.anisotropy = 16;
feinleinentexture.wrapS = feinleinentexture.wrapT = THREE.RepeatWrapping;
feinleinentexture.repeat.set( 5, 5 );
var feinleinen = new THREE.MeshPhongMaterial( { color: 0xffffff, map: feinleinentexture } );
// Chrome
var path = "textures/chrome/";
var format = '.jpg';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
var envMap = THREE.ImageUtils.loadTextureCube( urls, THREE.CubeReflectionMapping );
var chrome = new THREE.MeshPhongMaterial( {
color : 0x151515,
specular : 0xffffff,
shininess : 200,
envMap : envMap,
combine : THREE.MixOperation, // or THREE.AddOperation, THREE.MultiplyOperation
reflectivity : 0.8
} );
// basis
var basisGeometry = new THREE.BoxGeometry(1.8,0.012,3);
var basis = new THREE.Mesh(basisGeometry, feinleinen);
basis.castShadow = false;
basis.receiveShadow = true;
basis.position.set( 0, -0.47, 0 );
scene.add(basis);
// 2 Ring
var loader = new THREE.JSONLoader();
loader.load('/models/2ring.js', function(geo, mat){
var mesh = new THREE.Mesh(geo, chrome);
mesh.position.set( 0.08, - 0.477, -0.2 );
mesh.rotation.set( 0, - Math.PI / 0.67, 0 );
mesh.scale.set( 0.1, 0.1, 0.1 );
mesh.castShadow = true;
mesh.receiveShadow = true;
loadJson(mesh );
});
function loadJson(mesh){
scene.add( mesh );
}
// Lights
scene.add( new THREE.AmbientLight( 0x777777 ) );
addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
addShadowedLight( 0.5, 1, -1, 0xffffff, 1 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( scene.fog.color );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
renderer.shadowMapCullFace = THREE.CullFaceBack;
previewDiv.appendChild (renderer.domElement);
// resize
window.addEventListener( 'resize', onWindowResize, false );
}
function addShadowedLight( x, y, z, color, intensity ) {
var directionalLight = new THREE.DirectionalLight( color, intensity );
directionalLight.position.set( x, y, z )
scene.add( directionalLight );
directionalLight.castShadow = true;
// directionalLight.shadowCameraVisible = true;
var d = 1;
directionalLight.shadowCameraLeft = -d;
directionalLight.shadowCameraRight = d;
directionalLight.shadowCameraTop = d;
directionalLight.shadowCameraBottom = -d;
directionalLight.shadowCameraNear = 1;
directionalLight.shadowCameraFar = 4;
directionalLight.shadowMapWidth = 2048;
directionalLight.shadowMapHeight = 2048;
directionalLight.shadowBias = -0.005;
directionalLight.shadowDarkness = 0.15;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.lookAt( cameraTarget );
controls.update();
renderer.render( scene, camera );
}
</script>
You want an object to reflect itself when using a three.js renderer.
Environment mapping, which you have implemented, is based on an approximation that the environment being reflected is (infinitely) far away.
Even if you used a CubeCamera for your environment map, as in this example, you would have the same problem.
The solution using three.js is to use a form of raytracing. three.js has a RaytracingRenderer, and a simple demo, but that renderer is currently not highly-supported, nor does it run at real-time frame rates.
three.js r.71

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;

Raycasting and container in Three.js

I have been struggling with issues concerning raycasting on small circlegeometries on a sphere.
I know raycasting can't be done with sprites and this is why I use circlegeometries, but it doesn't work all the time, and moreover the raycasting doesn't always work on circles but sometimes around them as well.
Does anybody have an idea ? Here is a JSBin to show you basically
Edit :
I updated my previous version of JSBin, you can click any circleGeometries it will work here, run it with output tab only open for better results
This is related to the renderer width and height properties, my sphere isn't in fullscreen and this is why it fails.
Does anybody have an idea on how to set up it right in order to get this to work perfectly ?
The formula used to compute intersections wasn't the good one, here is the one that works :
mouse.x = ( ( event.clientX - renderer.domElement.offsetLeft ) / renderer.domElement.width ) * 2 - 1;
mouse.y = - ( ( event.clientY - renderer.domElement.offsetTop ) / renderer.domElement.height ) * 2 + 1;
mouse x and y have slightly changed from the examples you can get, and are now fine.
var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
projector.unprojectVector(vector, camera);
var ray = new THREE.Raycaster(camera.position, vector.sub(
camera.position).normalize());
var intersects = ray.intersectObjects(objects);
if ( intersects.length > 0 ) {
//do something
}
if you looking for some thing like this....Your code might need little changes... check this link http://jsfiddle.net/ebeit303/rjJ6q/
// standard global variables
var container, scene, camera, renderer, controls, stats;
var clock = new THREE.Clock();
// custom global variables
var targetList = [];
var projector, mouse = { x: 0, y: 0 };
init();
animate();
// FUNCTIONS
function init()
{
// SCENE
scene = new THREE.Scene();
// CAMERA
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 100000;
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
scene.add(camera);
camera.position.set(600,0,-1200);
camera.lookAt(scene.position);
// RENDERER
renderer = new THREE.CanvasRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
container = document.getElementById( 'ThreeJS' );
container.appendChild( renderer.domElement );
// EVENTS
// CONTROLS
// this material causes a mesh to use colors assigned to faces
var faceColorMaterial = new THREE.MeshBasicMaterial(
{ color: 0xffffff, vertexColors: THREE.FaceColors } );
var sphereGeometry = new THREE.SphereGeometry( 500, 64, 64 );
for ( var i = 0; i < sphereGeometry.faces.length; i++ )
{
face = sphereGeometry.faces[ i ];
face.color.setRGB( 0, 0, 0.8 * Math.random() + 0.2 );
}
var sphere = new THREE.Mesh( sphereGeometry, faceColorMaterial );
sphere.rotation.set(0, 14.5, 0);
scene.add(sphere);
//targetList.push(sphere);
var j=0;
for (var i =0; i<100;i+=5){
//var circle = new THREE.CubeGeometry(5,5,5);
var circle = new THREE.CircleGeometry(5, 8, 0, Math.PI * 2);
//THREE.GeometryUtils.triangulateQuads(circle);
var circleMaterial = new THREE.MeshBasicMaterial({color: 0xDEF2EF});
circleMaterial.side = THREE.DoubleSide;
var mesh = new THREE.Mesh(circle, circleMaterial);
var Alon = i - 90;
var Alat = j;
var Aphi = Math.PI/2 - Alat * Math.PI / 180;
var Atheta = 2 * Math.PI - Alon * Math.PI / 180;
mesh.position.x = Math.sin(Aphi) * Math.cos(Atheta) * (501);
mesh.position.y = Math.cos(Aphi) * (501);
mesh.position.z = Math.sin(Aphi) * Math.sin(Atheta) * (501);
mesh.verticesNeedUpdate = true;
mesh.lookAt( sphere.position );
sphere.add(mesh);
targetList.push(mesh);
j++;
}
// initialize object to perform world/screen calculations
projector = new THREE.Projector();
// when the mouse moves, call the given function
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event )
{
// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
var intersects = ray.intersectObjects( targetList );
if ( intersects.length > 0 )
{
intersects[ 0 ].object.material.color.setRGB( 0.8 * Math.random() + 0.2,
0.8 * Math.random() + 0.2,
0.8 * Math.random() + 0.2 );
}
}
function animate()
{
requestAnimationFrame( animate );
render();
}
function render()
{
renderer.render( scene, camera );
}

How to click and slide into three js cube?

i have this code which works nice and i want to add a situation that when i click on the red cube all the page "jump" closer to the cube. (maybe the camera ?).
i do not have any idea and i will hope you can help me.
In general, i want to learn how to click in one object in three js and move into a second object in my page.
this is my code :
<html>
<head>
<script src="js/three.js"></script>
</head>
<body>
<script>
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(document.body.clientWidth, document.body.clientHeight);
document.body.appendChild(renderer.domElement);
renderer.setClearColorHex(0xEEEEEE, 1.0);
renderer.clear();
renderer.shadowCameraFov = 50;
renderer.shadowMapWidth = 1024;;
renderer.shadowMapHeight = 1024;
var fov = 45; // camera field-of-view in degrees
var width = renderer.domElement.width;
var height = renderer.domElement.height;
var aspect = width / height; // view aspect ratio
var near = 1; // near clip plane
var far = 10000; // far clip plane
var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = -400;
camera.position.x = 200;
camera.position.y = 350;
var scene = new THREE.Scene();
var cube = new THREE.Mesh(
new THREE.CubeGeometry(50, 50, 50),
new THREE.MeshLambertMaterial({ color: 0xff0000 })
);
scene.add(cube);
cube.castShadow = true;
cube.receiveShadow = true;
var plane = new THREE.Mesh(
new THREE.PlaneGeometry(400, 200, 10, 10),
new THREE.MeshLambertMaterial({ color: 0xffffff }));
plane.rotation.x = -Math.PI / 2;
plane.position.y = -25.1;
plane.receiveShadow = true;
scene.add(plane);
var light = new THREE.SpotLight();
light.castShadow = true;
light.position.set(170, 330, -160);
scene.add(light);
var litCube = new THREE.Mesh(
new THREE.CubeGeometry(50, 50, 50),
new THREE.MeshLambertMaterial({ color: 0xffffff }));
litCube.position.y = 50;
litCube.castShadow = true;
scene.add(litCube);
renderer.shadowMapEnabled = true;
renderer.render(scene, camera);
var paused = false;
var last = new Date().getTime();
var down = false;
var sx = 0, sy = 0;
window.onmousedown = function (ev) {
down = true; sx = ev.clientX; sy = ev.clientY;
};
window.onmouseup = function () { down = false; };
window.onmousemove = function (ev) {
if (down) {
var dx = ev.clientX - sx;
var dy = ev.clientY - sy;
camera.position.x += dx;
camera.position.y += dy;
sx += dx;
sy += dy;
}
}
function animate(t) {
if (!paused) {
last = t;
litCube.position.y = 60 - Math.sin(t / 900) * 25;
litCube.position.x = Math.cos(t / 600) * 85;
litCube.position.z = Math.sin(t / 600) * 85;
litCube.rotation.x = t / 500;
litCube.rotation.y = t / 800;
renderer.clear();
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
window.requestAnimationFrame(animate, renderer.domElement);
};
animate(new Date().getTime());
onmessage = function (ev) {
paused = (ev.data == 'pause');
};
</script>
</body>
</html>
waiting for your replay,
thanks :)
You need to implement different and separated parts to do this:
Selecting an object can be done by using a Raycaster, you'll find many examples here on SO and in the three.js examples such as this one
Orienting the camera - see camera.lookAt( target.position ) - and zooming can be done in many ways, but you might want to use a kind of Control to ease the camera placement process, such as one of these. The TrackballControls for example seems appropriate.
One last bit, as your title says "sliding", is how the "camera jump" is done. If you want a smooth zoom, you'll need a kind of easing function. Have a look on Tween.js for this.
vincent wrote an excellent answer. I just want to add an example to help to understand.
Jsfiddle
<script>
var container, stats;
var camera, scene, projector, raycaster, renderer, selected;
var target, zoom=false;
var mouse = new THREE.Vector2(), INTERSECTED;
var radius = 100, theta = 0;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
scene = new THREE.Scene();
var light = new THREE.DirectionalLight( 0xffffff, 2 );
light.position.set( 1, 1, 1 ).normalize();
scene.add( light );
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( -1, -1, -1 ).normalize();
scene.add( light );
var geometry = new THREE.CubeGeometry( 20, 20, 20 );
var cube = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: '#F3B557' } ) );
cube.rotation = new THREE.Euler(0,Math.PI/4,0);
cube.position = new THREE.Vector3(-20,0,0);
scene.add(cube);
cube = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: '#F05B47' } ) );
cube.rotation = new THREE.Euler(0,Math.PI/4,0);
cube.position = new THREE.Vector3(20,0,0);
scene.add(cube);
projector = new THREE.Projector();
raycaster = new THREE.Raycaster();
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
renderer.domElement.addEventListener( 'mousedown', onCanvasMouseDown, false);
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
// set lookAt position according to target position
if(target){
camera.lookAt( target.position );
}else{
camera.lookAt(new THREE.Vector3(0,0,0));
}
//zoom in and out
if(zoom && camera.fov>10){
camera.fov-=1;
camera.updateProjectionMatrix();
}else if(!zoom && camera.fov<70){
camera.fov+=1;
camera.updateProjectionMatrix();
}
camera.position = new THREE.Vector3(0,100,100);
// find intersections
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
raycaster.set( camera.position, vector.sub( camera.position ).normalize() );
var intersects = raycaster.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
if ( INTERSECTED != intersects[ 0 ].object ) {
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = intersects[ 0 ].object;
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
INTERSECTED.material.emissive.setHex( 0xff0000 );
}
} else {
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = null;
}
renderer.render( scene, camera );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
//detect selected cube
function onCanvasMouseDown( event ){
if(INTERSECTED){
target = INTERSECTED;
zoom = true;
}else{
zoom = false;
}
}
</script>

Categories

Resources