@@ -339,7 +339,7 @@ function callLayerPickingCallbacks(infos, mode) {
339339 * Pick at a specified pixel with a tolerance radius
340340 * Returns the closest object to the pixel in shape `{pickedColor, pickedLayer, pickedObjectIndex}`
341341 */
342- function getClosestFromPickingBuffer ( gl , {
342+ export function getClosestFromPickingBuffer ( gl , {
343343 pickedColors,
344344 layers,
345345 deviceX,
@@ -348,42 +348,53 @@ function getClosestFromPickingBuffer(gl, {
348348 deviceRect
349349} ) {
350350 assert ( pickedColors ) ;
351- let closestResultToCenter = NO_PICKED_OBJECT ;
352351
353352 // Traverse all pixels in picking results and find the one closest to the supplied
354353 // [deviceX, deviceY]
354+ const { x, y, width, height} = deviceRect ;
355355 let minSquareDistanceToCenter = deviceRadius * deviceRadius ;
356+ let closestPixelIndex = - 1 ;
356357 let i = 0 ;
357358
358- for ( let row = 0 ; row < deviceRect . height ; row ++ ) {
359- for ( let col = 0 ; col < deviceRect . width ; col ++ ) {
360- // Decode picked layer from color
361- const pickedLayerIndex = pickedColors [ i + 3 ] - 1 ;
362-
363- if ( pickedLayerIndex >= 0 ) {
364- const dx = col + deviceRect . x - deviceX ;
365- const dy = row + deviceRect . y - deviceY ;
366- const d2 = dx * dx + dy * dy ;
367-
368- if ( d2 <= minSquareDistanceToCenter ) {
369- minSquareDistanceToCenter = d2 ;
370-
371- // Decode picked object index from color
372- const pickedColor = pickedColors . slice ( i , i + 4 ) ;
373- const pickedLayer = layers [ pickedLayerIndex ] ;
374- if ( pickedLayer ) {
375- const pickedObjectIndex = pickedLayer . decodePickingColor ( pickedColor ) ;
376- closestResultToCenter = { pickedColor, pickedLayer, pickedObjectIndex} ;
377- } else {
378- log . error ( 0 , 'Picked non-existent layer. Is picking buffer corrupt?' ) ;
359+ for ( let row = 0 ; row < height ; row ++ ) {
360+ const dy = row + y - deviceY ;
361+ const dy2 = dy * dy ;
362+
363+ if ( dy2 > minSquareDistanceToCenter ) {
364+ // skip this row
365+ i += 4 * width ;
366+ } else {
367+ for ( let col = 0 ; col < width ; col ++ ) {
368+ // Decode picked layer from color
369+ const pickedLayerIndex = pickedColors [ i + 3 ] - 1 ;
370+
371+ if ( pickedLayerIndex >= 0 ) {
372+ const dx = col + x - deviceX ;
373+ const d2 = dx * dx + dy2 ;
374+
375+ if ( d2 <= minSquareDistanceToCenter ) {
376+ minSquareDistanceToCenter = d2 ;
377+ closestPixelIndex = i ;
379378 }
380379 }
380+ i += 4 ;
381381 }
382- i += 4 ;
383382 }
384383 }
385384
386- return closestResultToCenter ;
385+ if ( closestPixelIndex >= 0 ) {
386+ // Decode picked object index from color
387+ const pickedLayerIndex = pickedColors [ closestPixelIndex + 3 ] - 1 ;
388+ const pickedColor = pickedColors . slice ( closestPixelIndex , closestPixelIndex + 4 ) ;
389+ const pickedLayer = layers [ pickedLayerIndex ] ;
390+ if ( pickedLayer ) {
391+ const pickedObjectIndex = pickedLayer . decodePickingColor ( pickedColor ) ;
392+ return { pickedColor, pickedLayer, pickedObjectIndex} ;
393+ }
394+ log . error ( 0 , 'Picked non-existent layer. Is picking buffer corrupt?' ) ;
395+ }
396+
397+ return NO_PICKED_OBJECT ;
387398}
388399/* eslint-enable max-depth, max-statements */
389400
0 commit comments