ifcviewer: benchmark CLI, settle recull fix, and Phase 3G documentation

Add --camera tx,ty,tz,dist,yaw,pitch and --benchmark N CLI args for
reproducible performance measurement.  The benchmark orbits the camera
(0.5°/frame yaw) for N frames after a 5-frame warmup, prints
avg/median/p1/p99 frame times, then exits.  Press C during interactive
use to print the current camera as a --camera argument.

Fix settle recull to fire after ANY camera motion (not just when
IFC_MIN_PX_MOTION is set), ensuring HiZ artifacts from motion frames
are always cleared when the camera stops.

Document Phase 3G (motion-adaptive culling + HiZ during motion) in
README with benchmark results from 1.06M-instance scene:
  - Baseline:                    16.3 fps
  - IFC_MIN_PX_MOTION=10:       26.5 fps (1.6x)
  - IFC_HIZ_MOTION=1:           46.6 fps (2.9x)
  - Both combined:              51.0 fps (3.1x)
  - + GPU_CULL:                 52.0 fps (3.2x, negligible gain)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-04-18 21:27:28 +10:00
parent 930678e3d2
commit ed6e8d831e
6 changed files with 242 additions and 31 deletions
+13
View File
@@ -174,6 +174,10 @@ public:
void setSelectedObjectId(uint32_t id);
uint32_t pickObjectAt(int x, int y);
void setCamera(float tx, float ty, float tz, float dist, float yaw, float pitch);
void setBenchmarkFrames(int n);
QString cameraString() const;
struct FrameStats {
float fps;
float frame_time_ms;
@@ -194,6 +198,7 @@ signals:
protected:
void exposeEvent(QExposeEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
bool event(QEvent* event) override;
private:
@@ -381,6 +386,14 @@ private:
// When the camera stops, re-cull once at the base threshold.
bool last_cull_was_motion_ = false;
// Benchmark mode: render N frames, collect stats, then exit.
int benchmark_total_ = 0;
int benchmark_count_ = 0;
int benchmark_warmup_ = 5;
float benchmark_yaw_start_ = 0.0f;
float benchmark_yaw_speed_ = 0.5f; // degrees per frame
std::vector<float> benchmark_frame_times_;
// Per-frame stats
uint32_t visible_triangles_ = 0;
uint32_t visible_objects_ = 0;