Jump to content

Converting 3D vertex to 2D point on screen


joshcamas
 Share

Recommended Posts

You have to project it with this function:

BABYLON.Vector3.Project(vector, world, transform, viewport)

vector is your 3d vector you want to transform

world can be set to identity unless your vector3 is expressed in object local world

transform can be get from the scene with scene.getTransformMatrix()

the viewport is defined on your camera: camera.viewport.toGlobal(engine)

 

Hope this helps:)

Link to comment
Share on other sites

  • 5 months later...

Did not really see a good match for this being added to repository.  Might be think out loud, sorry.   Let's say something like this is in Camera:

public getWindowCoordinateFor(target : Vector3) : Vector3{    return Vector3.Project(target, Matrix.Identity(), this._scene.getTransformMatrix(), this.viewport.toGlobal(this._scene.getEngine()) );}

I know the positions of the front corners of a dialog panel.

public getFourCorners() : {topLeft : BABYLON.Vector3; botLeft : BABYLON.Vector3; topRight : BABYLON.Vector3; botRight : BABYLON.Vector3} {    return {        topLeft  : new BABYLON.Vector3(this._actualBelowOriginX, this._actualAboveOriginY, 0).addInPlace(this.position),        botLeft  : new BABYLON.Vector3(this._actualBelowOriginX, this._actualBelowOriginY, 0).addInPlace(this.position),        topRight : new BABYLON.Vector3(this._actualAboveOriginX, this._actualAboveOriginY, 0).addInPlace(this.position),        botRight : new BABYLON.Vector3(this._actualAboveOriginX, this._actualBelowOriginY, 0).addInPlace(this.position)    }; }

My first order of business is ensuring that the combination of radius (using arc rotate camera) and camera viewport do not chop off part.  What would getWindowCoordinateFor() return if a coordinate would not currently show?

Link to comment
Share on other sites

Or would this implementation accurately show how far off screen a point was as well?

/**  * Determine where a point would be drawn in the window by this camera * @param {Vector3} target - the point to test * @return {Vector3} If the point would not currently be within the window, a negative *  value would be returned of how far off it is.  ignore Z element. */public getWindowCoordinateFor(target : Vector3) : Vector3{     var engine = this._scene.getEngine()     var ret = Vector3.Project(target, Matrix.Identity(), this._scene.getTransformMatrix(), this.viewport.toGlobal(engine) );     if (ret.x > engine.getRenderWidth() ){         ret.x = engine.getRenderWidth() - ret.x;     }     if (ret.y > engine.getRenderHeight() ){         ret.y = engine.getRenderHeight() - ret.y;     }                 return ret; }
Link to comment
Share on other sites

Not looking good, when the panel clearly was too wide to fit was compared, results were "wrong":

post-8492-0-39299100-1427911948.png

This got:

topLeft : {X: -8.94 Y: 5.4 Z:0}, coords: {X: 78.62  Y:262.19 Z:0.96}botLeft : {X: -8.94 Y:-5.4 Z:0}, coords: {X: 78.72  Y:651.03 Z:0.96}topRight: {X:  8.94 Y: 5.4 Z:0}, coords: {X: 722.23 Y:262.10 Z:0.96}botRight: {X:  8.94 Y:-5.4 Z:0}, coords: {X: 722.14 Y:651.12 Z:0.96}

Of course, it could just be my screw up.  Think I am better off though determining the widest and highest panel that will fit at a given fixed distance from the camera.  When a panel is displayed, scale / position to fit.  How to figure that out?  2 loops (width / height) using this, increasing till too big.  Any better way?

Link to comment
Share on other sites

  • 2 months later...

I simply tried to find 2D point in browser screen for a Mesh in my scene . I could see the mesh center position was right in middle of the camera viewport (canvas view in brower). But doing following isn't giving correct output

 

var p = BABYLON.Vector3.Project(mesh.getAbsolutePosition(), BABYLON.Matrix.Identity(), scene.getTransformMatrix(), camera.viewport.toGlobal(engine));

 

result : 

p.x= 298.332677959695

p.y= 13648.96603919772

 

My screen resolution is 1366 x 768 . I am opening this in chrome and my canvas hosting babylon is beginning at 75px from top and is upto 80% of screen in width. 

Link to comment
Share on other sites

I am basically trying to replicate functionality of  "clickable lables" of debug layer. Where a label would appear at center of mesh. (But obviously with my own info instead of mesh name) 

 

So for that, I think the above line of code is right and that mesh.getAbsolutePosition()  should give me the position of center of mesh in world system. 

 

I found and checked that example in playground from this thread. And I think I am doing same thing. But getting weird out put . 

Could it be because my meshs are too large  ? They are like 1800 x 4000  unit. I know it shouldn't be . But just speculating it. 

Link to comment
Share on other sites

Hi Temechon , 

 

getAbsolutePosition is not the problem. It is not that it is giving wrong position . The problem is the result of Vector3.Project() method. 

 

Please check my original post below: 

 

I simply tried to find 2D point in browser screen for a Mesh in my scene . I could see the mesh center position was right in middle of the camera viewport (canvas view in brower). But doing following isn't giving correct output

 

var p = BABYLON.Vector3.Project(mesh.getAbsolutePosition(), BABYLON.Matrix.Identity(), scene.getTransformMatrix(), camera.viewport.toGlobal(engine));

 

result : 

p.x= 298.332677959695

p.y= 13648.96603919772

 

My screen resolution is 1366 x 768 . I am opening this in chrome and my canvas hosting babylon is beginning at 75px from top and is upto 80% of screen in width. 

 

Link to comment
Share on other sites

Hi dsman. I don't know if I understood right, but I'll tell you a problem with projection that i found and solved it.

If your canvas renderer haven't the same resolution like your device, the function "BABYLON.Vector3.Project" works wrong in Chrome, in firefox works well.

So if you modify from html your canvas properties width and height (it means that you no use 100% values) or from js, or if you use function like:

hardwareScalingLevel = 1.3;scene.getEngine().setHardwareScalingLevel(hardwareScalingLevel);

and hardwareScalingLevel have a different value than 1, the function "BABYLON.Vector3.Project" wil not works very well in Chrome.

A possible solution, after projection, divide your vector by  hardwareScalingLevel.




			
		
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...