feat/vtk-3d-view #7
|
|
@ -4002,12 +4002,13 @@ struct PlacedSource {
|
||||||
|
|
||||||
vtkSmartPointer<vtkTransform> world; // T:Scale(1,1,exagg)→RotateZ→Translate
|
vtkSmartPointer<vtkTransform> world; // T:Scale(1,1,exagg)→RotateZ→Translate
|
||||||
vtkSmartPointer<vtkTransform> worldInv; // T⁻¹(相机逆变换到局部帧)
|
vtkSmartPointer<vtkTransform> worldInv; // T⁻¹(相机逆变换到局部帧)
|
||||||
vtkSmartPointer<vtkVolumeProperty> prop; // 逐线 2/98 分位标定的传函(底图+高清共用)
|
vtkSmartPointer<vtkVolumeProperty> prop; // 逐线 2/98 分位标定的传函
|
||||||
vtkSmartPointer<vtkVolume> baseVolume; // 常驻粗底图(永在场,套 T)
|
// P12:每线只渲【一个】体(不再底图层 + 高清层叠双渲,20 线=40 体爆 1fps)。
|
||||||
vtkSmartPointer<vtkSmartVolumeMapper> baseMapper;
|
// 该体输入由引擎按相机选的 LOD 决定:起步喂 baseImage()(粗 whole,小且不空),
|
||||||
vtkSmartPointer<vtkVolume> hiresVolume; // 高清叠加(就绪后局部覆盖,套 T)
|
// 引擎备好更合适的 currentImages() 后整图换上 → 任何时刻每线 ≤1 体 → 最多 20 体。
|
||||||
vtkSmartPointer<vtkSmartVolumeMapper> hiresMapper;
|
vtkSmartPointer<vtkVolume> volume; // 唯一体(套 T)
|
||||||
vtkSmartPointer<vtkImageData> currentImg; // 持当前高清单图引用(mapper 仅持裸指针)
|
vtkSmartPointer<vtkSmartVolumeMapper> mapper;
|
||||||
|
vtkSmartPointer<vtkImageData> currentImg; // 持当前单图引用(mapper 仅持裸指针)
|
||||||
|
|
||||||
double worldBounds[6] = {0, 0, 0, 0, 0, 0}; // 该线(含 T+底图盒)的世界 AABB(视锥裁剪用)
|
double worldBounds[6] = {0, 0, 0, 0, 0, 0}; // 该线(含 T+底图盒)的世界 AABB(视锥裁剪用)
|
||||||
bool culled = false; // 本帧是否被视锥裁掉(两层皆隐 → 真跳过)
|
bool culled = false; // 本帧是否被视锥裁掉(两层皆隐 → 真跳过)
|
||||||
|
|
@ -4082,17 +4083,16 @@ void viewAllSubmitOneLine(PlacedSource& ps, vtkCamera* worldCam,
|
||||||
1.0});
|
1.0});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 非阻塞拉取该线后台已就绪的高清单图,喂高清 mapper(无新结果→沿用上一帧)。
|
// 非阻塞拉取该线后台已就绪的引擎单图,换上唯一体的 mapper(无新结果→沿用上一帧)。
|
||||||
// 返回 1=换上新图。
|
// 返回 1=换上新图。P12:单体单层,引擎选 LOD(远→粗 whole,近→细局部)。
|
||||||
int viewAllPickOneLine(PlacedSource& ps) {
|
int viewAllPickOneLine(PlacedSource& ps) {
|
||||||
if (ps.culled) return 0;
|
if (ps.culled) return 0;
|
||||||
auto imgs = ps.source->currentImages(); // 内部 takeLatest(非阻塞)
|
auto imgs = ps.source->currentImages(); // 内部 takeLatest(非阻塞)
|
||||||
if (imgs.empty() || imgs[0] == nullptr) return 0;
|
if (imgs.empty() || imgs[0] == nullptr) return 0;
|
||||||
if (imgs[0] == ps.currentImg) return 0;
|
if (imgs[0] == ps.currentImg) return 0;
|
||||||
ps.currentImg = imgs[0];
|
ps.currentImg = imgs[0];
|
||||||
ps.hiresMapper->SetInputData(ps.currentImg);
|
ps.mapper->SetInputData(ps.currentImg);
|
||||||
ps.hiresMapper->Update();
|
ps.mapper->Update();
|
||||||
ps.hiresVolume->SetVisibility(1);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4134,14 +4134,9 @@ void viewAllRefreshFrustum(ViewAllState* st) {
|
||||||
for (PlacedSource& ps : *st->lines) {
|
for (PlacedSource& ps : *st->lines) {
|
||||||
const bool outside = aabbOutsideFrustum(ps.worldBounds, planes);
|
const bool outside = aabbOutsideFrustum(ps.worldBounds, planes);
|
||||||
ps.culled = outside;
|
ps.culled = outside;
|
||||||
ps.baseVolume->SetVisibility(outside ? 0 : 1);
|
// P12:每线唯一体。视锥外→隐(真跳过 ray-cast);可见→显并提交引擎目标(局部帧)。
|
||||||
if (outside) {
|
ps.volume->SetVisibility(outside ? 0 : 1);
|
||||||
ps.hiresVolume->SetVisibility(0);
|
if (!outside) viewAllSubmitOneLine(ps, st->cam, st->aspect, st->viewportH);
|
||||||
} else {
|
|
||||||
// 可见:提交引擎目标(局部帧),高清可见性由 pick 决定(有就绪图才显)。
|
|
||||||
viewAllSubmitOneLine(ps, st->cam, st->aspect, st->viewportH);
|
|
||||||
ps.hiresVolume->SetVisibility(ps.currentImg != nullptr ? 1 : 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4363,32 +4358,24 @@ int cmdViewAll(int argc, char** argv) {
|
||||||
ps.worldInv->DeepCopy(ps.world);
|
ps.worldInv->DeepCopy(ps.world);
|
||||||
ps.worldInv->Inverse();
|
ps.worldInv->Inverse();
|
||||||
|
|
||||||
// 逐线传函(从常驻底图标定)+ 底图层 + 高清层,两层皆套世界变换 T。
|
// 逐线传函(从常驻底图标定)。P12:每线只建【一个】体(套世界变换 T),
|
||||||
|
// 起步喂粗底图(小且不空),引擎备好更合适 LOD 单图后整图换上。
|
||||||
ps.prop = buildLineProperty(ps.meta, ps.source->baseImage());
|
ps.prop = buildLineProperty(ps.meta, ps.source->baseImage());
|
||||||
|
|
||||||
ps.baseMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
|
ps.mapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
|
||||||
ps.baseMapper->SetRequestedRenderMode(vtkSmartVolumeMapper::GPURenderMode);
|
ps.mapper->SetRequestedRenderMode(vtkSmartVolumeMapper::GPURenderMode);
|
||||||
ps.baseMapper->SetAutoAdjustSampleDistances(1);
|
|
||||||
ps.baseMapper->SetInteractiveAdjustSampleDistances(1);
|
|
||||||
ps.baseVolume = vtkSmartPointer<vtkVolume>::New();
|
|
||||||
if (ps.source->baseImage() != nullptr) {
|
|
||||||
ps.baseMapper->SetInputData(ps.source->baseImage());
|
|
||||||
ps.baseMapper->Update();
|
|
||||||
}
|
|
||||||
ps.baseVolume->SetMapper(ps.baseMapper);
|
|
||||||
ps.baseVolume->SetProperty(ps.prop);
|
|
||||||
ps.baseVolume->SetUserTransform(ps.world);
|
|
||||||
|
|
||||||
ps.hiresMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
|
|
||||||
ps.hiresMapper->SetRequestedRenderMode(vtkSmartVolumeMapper::GPURenderMode);
|
|
||||||
// #1 拖动降采样:交互式采样距离自适应(拖动→大步长降采样跟手,松手→全质量)。
|
// #1 拖动降采样:交互式采样距离自适应(拖动→大步长降采样跟手,松手→全质量)。
|
||||||
ps.hiresMapper->SetAutoAdjustSampleDistances(1);
|
ps.mapper->SetAutoAdjustSampleDistances(1);
|
||||||
ps.hiresMapper->SetInteractiveAdjustSampleDistances(1);
|
ps.mapper->SetInteractiveAdjustSampleDistances(1);
|
||||||
ps.hiresVolume = vtkSmartPointer<vtkVolume>::New();
|
ps.volume = vtkSmartPointer<vtkVolume>::New();
|
||||||
ps.hiresVolume->SetMapper(ps.hiresMapper);
|
if (ps.source->baseImage() != nullptr) {
|
||||||
ps.hiresVolume->SetProperty(ps.prop);
|
ps.mapper->SetInputData(ps.source->baseImage());
|
||||||
ps.hiresVolume->SetUserTransform(ps.world);
|
ps.mapper->Update();
|
||||||
ps.hiresVolume->SetVisibility(0); // 无就绪高清前不显(底图兜底)
|
ps.currentImg = ps.source->baseImage(); // 起步即有图(不空白)
|
||||||
|
}
|
||||||
|
ps.volume->SetMapper(ps.mapper);
|
||||||
|
ps.volume->SetProperty(ps.prop);
|
||||||
|
ps.volume->SetUserTransform(ps.world);
|
||||||
|
|
||||||
// 该线世界 AABB(底图模型盒经 T 变换的 8 角包络)→ 视锥裁剪用。
|
// 该线世界 AABB(底图模型盒经 T 变换的 8 角包络)→ 视锥裁剪用。
|
||||||
if (ps.source->baseImage() != nullptr) {
|
if (ps.source->baseImage() != nullptr) {
|
||||||
|
|
@ -4439,11 +4426,11 @@ int cmdViewAll(int argc, char** argv) {
|
||||||
vtkOutputWindow::SetInstance(capWin);
|
vtkOutputWindow::SetInstance(capWin);
|
||||||
|
|
||||||
for (PlacedSource& ps : lines) {
|
for (PlacedSource& ps : lines) {
|
||||||
ren->AddVolume(ps.baseVolume); // 先加底图 → 底层常渲
|
ren->AddVolume(ps.volume); // P12:每线唯一体(引擎 LOD 单层)
|
||||||
ren->AddVolume(ps.hiresVolume); // 后加高清 → 叠在底图上
|
|
||||||
}
|
}
|
||||||
std::cout << "[view-all] 已加入场景线数=" << lines.size()
|
std::cout << "[view-all] 已加入场景线数=" << lines.size()
|
||||||
<< "(底图常驻 + 高清叠加,各 ≤16384 单纹理,绝不撞 GL 纹理墙)\n";
|
<< "(每线唯一体=" << lines.size()
|
||||||
|
<< " 体,引擎 LOD 单层,各 ≤16384 单纹理,绝不撞 GL 纹理墙)\n";
|
||||||
|
|
||||||
ViewAllState st;
|
ViewAllState st;
|
||||||
st.lines = &lines;
|
st.lines = &lines;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue