Coder Social home page Coder Social logo

2D mode issues about cesium HOT 27 CLOSED

cesiumgs avatar cesiumgs commented on May 23, 2024
2D mode issues

from cesium.

Comments (27)

pjcozzi avatar pjcozzi commented on May 23, 2024

@jktaylor - for the sun light, use affectedByLighting for now. We are working on proper lighting as part of materials, but probably won't be done until the end of the summer.

pickEllipsoid probably shots a ray through the WGS84 ellipsoid, not the 2D map, so I would not expect it to be right. @bagnell - can you take a look?

from cesium.

djone010 avatar djone010 commented on May 23, 2024

Since this is kind of related, I also wanted to ask if there is a way to get a screen pixel location from a globe coordinate?

from cesium.

pjcozzi avatar pjcozzi commented on May 23, 2024

@jktaylor There is not a function to do so, but we welcome such a contribution. Convert from cartographic to cartesian, then create a function on the CentralBody, computeScreenSpacePosition that transforms it from model to window coordinates using code similar to Billboard.prototype.computeScreenSpacePosition. It will actually be less code since we will not need to consider eye and pixel offsets used by billboards, and we can use the model-view-projection matrix to go right to clip coordinates, instead of going to eye coordinates first. @bagnell can provide further guidance.

from cesium.

bagnell avatar bagnell commented on May 23, 2024

@jktaylor You could use the function Transforms.pointToWindowCoordinates that takes the model-view-projection matrix, viewport matrix and the point in model coordinates to get the point in window coordinates.

Also, @pjcozzi is right about pickEllipsoid only working in 3D mode, but I'm working on adding picking the maps in 2D and Columbus View.

from cesium.

djone010 avatar djone010 commented on May 23, 2024

@bagnell I tried what you suggested in the sandbox "Show cartographic position on mouse-over", and it is not giving the correct answer.

function(movement) {
var p = scene.getCamera().pickEllipsoid(ellipsoid, movement.endPosition);
if (p) {
var d = Cesium.Math.cartographic2ToDegrees(ellipsoid.toCartographic2(p));
label.setShow(true);
label.setText("(" + d.longitude.toFixed(2) + ", " + d.latitude.toFixed(2) + ")");
label.setPosition(p);
var px = Cesium.Transforms.pointToWindowCoordinates(scene.getUniformState().getModelViewProjection(),scene.getUniformState().getViewProjection(),ellipsoid.cartographicDegreesToCartesian(d));
console.log("pToWindow: "+px);
console.log("orig: "+movement.endPosition);
} else {
label.setText("");
}
}, Cesium.MouseEventType.MOVE);

I'm seeing in console

pToWindow: (-0.028427104913234247, 0.1603221355997794)
orig: (813, 574)

What am I doing wrong?

from cesium.

djone010 avatar djone010 commented on May 23, 2024

Nevermind, I should have read the API more closely. It should have been getViewportTransformation()

Cesium.Transforms.pointToWindowCoordinates(scene.getUniformState().getModelViewProjection(),scene.getUniformState().getViewportTransformation(),ellipsoid.cartographicDegreesToCartesian(d))

Thanks a lot for your help!

from cesium.

djone010 avatar djone010 commented on May 23, 2024

@bagnell pointToWindowCoordinates doesn't exactly give me what I expected, but I can easily fix it. In my example above, you can see that the y screen coordinate that I get back is not the same as the y that was passed in from the mouse event. I think it is because cesium considers y=0 to be at the bottom of the screen and the mouse event considers y=0 the top of the screen.

from cesium.

bagnell avatar bagnell commented on May 23, 2024

@jktaylor The changes for picking the ellipsoid have been merged into master. You should use Scene.pickEllipsoid instead of Camera.pickEllipsoid.

The origin in window coordinates is the bottom left for WebGL and the top left for the browser. I'm going to submit another issue to change public functions to use the top left because that is what most people are expecting.

from cesium.

djone010 avatar djone010 commented on May 23, 2024

@bagnell we are still seeing an issue in 2D mode where the cartographic degrees for longitude is about 110 degrees east of where it should be. You can easily reproduce this in the sandbox example for "show cartographic position on mouse over" by pasting this at the top.

transitioner = new Cesium.SceneTransitioner(scene);
transitioner.to2D();

from cesium.

bagnell avatar bagnell commented on May 23, 2024

@jktaylor The issue was in creating a pick ray with an orthographic frustum. I pushed the fix to master.

from cesium.

djone010 avatar djone010 commented on May 23, 2024

@bagnell Looks good, Thanks for the quick fix!

There is also a problem with the Camera class viewextent function when in 2D mode. The map flips sideways very strangely. See what I mean in the Sandbox Camera "View an extent" example:

transitioner = new Cesium.SceneTransitioner(scene);
transitioner.to2D();

from cesium.

bagnell avatar bagnell commented on May 23, 2024

@jktaylor I added new functions to the camera to view extents in 2D and Columbus view; however, you should now use Scene.viewExtent which will call the correct function depending on which mode the scene is in. The changes have been merged into master.

from cesium.

djone010 avatar djone010 commented on May 23, 2024

@bagnell I finally got a chance to check out these enhancements that you have made, and I still have a few issues.

Not a major problem at the moment, but flyto does not work in 2D mode as in the fly to Los Angeles example in the sandbox.

ViewExtent works in 2D mode, however we are removing the camera in order to let the user mouse drag a rectangle to create the extent in which to zoom to. When we add the camera back, the camera is "glued" to this extent and always returns to it after trying to move away. You can easily reproduce this in the sandbox with the following code snippet.

var transitioner = new Cesium.SceneTransitioner(scene, ellipsoid);

var west = Cesium.Math.toRadians(-77.0);
var south = Cesium.Math.toRadians(38.0);
var east = Cesium.Math.toRadians(-72.0);
var north = Cesium.Math.toRadians(42.0);

var extent = new Cesium.Extent(west, south, east, north);
transitioner.to2D();
scene.getCamera().getControllers().removeAll();
scene.viewExtent(extent, ellipsoid);
scene.getCamera().getControllers().add2D(scene.scene2D.projection);

Is there a better way that we can temporarily deactivate the camera controls without removing them altogether?

from cesium.

djone010 avatar djone010 commented on May 23, 2024

Also, before this change we could zoom to a full view over the globe centered at point x,y by adding a 45 degree buffer around the point, but that no longer works. The resulting camera view is no longer centered at point x,y. Is there a better way we could center the globe at a given point that would be compatible with all view modes?

from cesium.

bagnell avatar bagnell commented on May 23, 2024

@jktaylor I fixed the problem with adding the 2D mouse control after calling viewExtent in branch "camera-2d". It should be in master soon. Unfortunately, there isn't a better way to temporarily deactivate a camera control, but in the future we want to redo how to add/remove/configure the camera controls.

I'm not sure I understand your second post. You have a point in 2D and you want to set the camera position/direction/up with that point in all modes?

from cesium.

djone010 avatar djone010 commented on May 23, 2024

@bagnell What I mean is, we were using the viewextent function to show a full view of the globe with the camera centered at a given longitude, latitude. We did this by creating a 45 degree window around the position and calling viewextent with those bounds. Now that does not work anymore except for nice cases like longitude:0, latitude:0. I wish there was a centerAt(position) function that would pan the camera to the given position without changing zoom level and work for all view modes.

from cesium.

djone010 avatar djone010 commented on May 23, 2024

Or better yet, a function like the flyto that goes to a x,y,z without the animation.

from cesium.

djone010 avatar djone010 commented on May 23, 2024

Another issue with 2D mode (and Columbus view as well) Transforms.pointToWindowCoordinates doesn't give the correct answer. Maybe I'm not using it correctly, but it works fine in 3D mode. Paste this into the _handleMouseMove of CesiumViewerWidget and try the other modes.

_handleMouseMove : function(movement) {
var p = this.scene.pickEllipsoid(movement.endPosition,this.ellipsoid);
if (p) {
var d = this.ellipsoid.cartesianToCartographic(p);
var px = Transforms.pointToWindowCoordinates(this.scene.getUniformState().getModelViewProjection(),this.scene.getUniformState().getViewportTransformation(),this.ellipsoid.cartographicToCartesian(d));
px.y=this.canvas.clientHeight-px.y;
console.log("pToWindow: "+px);
console.log("orig: "+movement.endPosition);
}

.....

from cesium.

bagnell avatar bagnell commented on May 23, 2024

pickEllipsoid returns a cartesian in world coordinates that is a point on the surface of the ellipsoid centered at the origin in 3D. That is why converting to/from a cartographic works, but it isn't the point you want to use for finding the window coordinates. So what you need to do is project it to 2D and transform it to the yz-plane. Paste this code into the Skeleton Example:

handler.setMouseAction(function(movement) {
    var p = scene.pickEllipsoid(movement.endPosition,ellipsoid);
    if (p) {
        if (scene.mode !== Cesium.SceneMode.SCENE3D) {
            p = scene.scene2D.projection.project(ellipsoid.cartesianToCartographic(p));
            p = new Cesium.Cartesian3(p.z, p.x, p.y);
        }
        var px = Cesium.Transforms.pointToWindowCoordinates(scene.getUniformState().getViewProjection(), scene.getUniformState().getViewportTransformation(), p);
        px.y=canvas.clientHeight-px.y;
        console.log("pToWindow: "+px);
        console.log("orig: "+movement.endPosition);
    }
}, Cesium.MouseEventType.MOVE);

You can press "1", "2", and "3" to transition to 2D, Columbus view and 3D.

from cesium.

bagnell avatar bagnell commented on May 23, 2024

I forgot to mention that there's another issue for setting camera orientation over a flight path. It'll be easier to get the camera flight into 2D/CV once that is finished.

from cesium.

djone010 avatar djone010 commented on May 23, 2024

Thanks for clearing that up Dan. That works great now!

from cesium.

djone010 avatar djone010 commented on May 23, 2024

@bagnell I am seeing a very strange issue with the same code snippet inside of the cesium viewer. When you drag dynamic data into the viewer, the pointToWindowCoordinates function is totally off in 3D mode, but is fine in the other views. Paste this inside _handleMouseMove of CesiumViewerWidget and drop in the simple.czml.

var p = this.scene.pickEllipsoid(movement.endPosition,this.ellipsoid);
if (p) {
if (this.scene.mode !== SceneMode.SCENE3D) {
p = this.scene.scene2D.projection.project(this.ellipsoid.cartesianToCartographic(p));
p = new Cartesian3(p.z, p.x, p.y);
}
var d = this.ellipsoid.cartesianToCartographic(p);
var px = Transforms.pointToWindowCoordinates(this.scene.getUniformState().getModelViewProjection(),this.scene.getUniformState().getViewportTransformation(),this.ellipsoid.cartographicToCartesian(d));
px.y=this.canvas.clientHeight-px.y;
console.log("pToWindow: "+px);
console.log("orig: "+movement.endPosition);
}

from cesium.

djone010 avatar djone010 commented on May 23, 2024

Oh, I also had to add SceneMode into the imports by the way.

from cesium.

bagnell avatar bagnell commented on May 23, 2024

In the call to pointToWindowCoordinates, use this.scene.getUniformState().getViewProjection() instead of this.scene.getUniformState().getModelViewProjection() like in the code I posted above :). The model matrix gets set to the model matrix of the primitive before rendering each primitive (in this case probably the satellite marker) but doesn't get reset to the identity. The model matrix transforms a point from model coordinates to world coordinates. But this doesn't matter in your case because you already have a point in world coordinates so you just need the view-projection matrix.

from cesium.

djone010 avatar djone010 commented on May 23, 2024

Oh sorry, I did not notice that difference. Works great now! Thanks again for your help and patience.

from cesium.

bagnell avatar bagnell commented on May 23, 2024

Thank you for posting the bugs you find, especially with code that demonstrates it. I find it difficult to test all of the camera features across all of the view modes for consistency and I appreciate the help.

For the view extent problem you are having, I plan to add an optional height parameter to the function. Would that fix your problem? But I'm not sure when I can get to it. I have to spend some time working on another project.

from cesium.

djone010 avatar djone010 commented on May 23, 2024

I know how hard it can be to reproduce or understand an issue someone is seeing, so I try to provide clear examples. Then you don't have to waste your time trying to figure out what my issue even is.

I'm just needing something like a scene.view(position) where x and y are positions on the globe's surface and z is the altitude. The flyto does this, but I would like to do it without the animation. Using the flyto with a very short animation time looks ok, but an instant switch would be nicer. I would try to contribute this, but I don't quite understand all of the 3D math logic.

I think I will close this now because the main 2D viewing issues that I brought up seem to be resolved now.

from cesium.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.