@@ -146,6 +146,17 @@ export class RasterTileNode {
146146 private projectTo3857 : ProjectionFunction ;
147147 private projectTo4326 : ProjectionFunction ;
148148
149+ /**
150+ * A cached bounding volume for this tile, used for frustum culling
151+ *
152+ * This stores the result of `getBoundingVolume`.
153+ */
154+ private _boundingVolume ?: {
155+ /** The zrange used to compute this bounding volume. */
156+ zRange : ZRange ;
157+ result : { boundingVolume : OrientedBoundingBox ; commonSpaceBounds : Bounds } ;
158+ } ;
159+
149160 constructor (
150161 x : number ,
151162 y : number ,
@@ -408,6 +419,15 @@ export class RasterTileNode {
408419 zRange : ZRange ,
409420 project : ( ( xyz : number [ ] ) => number [ ] ) | null ,
410421 ) : { boundingVolume : OrientedBoundingBox ; commonSpaceBounds : Bounds } {
422+ const cached = this . _boundingVolume ;
423+ if (
424+ cached &&
425+ cached . zRange [ 0 ] === zRange [ 0 ] &&
426+ cached . zRange [ 1 ] === zRange [ 1 ]
427+ ) {
428+ return cached . result ;
429+ }
430+
411431 // Case 1: Globe view - need to construct an oriented bounding box from
412432 // reprojected sample points, but also using the `project` param
413433 if ( project ) {
@@ -425,7 +445,9 @@ export class RasterTileNode {
425445
426446 // Case 4: Generic case - sample reference points and reproject to
427447 // Web Mercator, then convert to deck.gl common space
428- return this . _getGenericBoundingVolume ( zRange ) ;
448+ const result = this . _getGenericBoundingVolume ( zRange ) ;
449+ this . _boundingVolume = { zRange, result } ;
450+ return result ;
429451 }
430452
431453 /**
0 commit comments