@@ -142,8 +142,14 @@ function findFocusedMonitor(quaternion, position, monitorVectors, currentFocused
142142 * @returns {Object } - containing `begin`, `center`, and `end` radians for rotating the given monitor
143143 */
144144function monitorWrap ( cachedMonitorRadians , monitorSpacingPixels , monitorBeginPixel , monitorLengthPixels , lengthToRadianFn ) {
145- let closestWrapPixel = monitorBeginPixel ;
146- let closestWrap = cachedMonitorRadians [ monitorBeginPixel ] ;
145+ // Monitor coordinates can become fractional due to size adjustment.
146+ // If a monitor edge lands extremely close to a cached pixel key, snap to it;
147+ // otherwise tiny negative gaps can cause us to subtract a full spacing interval.
148+ let beginPixel = monitorBeginPixel ;
149+ const pixelEpsilon = Math . max ( 1e-6 , Math . abs ( monitorLengthPixels ) * 1e-6 ) ;
150+
151+ let closestWrapPixel = beginPixel ;
152+ let closestWrap = cachedMonitorRadians [ beginPixel ] ;
147153 if ( closestWrap === undefined ) {
148154 closestWrapPixel = Object . keys ( cachedMonitorRadians ) . reduce ( ( previousPixel , currentPixel ) => {
149155 if ( previousPixel === undefined ) return currentPixel ;
@@ -167,10 +173,16 @@ function monitorWrap(cachedMonitorRadians, monitorSpacingPixels, monitorBeginPix
167173 closestWrap = cachedMonitorRadians [ closestWrapPixel ] ;
168174 }
169175
176+ const closestWrapPixelNumber = Number ( closestWrapPixel ) ;
177+ if ( Number . isFinite ( closestWrapPixelNumber ) && Math . abs ( closestWrapPixelNumber - beginPixel ) < pixelEpsilon ) {
178+ beginPixel = closestWrapPixelNumber ;
179+ closestWrapPixel = closestWrapPixelNumber ;
180+ }
181+
170182 const spacingRadians = lengthToRadianFn ( monitorSpacingPixels ) ;
171- if ( closestWrapPixel !== monitorBeginPixel ) {
183+ if ( closestWrapPixel !== beginPixel ) {
172184 // there's a gap between the cached wrap value and this one
173- const gapPixels = monitorBeginPixel - closestWrapPixel ;
185+ const gapPixels = beginPixel - closestWrapPixel ;
174186 const gapRadians = lengthToRadianFn ( gapPixels ) ;
175187
176188 // use Math.floor so if it's negative (this monitor is to the left of or above the closest) it will always
@@ -179,7 +191,7 @@ function monitorWrap(cachedMonitorRadians, monitorSpacingPixels, monitorBeginPix
179191
180192 // update the closestWrap value and cache it
181193 closestWrap = closestWrap + gapRadians + appliedSpacingRadians ;
182- closestWrapPixel = monitorBeginPixel ;
194+ closestWrapPixel = beginPixel ;
183195 cachedMonitorRadians [ closestWrapPixel ] = closestWrap ;
184196 }
185197
@@ -188,7 +200,7 @@ function monitorWrap(cachedMonitorRadians, monitorSpacingPixels, monitorBeginPix
188200 const endRadians = closestWrap + monitorRadians ;
189201
190202 // since we're computing the end values for this monitor, cache them too in case they line up with a future monitor
191- const nextMonitorPixel = monitorBeginPixel + monitorLengthPixels ;
203+ const nextMonitorPixel = beginPixel + monitorLengthPixels ;
192204 if ( cachedMonitorRadians [ nextMonitorPixel ] === undefined )
193205 cachedMonitorRadians [ nextMonitorPixel ] = endRadians + spacingRadians ;
194206
@@ -301,7 +313,7 @@ function monitorsToPlacements(fovDetails, monitorDetailsList, monitorSpacing) {
301313 centerNoRotate : [
302314 monitorCenterRadius ,
303315
304- // west is flat when wrapping horizontally
316+ // west is flat when wrapping vertically
305317 westCenterPixels ,
306318
307319 // up is centered about the FOV center
0 commit comments