Mouse Hover not working with different 3dObjects - javascript

I am trying to make 3d Line chart ... Here
for points and lines are working good but i wanted to listen mouse hover on points ( spheres ) only not on lines or grid or other grid object ...
for that I have separate 3d-objects and wrapper them all in different 3d-objects..
i.e.
grid-object have all grid
points-object have all points
lines-object have all lines..
lineContainer = new THREE.Object3D();
d3.select( lineContainer )
.selectAll()
.data(currentVal)
.enter().append(
function (d, i) {
var LineMaterial = new THREE.LineBasicMaterial({color: d.color});
var PI2 = Math.PI * 2;
var geometry = new THREE.Geometry();
var k = -10;
d.points.forEach(function(p){
var _x = x1(p.id);
var _y = y1(p.y);
var _z = (i+1)*10;
geometry.vertices.push(new THREE.Vector3(_x,_y,_z));
});
// for (var j = 0; j < 30; j++) {
// var _point = new THREE.SphereGeometry(0.8);
// var _pointmaterial = new THREE.MeshBasicMaterial( {color: _color(i)} );
// var sphere = new THREE.Mesh( _point, _pointmaterial );
// sphere.position.set(_x,_y,_z);
// parentTransform.add( sphere );
// };
var line = new THREE.Line(geometry, LineMaterial);
line.userdata = d.id;
line.material.linewidth = 2;
return line;
}
);
mainContainer.add( lineContainer );
pointsContainer = new THREE.Object3D();
d3.select( pointsContainer )
.selectAll()
.data(_allPoints)
.enter().append(
function (d, i) {
var _x = x1(d.id);
var _y = y1(d.y);
var _z = d.z*10;
var _point = new THREE.SphereGeometry(1.8);
var _pointmaterial = new THREE.MeshBasicMaterial( {color: d.color} );
var sphere = new THREE.Mesh( _point, _pointmaterial );
// sphere.classes = "points";
sphere.position.set(_x,_y,_z);
sphere.userdata = d;
var _toolTipValue = ""+d.id+"("+d.line+")";
var spritey = makeTextSprite( _toolTipValue, { fontsize: 14} );
spritey.position.set(_x-5,_y+8,_z);
spritey.visible = false;
d.bindedTip = spritey;
tooltipContainer.add(spritey);
return sphere;
});
mainContainer.add(pointsContainer);
scene.add(mainContainer);
function render() {
if(!tooltipShow){
// find intersections
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
// vector.unproject( camera )
projector.unprojectVector( vector, camera );
raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
// raycaster.setFromCamera( mouse, camera );
//lineintersect
// var intersects = raycaster.intersectObjects( lineContainer.children, true);
var pointIntersects = raycaster.intersectObjects( pointsContainer.children, true);
// console.log(pointIntersects);
if ( pointIntersects.length > 0 ) {
console.log(pointIntersects)
if ( currentPointIntersected !== undefined ) {
}
if(currentPointIntersected != pointIntersects[ 0 ].object){
currentPointIntersected = pointIntersects[ 0 ].object;
console.log(currentIntersected);
_allPoints.forEach(function(e,i){
if(e.id && e.bindedTip){
if(e.id == currentPointIntersected.userdata.id){
e.bindedTip.visible = true;
e.bindedTip.getTexture().needsUpdate = true;
e.isHover = true;
}else{
e.bindedTip.visible = false;
e.bindedTip.getTexture().needsUpdate = true;
e.isHover = false;
}
}
});
}
} else {
if ( currentPointIntersected !== undefined ) {
currentPointIntersected.material.linewidth = 1;
}
currentPointIntersected = undefined;
}
}
renderer.render( scene, camera );
stats.update();
}
I have use same code and same version on THREEjs from here
but is only listen upper level points not the point that are behind in z-axis ....
how can I can manage that...

I added new scene and render two scenes in renderer ... And bind mouse on top scene ..and all other elements in another scene ..

Related

Three.js scene gets hanged and becomes slow

The threejs scene consists of sphere and plane geometry, The sphere is textured with image and plane geometry
is textured with 2d text, and plane geometry is attached with click event, When I click on plane geometry
with the mouse I need to remove the previous sphere and plane geometry and load new sphere with new textured
image and new plane geometry which is happening, but the previous sphere and plane geometry are still remaining in memory and i need
to remove those objects, i tried using "dispose" method but that didn't help me may be i am making some mistake
to implement the dispose method,because of this the scene gets hanged, can someone please help me how to solve
this problem. I have added part of my code which might give an idea regarding the problem.https://jsfiddle.net/v1ayw803/
var spheregeometry = new THREE.SphereGeometry(radius, 20, 20, 0, -6.283, 1, 1);
var texture = THREE.ImageUtils.loadTexture(response.ImagePath);
texture.minFilter = THREE.NearestFilter;
var spherematerial = new THREE.MeshBasicMaterial({map: texture});
var sphere = new THREE.Mesh(spheregeometry, spherematerial);
//texture.needsUpdate = true;
scene.add(sphere);
var objects = [];
var objects_sphere = [];
objects_sphere.push(sphere);
for(var i=0; i<spriteResponse.length; i++)
{
var cardinal = {ID: parseInt(spriteResponse[i].ID), lat: parseFloat(spriteResponse[i].lat), lon: parseFloat(spriteResponse[i].lng), name: spriteResponse[i].name};
//var sprite = new labelBox(cardinal, radius, root);
//sprite.update(); was previously commented
//spritearray.push(sprite);
var phi = Math.log( Math.tan( cardinal.lat*(Math.PI/180) / 2 + Math.PI / 4 ) / Math.tan( click_marker.getPosition().lat()* (Math.PI/180) / 2 + Math.PI / 4) );
var delta_lon = Math.abs( click_marker.getPosition().lng() - cardinal.lon )*Math.PI/180;
var bearing = Math.atan2( delta_lon , phi ) ;
var Z_value = Math.cos(bearing)*(radius*0.75);
var X_value = Math.sin(bearing)*(radius*0.75);
var canvas = document.createElement('canvas');
context = canvas.getContext('2d');
metrics = null,
textHeight = 32,
textWidth = 0,
// actualFontSize = 2;
context.font = "normal " + textHeight + "px Arial";
metrics = context.measureText(cardinal.name);
var textWidth = metrics.width;
//var textHeight = metrics.height;
canvas.width = textWidth;
canvas.height = textHeight;
context.font = "normal " + textHeight + "px Arial";
context.textAlign = "center";
context.textBaseline = "middle";
context.beginPath();
context.rect(0, 0, textWidth, textHeight);
context.fillStyle = "white";
context.fill();
context.fillStyle = "black";
context.fillText(cardinal.name, textWidth / 2, textHeight / 2);
texture_plane = new THREE.Texture(canvas);
var GPU_Value = renderer.getMaxAnisotropy();
texture_plane.anisotropy = GPU_Value;
texture_plane.needsUpdate = true;
//var spriteAlignment = new THREE.Vector2(0,0) ;
material = new THREE.MeshBasicMaterial( {color: 0xffffff,side: THREE.DoubleSide ,map : texture_plane} );
material.needsUpdate = true;
//material.transparent=true;
geometry = new THREE.PlaneGeometry(0.3, 0.2);
plane = new THREE.Mesh( geometry, material );
plane.database_id = cardinal.ID;
plane.LabelText = cardinal.name;
//plane.scale.set( 0.3, 0.3,1 );
plane.scale.set( textWidth/165, textHeight/70, 1 );
plane.position.set(X_value,0,Z_value);
plane.coordinates = { X: X_value, Z: Z_value};
plane.lat_lon = { LAT: cardinal.lat, LON: cardinal.lon};
plane.textWidth = textWidth;
plane.textHeight = textHeight;
objects.push( plane );
scene.add(plane);
plane.userData = { keepMe: true };
//objects.push( plane );
//plane.id = cardinal.ID;
//var direction = camera.getWorldDirection();
camera.updateMatrixWorld();
var vector = camera.position.clone();
vector.applyMatrix3( camera.matrixWorld );
plane.lookAt(vector);
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event )
{
//clearScene();
event.preventDefault();
var mouse = new THREE.Vector2();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
var raycaster = new THREE.Raycaster();
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( objects );
var matched_marker = null;
if(intersects.length != 0)
{
for ( var i = 0; intersects.length > 0 && i < intersects.length; i++)
{
var x_id = intersects[0].object.database_id;
for( var j = 0; markers.length > 0 && j < markers.length; j++)
{
if(x_id == markers[j].ID)
{
matched_marker = markers[j];
break;
}
}
if(matched_marker != null)
{
break;
}
}
// loadScene();
clean_data();
google.maps.event.trigger( matched_marker, 'click' );
}
}
function clean_data()
{
for(var k=0;k<objects_sphere.length;k++)
{
scene.remove( objects_sphere[k] );
objects_sphere[k].geometry.dispose();
objects_sphere[k].material.map.dispose();
objects_sphere[k].material.dispose();
}
for (var j=0; j<objects.length; j++)
{
scene.remove( objects[j] );
objects[j].geometry.dispose();
objects[j].material.map.dispose();
objects[j].material.dispose();
// objects[j].material.needsUpdate = true;
}
/*spheregeometry.dispose();
spherematerial.dispose();
texture.dispose();
scene.remove( sphere );*/
} `
It looks like you're never rerendering the scene in either the example code or the jsFiddle. If you remove your object from the scene and the objects remain, it's likely that you've not rendered the scene again. Try adding a render loop.
animationLoop () {
myrenderer.render(myScene, myCamera)
window.requestAnimationFrame(animationLoop)
}

How to add color on click event dynamically?

How to add color onclick event using three js? Can anyone help? I have the below code:
var pts = [], numPts = 5;
for ( var i = 0; i < numPts * 2; i ++ ) {
var l = i % 2 == 1 ? 10 : 20;
var a = i / numPts * Math.PI;
pts.push( new THREE.Vector2 ( Math.cos( a ) * l, Math.sin( a ) * l ) );
}
var shape = new THREE.Shape( pts );
var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
var material2 = new THREE.MeshLambertMaterial( { color: 0x66CC00, wireframe: false } );
var mesh = new THREE.Mesh( geometry, material2 );
scene.add( mesh );
You need to assign a new color in the color property of the material of the mesh in your onclick handler. For example, to make it red just add the following lines in your onclick handler -
mesh.material.color = new THREE.Color(0xff0000);
mesh.material.needsUpdate = true;
Update:
Declare the variable mesh in global space then initiate it in the function like this -
var mesh;
function init() {
var pts = [], numPts = 5;
for ( var i = 0; i < numPts * 2; i ++ ) {
var l = i % 2 == 1 ? 10 : 20;
var a = i / numPts * Math.PI;
pts.push( new THREE.Vector2 ( Math.cos( a ) * l, Math.sin( a ) * l ) );
}
var shape = new THREE.Shape( pts );
var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
var material2 = new THREE.MeshLambertMaterial( { color: 0x66CC00, wireframe: false } );
mesh = new THREE.Mesh( geometry, material2 );
scene.add( mesh );
}

Updating Three.js Skeletal Animations to New Mixer Based System

The mixer system was introduced in r73, and I've been trying since then to update my game to this new system.
I am ALMOST there except one thing. Cross-fading on some animations with certain geometries have a slight delay that did not exist in r72. I hacked r72's BlendCharacter and Animation functions to allow callbacks and it works great. In 73 this was not necessary has it has this functionality built in via an event trigger.
In the following fiddle everything works as intended (r72).
http://jsfiddle.net/titansoftime/a93w5hw0/
<script src="http://www.titansoftime.com/webgl/Three72.full.js"></script>
<script src="http://www.titansoftime.com/webgl/BlendCharacter2.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/loaders/DDSLoader.js"></script>
var scene, camera, renderer, ambient, directional;
var mesh, geoCache={};
var clock, jsLoader, ddsLoader;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 20;
camera.position.y = 10;
ambient = new THREE.AmbientLight(0xffffff);
scene.add(ambient);
directional = new THREE.DirectionalLight(0xffffff,1);
directional.position.set(1,1,0);
scene.add(directional);
clock = new THREE.Clock();
jsLoader = new THREE.JSONLoader(true);
ddsLoader = new THREE.DDSLoader();
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xffffff, 1 );
document.getElementById('idle').onclick = function(e){
play('Idle',true);
};
document.getElementById('run').onclick = function(e){
play('Run',true);
};
document.getElementById('melee').onclick = function(e){
play('MelleAttack');
};
document.getElementById('magic').onclick = function(e){
play('MagicAttack');
};
document.body.appendChild( renderer.domElement );
loadFloor();
loadModel();
}
function createModel(json){
var geo, geo2;
if( geoCache[json.name] ){
geo = geoCache[json.name];
}else{
geo2 = jsLoader.parse(json).geometry;
var m = new THREE.SkinnedMesh( geo2 );
m.normalizeSkinWeights();
geo2 = m.geometry;
geo = new THREE.BufferGeometry().fromGeometry(geo2);
geo.bones = geo2.bones;
geo.animations = geo2.animations;
geoCache[json.name] = geo;
}
var tex = ddsLoader.load('http://www.titansoftime.com/utils.php?task=getTexture&id=16');
var mat = new THREE.MeshPhongMaterial({map:tex,skinning:true,side:THREE.DoubleSide});
mesh = new THREE.BlendCharacter();
mesh.load(geo,mat);
//mesh.scale.set(10,10,10);
//mesh.mixer = new THREE.AnimationMixer( mesh );
//parseAnimations();
scene.add(mesh);
play('Idle',true);
camera.lookAt(new THREE.Vector3(mesh.position.x,7,mesh.position.z));
}
function loadModel(){
$.ajax({
url: 'http://www.titansoftime.com/utils.php',
data: 'task=getModel&id=16',
crossDomain: true,
type: 'POST',
success: function(response){
createModel(JSON.parse(response));
}
});
}
function loadFloor(){
var geo = new THREE.PlaneBufferGeometry(50,50);
geo.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));
var mat = new THREE.MeshBasicMaterial({color:0x0000ff});
var mesh = new THREE.Mesh(geo,mat);
scene.add(mesh);
}
function play(name,loop){
loop = loop || false;
var anim = mesh.animations[name];
anim.loop = loop;
if( mesh.currentAnimation ){
var cur = mesh.animations[mesh.currentAnimation];
var theTime = 0.175;
if( !cur.loop ){
var diff = cur.data.length - cur.currentTime;
theTime = Math.max(0,Math.min(theTime,diff));
}
console.log('blending: '+name);
mesh.crossfade(name,theTime,function(){
play('Idle',true)
});
}else{
console.log('playing: '+name);
mesh.play(name,loop);
}
}
function animate() {
requestAnimationFrame( animate );
var delta = clock.getDelta();
if( mesh ){
mesh.update( delta );
}
THREE.AnimationHandler.update(delta);
renderer.render( scene, camera );
}
This one (r78) works almost fine except for one animation (Magic Attack) has a small but noticeable delay before returning to the Idle animation. On other models it's the Melee animation, on some there is no problem at all. Super confused as they all work properly in 72.
http://jsfiddle.net/titansoftime/2sh95etj/
<script src="https://rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/master/examples/js/loaders/DDSLoader.js"></script>
var scene, camera, renderer, ambient, directional;
var mesh, geoCache={};
var clock, jsLoader, ddsLoader;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 20;
camera.position.y = 10;
ambient = new THREE.AmbientLight(0xffffff);
scene.add(ambient);
directional = new THREE.DirectionalLight(0xffffff,1);
directional.position.set(1,1,0);
scene.add(directional);
clock = new THREE.Clock();
jsLoader = new THREE.JSONLoader(true);
ddsLoader = new THREE.DDSLoader();
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xffffff, 1 );
document.getElementById('idle').onclick = function(e){
play('Idle',true);
};
document.getElementById('run').onclick = function(e){
play('Run',true);
};
document.getElementById('melee').onclick = function(e){
play('MelleAttack');
};
document.getElementById('magic').onclick = function(e){
play('MagicAttack');
};
document.body.appendChild( renderer.domElement );
loadFloor();
loadModel();
}
function createModel(json){
var geo, geo2;
if( geoCache[json.name] ){
geo = geoCache[json.name];
}else{
geo2 = jsLoader.parse(json).geometry;
var m = new THREE.SkinnedMesh( geo2 );
m.normalizeSkinWeights();
geo2 = m.geometry;
geo = new THREE.BufferGeometry().fromGeometry(geo2);
geo.bones = geo2.bones;
geo.animations = geo2.animations;
geoCache[json.name] = geo;
}
var tex = ddsLoader.load('http://www.titansoftime.com/utils.php?task=getTexture&id=16');
var mat = new THREE.MeshPhongMaterial({map:tex,skinning:true,side:THREE.DoubleSide});
mesh = new THREE.SkinnedMesh(geo,mat);
//mesh.scale.set(10,10,10);
mesh.mixer = new THREE.AnimationMixer( mesh );
parseAnimations();
play('Idle',true);
scene.add(mesh);
camera.lookAt(new THREE.Vector3(mesh.position.x,7,mesh.position.z));
}
function loadModel(){
$.ajax({
url: 'http://www.titansoftime.com/utils.php',
data: 'task=getModel&id=16',
crossDomain: true,
type: 'POST',
success: function(response){
createModel(JSON.parse(response));
}
});
}
function loadFloor(){
var geo = new THREE.PlaneBufferGeometry(50,50);
geo.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));
var mat = new THREE.MeshBasicMaterial({color:0x0000ff});
var mesh = new THREE.Mesh(geo,mat);
scene.add(mesh);
}
function play(name,loop){
var to = mesh.animations[ name ];
if( mesh.currentAnimation ){
var from = mesh.animations[ mesh.currentAnimation ];
to.reset();
if( loop ){
to.setLoop(THREE.LoopRepeat);
to.clampWhenFinished = false;
}else{
to.setLoop(THREE.LoopOnce, 0);
to.clampWhenFinished = true;
mesh.mixer.addEventListener('finished',function(e){
play('Idle',true);
});
}
from.play();
to.play();
from.enabled = true;
to.enabled = true;
from.crossFadeTo( to, 0.3 );
}else{
to.play();
}
mesh.currentAnimation = name;
}
function parseAnimations(){
var o, anim, anims = {};
console.log(mesh);
for( var i=0,len=mesh.geometry.animations.length;i<len;i++){
o = mesh.geometry.animations[i];
if( o ){
anim = mesh.mixer.clipAction(o,mesh);
anim.setEffectiveWeight(1);
anims[o.name] = anim;
}
}
mesh.animations = anims;
}
function animate() {
requestAnimationFrame( animate );
var delta = clock.getDelta();
if( mesh ){
if( mesh.mixer ){
mesh.mixer.update( delta );
}
}
renderer.render( scene, camera );
}
Why is this happening?
UPDATE: I noticed this is issue is not limited to blending between animations. One of my animations just looping now has a delay!
72: http://jsfiddle.net/titansoftime/8v0pasp5/
78: http://jsfiddle.net/titansoftime/n6apnj3z/
What is going on!? Was there some sort of auto correcting behavior or something along those lines in 72 that has been removed?
This is a bug in three.js.
https://github.com/mrdoob/three.js/issues/9056
Closing.

JavaScript Double Click Function Three.js

I've got a double click function to allow the user to double click on a car model and it displays which objects have been intersected; e.g. wipers, grille, tyres and so on, and this function displays them in a list with the number of items the double click intersected with.
However, I am now trying to get it so that when a certain part of the car is clicked, for example, the tyres, it will display a paragraph with information on them. I can see how this is just a case of checking the name of the intersecting object and then displaying the relevant text if it intersects it, but every time I go to do what I think is right, it just breaks the already existing function to the point where the whole thing won't run.
I'm not exactly a JavaScript or Three.js pro at all, but trying to progress my function further is proving to be rather difficult.
Any suggestions? I've included the entire double click function, however it's when it's checking if there has been intersections near the bottom that is where the alterations need to be.
// On Mouse double click event function
function onDoubleClick(event) {
// Set the mouse down flag to false
mouseDown = false;
// Canvas x (left) and y (top) position
var canvasLeft = 0;
var canvasTop = 0;
// "event.clientX" is the mouse x position. "event.clientY" is the mouse y position
var tempX = event.clientX - canvasLeft;
var tempY = event.clientY - canvasTop;
// Create a normalised vector in 2d space
var vector = new THREE.Vector3((tempX / window.innerWidth) * 2 - 1, - (tempY / innerHeight) * 2 + 1, 0.5);
// Unproject a 2D point into the 3D word
// Use the camera projection matrix to transform the vector to the 3D world space
vector.unproject(camera);
// Send a ray in the direction the user has clicked from the cameras position
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
// Check if the ray has intersected with any objects and get intersections
var intersects = raycaster.intersectObjects(objects, true);
// Check if intersected with objects
if (intersects.length > 0) {
var tempStr = "Number of items: " + intersects.length + " ";
// List the items that were hit
for(var i=0; i < intersects.length; i++){
if(intersects[i].object.name != ""){
// The mesh name set above
tempStr += " | Name: " + intersects[i].object.name;
} else {
// The names inside the model
tempStr += " | Name: " + intersects[i].object.parent.name;
}
}
//Debug information
document.getElementById("debugInfo").innerHTML = tempStr + ".<br>";
//END
}
}
EDIT:
This is the entire code for the javascript file, as altering elements of the double click function seems to stop the page from loading.
window.onload = init;
// declare variables
var scene,camera,renderer, container;
var controls, guiControls, datGUI;
var grid, color;
var cube, cubeGeometry, cubeMaterial;
var plane, planeGeometry, planeMaterial;
var skyBoxMesh, texture_placeholder;
var spotLight;
var stats;
// Handles the mouse events.
var mouseOverCanvas;
var mouseDown;
// An array of objects that can be clicked on
var objects = [];
//DAE models
var showroom ,carOld, carNew;
var daeObject;
var animations;
var kfAnimations = [];
var kfAnimationsLength = 0;
var lastFrameCurrentTime = [];
var clock = new THREE.Clock();
var mouseOverCanvas, mouseDown;
var objectsClick=[];
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
//creates empty scene
scene = new THREE.Scene();
//camera
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, .1, 500);
camera.position.x = 40;
camera.position.y = 40;
camera.position.z = 40;
camera.lookAt(scene.position);
//renderer
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setClearColor(0xe6f2ff);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMapSoft = true;
container.appendChild( renderer.domElement );
// Add an event to set if the mouse is over our canvas
renderer.domElement.onmouseover=function(e){ mouseOverCanvas = true; }
renderer.domElement.onmousemove=function(e){ mouseOverCanvas = true; }
renderer.domElement.onmouseout=function(e){ mouseOverCanvas = false; }
renderer.domElement.onmousedown=function(e){ mouseDown = true; }
renderer.domElement.onmouseup=function(e){ mouseDown = false; }
// Double Click Event. Set a function called "onDoubleClick"
renderer.domElement.ondblclick=onDoubleClick;
// stats
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
//adds controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render);
var ambient = new THREE.AmbientLight( 0xadad85 );
scene.add( ambient );
//---------- creates grid ---------------
grid = new THREE.GridHelper(50,5);
color= new THREE.Color("rgb(255,0,0)");
grid.setColors( 0x000000);
scene.add(grid);
//----------- creates cube --------------
cubeGeometry = new THREE.BoxGeometry(5,5,5);
cubeMaterial = new THREE.MeshPhongMaterial({color: 0xff3300});
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = 0;
cube.position.y = 6;
cube.position.z = 2.5;
cube.castShadow = true;
scene.add(cube);
//----------- creates plane ---------------
planeGeomenty= new THREE.PlaneGeometry(100,100,100);
planeMaterial = new THREE.MeshLambertMaterial({color: 0x00cc00});
plane = new THREE.Mesh(planeGeomenty, planeMaterial);
//position the add objects to the scene
plane.rotation.x = -.5*Math.PI;
plane.receiveShadow = true;
scene.add(plane);
//------------- skyBox --------------
texture_placeholder = document.createElement('canvas');
texture_placeholder.width = 128;
texture_placeholder.height = 128;
var context = texture_placeholder.getContext('2d');
context.fillStyle = 'rgb(200,200, 200)';
context.fillRect(0, 0,texture_placeholder.width, texture_placeholder.height);
var materials = [
loadTexture('images/skybox/posX.jpg'),
loadTexture('images/skybox/negX.jpg'),
loadTexture('images/skybox/posY.jpg'),
loadTexture('images/skybox/negY.jpg'),
loadTexture('images/skybox/posZ.jpg'),
loadTexture('images/skybox/negZ.jpg')
];
skyBoxMesh = new THREE.Mesh(new THREE.BoxGeometry(500,500,500,7,7,7),
new THREE.MeshFaceMaterial(materials));
skyBoxMesh.scale.x = -1;
scene.add(skyBoxMesh);
//---------- loads collada files -----------
loadCollada();
daeObject = cube;
// initialise datGUI controls values
guiControls = new function() {
this.rotationY = 0.0;
this.positionX = 0.0;
this.positionY = 0.0;
this.positionZ = -10;
this.lightX = 20;
this.lightY = 35;
this.lightZ = 40;
this.intensity = 1;
this.distance = 0;
this.angle = 1.570;
this.target = cube;
}
//add spotLight with starting parameters
spotLight = new THREE.SpotLight(0xffffff);
spotLight.castShadow = true;
spotLight.position.set(20,35,40);
spotLight.intensity = guiControls.intensity;
spotLight.distance = guiControls.distance;
spotLight.angle = guiControls.angle;
scene.add(spotLight);
//adds controls on the scene
datGUI = new dat.GUI();
// datGUI.add(guiControls, 'positionZ', 0, 1);
datGUI.add(guiControls, 'positionZ', -10, 25, 0.5). name("Move the car");
datGUI.add(guiControls, 'rotationY', 0, 1).name('Rotate the car');
datGUI.add(guiControls, 'lightX', -60, 180);
datGUI.add(guiControls, 'lightY', 0, 180);
datGUI.add(guiControls, 'lightZ', -60, 180);
datGUI.add(guiControls, 'target',[ 'cube','Modern Mini', 'Classic Mini']).onChange(function() {
if(guiControls.target == 'cube'){
spotLight.target = cube;
daeObject = cube;
}
else if(guiControls.target == 'Classic Mini'){
spotLight.target = carOld;
daeObject = carOld;
}
else if(guiControls.target = 'Modern Mini'){
spotLight.target = carNew;
daeObject = carNew;
}
});
datGUI.add(guiControls, 'intensity', 0.01, 5).onChange(function (value){
spotLight.intensity = value;
});
datGUI.add(guiControls, 'distance', 0, 1000).onChange(function (value){
spotLight.distance = value;
});
datGUI.add(guiControls, 'angle', 0.001, 1.570).onChange(function (value){
spotLight.angle = value;
});
datGUI.close();
container.appendChild(renderer.domElement);
window.addEventListener( 'resize', onWindowResize, false );
}
//------------------------- END INIT() ----------------------------
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function loadCollada() {
//--- Loads the Classic Mini ---
colladaLoader = new THREE.ColladaLoader();
colladaLoader.options.convertUpAxis = true;
colladaLoader.load( 'dae_files/ClassicMini.dae', function ( collada ) {
carOld = collada.scene; // stores dae file to a global variable
carOld.position.set( 14.5, 1.8, -10 );
carOld.scale.set( 0.04, 0.04, 0.04 );
carOld.traverse(function (child) {
child.castShadow = true;
child.receiveShadow = true;
});
carOld.updateMatrix();
carOld.name = "Classic";
scene.add( carOld );
objects.push( carOld );
} );
//--- loads Modern Mini ---
colladaLoader = new THREE.ColladaLoader();
colladaLoader.options.convertUpAxis = true;
colladaLoader.load( 'dae_files/ModernMini.dae', function ( collada ) {
carNew = collada.scene;
carNew.position.set( -14.5, 6.3, -10 );
carNew.scale.set( 0.06, 0.06, 0.06 );
// creates shadow
carNew.traverse(function (child) {
child.castShadow = true;
child.receiveShadow = true;
});
carNew.updateMatrix();
carNew.name = "Modern";
scene.add( carNew );
objects.push( carNew );
} );
//--- loads the Showroom ---
colladaLoader = new THREE.ColladaLoader();
colladaLoader.options.convertUpAxis = true;
colladaLoader.load( 'dae_files/roomAnim2.dae', function collada( collada ) {
showroom = collada.scene;
animations = collada.animations;
kfAnimationsLength = animations.length;
// Initialise last frame current time.
for ( var i = 0; i < kfAnimationsLength; i++ ) {
lastFrameCurrentTime[i] = 0;
}
// Get all the key frame animations.
for ( var i = 0; i < kfAnimationsLength; i++ ) {
var anim = animations[ i ];
var keyFrameAnim = new THREE.KeyFrameAnimation( anim );
keyFrameAnim.timeScale = 1;
keyFrameAnim.loop = false;
kfAnimations.push( keyFrameAnim );
anim = kfAnimations[i];
anim.play();
}
showroom.position.set(0, 0, -20);
showroom.scale.set(0.06, 0.06, 0.06);
showroom.traverse(function (child) {
child.castShadow = true;
child.receiveShadow = true;
});
showroom.updateMatrix();
scene.add( showroom );
animate();
} );
}
// On Mouse double click event function
function onDoubleClick(event) {
// Set the mouse down flag to false
mouseDown = false;
// Canvas x (left) and y (top) position
var canvasLeft = 0;
var canvasTop = 0;
// "event.clientX" is the mouse x position. "event.clientY" is the mouse y position
var tempX = event.clientX - canvasLeft;
var tempY = event.clientY - canvasTop;
// Create a normalised vector in 2d space
var vector = new THREE.Vector3((tempX / window.innerWidth) * 2 - 1, - (tempY / innerHeight) * 2 + 1, 0.5);
// Unproject a 2D point into the 3D word
// Use the camera projection matrix to transform the vector to the 3D world space
vector.unproject(camera);
// Send a ray in the direction the user has clicked from the cameras position
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
// Check if the ray has intersected with any objects and get intersections
var intersects = raycaster.intersectObjects(objects, true);
// Check if intersected with objects
if (intersects.length > 0) {
var tempStr = "Number of items: " + intersects.length + " ";
// List the items that were hit
for(var i=0; i < intersects.length; i++){
if(intersects[i].object.name != ""){
// The mesh name set above
tempStr += " | Name: " + intersects[i].object.name;
} else {
// The names inside the model
tempStr += " | Name: " + intersects[i].object.parent.name;
}
}
//Debug information
document.getElementById("debugInfo").innerHTML = tempStr + ".<br>";
//END
}
}
function loopAnimations(){
// Loop through all animations
for ( var i = 0; i < kfAnimationsLength; i++ ) {
// Check if the animation is player and not paused.
if(kfAnimations[i].isPlaying && !kfAnimations[i].isPaused){
if(kfAnimations[i].currentTime == lastFrameCurrentTime[i]) {
kfAnimations[i].stop();
//kfAnimations[i].play();
lastFrameCurrentTime[i] = 0;
}
}
}
}
function play_pauseAnim() {
//checks is there animation and is it paused
if(kfAnimationsLength > 0) {
if(kfAnimations[0].isPlaying) {
for(i = 0; i < kfAnimationsLength; i++){
kfAnimations[i].stop();
}
}else {
for(i = 0; i < kfAnimationsLength; i++) {
lastFrameCurrentTime[i] = 0;
//kfAnimations[i].play(kfAnimations[i].currentTime);
kfAnimations[i].play(0);
}
}
}
}
function checkTime(){
if(kfAnimationsLength > 0) {
if(kfAnimations[0].isPlaying) {
if(kfAnimations[0].currentTime > 3){
play_pauseAnim();
}
}
}
}
// create a render loop to draw the scene 60 times per second
function render() {
//checkTime();
daeObject.rotation.y += guiControls.rotationY;
//if (daeObject.position.z < 25) {
daeObject.position.z = guiControls.positionZ;
//}
spotLight.rotation.x += guiControls.rotationX;
spotLight.rotation.y += guiControls.rotationY;
spotLight.rotation.z += guiControls.rotationZ;
stats.update();
}
function animate () {
var deltaTime = clock.getDelta();
for ( var i = 0; i < kfAnimationsLength; i++ ) {
// Get a key frame animation.
var anim = kfAnimations[i];
anim.update( deltaTime );
}
loopAnimations();
requestAnimationFrame(animate);
// Update last frame current time.
for ( var i = 0; i < kfAnimationsLength; i++ ) {
lastFrameCurrentTime[i] = kfAnimations[i].currentTime;
}
render();
renderer.render(scene, camera);
}
// Loads skybox texture
function loadTexture(path) {
var texture = new THREE.Texture(texture_placeholder);
var material = new THREE.MeshBasicMaterial({
map: texture,
overdraw: 0.5
});
var image = new Image();
image.onload = function() {
texture.image = this;
texture.needsUpdate = true;
};
image.src = path;
return material;
}
Macast,
Please, check if you haven't forgotten in your code:
var objets = [];
var raycaster = new THREE.Raycaster();
And for each part of the car this line :
objects.push( mesh );
Ex:
var geometry = new THREE.RingGeometry( 1, 5, 32 );
var material = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.DoubleSide } );
var simpleTire = new THREE.Mesh( geometry, material );
simpleTire.name = 'tire';
objects.push( simpleTire );
scene.add( simpleTire );
Then, it's simple :
if ( intersects.length > 0 ) {
switch(intersects[0].object.name){
case 'tire':
console.log('A pretty red tire');
break;
case 'motor':
console.log('An electric motor');
break;
}
}

How to set my camera behind my mesh

I created a city and a character in blender and imported thoses two JSON objects in my script. I want to move my character through the city and have this character at the center of my Screen. Now my problem is that my character is on the right side of my screen and not at the center. Does someone knows how to set my character at the center of my screen with my camera?
Here is a picture of my screen.
var scene, renderer, camera, lua;
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(90,window.innerWidth/window.innerHeight,0.1,50000);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor (0xffffff, 1);
document.body.appendChild(renderer.domElement);
var loader = new THREE.JSONLoader();
loader.load("city.json", function(geomtry , materials){
var material = new THREE.MeshFaceMaterial(materials);
var city = new THREE.Mesh(geomtry,material);
scene.add(city);
})
//my character
loader.load("lua2.json", function (geometry, materials){
var m = THREE.MeshFaceMaterial(materials);
lua = new THREE.Mesh(geometry,m);
//lua.position.set(0,3,0);
lua.position.set(0,2,0);
scene.add(lua);
})
camera.lookAt(scene);
var light = new THREE.PointLight();
//light.position.set(-100,200,100);
light.position.set(0,500,0);
scene.add(light);
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
update();
};
function update()
{
var delta = clock.getDelta();
var moveDistance = 5 * delta;
var rotateAngle = Math.PI / 2 * delta;
// local transformations
// move forwards/backwards/left/right
if ( keyboard.pressed("S") )
lua.translateZ( -moveDistance );
if ( keyboard.pressed("Z") )
lua.translateZ( moveDistance );
if ( keyboard.pressed("D") )
lua.translateX( -moveDistance );
if ( keyboard.pressed("Q") )
lua.translateX( moveDistance );
// rotate left/right/up/down
var rotation_matrix = new THREE.Matrix4().identity();
if ( keyboard.pressed("Y") )
lua.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle);
if ( keyboard.pressed("B") )
lua.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle);
if ( keyboard.pressed("G") )
lua.rotateOnAxis( new THREE.Vector3(1,0,0), rotateAngle);
if ( keyboard.pressed("H") )
lua.rotateOnAxis( new THREE.Vector3(1,0,0), -rotateAngle);
var relativeCameraOffset = new THREE.Vector3(0,0,0);
var cameraOffset = relativeCameraOffset.applyMatrix4( lua.matrixWorld );
camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.5,50000);
camera.position.x = lua.position.x;
camera.position.y = lua.position.y+1;
camera.position.z = lua.position.z-2;
//camera.position.x = cameraOffset.x;
//camera.position.y = cameraOffset.y;
//camera.position.z = cameraOffset.z;
camera.lookAt( lua.position );
}
render();
You can change your camera position and rotation
camera.position.x=100
camera.rotation.x=Math.PI

Categories