-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Cache pickposition #5169
Changes from 5 commits
c19e304
5a5e386
f1eb982
7dbe7af
ca9943e
6221b4d
d6baa02
0286fa4
e1f1fd1
3f7f48d
b7037d0
4354961
8003650
5ea9b54
e92cebd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -321,6 +321,8 @@ define([ | |
this._cameraStartFired = false; | ||
this._cameraMovedTime = undefined; | ||
|
||
this._pickPositionCache = {}; | ||
|
||
/** | ||
* Exceptions occurring in <code>render</code> are always caught in order to raise the | ||
* <code>renderError</code> event. If this property is true, the error is rethrown | ||
|
@@ -2523,6 +2525,8 @@ define([ | |
var scratchEyeTranslation = new Cartesian3(); | ||
|
||
function render(scene, time) { | ||
scene._pickPositionCache = {}; //clean <cache></cache> | ||
|
||
if (!defined(time)) { | ||
time = JulianDate.now(); | ||
} | ||
|
@@ -2616,6 +2620,7 @@ define([ | |
* @private | ||
*/ | ||
Scene.prototype.render = function(time) { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove empty line. |
||
try { | ||
render(this, time); | ||
} catch (error) { | ||
|
@@ -3024,7 +3029,7 @@ define([ | |
|
||
var scratchPickPositionCartographic = new Cartographic(); | ||
|
||
/** | ||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Undo this change, the old formatting is consistent with the other comments. |
||
* Returns the cartesian position reconstructed from the depth buffer and window position. | ||
* <p> | ||
* The position reconstructed from the depth buffer in 2D may be slightly different from those | ||
|
@@ -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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned before, the caching belongs in |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code added here belongs in |
||
if(defined(windowPosition)){ | ||
cacheKey = windowPosition.x + '-' + windowPosition.y; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not use |
||
} | ||
|
||
if(defined(windowPosition) && this._pickPositionCache.hasOwnProperty(cacheKey)){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style, add space: |
||
return Cartesian2.clone(this._pickPositionCache[cacheKey], result); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When this code is moved to |
||
|
||
result = this.pickPositionWorldCoordinates(windowPosition, result); | ||
if (defined(result) && this.mode !== SceneMode.SCENE3D) { | ||
Cartesian3.fromElements(result.y, result.z, result.x, result); | ||
|
@@ -3053,6 +3068,9 @@ define([ | |
var cart = projection.unproject(result, scratchPickPositionCartographic); | ||
ellipsoid.cartographicToCartesian(cart, result); | ||
} | ||
|
||
this._pickPositionCache[cacheKey] = Cartesian2.clone(result); | ||
|
||
return result; | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -838,6 +838,43 @@ defineSuite([ | |
}); | ||
}); | ||
|
||
it('pickPosition caches results per frame',function(){ | ||
var s = createScene(); | ||
if (!s.pickPositionSupported) { | ||
return; | ||
} | ||
|
||
var rectangle = Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0); | ||
s.camera.setView({ destination : rectangle }); | ||
|
||
var canvas = s.canvas; | ||
var windowPosition = new Cartesian2(canvas.clientWidth / 2, canvas.clientHeight / 2); | ||
spyOn(s, 'pickPositionWorldCoordinates').and.callThrough(); | ||
|
||
expect(s).toRenderAndCall(function() { | ||
s.pickPosition(windowPosition); | ||
expect(s.pickPositionWorldCoordinates).toHaveBeenCalled(); | ||
|
||
s.pickPosition(windowPosition); | ||
expect(s.pickPositionWorldCoordinates.calls.count()).toEqual(1); | ||
|
||
var rectanglePrimitive = createRectangle(rectangle); | ||
rectanglePrimitive.appearance.material.uniforms.color = new Color(1.0, 0.0, 0.0, 1.0); | ||
|
||
var primitives = s.primitives; | ||
primitives.add(rectanglePrimitive); | ||
}); | ||
|
||
expect(s).toRenderAndCall(function() { | ||
s.pickPosition(windowPosition); | ||
expect(s.pickPositionWorldCoordinates.calls.count()).toEqual(2); | ||
|
||
s.pickPosition(windowPosition); | ||
expect(s.pickPositionWorldCoordinates.calls.count()).toEqual(2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's fine to just do just one There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
}); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove empty line. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
}); | ||
|
||
it('pickPosition throws without windowPosition', function() { | ||
expect(function() { | ||
scene.pickPosition(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix comment.