feat/vtk-3d-view #7
|
|
@ -180,6 +180,17 @@ void TileBasemap::refineTile(int z, int x, int y, std::set<long long>& out, int&
|
|||
const geopro::render::LonLatBox b = geopro::render::tileBounds(z, x, y);
|
||||
const auto sw = frame_->toLocal(b.south, b.west);
|
||||
const auto ne = frame_->toLocal(b.north, b.east);
|
||||
|
||||
// 视锥剔除:瓦片 AABB 全在某视锥面外侧 → 不在视野内,直接丢弃(否则会在屏幕外乱细分耗尽预算)。
|
||||
const double zmin = -1000.0, zmax = 1000.0; // 地形起伏远小于瓦片尺度,给宽松 z 带
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
const double* pl = &frustum_[p * 4]; // 内法向:内侧 a·x+b·y+c·z+d ≥ 0
|
||||
const double vx = pl[0] >= 0 ? ne.x : sw.x; // 取最朝法向的角点(p-vertex)
|
||||
const double vy = pl[1] >= 0 ? ne.y : sw.y;
|
||||
const double vz = pl[2] >= 0 ? zmax : zmin;
|
||||
if (pl[0] * vx + pl[1] * vy + pl[2] * vz + pl[3] < 0.0) return; // 全在外 → 剔除
|
||||
}
|
||||
|
||||
const double cx = (sw.x + ne.x) * 0.5, cy = (sw.y + ne.y) * 0.5; // 瓦片中心(局部米)
|
||||
const double g = std::max(std::abs(ne.x - sw.x), std::abs(ne.y - sw.y)); // 瓦片地面尺寸(米)
|
||||
|
||||
|
|
@ -219,6 +230,16 @@ void TileBasemap::refresh() {
|
|||
projParallel_ = cam->GetParallelProjection();
|
||||
projK_ = projParallel_ ? H / (2.0 * std::max(1.0, cam->GetParallelScale()))
|
||||
: H / (2.0 * std::tan(cam->GetViewAngle() * 0.5 * kPi / 180.0));
|
||||
const double aspect = (sz && sz[1] > 0) ? double(sz[0]) / double(sz[1]) : 1.0;
|
||||
cam->GetFrustumPlanes(aspect, frustum_); // 6 视锥面(供 refineTile 剔除屏幕外瓦片)
|
||||
// 用焦点(必在视锥内)统一各面方向为"内侧≥0",规避 VTK 法向内/外约定差异(否则可能全剔成黑屏)。
|
||||
double fp[3];
|
||||
cam->GetFocalPoint(fp);
|
||||
for (int p = 0; p < 6; ++p) {
|
||||
double* pl = &frustum_[p * 4];
|
||||
if (pl[0] * fp[0] + pl[1] * fp[1] + pl[2] * fp[2] + pl[3] < 0.0)
|
||||
for (int k = 0; k < 4; ++k) pl[k] = -pl[k];
|
||||
}
|
||||
|
||||
// 四叉树:从数据中心一圈粗根块出发,按屏幕误差细分 → 近细远粗、铺满视野,无单层级盲区。
|
||||
desired_.clear();
|
||||
|
|
|
|||
|
|
@ -71,10 +71,11 @@ private:
|
|||
std::set<long long> inFlight_; // 在途瓦片(续到起伏/平面最终落地)
|
||||
std::map<long long, QImage> demCache_; // DEM 块缓存(key=DEMz/x/y),跨隐藏/重选复用
|
||||
std::map<long long, vtkSmartPointer<vtkTexture>> texCache_; // 影像纹理缓存,重选/缩放回看免重拉
|
||||
// 四叉树当前帧相机参数(refresh 写, refineTile 读):相机位置 + 投影系数。
|
||||
// 四叉树当前帧相机参数(refresh 写, refineTile 读):相机位置 + 投影系数 + 视锥 6 面。
|
||||
double camX_ = 0, camY_ = 0, camZ_ = 0;
|
||||
double projK_ = 1.0;
|
||||
bool projParallel_ = false;
|
||||
double frustum_[24] = {0}; // 6 个视锥平面(内法向),AABB 全在某面外则剔除
|
||||
struct PendingGet { QString url; std::function<void(QNetworkReply*)> cb; };
|
||||
std::deque<PendingGet> netQueue_; // 限并发请求队列(防瓦片暴发饱和卡死)
|
||||
int netInFlight_ = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue