1

I'm struggling with a problem: I need to position a DIV over a WebGL animation. I rotate a mesh, based on a PlaneGeometry to occupy a rectangular size, then I'd like top position there the DIV, so I need to know what is the X,Y coordinate and the rendered dimensions of the plane.

enter image description here

I've tried the THREE.Projection class, but didn't help, even if I projected the [0] verticle using .projectVector. It computed:

x: -0.1994540991160383
y: 0.17936202821347358
z: 0.9970982652556688

...which was little help to me.

Tibor Szasz
  • 3,028
  • 2
  • 18
  • 23

2 Answers2

1

To project a 3D point position to screen coordinates, relative to the renderer's canvas, do this:

var projector = new THREE.Projector();
var pos = projector.projectVector( position, camera );

var xcoord = Math.round( (  pos.x + 1 ) * canvas.width  / 2 );
var ycoord = Math.round( ( -pos.y + 1 ) * canvas.height / 2 );

where canvas is, in this case, renderer.domElement.

A point in the upper left corner of your visible world will project to ( 0, 0 ).

three.js r.53

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • I looped through each verticle of the plane and the answer should be 125, but no value came close. Or rephrasing the question: how do I find the upper left 3D point position of the plane? – Tibor Szasz Dec 25 '12 at 21:04
  • If I subtract the top left verticle vector from the position vector, the above script gives and incorrect result, What am I missing? – Tibor Szasz Dec 26 '12 at 12:39
  • I don't know what you are missing, because I don't know what you are doing. Can you provide a simple, live example? (jsfiddle) Remember, I can't debug your code for you, but I will try to help. – WestLangley Dec 26 '12 at 15:52
  • I solved it. I thought I explained it well :( I post the answer below. – Tibor Szasz Dec 26 '12 at 17:31
0

I found the solution. The top left point is indeed the 0 index of the plane's vertices, but you have to take into account the already performed transformations as well.

function calculateLayer()
{
    // multiplyVector3 applies the performed transformations to the object's coordinates.
    var topLeft = tubeCard.matrixWorld.multiplyVector3( tubeCard.geometry.vertices[0].clone() );
    // index 24 is the bottom right, because the plane has 4x4 faces
    var bottomRight = tubeCard.matrixWorld.multiplyVector3( tubeCard.geometry.vertices[24].clone() );
    return {
            topLeft: convert3Dto2D( topLeft ),
            bottomRight: convert3Dto2D( bottomRight )
        }
}

function convert3Dto2D( positionVector )
{
    var projector = new THREE.Projector();
    var pos = projector.projectVector( positionVector, camera );

    var xcoord = Math.round( (  pos.x + 1 ) * window.innerWidth  / 2 );
    var ycoord = Math.round( ( -pos.y + 1 ) * window.innerHeight / 2 );

    return { x: xcoord, y: ycoord };
}

So once you have the correct coordinates, applied with the transformations, you just have to use the 3d to 2d conversion thanks to WestLangley.

Tibor Szasz
  • 3,028
  • 2
  • 18
  • 23