diff options
Diffstat (limited to 'src/render/backend/cameralens.cpp')
-rw-r--r-- | src/render/backend/cameralens.cpp | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/src/render/backend/cameralens.cpp b/src/render/backend/cameralens.cpp index e60a32422..ef71507eb 100644 --- a/src/render/backend/cameralens.cpp +++ b/src/render/backend/cameralens.cpp @@ -39,8 +39,14 @@ #include "cameralens_p.h" #include <Qt3DRender/qcameralens.h> +#include <Qt3DRender/private/nodemanagers_p.h> +#include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/qcameralens_p.h> #include <Qt3DRender/private/renderlogging_p.h> +#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/entity_p.h> +#include <Qt3DRender/private/sphere_p.h> +#include <Qt3DRender/private/computefilteredboundingvolumejob_p.h> #include <Qt3DCore/qentity.h> #include <Qt3DCore/qpropertyupdatedchange.h> #include <Qt3DCore/qtransform.h> @@ -52,8 +58,35 @@ using namespace Qt3DCore; namespace Qt3DRender { namespace Render { + +namespace { + +class GetBoundingVolumeWithoutCameraJob : public ComputeFilteredBoundingVolumeJob +{ +public: + GetBoundingVolumeWithoutCameraJob(CameraLens *lens, + QNodeCommand::CommandId commandId) + : m_lens(lens), m_commandId(commandId) + { + } + +protected: + void finished(const Sphere &sphere) override + { + m_lens->notifySceneBoundingVolume(sphere, m_commandId); + } + +private: + CameraLens *m_lens; + QNodeCommand::CommandId m_commandId; +}; + +} // namespace + CameraLens::CameraLens() - : BackendNode() + : BackendNode(QBackendNode::ReadWrite) + , m_renderAspect(nullptr) + , m_exposure(0.0f) { } @@ -67,11 +100,52 @@ void CameraLens::cleanup() QBackendNode::setEnabled(false); } +void CameraLens::setRenderAspect(QRenderAspect *renderAspect) +{ + m_renderAspect = renderAspect; +} + void CameraLens::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) { const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QCameraLensData>>(change); const auto &data = typedChange->data; m_projection = data.projectionMatrix; + m_exposure = data.exposure; +} + +void CameraLens::computeSceneBoundingVolume(QNodeId entityId, + QNodeId cameraId, + QNodeCommand::CommandId commandId) +{ + if (!m_renderer || !m_renderAspect) + return; + NodeManagers *nodeManagers = m_renderer->nodeManagers(); + + Entity *root = m_renderer->sceneRoot(); + if (!entityId.isNull()) + root = nodeManagers->renderNodesManager()->lookupResource(entityId); + if (!root) + return; + + Entity *camNode = nodeManagers->renderNodesManager()->lookupResource(cameraId); + ComputeFilteredBoundingVolumeJobPtr job(new GetBoundingVolumeWithoutCameraJob(this, commandId)); + job->addDependency(m_renderer->expandBoundingVolumeJob()); + job->setRoot(root); + job->ignoreSubTree(camNode); + m_renderAspect->scheduleSingleShotJob(job); +} + +void CameraLens::notifySceneBoundingVolume(const Sphere &sphere, QNodeCommand::CommandId commandId) +{ + if (m_pendingViewAllCommand != commandId) + return; + if (sphere.radius() > 0.f) { + QVector<float> data = { sphere.center().x(), sphere.center().y(), sphere.center().z(), + sphere.radius() }; + QVariant v; + v.setValue(data); + sendCommand(QLatin1Literal("ViewAll"), v, m_pendingViewAllCommand); + } } void CameraLens::setProjection(const QMatrix4x4 &projection) @@ -79,6 +153,11 @@ void CameraLens::setProjection(const QMatrix4x4 &projection) m_projection = projection; } +void CameraLens::setExposure(float exposure) +{ + m_exposure = exposure; +} + void CameraLens::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) { switch (e->type()) { @@ -88,18 +167,63 @@ void CameraLens::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) if (propertyChange->propertyName() == QByteArrayLiteral("projectionMatrix")) { QMatrix4x4 projectionMatrix = propertyChange->value().value<QMatrix4x4>(); m_projection = projectionMatrix; + } else if (propertyChange->propertyName() == QByteArrayLiteral("exposure")) { + setExposure(propertyChange->value().toFloat()); } markDirty(AbstractRenderer::AllDirty); } break; + case CommandRequested: { + QNodeCommandPtr command = qSharedPointerCast<QNodeCommand>(e); + + if (command->name() == QLatin1Literal("QueryRootBoundingVolume")) { + m_pendingViewAllCommand = command->commandId(); + QVariant v = command->data(); + QNodeId id = v.value<QNodeId>(); + computeSceneBoundingVolume({}, id, command->commandId()); + } else if (command->name() == QLatin1Literal("QueryEntityBoundingVolume")) { + m_pendingViewAllCommand = command->commandId(); + QVariant v = command->data(); + QVector<QNodeId> ids = v.value<QVector<QNodeId>>(); + if (ids.size() == 2) + computeSceneBoundingVolume(ids[0], ids[1], command->commandId()); + } + } + break; + default: break; } BackendNode::sceneChangeEvent(e); } +CameraLensFunctor::CameraLensFunctor(AbstractRenderer *renderer, QRenderAspect *renderAspect) + : m_manager(renderer->nodeManagers()->manager<CameraLens, CameraManager>()) + , m_renderer(renderer) + , m_renderAspect(renderAspect) +{ +} + +QBackendNode *CameraLensFunctor::create(const QNodeCreatedChangeBasePtr &change) const +{ + CameraLens *backend = m_manager->getOrCreateResource(change->subjectId()); + backend->setRenderer(m_renderer); + backend->setRenderAspect(m_renderAspect); + return backend; +} + +QBackendNode *CameraLensFunctor::get(QNodeId id) const +{ + return m_manager->lookupResource(id); +} + +void CameraLensFunctor::destroy(QNodeId id) const +{ + m_manager->releaseResource(id); +} + } // namespace Render } // namespace Qt3DRender |