diff --git a/.idea/cesium.iml b/.idea/cesium.iml index 5ecdb1a3e790..075b2a75ef2b 100644 --- a/.idea/cesium.iml +++ b/.idea/cesium.iml @@ -9,4 +9,4 @@ - \ No newline at end of file + diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml index d45df048bf58..4bb85da06f3a 100644 --- a/.idea/jsLibraryMappings.xml +++ b/.idea/jsLibraryMappings.xml @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/.idea/runConfigurations/Run_tests.xml b/.idea/runConfigurations/Run_tests.xml index 4a52554ce6db..fb0f97e40d3d 100644 --- a/.idea/runConfigurations/Run_tests.xml +++ b/.idea/runConfigurations/Run_tests.xml @@ -7,4 +7,4 @@ - \ No newline at end of file + diff --git a/CHANGES.md b/CHANGES.md index b93d70feaacf..8f6d9fa25aad 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Change Log * Fixed issue with displaying `MapboxImageryProvider` default token error message [#5191](https://github.com/AnalyticalGraphicsInc/cesium/pull/5191) * Added a `depthFailMaterial` property to line entities, which is the material used to render the line when it fails the depth test. [#5160](https://github.com/AnalyticalGraphicsInc/cesium/pull/5160) * Upgrade FXAA to version 3.11. [#5200](https://github.com/AnalyticalGraphicsInc/cesium/pull/5200) +* `Scene.pickPosition` now caches results per frame to increase performance [#5117](https://github.com/AnalyticalGraphicsInc/cesium/issues/5117) * Fix billboards not initially clustering. [#5208](https://github.com/AnalyticalGraphicsInc/cesium/pull/5208) ### 1.32 - 2017-04-03 diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 33b8cfec3b26..d0bcf630c963 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -321,6 +321,9 @@ define([ this._cameraStartFired = false; this._cameraMovedTime = undefined; + this._pickPositionCache = {}; + this._pickPositionCacheDirty = false; + this._minimumDisableDepthTestDistance = 0.0; /** @@ -2548,6 +2551,8 @@ define([ var scratchEyeTranslation = new Cartesian3(); function render(scene, time) { + scene._pickPositionCacheDirty = true; + if (!defined(time)) { time = JulianDate.now(); } @@ -2979,6 +2984,15 @@ define([ } //>>includeEnd('debug'); + var cacheKey = windowPosition.toString(); + + if (this._pickPositionCacheDirty){ + this._pickPositionCache = {}; + this._pickPositionCacheDirty = false; + } else if (this._pickPositionCache.hasOwnProperty(cacheKey)){ + return Cartesian3.clone(this._pickPositionCache[cacheKey], result); + } + var context = this._context; var uniformState = context.uniformState; @@ -3040,10 +3054,12 @@ define([ uniformState.update(this.frameState); } + this._pickPositionCache[cacheKey] = Cartesian3.clone(result); return result; } } + this._pickPositionCache[cacheKey] = undefined; return undefined; }; @@ -3078,6 +3094,7 @@ define([ var cart = projection.unproject(result, scratchPickPositionCartographic); ellipsoid.cartographicToCartesian(cart, result); } + return result; }; diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index eed4a60940bf..74c8141709db 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -33,6 +33,7 @@ defineSuite([ 'Scene/Scene', 'Scene/ScreenSpaceCameraController', 'Scene/TweenCollection', + 'Scene/SceneTransforms', 'Specs/createCanvas', 'Specs/createScene', 'Specs/equals', @@ -72,6 +73,7 @@ defineSuite([ Scene, ScreenSpaceCameraController, TweenCollection, + SceneTransforms, createCanvas, createScene, equals, @@ -838,6 +840,41 @@ defineSuite([ }); }); + it('pickPosition caches results per frame',function(){ + if (!scene.pickPositionSupported) { + return; + } + + var rectangle = Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0); + scene.camera.setView({ destination : rectangle }); + + var canvas = scene.canvas; + var windowPosition = new Cartesian2(canvas.clientWidth / 2, canvas.clientHeight / 2); + spyOn(SceneTransforms, 'transformWindowToDrawingBuffer').and.callThrough(); + + expect(scene).toRenderAndCall(function() { + scene.pickPosition(windowPosition); + expect(SceneTransforms.transformWindowToDrawingBuffer).toHaveBeenCalled(); + + scene.pickPosition(windowPosition); + expect(SceneTransforms.transformWindowToDrawingBuffer.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 = scene.primitives; + primitives.add(rectanglePrimitive); + }); + + expect(scene).toRenderAndCall(function() { + scene.pickPosition(windowPosition); + expect(SceneTransforms.transformWindowToDrawingBuffer.calls.count()).toEqual(2); + + scene.pickPosition(windowPosition); + expect(SceneTransforms.transformWindowToDrawingBuffer.calls.count()).toEqual(2); + }); + }); + it('pickPosition throws without windowPosition', function() { expect(function() { scene.pickPosition();