1
votes

In three.js, I create a plane:

var planGeom = new THREE.PlaneGeometry( 5,5,1,1 );
var planMat = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
var plan = new THREE.Mesh( planGeom, planMat );

Then I set the vertices coordinates :

for(var i=0;i<4;i++){
    planGeom .vertices[i].x =  myCoordsTab[i].x;   
    planGeom .vertices[i].y =  myCoordsTab[i].y;
    planGeom .vertices[i].z =  myCoordsTab[i].z;
}

And finally :

scene.add( plan );

The plane appears at the good position in the 3D scene but when I output its position :

console.log(plan.position.x+' '+plan.position.y+' '+plan.position.z);

I get (0,0,0).

Then, when I try to check if I click on that plane with :

var vector = new THREE.Vector3( mousex, mousey, 0.5 );
projector = new THREE.Projector();
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( scene.children );

it always returns that I clicked on the plane, wherever I clicked in the scene. I have no problem to check the clicks with a SphereGeometry for example.

So how to check a click on a PlaneGeometry if it (apparently) always stays in (0,0,0), which makes that all clicks are considered to be on the plane?

I use three.js 53, a very old version I know, but I work on a big project I started long time ago and there are too much things to change with the last version, so I hope that problem can be solved in version 53.

EDIT :

Using

plan.geometry.verticesNeedUpdate = true;
plan.geometry.computeCentroids();

I have now something which works but not in all cases. I have :

camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );

If I define the vertices of my PlaneGeometry like that :

planGeom .vertices[0].x =  50;
planGeom .vertices[0].y =  20;
planGeom .vertices[0].z =  -20;

planGeom .vertices[1].x =  50;
planGeom .vertices[1].y =  20;
planGeom .vertices[1].z =  20;

planGeom .vertices[2].x =  50;
planGeom .vertices[2].y =  -20;
planGeom .vertices[2].z =  -20;

planGeom .vertices[3].x =  50;
planGeom .vertices[3].y =  -20;
planGeom .vertices[3].z =  20;

the plane is in front of the camera (at distance 50, I can see the whole plane) and intersectObjects returns that I click on the plane wherever I click in the scene, and returns for each click :

(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z) = (0, 0, 0)

But if I define it like :

planGeom .vertices[0].x =  -20;
planGeom .vertices[0].y =  20;
planGeom .vertices[0].z =  -50;

planGeom .vertices[1].x =  20;
planGeom .vertices[1].y =  20;
planGeom .vertices[1].z =  -50;

planGeom .vertices[2].x =  -20;
planGeom .vertices[2].y =  -20;
planGeom .vertices[2].z =  -50;

planGeom .vertices[3].x =  20;
planGeom .vertices[3].y =  -20;
planGeom .vertices[3].z =  -50;

the plane is on the left of the camera and intersectObjects returns exactly the coordinates of the 3D point I click on and only when I click on the plane; one click on each corner returns the coordinates of the corresponding vertex. For example :

(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z) = (planGeom .vertices[0].x, planGeom .vertices[0].y, planGeom .vertices[0].z)

A click in the center of the plane gives :

(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z) = (0, 0, -50)

So now, I wonder why it doesn't work in all cases? I will do a simple example, which will be more simple than all those explanations :).

EDIT

Here is an example : the plane you see first, in front of the camera, returns an intersection for every click in the scene. The second plane, on the left (drag the scene to rotate), returns a good intersection point. http://jsfiddle.net/9ggk00so/1/

EDIT

Working code : http://jsfiddle.net/9ggk00so/3/

Indeed, one instruction was missing :

plan.geometry.verticesNeedUpdate = true;
plan.geometry.computeFaceNormals();//ok with that one
plan.geometry.computeCentroids();
1
The plane“s position is correct at (0,0,0), what do you expect the 'real' position to be? I guess you just want the world position of the intersection point when raycasting at your deformed plane? - Falk Thiele
@FalkThiele In fact, I expect to have the center of the quadrilateral defined by the new four vertices. I don't understand why it is (0,0,0) since the PlaneGeometry doesn't seem to be an infinite plan but a limited quadrilateral in space. (threejs.org/docs/#Reference/Extras.Geometries/PlaneGeometry) - SteveTJS
You are modifying the position of the geometry, which can be different than the position of the mesh. You can retrieve the center of the boundingBox or boundingSphere of your geometry if that is what you are looking for. - Falk Thiele
@FalkThiele Not really what I want. I edited my post for more precisions. - SteveTJS

1 Answers

0
votes

The objects position shouldn't matter at all for the intersection check. The geometry is more important in this case. After you updated the vertices array you should set planGeom.verticesNeedUpdate = true;.

Geometry Reference

You just moved the vertices in the plane's local coordinate system, but not the plane in the world coordinate system. So, the plane's matrix didn't change and your console.log gives you (0,0,0).

EDIT:

Maybe the vector for the raycaster is wrong. Are mousex and mousey direct from the mouse event? I'm missing those lines:

var mousex = (event.clientX / SCREEN_WIDTH) * 2 - 1;
var mousey =  - (event.clientY / SCREEN_HEIGHT) * 2 + 1;

var vector = new THREE.Vector3(mousex, mousey, 0.5);

// if your canvas doesn't fill the page
// you need to determine the offset of the canvas and consider it as follows

var mousex = ((event.clientX - offsetX) / SCREEN_WIDTH) * 2 - 1;
var mousey = - ((event.clientY - offsetY) / SCREEN_HEIGHT) * 2 + 1;

var vector = new THREE.Vector3(mousex, mousey, 0.5);

Raycaster Reference