Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First rough integration + ol.view sync + initial demos #16

Merged
merged 42 commits into from Aug 8, 2014
Merged

First rough integration + ol.view sync + initial demos #16

merged 42 commits into from Aug 8, 2014

Conversation

klokan
Copy link
Member

@klokan klokan commented Jul 30, 2014

This PR is made to have our source code directly visible to all memebers of the kick-off. It is not code ready to be merged yet.

It is demonstrating a possible minimalistic version of ol3factory discussed in #6 and #8 with only basic switching between 2D ol3 and 3D cesium with preserved center, resolution and rotation - with sync only during the switch of the view.

Check primarily the source code of the example, deployed at:
http://klokantech.github.io/ol3-cesium/

Before a real code review and merge to master this PR must be significantly improved.
A must have is a compilation via ADVANCED - where we miss ol3 externs. See: #15

* @type {ol.TransformFunction}
* @private
*/
this.toLatLng_ = ol.proj.getTransform(this.view_.getProjection(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toLonLat would sound more correct to me

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks

var visibleMapUnits = meters / circ;
var resolution = visibleMapUnits / this.canvas_.width;

return resolution;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my own knowledge I'd be very interested to fully understand these calcDistanceForResolution_ and calcResolutionForDistance_ functions. Any pointers for me? Thanks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to make the code more easy to read. I hope it's clearer now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice. Thanks a lot for that. The role of the circ variable was not clear to me. Clearer now.

@klokan
Copy link
Member Author

klokan commented Aug 5, 2014

There is a new example for side-by-side live ol.View synchronization and improved 2d/3d switching.
http://klokantech.github.io/ol3-cesium/sidebyside.html

Terrain is turned on - for testing the ol.View sync implementation according #9.

Closure ADVANCED compilation is now applied (blocking #15 closed).

@elemoine
Copy link
Member

elemoine commented Aug 5, 2014

Quick comment: I cannot open this PR's commit pages. I get 404s probably because klokantech/ol3-cesium is a private repo I don't have access to. Any idea on how to solve that problem?

@@ -0,0 +1,28 @@
PLOVR = ./plovr-81ed862.jar
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ol3 we decided to go without Plovr and use the closure-util node package instead. I'd suggest that we do the same for ol3-cesium.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. We are aware of this.

Our target now was to have as fast as possible a correct ADVANCED compilable JavaScript code. We use plovr in the company heavily - this has been fastest for us for the first PR.

Anybody familiar with npm/node closure compiler is welcome to make the switch. Plovr can be deprecated on the ol3cesium and replaced by node package instead.
Pull request after this accepted for master is welcome.

@elemoine
Copy link
Member

elemoine commented Aug 5, 2014

Thanks a lot for putting this together. I think this is a very good base for discussion. I've left a couple of comments in the code (some of which have already been addressed by @petrsloup already). Here's another one:

In the case of side-by-side ol3/cesium (as in this PR's sidebyside.html example) there are two ol3 maps as one ol3 map is required for ol3cesium. That seems weird to me. In that case I would expect to use an ol3 map for the 2D part, a Cesium globe for the 3D part, and ol3-cesium for the synchronizing the view between the map and the globe.

);

var osm = new Cesium.OpenStreetMapImageryProvider();
this.scene_.imageryLayers.addImageryProvider(osm);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defining an initial camera lookAt and adding an OSM imagery provider is assuming too much on the user's intent. This is probably obvious but I thought I could still mention it.

* need to be calculated _at the target_.
*/
if (target) {
var pos = this.cam_.positionWC; //this forces the update
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the difference between reading this.cam_.positionWC and reading this.cam_.position is that reading positionWC has a side-effect (there's a defineProperty getter for it). Why do we need to force an update and use positionWC here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is mainly that positionWC (WC ~ "World Coordinates") can contain different values than position (which is in specific coordinate system of the camera). However, these values should always be equal for Cesium.SceneMode.SCENE3D, which is the only mode we are interested in. So we can probably save some calculations by accessing position directly. I will change this soon.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I do not understand what you mean by "specific system of the camera", but that's probably a sufficient explanation for now :-)

@petrsloup
Copy link
Member

I think I have addressed all the comments from this PR and all the modifications we talked about.
Please review.

The compiled demos can be tested here:
http://klokantech.github.io/ol3-cesium/index.html
http://klokantech.github.io/ol3-cesium/sidebyside.html
http://klokantech.github.io/ol3-cesium/exports.html

@elemoine
Copy link
Member

elemoine commented Aug 6, 2014

Thanks for updating the PR. We will continue reviewing it tomorrow. Our review will be complete by tomorrow night, so we'll probably be able to merge the PR on Friday.

*/
olcs.Camera.prototype.readFromView = function() {
this.distance_ = this.calcDistanceForResolution_(
this.view_.getResolution() || 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this || 0.


// TILT
this.tilt_ = Math.acos(Cesium.Cartesian3.dot(targetNormal,
targetToCamera)) || 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor but for the sake of clarity I'd rather do

var tiltAngle = Math.acos(Cesium.Cartesian3.dot(targetNormal, targetToCamera));
this.tilt_ = isNaN(tiltAngle) ? 0 : tiltAngle;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it looks like that the tilt angle calculated here is not the same angle as the tilt angle on the drawing in #17. Is this correct? What's the reason for this? Is it because you want this angle to stay constant when the distance between the camera and the target changes?

What puzzles us (@fredj, @gberaudo and I) is that after a setTilt the updateCamera function uses tilt_ as follows:

if (this.tilt_) {
  this.cam_.lookUp(this.tilt_);
}

Doing cam.lookUp(this.tilt_) does not make sense to me if tilt_ is the angle between the "target normal" vector and the "target to camera" vector?

Are we missing something here? Thanks for any response.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, updateCamera doing this.cam_.lookUp(this.tilt_) now makes sense to me.

Calling this.cam_.setGeographicPosition(carto) actually resets the direction of the camera (towards the world origin). So by doing this.cam_.lookUp(this.tilt_) we rotate the camera around its right vector to reset the actual tilt angle to its original value.

So the behavior is correct.

What is a bit strange though is that the angle the user passes to setTilt is not the angle between the camera direction and the vector that goes from the world origin to the camera. This is a bit confusing IMO. It is that latter definition of tilt which the user expects to deal with.

@elemoine
Copy link
Member

elemoine commented Aug 7, 2014

Again, thanks for the work on this. We've added more comments in the commits.

There's one comment about setTilt. When calling setTilt the user doesn't expect to be changing the angle "at the ground" (i.e. between the "world origin to target" and the "target to camera" vectors). Instead I think the user expects to change the angle between the "camera to world origin" and the "camera to target" vectors.

Another comment is that in "stack mode" the ol3 view is continuously updated when the user navigates in the globe, and the Cesium camera is continuously updated when the user navigates the 2D map. I think this may cause performance problems for more complex rendering (with vector layers with lots of features for example). In a "stack mode" application – with a 2D/3D switch button – you actually just need to do 2D/3D view conversions when the user clicks the 2D/3D switch button.

We agree to merge this PR when our commit comments are addressed. But we still think that in the end the library should be flexible enough to address different use-cases. The "2D/3D switcher" case, where the 2D/3D views need to be synchronized only when the 2D/3D switcher is pressed, is one of them.

We strongly think that flexibility can be obtained by factoring out code in small core static functions that applications can use. These functions can hide complex math and shorten often written code. Their names and descriptions should completely represent their actions.

@klokan
Copy link
Member Author

klokan commented Aug 8, 2014

Thank you everybody for the review and comments on this PR - and @petrsloup - great job!

Some more points appeared in the last comment:

  1. Tilt angle at camera vs at target/center

We were discussing this again. The user is naturally moving the target/center and this is essential for OLCesium wrapper and interaction with ol.view - camera is beeing manipulated only secondary. If we would use the titl angle assigned to camera it would hugely complicate the calculations and limit us further in the implementation of navigation. We feel it is unnatural and does not really make sense.
We created a new illustration of what is what on the OLCesium camera. It is now part of #8.
For the reference, this is the difference:

  1. No rendering if invisible & lazy sync

To be discussed and resolved as part of #19

I am merging now this PR. Thanks again to everybody!

klokan added a commit that referenced this pull request Aug 8, 2014
First rough integration + ol.view sync + initial demos
@klokan klokan merged commit f363cf2 into openlayers:master Aug 8, 2014
@elemoine
Copy link
Member

elemoine commented Aug 8, 2014

Is your tilt angle the same as Google Earth's "lookAt tilt"? See https://developers.google.com/earth/documentation/camera_control#tilt

@klokan
Copy link
Member Author

klokan commented Aug 8, 2014

It seems so (beside degrees vs radians)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants