Comments (27)
@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.
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.
@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.
@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.
@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.
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.
@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.
@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.
@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.
@jktaylor The issue was in creating a pick ray with an orthographic frustum. I pushed the fix to master.
from cesium.
@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.
@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.
@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.
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.
@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.
@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.
Or better yet, a function like the flyto that goes to a x,y,z without the animation.
from cesium.
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.
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.
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.
Thanks for clearing that up Dan. That works great now!
from cesium.
@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.
Oh, I also had to add SceneMode into the imports by the way.
from cesium.
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.
Oh sorry, I did not notice that difference. Works great now! Thanks again for your help and patience.
from cesium.
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.
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)
- use request.cancelFunction ,but Cesium.Cesium3DTileset.fromUrl not abort HOT 1
- When loading 3D Tiles, there is an issue where some random tiles’ b3dm data cannot be loaded HOT 2
- Polyline Entity is not rendered in request render mode
- The problem of 3dtileset being obstructed by terrain. HOT 4
- Having trouble resolving compilation errors when installing version 1.115 of Cesium in Vue3 using npm. HOT 2
- viewer.ready is undefined HOT 1
- async version of Resource Proxy getURL HOT 3
- 3D models rendering is wrong with vertical exaggeration above 1 HOT 6
- Add support for glTF KHR_materials_specular extension
- Turn off vertical exaggeration for some Models in the Scene HOT 4
- Cesium Install Fails on Gentoo @Playwright HOT 3
- Create points and billboards set different colors, execute clear all entities, and then create again, the color of the point will apply the color of the billboard HOT 1
- How can set Material class->fabric->uniforms->texture in repeat Mode ?default is clamp HOT 1
- Billboards rendering partially in 2D at particular zoom level HOT 1
- strokeWidth setting does not take effect HOT 2
- Add serial numbers to each demo in Sandcastle HOT 1
- Two node_modules directories need to be added to.gitignore HOT 3
- Cesium3DTileset flickers in large data. HOT 3
- Add `cspell` checking
- Orthographic camera projection HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cesium.