summaryrefslogtreecommitdiffstats
path: root/src/render/backend/cameralens.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/backend/cameralens.cpp')
-rw-r--r--src/render/backend/cameralens.cpp126
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