Three.js raycast from camera center - three.js

i try since weeks to raycast from the centre of a perspectivecamera. without event.client.x and y, because i use the device orientation:
var raycaster = new THREE.Raycaster();
var vector = new THREE.Vector3( 0, 0, 0 ); // instead of event.client.x and event.client.y
var direction = new THREE.Vector3( 0, 0, -1 ).transformDirection( camera.matrixWorld );
raycaster.set( vector, direction );
var intersects = raycaster.intersectObjects(objects);
i have a perspectivecamera on (0,0,0) … i use the device orientation instead keyboard and mouse to obtain the Rotation… and want to hit a cube with a raycast sent from the center of my cam. i try a lot of examples for a three.js raycast, but no success.
what the hell is wrong with my raycast????

For your raycast vector and direction use the cameras world vectors:
raycaster.set( camera.getWorldPosition(), camera.getWorldDirection() );

Use simple:
raycaster.setFromCamera( new THREE.Vector2(), camera );
http://jsfiddle.net/gLbkg21e/

Related

How to move an object in particular direction with specific distance in three.js

I need to move an object along directional vector through some distance. I fount translateOnAxis(vector, distance) of Object3D class. But I'm not able to understand how it works.
I've an object- sphere. I'm scaling it to look like ellipse. And setting position and direction. Now I need this object to move in the same direction which I'm setting it to, through some distance. When I apply it, I can't see the object. Can anybody suggest how it can be achieved?
var geometry = new THREE.SphereGeometry( radius, 64, 64, 0, -Math.PI );
geometry.applyMatrix( new THREE.Matrix4().makeScale( 1, 1, zScale ); //scaling it to look like ellipse
var direction = new THREE.Vector3( xDir, yDir, zDir);
var ellipse = new THREE.Mesh( geometry, material );
ellipse.lookAt(direction);
ellipse.position.set( xPos, yPos, zPos);
ellipse.translateOnAxis(direction, distance);
Your pasted code is buggy.
You're missing a ) on your applyMatrix line.
Are you using a debugger and observing console errors/warnings?

Is there ANY way to have the three.js camera lookat being rendered off-center?

Is there a way to setup the Three.js renderer in such a way that the lookat point of the camera is not in the center of the rendered image?
To clarify: image a scene with just one 1x1x1m cube at ( 0, 0, 0 ). The camera is located at ( 0, 0, 10 ) and the lookat point is at the origin, coinciding with the center of the cube. If I render this scene as is, I might end up with something like this:
normal render
However I'd like to be able to render this scene in such a way that the lookat point is in the upper left corner, giving me something like this:
desired render
If the normal image is 800x600, then the result I envision would be as if I rendered a 1600x1200 image with the lookat in the center and then cropped that normal image so that only the lower right part remains.
Of course, I can change the lookat to make the cube go to the upper left corner, but then I view the cube under an angle, giving me an undesired result like this:
test.moobels.com/temp/cube_angle.jpg
I could also actually render the full 1600x1200 image and hide 3/4 of the image, but one would hope there is a more elegant solution. Does anybody know it?
If you want your perspective camera to have an off-center view, the pattern you need to use is:
camera = new THREE.PerspectiveCamera( for, aspect, near, far );
camera.setViewOffset( fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight );
See the docs: https://threejs.org/docs/#api/cameras/PerspectiveCamera
You can find examples of this usage in this example and this example.
three.js r.73
Here's a simple solution:
Assuming your cube is 4 x 4 x 4, at position 0, 0, 0:
var geometry = new THREE.BoxGeometry( 4, 4, 4 );
var material = new THREE.MeshBasicMaterial( { color: 0x777777 } );
var cube = new THREE.Mesh( geometry, material );
cube.position.set( 0, 0, 0 );
Get cube's position:
var Vx = cube.position.x,
Vy = cube.position.y,
Vz = cube.position.z;
Then deduct by 2 from x position, then add 2 to y and z position, and use the values to create a new Vector3:
var newVx = Vx - 2,
newVy = Vy + 2;
newVz = Vz + 2;
var xyz = new THREE.Vector3(newVx, newVy, newVz)
Then camera lookAt:
camera.lookAt(xyz);
Using console log, it would show that the camera is now looking at -2, 2, 2, which is the upper-left of your cube.
console.log(xyz);

Using raycasting to check the object in front of a Perspective Camera with first person controls

I've got a Perspective Camera and would like to use Raycasting to find the object in front of the player. I can't find any tutorials on how to do this, instead of clicking an object with the mouse pointer which I don't want to do. Where can I find out how to do this, or how do I implement this myself? Or do I just use the raycaster by itself?
This is simple.
Based on the code of the raycasting example with terrain
http://threejs.org/examples/#webgl_geometry_terrain_raycast
And on this reference
http://threejs.org/docs/#Reference/Core/Raycaster
You can see that all you have to do is change the second parameter of the Raycaster constructor to a vector that points in the same direction as the camera does.
So the following code from the example
var mouseX = ( event.clientX / window.innerWidth ) * 2 - 1;
var mouseY = -( event.clientY / window.innerHeight ) * 2 + 1;
var vector = new THREE.Vector3( mouseX, mouseY, camera.near );
// Convert the [-1, 1] screen coordinate into a world coordinate on the near plane
var projector = new THREE.Projector();
projector.unprojectVector( vector, camera );
var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
becomes
var vector = new THREE.Vector3(0, 0, -1);
vector = camera.localToWorld(vector);
vector.sub(camera.position); // Now vector is a unit vector with the same direction as the camera
var raycaster = new THREE.Raycaster( camera.position, vector);
Using this should always create a raycaster that selects objects pointed to by the camera, independent of the type of camera you use, or its controls.

Ray intersection when using morphtargets not working

Slightly complex, so bear with me:
Ray intersect works perfectly when an object has no morphTargets.
When an object has morphTargets only the original position can be intersected, that is to say, if I morph a model from 0,0,0 to 50,50,50 the ray will not intersect with the object at 50,50,50, instead, when I mouse over 0,0,0 I get an intersection (even though the object is no longer there!?).
Is there some sort of flag I need to turn on to make three.js aware that the verts have moved?
Edit, code added.
This makes my mesh and adds it to the objects array (which ray intersect uses):
function createDeer( deerGeometry, materials ) {
mesh = new THREE.MorphAnimMesh( deerGeometry, new THREE.MeshLambertMaterial( { color: 0xE8E8E8, ambient: 0xE8E8E8, morphTargets: true, vertexColors: THREE.FaceColors } ) );
mesh.scale.set( 3, 3, 3 );
mesh.position.set( 0, -3, 0 );
mesh.rotation.set( 0, 0, 0 );
mesh.castShadow = true;
mesh.receiveShadow = true;
mesh.geometry.dynamic = true;
scene.add( mesh );
objects.push( mesh );
}
Ray intersection happens on mouseDown (there's a mouseOver as well, same thing), like I said, the code works fine, it's just intersecting with the original unmorphed mesh:
function onDocumentMouseDown( event ) {
event.preventDefault();
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( objects );
if ( intersects.length > 0 ) {
SELECTED = intersects[ 0 ].object;
for(var i=0; i<objects.length; i++)
{
if(SELECTED.position.x == objects[0].position.x) {
thisObject = i;
}
}
}
var intersects = ray.intersectObject( plane );
container.style.cursor = 'pointer';
}
}
I've decided the problem must be related to the fact that the position of the deer (as in the mesh transform) never changes, however the vertices do move away, and as the ray intersect is comparing object positions perhaps the problem is here?
I've made a pull request that has been merged and fixes this.
Note that for it to work, the boundingSphere of the object needs to contain the full extent of the morphing
The MorphTarget animation takes place entirely on GPU (in the shaders code) while the ray intersection is always computed on CPU. So in fact, there's no easy way to achieve what you're describing here.

Ray intersectObject with Particlesystem ( capture mouse click on ParticleSystem )

Is there any way to capture mouse click in ParticleSystem? With Mesh and Paticle its working fine but if i call intersectObject on a ParicleSystem the intersects length is always 0.
vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
ray.set(camera.position,vector.subSelf( camera.position ).normalize() );
intersects = ray.intersectObjects( particleSystem );
console.log(intersects.length);
Heres is an example with interactive particles: https://dl.dropbox.com/u/4253186/three/examples/webgl_interactive_particles.html
but its not working with the latest version of three.js.
Ray.intersectObjects() does not support ParticleSystem in the current version of three.js (r.53).
So the answer is 'no', unless you modify the library yourself.

Resources