gpt4 book ai didi

qt3d - 连续触发光线转换测试

转载 作者:行者123 更新时间:2023-12-02 03:23:38 25 4
gpt4 key购买 nike

已关注 this answer ,我正在进行连续的光线转换:

m_rayCaster = new Qt3DRender::QRayCaster(m_scene->rootEntity());
m_rayCaster->setRunMode(Qt3DRender::QAbstractRayCaster::SingleShot);
m_scene->rootEntity()->addComponent(m_rayCaster);

我有这些插槽来处理是否以及何时应该进行下一个连续光线转换测试:

QObject::connect(m_rayCaster, &Qt3DRender::QRayCaster::hitsChanged, this, &RayCastHandler::handleRayCasterHits);
QObject::connect(m_rayCaster, &Qt3DCore::QNode::enabledChanged, this, &RayCastHandler::handleRayCasterEnabledChange);
QObject::connect(this, &RayCastHandler::isPreviousTestDoneChanged, this, &RayCastHandler::handleIsPreviousTestDoneChange);
QObject::connect(this, &RayCastHandler::isNextTestRequiredChanged, this, &RayCastHandler::handleIsNextTestRequiredChange);

插槽设置条件并检查它们:

void RayCastHandler::handleRayCasterHits(const Qt3DRender::QAbstractRayCaster::Hits hits)
{
analyzeHits(hits);
bool required = isNextTestRequired(/* according to m_testCounter, m_testsTotal, ... */);
emit isNextTestRequiredChanged(required);
emit isPreviousTestDoneChanged(true);
return;
}

void RayCastHandler::handleRayCasterEnabledChange(const bool enabled)
{
m_isRayCasterEnabled = enabled;
triggerNextTestIfAllConditionsAreTrue();
return;
}

void RayCastHandler::handleIsPreviousTestDoneChange(const bool done)
{
m_isPreviousTestDone = done;
triggerNextTestIfAllConditionsAreTrue();
return;
}

void RayCastHandler::handleIsNextTestRequiredChange(const bool required)
{
m_isNextTestRequired = required;
if (!m_isNextTestRequired)
emit rayCastResultsChanged(m_collisions);
triggerNextTestIfAllConditionsAreTrue();
return;
}

检查是否需要下一次光线转换测试的代码:

bool RayCastHandler::isNextTestRequired(int &testCounter, const int &testsTotal)
{
testCounter++;
if (testCounter >= testsTotal) {
return false;
}
return true;
}

最后,检查触发下一次光线转换测试的所有条件的函数是:

bool RayCastHandler::triggerNextTestIfAllConditionsAreTrue()
{
if (m_isPreviousTestDone && m_isNextTestRequired && m_isRayCasterEnabled) {
triggerTest(/* Will trigger next ray cast test */);
m_isPreviousTestDone = false;
m_isNextTestRequired = false;
m_isRayCasterEnabled = false;
}
}

代码工作正常,但在连续转换几条光线后,它停止了。

通过登录控制台,我观察到 m_rayCaster 看起来是随机启用/禁用的。我的意思是,有时在完成光线转换测试后,它会自行禁用,有时会自行启用!我想知道是否有人可以介绍一下 Qt3DRender::QRayCaster 启用/禁用逻辑的引用。我稍微查看了一下它的源代码,我想知道哪一段源代码可以帮助我弄清楚。

最佳答案

只是想分享我的观察:

我通过仅保留两个信号槽连接来简化代码:

QObject::connect(m_rayCaster, &Qt3DRender::QRayCaster::hitsChanged, this, &RayCastHandler::handleRayCasterHits);
QObject::connect(m_rayCaster, &Qt3DCore::QNode::enabledChanged, this, &RayCastHandler::handleRayCasterEnabledChange);

一个插槽分析光线转换器的命中:

void RayCastHandler::handleRayCasterHits(const Qt3DRender::QAbstractRayCaster::Hits hits)
{
analyzeHits( ... , hits);
return;
}

如果光线转换器已禁用自身,则另一个插槽将运行下一个连续的光线转换测试:

void RayCastHandler::handleRayCasterEnabledChange(const bool enabled)
{
// When the component disables itself, it is ready for the next ray-cast test
if (!enabled) {
bool required = isNextTestRequired( ... );
if (required)
triggerTest( ... );
else
// Send final ray-cast results by a signal, if next test is NOT needed
emit rayCastResultsChanged( ... );
}
return;
}
<小时/>

只要我触发带有时间延迟的光线转换测试,上面的代码就可以工作。有时我必须增加上述延迟时间才能使其发挥作用。但至少它有效。虽然它很痛苦,因为它不可靠:

void RayCastHandler::triggerTest( ... )
{
...
// 1 millisecond delay time
QTimer::singleShot(1, [rayCaster, origin, direction, length](){rayCaster->trigger(origin, direction, length);});

...
}

但是,如果我不使用延迟时间,在某些时候,光线转换器会意外停止,而不发送任何包含命中结果的信号,并且光线转换器永远保持启用状态。看起来光线转换器卡住了:

void RayCastHandler::triggerTest( ... )
{
...
// No delay
rayCaster->trigger(origin, direction, length);

...
}

关于qt3d - 连续触发光线转换测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57995843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com