Projecting point to screen coords in Columbus/2D view

Today we added support to switch between 3D and the other projection modes.

However all code that we had where we overlayed HTML content on top of Cesium using world to screenspace conversion produces wrong results in non-3D mode.

Here’s the code I’m using:

var frustum = this._camera.frustum;

    var model = Cesium.Matrix4.IDENTITY;
   
    var view = this._camera.viewMatrix;
    var projection = frustum.projectionMatrix;
    var modelView = new Cesium.Matrix4();
    Cesium.Matrix4.multiply(view, model, modelView);
    var modelViewProjectionMatrix = new Cesium.Matrix4();
    Cesium.Matrix4.multiply(projection, modelView, modelViewProjectionMatrix);
    var viewportTransformation = new Cesium.Matrix4();
    Cesium.Matrix4.computeViewportTransformation({ x : 0, y:0,  width : viewportWidth, height : viewportHeight}, 0.0, 1.0, viewportTransformation);
  
    var tempPos = Cesium.Transforms.pointToWindowCoordinates(modelViewProjectionMatrix, viewportTransformation, `this.position`);

``

This code works fine for 3D, why it produces wrong results in Columbus or 2D mode?
Every overlayed HTML element appears in the wrong place.

Also, is there any easier way to do this, withhout having to manually do all those matrix multiplications?
Why the Scene class does not have some method that projects any Cartesian or Carthographic to screen coords?

I believe you’re looking for SceneTransforms.wgs84ToWindowCoordinates:

http://cesiumjs.org/Cesium/Build/Documentation/SceneTransforms.html

SceneTransforms.wgs84ToWindowCoordinates is what you are looking for. I agree, it should probably be on the scene itself, I wrote up https://github.com/AnalyticalGraphicsInc/cesium/issues/2645 so this gets taken care of in the future.

Thank you both, that’s it, works fine for all 3 projection modes.

It returns an inverted Y coordinate though, is that expected?
To workaround this, I currently do something like
result.y = viewportHeight - result.y;

While HTML coordinates start in the top left, WebGL coordinates start in the bottom right. I we automatically adjusted this everywhere it matters, but apparently not. When we do expose a function on scene, I’ll be sure that it is top left, since that’s what everyone expects. Thanks.