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

Cache pickposition #5169

Merged
merged 15 commits into from
Apr 18, 2017
Merged

Cache pickposition #5169

merged 15 commits into from
Apr 18, 2017

Conversation

ateshuseyin
Copy link
Contributor

fixes #5117

@hpinkos
Copy link
Contributor

hpinkos commented Mar 31, 2017

Thanks @ateshuseyin! It looks like you have a jsHint error:

Specs/Scene/SceneSpec.js
line 852  col 68  Unnecessary semicolon.

You can run jsHint locally with npm run jsHint

@lilleyse do you want to review this?

@lilleyse
Copy link
Contributor

Yes, I should be able to review today.

Copy link
Contributor

@lilleyse lilleyse left a comment

Choose a reason for hiding this comment

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

Thanks @ateshuseyin for adding this ability. Just these comments.

@@ -3043,6 +3046,21 @@ define([
* @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported.
*/
Scene.prototype.pickPosition = function(windowPosition, result) {

Copy link
Contributor

@lilleyse lilleyse Mar 31, 2017

Choose a reason for hiding this comment

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

The code added here belongs in pickPositionWorldCoordinates. The test may need to be adjusted for that.

@@ -2616,6 +2616,7 @@ define([
* @private
*/
Scene.prototype.render = function(time) {
pickPositionCache = {}; //clean cache
Copy link
Contributor

Choose a reason for hiding this comment

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

Place this in function render instead.

return cached.clone();
}

return cached;
Copy link
Contributor

Choose a reason for hiding this comment

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

This area can be simplified to return Cartesian2.clone(cached, result). If result is undefined it will create a new Cartesian2. If cached is undefined it will return undefined.

@@ -3043,6 +3046,21 @@ define([
* @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported.
*/
Scene.prototype.pickPosition = function(windowPosition, result) {

if(defined(windowPosition) && pickPositionCache.hasOwnProperty(windowPosition.toString())){
var cached = pickPositionCache[windowPosition.toString()];
Copy link
Contributor

Choose a reason for hiding this comment

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

windowPosition.toString() can be saved to its own variable so it is not computed multiple times.

Copy link
Contributor

Choose a reason for hiding this comment

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

You may want to add a comment somewhere that the cached result could be undefined. This way it is clear to whoever is reading that hasOwnProperty is used instead of just defined.

@@ -3053,6 +3071,9 @@ define([
var cart = projection.unproject(result, scratchPickPositionCartographic);
ellipsoid.cartographicToCartesian(cart, result);
}

pickPositionCache[windowPosition.toString()] = defined(result) ? result.clone() : result;
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment here about using Cartesian2.clone(result)

expect(s.pickPositionWorldCoordinates.calls.count()).toEqual(2);

s.pickPosition(windowPosition);
expect(s.pickPositionWorldCoordinates.calls.count()).toEqual(2);
Copy link
Contributor

Choose a reason for hiding this comment

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

It's fine to just do just one expect(s.pickPositionWorldCoordinates) check at the end.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Second expect is necessary I think. First pickPosition is calculated and call count increment but at second result is returned from cache

Copy link
Contributor

Choose a reason for hiding this comment

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

One check should be fine because if the result is 2 then all the previous steps have used the cache correctly. But I'm also ok with keeping it as-is.


var canvas = s.canvas;
var windowPosition = new Cartesian2(canvas.clientWidth / 2, canvas.clientHeight / 2);
spyOn(s, 'pickPositionWorldCoordinates').and.callThrough();;
Copy link
Contributor

Choose a reason for hiding this comment

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

Extra ; as @hpinkos mentioned.

// position = s.pickPosition(windowPosition);

// expect(s.pickPositionWorldCoordinates.calls.count()).toEqual(1);
// });
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove commented code.

@@ -3024,7 +3025,9 @@ define([

var scratchPickPositionCartographic = new Cartographic();

/**
var pickPositionCache={};
Copy link
Contributor

Choose a reason for hiding this comment

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

Style: var pickPositionCache = {};

Copy link
Contributor

Choose a reason for hiding this comment

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

In the case of multiple scenes, this may be better as a private variable of Scene.

@ateshuseyin
Copy link
Contributor Author

fixed belong to review.

@@ -2523,6 +2525,8 @@ define([
var scratchEyeTranslation = new Cartesian3();

function render(scene, time) {
scene._pickPositionCache = {}; //clean <cache></cache>
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix comment.

@@ -2616,6 +2620,7 @@ define([
* @private
*/
Scene.prototype.render = function(time) {

Copy link
Contributor

Choose a reason for hiding this comment

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

Remove empty line.

@@ -3024,7 +3029,7 @@ define([

var scratchPickPositionCartographic = new Cartographic();

/**
/**
Copy link
Contributor

Choose a reason for hiding this comment

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

Undo this change, the old formatting is consistent with the other comments.

@@ -3043,6 +3048,16 @@ define([
* @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported.
*/
Scene.prototype.pickPosition = function(windowPosition, result) {
var cacheKey;
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned before, the caching belongs in pickPositionWorldCoordinates. For example, both Camera and ScreenSpaceCameraController call it instead of pickPosition.

var cacheKey;

if(defined(windowPosition)){
cacheKey = windowPosition.x + '-' + windowPosition.y;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use toString like before?


if(defined(windowPosition) && this._pickPositionCache.hasOwnProperty(cacheKey)){
return Cartesian2.clone(this._pickPositionCache[cacheKey], result);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

When this code is moved to pickPositionWorldCoordinates the defined(windowPosition) checks here and above won't be needed.

cacheKey = windowPosition.x + '-' + windowPosition.y;
}

if(defined(windowPosition) && this._pickPositionCache.hasOwnProperty(cacheKey)){
Copy link
Contributor

Choose a reason for hiding this comment

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

Style, add space: if (defined(windowPosition)

expect(s.pickPositionWorldCoordinates.calls.count()).toEqual(2);

s.pickPosition(windowPosition);
expect(s.pickPositionWorldCoordinates.calls.count()).toEqual(2);
Copy link
Contributor

Choose a reason for hiding this comment

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

One check should be fine because if the result is 2 then all the previous steps have used the cache correctly. But I'm also ok with keeping it as-is.

s.pickPosition(windowPosition);
expect(s.pickPositionWorldCoordinates.calls.count()).toEqual(2);
});

Copy link
Contributor

Choose a reason for hiding this comment

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

Remove empty line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

First pickPosition calculates and returns undefined. The second one returns undefined from cache. Third calculates a valid Cartesian3 then forth one returns valid value from cache. So both calls are needed to test correctly. Because the flow of undefined and valid results are seperate.

@pjcozzi
Copy link
Contributor

pjcozzi commented Apr 3, 2017

Thanks for this contribution, @ateshuseyin!

@lilleyse please ping me when you think this is ready, I'd like to take a quick look before merging into master.

@ateshuseyin
Copy link
Contributor Author

Thanks cesium. It is great work.

I think all done.

@@ -2954,6 +2958,12 @@ define([
}
//>>includeEnd('debug');

var cacheKey;
Copy link
Contributor

Choose a reason for hiding this comment

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

cacheKey needs to be set.

@ateshuseyin
Copy link
Contributor Author

@lilleyse I think this is last commit :)

@lilleyse
Copy link
Contributor

@pjcozzi this is ready for you to look at.

@@ -2548,6 +2550,8 @@ define([
var scratchEyeTranslation = new Cartesian3();

function render(scene, time) {
scene._pickPositionCache = {}; //clean cache
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we avoid doing this allocation per frame? We are really careful about not doing allocation per vertex, per command, per primitive, etc., but we even try to avoid per frame allocations.

Instead, perhaps set a flag like _pickPositionCacheDirty to true. Then in pickPositionWorldCoordinates, clear the cache and set dirty to false if it was true.

@pjcozzi
Copy link
Contributor

pjcozzi commented Apr 12, 2017

Just that comment. Thanks again @ateshuseyin, nice job with the tests!

@ateshuseyin
Copy link
Contributor Author

@pjcozzi done

@lilleyse
Copy link
Contributor

This looks ready to me, @pjcozzi do you want to merge?

@pjcozzi
Copy link
Contributor

pjcozzi commented Apr 18, 2017

Looks good, but are we sure about all the changes to the .idea/* files that came in with 4354961?

@lilleyse
Copy link
Contributor

I think those are related to the recent Webstorm update, which haven't been incorporated into 3d-tiles yet. I'll merge master into 3d-tiles first to be sure.

@lilleyse
Copy link
Contributor

They aren't in master, so I just reverted those changes.

@pjcozzi
Copy link
Contributor

pjcozzi commented Apr 18, 2017

Thanks @ateshuseyin @lilleyse!

@pjcozzi pjcozzi merged commit 11aa2bc into CesiumGS:master Apr 18, 2017
@ateshuseyin ateshuseyin deleted the cache-pickposition branch May 20, 2017 20:00
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.

Cache pickPosition
4 participants