From a4e074497f379a61a8653b739fdd72de92d4cc69 Mon Sep 17 00:00:00 2001 From: brige Date: Wed, 12 Nov 2025 23:02:32 +0800 Subject: [PATCH] modify speed to menu --- src/ui/Menu/PlayManagerMenu.cpp | 12 +++++--- src/workspace/Timestep.cpp | 48 +++++++++++++---------------- src/workspace/Timestep.h | 13 +++----- src/workspace/WorkSpaceXMLParse.cpp | 8 +++-- src/workspace/WorkSpaceXMLWrite.cpp | 1 + 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/ui/Menu/PlayManagerMenu.cpp b/src/ui/Menu/PlayManagerMenu.cpp index e2f26861..db21c462 100644 --- a/src/ui/Menu/PlayManagerMenu.cpp +++ b/src/ui/Menu/PlayManagerMenu.cpp @@ -129,7 +129,8 @@ void PlayManagerMenu::OnTimestepChanged(Timestep* timestep) { timestep->GetRange(minTime_, maxTime_, step); ui->lbtime->setText(QString::number(minTime_, 'f', 3)); ui->lbtimeTotal->setText(QString("/%1(s)").arg(maxTime_)); - ui->lbUp->setText(QString("x%1").arg(step)); + double speed = timestep->GetSpeed(); + ui->lbUp->setText(QString("x%1").arg(speed)); ui->horizontalSlider->setRange((int)(minTime_ * 1000), (int)(maxTime_ * 1000)); @@ -139,17 +140,18 @@ void PlayManagerMenu::OnTimestepChanged(Timestep* timestep) { ui->horizontalSlider->setValue(int(dt)); } ); - connect(timestep, &Timestep::StepChanged, [this](double step) { - ui->lbUp->setText(QString("x%1").arg(step)); + // 监听倍速改变(SpeedChanged):更新显示为 x倍速 + connect(timestep, &Timestep::StepChanged, [this](double speed) { + ui->lbUp->setText(QString("x%1").arg(speed)); } ); // 当时间范围更新(例如用户在属性面板设置了起止时间)时,刷新显示与滑条范围 - connect(timestep, &Timestep::RangeChanged, [this](double minTime, double maxTime, double step) { + connect(timestep, &Timestep::RangeChanged, [this](double minTime, double maxTime, double step, double speed) { minTime_ = minTime; maxTime_ = maxTime; ui->lbtime->setText(QString::number(minTime_, 'f', 3)); ui->lbtimeTotal->setText(QString("/%1(s)").arg(maxTime_)); - ui->lbUp->setText(QString("x%1").arg(step)); + ui->lbUp->setText(QString("x%1").arg(speed)); ui->horizontalSlider->setRange((int)(minTime_ * 1000), (int)(maxTime_ * 1000)); ui->horizontalSlider->setValue((int)(minTime_ * 1000)); }); diff --git a/src/workspace/Timestep.cpp b/src/workspace/Timestep.cpp index 43cec0fd..fa6d75d1 100644 --- a/src/workspace/Timestep.cpp +++ b/src/workspace/Timestep.cpp @@ -15,34 +15,29 @@ Timestep::Timestep(WorkSpace* parent /*= nullptr*/) noexcept : QObject((QObject*)parent) , workSpace_(parent) { - // 默认最大时间为 0,由数据或手动区间设置 - // 初始化为 1.0x,如果列表中没有 1.0,则取最接近中间的默认索引 auto it = std::find(speedLevels_.begin(), speedLevels_.end(), 1.0); speedIndex_ = it != speedLevels_.end() ? int(std::distance(speedLevels_.begin(), it)) : speedIndex_; - currentStep_ = speedLevels_[speedIndex_]; + currentSpeed_ = speedLevels_[speedIndex_]; } void Timestep::SetManualRange(double start, double end) { hasManualRange_ = true; manualStart_ = start; manualEnd_ = end; - // 当设置手动区间时,更新最大时间使播放边界正确 maxTime_ = end; // 通知 UI 更新范围与步进 - double minTime = 0.0, maxTime = 0.0, step = 0.0; + double minTime = 0.0, maxTime = 0.0, step = 1.0; GetRange(minTime, maxTime, step); - emit RangeChanged(minTime, maxTime, step); + emit RangeChanged(minTime, maxTime, step, currentSpeed_); } void Timestep::ClearManualRange() { hasManualRange_ = false; manualStart_ = 0.0; manualEnd_ = 0.0; - // 恢复为数据驱动的最大时间,保留当前 maxTime_ - // 通知 UI 更新范围与步进 - double minTime = 0.0, maxTime = 0.0, step = 0.0; + double minTime = 0.0, maxTime = 0.0, step = 1.0; GetRange(minTime, maxTime, step); - emit RangeChanged(minTime, maxTime, step); + emit RangeChanged(minTime, maxTime, step, currentSpeed_); } void Timestep::GetRange(double& minTime, double& maxTime, double& step) { @@ -53,7 +48,7 @@ void Timestep::GetRange(double& minTime, double& maxTime, double& step) { minTime = 0.0; maxTime = maxTime_; } - step = currentStep_; + step = stepInterval_; } void Timestep::Update(double dt) { @@ -66,7 +61,7 @@ void Timestep::Update(double dt) { return; } - double deltaTime = dt * currentStep_; + double deltaTime = dt * stepInterval_ * currentSpeed_; current_ += deltaTime; workSpace_->OnFrame(deltaTime); @@ -95,7 +90,6 @@ void Timestep::Start() { return; } workSpace_->Begin(); - // 保持当前倍速,不在开始时重置为 1x emit StatusChanged((int)playStatus_); } @@ -128,11 +122,6 @@ void Timestep::Stop() { return; } workSpace_->End(); - // 停止时也恢复为 1x,避免停后再次播放仍是异常倍率 - auto it = std::find(speedLevels_.begin(), speedLevels_.end(), 1.0); - speedIndex_ = it != speedLevels_.end() ? int(std::distance(speedLevels_.begin(), it)) : speedIndex_; - currentStep_ = speedLevels_[speedIndex_]; - emit StepChanged(currentStep_); emit StatusChanged((int)playStatus_); } @@ -141,24 +130,23 @@ void Timestep::Up() { if (speedIndex_ < int(speedLevels_.size()) - 1) { ++speedIndex_; } - currentStep_ = speedLevels_[speedIndex_]; - emit StepChanged(currentStep_); + currentSpeed_ = speedLevels_[speedIndex_]; + emit StepChanged(currentSpeed_); } void Timestep::SetDataMaxTime(double end) { maxTime_ = end; double minTime = 0.0, maxTime = 0.0, step = 0.0; GetRange(minTime, maxTime, step); - emit RangeChanged(minTime, maxTime, step); + emit RangeChanged(minTime, maxTime, step, currentSpeed_); } void Timestep::Down() { - // 降到上一个倍率(保底) if (speedIndex_ > 0) { --speedIndex_; } - currentStep_ = speedLevels_[speedIndex_]; - emit StepChanged(currentStep_); + currentSpeed_ = speedLevels_[speedIndex_]; + emit StepChanged(currentSpeed_); } void Timestep::SetSpeed(double speed) { @@ -175,6 +163,14 @@ void Timestep::SetSpeed(double speed) { } } speedIndex_ = bestIdx; - currentStep_ = speedLevels_[speedIndex_]; - emit StepChanged(currentStep_); + currentSpeed_ = speedLevels_[speedIndex_]; + emit StepChanged(currentSpeed_); +} + +void Timestep::SetStep(double step) { + // 更新时间轴步进间隔,并通知 UI 范围与步进发生变化 + stepInterval_ = step; + double minTime = 0.0, maxTime = 0.0, s = 0.0; + GetRange(minTime, maxTime, s); + emit RangeChanged(minTime, maxTime, s, currentSpeed_); } diff --git a/src/workspace/Timestep.h b/src/workspace/Timestep.h index 31e680ff..c4444a7e 100644 --- a/src/workspace/Timestep.h +++ b/src/workspace/Timestep.h @@ -25,6 +25,7 @@ public: double GetCurrent() const { return current_; } + double GetSpeed() const { return currentSpeed_; } bool IsPause(); bool IsStoped(); @@ -35,17 +36,15 @@ public: void Up(); void Down(); - // 设置播放速度(倍率),会选取最接近的预设倍率并触发 StepChanged void SetSpeed(double speed); + void SetStep(double step); - // 设置数据驱动的默认最大时间(非手动区间),用于没有文件步长时的播放边界 void SetDataMaxTime(double end); WorkSpace* GetWorkSpace() const { return workSpace_; } - // 手动时间区间(可选):允许用户指定起止时间,替代或重映射步骤 void SetManualRange(double start, double end); void ClearManualRange(); bool HasManualRange() const { return hasManualRange_; } @@ -56,16 +55,14 @@ Q_SIGNALS: void StatusChanged(int); void StepChanged(double); void TimeChanged(double); - // 当时间范围或步进倍率更新时通知 UI(例如设置手动区间或清除) - void RangeChanged(double minTime, double maxTime, double step); + void RangeChanged(double minTime, double maxTime, double step, double speed); private: double current_{ 0.0 }; double maxTime_{ 0.0 }; - // 播放速度(倍率),与 UI 显示一致,比如 0.5x、1x、2x - double currentStep_{ 1.0 }; - // 有限倍率列表,防止无限放大/缩小导致无法恢复 + double currentSpeed_{ 1.0 }; + double stepInterval_{ 1.0 }; std::vector speedLevels_{ 0.25, 0.5, 1.0, 2.0, 4.0, 8.0 }; int speedIndex_{ 2 }; // 默认指向 1.0x diff --git a/src/workspace/WorkSpaceXMLParse.cpp b/src/workspace/WorkSpaceXMLParse.cpp index c5b27ad2..ad402217 100644 --- a/src/workspace/WorkSpaceXMLParse.cpp +++ b/src/workspace/WorkSpaceXMLParse.cpp @@ -73,12 +73,16 @@ bool WorkSpaceXMLParse::ParseTimestep(const tinyxml2::XMLElement* element) { double start = 0.0; double end = 0.0; double step = 0.0; + double speed = 0.0; bool hasStart = (element->QueryDoubleAttribute("start", &start) == tinyxml2::XML_SUCCESS); bool hasEnd = (element->QueryDoubleAttribute("end", &end) == tinyxml2::XML_SUCCESS); bool hasStep = (element->QueryDoubleAttribute("step", &step) == tinyxml2::XML_SUCCESS); - + bool hasSpeed = (element->QueryDoubleAttribute("speed", &speed) == tinyxml2::XML_SUCCESS); + if (hasSpeed) { + t->SetSpeed(speed); + } if (hasStep) { - t->SetSpeed(step); + t->SetStep(step); } // 若标记为手动或具有完整的 start/end,则设置手动范围;否则按数据最大时间设置边界 diff --git a/src/workspace/WorkSpaceXMLWrite.cpp b/src/workspace/WorkSpaceXMLWrite.cpp index 17c754db..d6a28748 100644 --- a/src/workspace/WorkSpaceXMLWrite.cpp +++ b/src/workspace/WorkSpaceXMLWrite.cpp @@ -90,6 +90,7 @@ bool WorkSpaceXMLWrite::SaveTimeStep(tinyxml2::XMLElement* scene) { timestep->SetAttribute("start", start); timestep->SetAttribute("end", end); timestep->SetAttribute("step", step); + timestep->SetAttribute("speed", t->GetSpeed()); return true; }