@@ -41,9 +41,6 @@ class HipsTile
4141 StelTextureSP allsky; // allsky low res version of the texture.
4242 StelTextureSP normalAllsky; // allsky low res version of the texture.
4343 StelTextureSP horizonAllsky; // allsky low res version of the texture.
44-
45- // Used for smooth fade in
46- QTimeLine texFader;
4744};
4845
4946static QString getExt (const QString& format)
@@ -437,7 +434,7 @@ static bool isClipped(int n, double (*pos)[4])
437434 return false ;
438435}
439436
440- bool HipsSurvey::bindTextures (const HipsTile& tile)
437+ bool HipsSurvey::bindTextures (HipsTile& tile, const int orderMin, Vec2f& texCoordShift, float & texCoordScale, bool & tileIsLoaded )
441438{
442439 constexpr int colorTexUnit = 0 ;
443440 constexpr int normalTexUnit = 2 ;
@@ -446,22 +443,53 @@ bool HipsSurvey::bindTextures(const HipsTile& tile)
446443 if (normals && !tile.normalTexture && !tile.normalAllsky ) return false ;
447444 if (horizons && !tile.horizonTexture && !tile.horizonAllsky ) return false ;
448445
449- if (!tile.texture ->bind (colorTexUnit) && (!tile.allsky || !tile.allsky ->bind (colorTexUnit)))
450- return false ;
451- if (normals && tile.normalTexture && !tile.normalTexture ->bind (normalTexUnit) && (!tile.normalAllsky || !tile.normalAllsky ->bind (normalTexUnit)))
452- return false ;
453- if (horizons && tile.horizonTexture && !tile.horizonTexture ->bind (horizonTexUnit) && (!tile.horizonAllsky || !tile.horizonAllsky ->bind (horizonTexUnit)))
454- return false ;
446+ bool ok = tile.texture ->bind (colorTexUnit);
447+ if (!ok) ok = tile.allsky && tile.allsky ->bind (colorTexUnit);
448+ if (ok && normals)
449+ {
450+ ok = tile.normalTexture && tile.normalTexture ->bind (normalTexUnit);
451+ if (!ok) ok = tile.normalAllsky && tile.normalAllsky ->bind (normalTexUnit);
452+ }
453+ if (ok && horizons)
454+ {
455+ ok = tile.horizonTexture && tile.horizonTexture ->bind (horizonTexUnit);
456+ if (!ok) ok = tile.horizonAllsky && tile.horizonAllsky ->bind (horizonTexUnit);
457+ }
458+
459+ if (!ok) tileIsLoaded = false ;
455460
456- return true ;
461+ if (!ok && tile.order > orderMin)
462+ {
463+ // Current-level textures failed to bind, let's try the previous level
464+ const auto parentTile = getTile (tile.order - 1 , tile.pix / 4 );
465+ if (!parentTile) return false ;
466+ assert (parentTile->order == tile.order - 1 );
467+ assert (parentTile->order >= orderMin);
468+
469+ static const Vec2f bottomLeftPartUV[] = {Vec2f (0 ,0.5 ), Vec2f (0 ,0 ), Vec2f (0.5 ,0.5 ), Vec2f (0.5 ,0 )};
470+ const int pos = tile.pix % 4 ;
471+ // Like the multiplication of the texture transform by scale and shift matrix on the left:
472+ // transform = shift(bottomLeftPartUV[pos]) * scale(0.5) * transform
473+ texCoordShift = texCoordShift * 0 .5f + bottomLeftPartUV[pos];
474+ texCoordScale *= 0 .5f ;
475+
476+ ok = bindTextures (*parentTile, orderMin, texCoordShift, texCoordScale, tileIsLoaded);
477+ if (!ok) return false ;
478+ }
479+
480+ return ok;
457481}
458482
459483void HipsSurvey::drawTile (int order, int pix, int drawOrder, int splitOrder, bool outside,
460- const SphericalCap& viewportShape, StelPainter* sPainter , Vec3d observerVelocity, DrawCallback callback)
484+ const SphericalCap& viewportShape, StelPainter* sPainter ,
485+ Vec3d observerVelocity, DrawCallback callback)
461486{
462487 Vec3d pos;
463488 Mat3d mat3;
464489 const Vec2d uv[4 ] = {Vec2d (0 , 0 ), Vec2d (0 , 1 ), Vec2d (1 , 0 ), Vec2d (1 , 1 )};
490+ bool tileLoaded = true ;
491+ Vec2f texCoordShift (0 ,0 );
492+ float texCoordScale = 1 ;
465493 HipsTile *tile;
466494 int orderMin = getPropertyInt (" hips_order_min" , 3 );
467495 QVector<Vec3d> vertsArray;
@@ -521,26 +549,16 @@ void HipsSurvey::drawTile(int order, int pix, int drawOrder, int splitOrder, boo
521549 tile = getTile (order, pix);
522550
523551 if (!tile) return ;
524- if (!bindTextures (*tile)) return ;
552+ if (!bindTextures (*tile, orderMin, texCoordShift, texCoordScale, tileLoaded))
553+ return ;
525554
526- if (tile->texFader .state () == QTimeLine::NotRunning && tile->texFader .currentValue () == 0.0 )
527- tile->texFader .start ();
528- nbLoadedTiles++;
555+ if (tileLoaded)
556+ nbLoadedTiles++;
529557
530- if (order < drawOrder)
531- {
532- // If all the children tiles are loaded, we can skip the parent.
533- int i;
534- for (i = 0 ; i < 4 ; i++)
535- {
536- HipsTile* child = getTile (order + 1 , pix * 4 + i);
537- if (!child || child->texFader .currentValue () < 1.0 ) break ;
538- }
539- if (i == 4 ) goto skip_render;
540- }
558+ if (order < drawOrder) goto skip_render;
541559
542560 // Actually draw the tile, as a single quad.
543- alpha = color[3 ] * static_cast < float >(tile-> texFader . currentValue ()) ;
561+ alpha = color[3 ];
544562 if (alpha < 1 .0f )
545563 {
546564 sPainter ->setBlending (true );
@@ -553,7 +571,7 @@ void HipsSurvey::drawTile(int order, int pix, int drawOrder, int splitOrder, boo
553571 }
554572 sPainter ->setCullFace (true );
555573 nb = fillArrays (order, pix, drawOrder, splitOrder, outside, sPainter , observerVelocity,
556- vertsArray, texArray, indicesArray);
574+ texCoordShift, texCoordScale, vertsArray, texArray, indicesArray);
557575 if (!callback) {
558576 sPainter ->setArrays (vertsArray.constData (), texArray.constData ());
559577 sPainter ->drawFromArray (StelPainter::Triangles, nb, 0 , true , indicesArray.constData ());
@@ -577,6 +595,7 @@ void HipsSurvey::drawTile(int order, int pix, int drawOrder, int splitOrder, boo
577595
578596int HipsSurvey::fillArrays (int order, int pix, int drawOrder, int splitOrder,
579597 bool outside, StelPainter* sPainter , Vec3d observerVelocity,
598+ const Vec2f& texCoordShift, const float texCoordScale,
580599 QVector<Vec3d>& verts, QVector<Vec2f>& tex, QVector<uint16_t >& indices)
581600{
582601 Q_UNUSED (sPainter )
@@ -611,7 +630,7 @@ int HipsSurvey::fillArrays(int order, int pix, int drawOrder, int splitOrder,
611630 }
612631
613632 verts << pos;
614- tex << texPos;
633+ tex << texPos * texCoordScale + texCoordShift ;
615634 }
616635 }
617636 for (uint16_t i = 0 ; i < gridSize; i++)
0 commit comments