modify speed to menu

This commit is contained in:
brige 2025-11-12 23:02:32 +08:00
parent 3bb8f8000b
commit a4e074497f
5 changed files with 41 additions and 41 deletions

View File

@ -129,7 +129,8 @@ void PlayManagerMenu::OnTimestepChanged(Timestep* timestep) {
timestep->GetRange(minTime_, maxTime_, step); timestep->GetRange(minTime_, maxTime_, step);
ui->lbtime->setText(QString::number(minTime_, 'f', 3)); ui->lbtime->setText(QString::number(minTime_, 'f', 3));
ui->lbtimeTotal->setText(QString("/%1(s)").arg(maxTime_)); 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)); ui->horizontalSlider->setRange((int)(minTime_ * 1000), (int)(maxTime_ * 1000));
@ -139,17 +140,18 @@ void PlayManagerMenu::OnTimestepChanged(Timestep* timestep) {
ui->horizontalSlider->setValue(int(dt)); ui->horizontalSlider->setValue(int(dt));
} }
); );
connect(timestep, &Timestep::StepChanged, [this](double step) { // 监听倍速改变SpeedChanged更新显示为 x倍速
ui->lbUp->setText(QString("x%1").arg(step)); 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; minTime_ = minTime;
maxTime_ = maxTime; maxTime_ = maxTime;
ui->lbtime->setText(QString::number(minTime_, 'f', 3)); ui->lbtime->setText(QString::number(minTime_, 'f', 3));
ui->lbtimeTotal->setText(QString("/%1(s)").arg(maxTime_)); 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->setRange((int)(minTime_ * 1000), (int)(maxTime_ * 1000));
ui->horizontalSlider->setValue((int)(minTime_ * 1000)); ui->horizontalSlider->setValue((int)(minTime_ * 1000));
}); });

View File

@ -15,34 +15,29 @@
Timestep::Timestep(WorkSpace* parent /*= nullptr*/) noexcept Timestep::Timestep(WorkSpace* parent /*= nullptr*/) noexcept
: QObject((QObject*)parent) : QObject((QObject*)parent)
, workSpace_(parent) { , workSpace_(parent) {
// 默认最大时间为 0由数据或手动区间设置
// 初始化为 1.0x,如果列表中没有 1.0,则取最接近中间的默认索引
auto it = std::find(speedLevels_.begin(), speedLevels_.end(), 1.0); auto it = std::find(speedLevels_.begin(), speedLevels_.end(), 1.0);
speedIndex_ = it != speedLevels_.end() ? int(std::distance(speedLevels_.begin(), it)) : speedIndex_; speedIndex_ = it != speedLevels_.end() ? int(std::distance(speedLevels_.begin(), it)) : speedIndex_;
currentStep_ = speedLevels_[speedIndex_]; currentSpeed_ = speedLevels_[speedIndex_];
} }
void Timestep::SetManualRange(double start, double end) { void Timestep::SetManualRange(double start, double end) {
hasManualRange_ = true; hasManualRange_ = true;
manualStart_ = start; manualStart_ = start;
manualEnd_ = end; manualEnd_ = end;
// 当设置手动区间时,更新最大时间使播放边界正确
maxTime_ = end; maxTime_ = end;
// 通知 UI 更新范围与步进 // 通知 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); GetRange(minTime, maxTime, step);
emit RangeChanged(minTime, maxTime, step); emit RangeChanged(minTime, maxTime, step, currentSpeed_);
} }
void Timestep::ClearManualRange() { void Timestep::ClearManualRange() {
hasManualRange_ = false; hasManualRange_ = false;
manualStart_ = 0.0; manualStart_ = 0.0;
manualEnd_ = 0.0; manualEnd_ = 0.0;
// 恢复为数据驱动的最大时间,保留当前 maxTime_ double minTime = 0.0, maxTime = 0.0, step = 1.0;
// 通知 UI 更新范围与步进
double minTime = 0.0, maxTime = 0.0, step = 0.0;
GetRange(minTime, maxTime, step); GetRange(minTime, maxTime, step);
emit RangeChanged(minTime, maxTime, step); emit RangeChanged(minTime, maxTime, step, currentSpeed_);
} }
void Timestep::GetRange(double& minTime, double& maxTime, double& step) { 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; minTime = 0.0;
maxTime = maxTime_; maxTime = maxTime_;
} }
step = currentStep_; step = stepInterval_;
} }
void Timestep::Update(double dt) { void Timestep::Update(double dt) {
@ -66,7 +61,7 @@ void Timestep::Update(double dt) {
return; return;
} }
double deltaTime = dt * currentStep_; double deltaTime = dt * stepInterval_ * currentSpeed_;
current_ += deltaTime; current_ += deltaTime;
workSpace_->OnFrame(deltaTime); workSpace_->OnFrame(deltaTime);
@ -95,7 +90,6 @@ void Timestep::Start() {
return; return;
} }
workSpace_->Begin(); workSpace_->Begin();
// 保持当前倍速,不在开始时重置为 1x
emit StatusChanged((int)playStatus_); emit StatusChanged((int)playStatus_);
} }
@ -128,11 +122,6 @@ void Timestep::Stop() {
return; return;
} }
workSpace_->End(); 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_); emit StatusChanged((int)playStatus_);
} }
@ -141,24 +130,23 @@ void Timestep::Up() {
if (speedIndex_ < int(speedLevels_.size()) - 1) { if (speedIndex_ < int(speedLevels_.size()) - 1) {
++speedIndex_; ++speedIndex_;
} }
currentStep_ = speedLevels_[speedIndex_]; currentSpeed_ = speedLevels_[speedIndex_];
emit StepChanged(currentStep_); emit StepChanged(currentSpeed_);
} }
void Timestep::SetDataMaxTime(double end) { void Timestep::SetDataMaxTime(double end) {
maxTime_ = end; maxTime_ = end;
double minTime = 0.0, maxTime = 0.0, step = 0.0; double minTime = 0.0, maxTime = 0.0, step = 0.0;
GetRange(minTime, maxTime, step); GetRange(minTime, maxTime, step);
emit RangeChanged(minTime, maxTime, step); emit RangeChanged(minTime, maxTime, step, currentSpeed_);
} }
void Timestep::Down() { void Timestep::Down() {
// 降到上一个倍率(保底)
if (speedIndex_ > 0) { if (speedIndex_ > 0) {
--speedIndex_; --speedIndex_;
} }
currentStep_ = speedLevels_[speedIndex_]; currentSpeed_ = speedLevels_[speedIndex_];
emit StepChanged(currentStep_); emit StepChanged(currentSpeed_);
} }
void Timestep::SetSpeed(double speed) { void Timestep::SetSpeed(double speed) {
@ -175,6 +163,14 @@ void Timestep::SetSpeed(double speed) {
} }
} }
speedIndex_ = bestIdx; speedIndex_ = bestIdx;
currentStep_ = speedLevels_[speedIndex_]; currentSpeed_ = speedLevels_[speedIndex_];
emit StepChanged(currentStep_); 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_);
} }

View File

@ -25,6 +25,7 @@ public:
double GetCurrent() const { double GetCurrent() const {
return current_; return current_;
} }
double GetSpeed() const { return currentSpeed_; }
bool IsPause(); bool IsPause();
bool IsStoped(); bool IsStoped();
@ -35,17 +36,15 @@ public:
void Up(); void Up();
void Down(); void Down();
// 设置播放速度(倍率),会选取最接近的预设倍率并触发 StepChanged
void SetSpeed(double speed); void SetSpeed(double speed);
void SetStep(double step);
// 设置数据驱动的默认最大时间(非手动区间),用于没有文件步长时的播放边界
void SetDataMaxTime(double end); void SetDataMaxTime(double end);
WorkSpace* GetWorkSpace() const { WorkSpace* GetWorkSpace() const {
return workSpace_; return workSpace_;
} }
// 手动时间区间(可选):允许用户指定起止时间,替代或重映射步骤
void SetManualRange(double start, double end); void SetManualRange(double start, double end);
void ClearManualRange(); void ClearManualRange();
bool HasManualRange() const { return hasManualRange_; } bool HasManualRange() const { return hasManualRange_; }
@ -56,16 +55,14 @@ Q_SIGNALS:
void StatusChanged(int); void StatusChanged(int);
void StepChanged(double); void StepChanged(double);
void TimeChanged(double); void TimeChanged(double);
// 当时间范围或步进倍率更新时通知 UI例如设置手动区间或清除 void RangeChanged(double minTime, double maxTime, double step, double speed);
void RangeChanged(double minTime, double maxTime, double step);
private: private:
double current_{ 0.0 }; double current_{ 0.0 };
double maxTime_{ 0.0 }; double maxTime_{ 0.0 };
// 播放速度(倍率),与 UI 显示一致,比如 0.5x、1x、2x double currentSpeed_{ 1.0 };
double currentStep_{ 1.0 }; double stepInterval_{ 1.0 };
// 有限倍率列表,防止无限放大/缩小导致无法恢复
std::vector<double> speedLevels_{ 0.25, 0.5, 1.0, 2.0, 4.0, 8.0 }; std::vector<double> speedLevels_{ 0.25, 0.5, 1.0, 2.0, 4.0, 8.0 };
int speedIndex_{ 2 }; // 默认指向 1.0x int speedIndex_{ 2 }; // 默认指向 1.0x

View File

@ -73,12 +73,16 @@ bool WorkSpaceXMLParse::ParseTimestep(const tinyxml2::XMLElement* element) {
double start = 0.0; double start = 0.0;
double end = 0.0; double end = 0.0;
double step = 0.0; double step = 0.0;
double speed = 0.0;
bool hasStart = (element->QueryDoubleAttribute("start", &start) == tinyxml2::XML_SUCCESS); bool hasStart = (element->QueryDoubleAttribute("start", &start) == tinyxml2::XML_SUCCESS);
bool hasEnd = (element->QueryDoubleAttribute("end", &end) == tinyxml2::XML_SUCCESS); bool hasEnd = (element->QueryDoubleAttribute("end", &end) == tinyxml2::XML_SUCCESS);
bool hasStep = (element->QueryDoubleAttribute("step", &step) == 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) { if (hasStep) {
t->SetSpeed(step); t->SetStep(step);
} }
// 若标记为手动或具有完整的 start/end则设置手动范围否则按数据最大时间设置边界 // 若标记为手动或具有完整的 start/end则设置手动范围否则按数据最大时间设置边界

View File

@ -90,6 +90,7 @@ bool WorkSpaceXMLWrite::SaveTimeStep(tinyxml2::XMLElement* scene) {
timestep->SetAttribute("start", start); timestep->SetAttribute("start", start);
timestep->SetAttribute("end", end); timestep->SetAttribute("end", end);
timestep->SetAttribute("step", step); timestep->SetAttribute("step", step);
timestep->SetAttribute("speed", t->GetSpeed());
return true; return true;
} }