diff --git a/src/engine/game/game.cpp b/src/engine/game/game.cpp index 8d8213e6..07ea6e85 100644 --- a/src/engine/game/game.cpp +++ b/src/engine/game/game.cpp @@ -725,15 +725,17 @@ void Game::updateSceneGraph(float dt) { const Camera *camera = getActiveCamera(); if (!camera) return; - shared_ptr shadowReference; + // Select a reference node for dynamic lighting + shared_ptr lightingRefNode; shared_ptr partyLeader(_party.getLeader()); if (partyLeader && _cameraType == CameraType::ThirdPerson) { - shadowReference = partyLeader->getModelSceneNode(); + lightingRefNode = partyLeader->getModelSceneNode(); } else { - shadowReference = camera->sceneNode(); + lightingRefNode = camera->sceneNode(); } + _sceneGraph.setActiveCamera(camera->sceneNode()); - _sceneGraph.setShadowReference(shadowReference); + _sceneGraph.setLightingRefNode(lightingRefNode); _sceneGraph.setUpdateRoots(!_paused); _sceneGraph.update(dt); } diff --git a/src/engine/scene/node/modelnodescenenode.cpp b/src/engine/scene/node/modelnodescenenode.cpp index d863b630..e93f9a74 100644 --- a/src/engine/scene/node/modelnodescenenode.cpp +++ b/src/engine/scene/node/modelnodescenenode.cpp @@ -304,7 +304,7 @@ void ModelNodeSceneNode::drawSingle(bool shadowPass) { uniforms.combined.general.selfIllumColor = glm::vec4(_selfIllumColor, 1.0f); } if (isLightingEnabled()) { - const vector &lights = _modelSceneNode->lightsAffectedBy(); + const vector &lights = _sceneGraph->closestLights(); uniforms.combined.featureMask |= UniformFeatureFlags::lighting; if (_material.custom) { diff --git a/src/engine/scene/node/modelscenenode.cpp b/src/engine/scene/node/modelscenenode.cpp index 62091904..163be519 100644 --- a/src/engine/scene/node/modelscenenode.cpp +++ b/src/engine/scene/node/modelscenenode.cpp @@ -246,34 +246,6 @@ void ModelSceneNode::attach(const string &parent, const shared_ptr &n } } -void ModelSceneNode::updateAbsoluteTransform() { - SceneNode::updateAbsoluteTransform(); - _lightingDirty = true; -} - -void ModelSceneNode::updateLighting() { - if (!_lightingDirty) return; - - _lightsAffectedBy.clear(); - _sceneGraph->getLightsAt(*this, _lightsAffectedBy, kMaxLights, bind(&ModelSceneNode::isAffectableByLight, this, _1)); - _lightingDirty = false; - - for (auto &attached : _attachedModels) { - attached.second->setLightsAffectedBy(_lightsAffectedBy); - } -} - -bool ModelSceneNode::isAffectableByLight(const LightSceneNode &light) const { - if (light.isAmbientOnly()) { - return _usage == ModelUsage::Room; - } - return true; -} - -void ModelSceneNode::setLightingIsDirty() { - _lightingDirty = true; -} - bool ModelSceneNode::getNodeAbsolutePosition(const string &name, glm::vec3 &position) const { shared_ptr node(_model->findNodeByName(name)); if (!node) { @@ -313,9 +285,6 @@ void ModelSceneNode::setVisible(bool visible) { for (auto &attached : _attachedModels) { attached.second->setVisible(visible); } - if (visible) { - _lightingDirty = true; - } } void ModelSceneNode::setAlpha(float alpha) { @@ -330,10 +299,6 @@ void ModelSceneNode::setProjectileSpeed(float speed) { _projectileSpeed = speed; } -void ModelSceneNode::setLightsAffectedBy(const vector &lights) { - _lightsAffectedBy = lights; -} - void ModelSceneNode::setWalkmesh(shared_ptr walkmesh) { _walkmesh = move(walkmesh); } diff --git a/src/engine/scene/node/modelscenenode.h b/src/engine/scene/node/modelscenenode.h index ab293764..4d735fa5 100644 --- a/src/engine/scene/node/modelscenenode.h +++ b/src/engine/scene/node/modelscenenode.h @@ -83,17 +83,6 @@ public: // END Attachments - // Dynamic lighting - - void updateLighting(); - void setLightingIsDirty(); - - const std::vector &lightsAffectedBy() const { return _lightsAffectedBy; } - - void setLightsAffectedBy(const std::vector &lights); - - // END Dynamic lighting - private: IAnimationEventListener *_animEventListener; @@ -109,14 +98,9 @@ private: std::unordered_map> _attachedModels; bool _visible { true }; float _alpha { 1.0f }; - std::vector _lightsAffectedBy; - bool _lightingDirty { true }; float _projectileSpeed { 0.0f }; void initModelNodes(); - void updateAbsoluteTransform() override; - - bool isAffectableByLight(const LightSceneNode &light) const; std::unique_ptr getModelNodeSceneNode(graphics::ModelNode &node) const; }; diff --git a/src/engine/scene/scenegraph.cpp b/src/engine/scene/scenegraph.cpp index 6c887564..0106c98c 100644 --- a/src/engine/scene/scenegraph.cpp +++ b/src/engine/scene/scenegraph.cpp @@ -86,11 +86,10 @@ void SceneGraph::cullRoots() { } void SceneGraph::updateLighting() { - // Associate each model node with light sources - for (auto &root : _roots) { - if (root->type() == SceneNodeType::Model) { - static_pointer_cast(root)->updateLighting(); - } + _closestLights.clear(); + + if (_lightingRefNode) { + getLightsAt(*_lightingRefNode, _closestLights, kMaxLights, [](auto &light) { return !light.isAmbientOnly(); }); } } @@ -167,9 +166,9 @@ void SceneGraph::refreshFromSceneNode(const std::shared_ptr &node) { void SceneGraph::refreshShadowLight() { const LightSceneNode *nextShadowLight = nullptr; - if (_shadowReference) { + if (_lightingRefNode) { vector lights; - getLightsAt(*_shadowReference, lights, 1, [](auto &light) { return light.isShadow(); }); + getLightsAt(*_lightingRefNode, lights, 1, [](auto &light) { return light.isShadow(); }); if (!lights.empty()) { nextShadowLight = lights.front(); diff --git a/src/engine/scene/scenegraph.h b/src/engine/scene/scenegraph.h index de214c30..5a228b5a 100644 --- a/src/engine/scene/scenegraph.h +++ b/src/engine/scene/scenegraph.h @@ -66,7 +66,6 @@ public: void setUpdateRoots(bool update) { _updateRoots = update; } void setActiveCamera(std::shared_ptr camera) { _activeCamera = std::move(camera); } - void setShadowReference(std::shared_ptr reference) { _shadowReference = std::move(reference); } void setUniformsPrototype(graphics::ShaderUniforms &&uniforms) { _uniformsPrototype = uniforms; } // Roots @@ -77,7 +76,7 @@ public: // END Roots - // Lights and shadows + // Lighting and shadows /** * Fill lights vector with up to count lights, sorted by priority and @@ -90,12 +89,14 @@ public: std::function predicate = [](auto &light) { return true; }) const; const glm::vec3 &ambientLightColor() const { return _ambientLightColor; } + const std::vector closestLights() const { return _closestLights; } const LightSceneNode *shadowLight() const { return _shadowLight; } float shadowStrength() const { return _shadowStrength; } void setAmbientLightColor(glm::vec3 color) { _ambientLightColor = std::move(color); } + void setLightingRefNode(std::shared_ptr node) { _lightingRefNode = std::move(node); } - // END Lights and shadows + // END Lighting and shadows // Fog @@ -127,19 +128,20 @@ private: std::vector>> _particles; std::vector>> _grassClusters; - glm::vec3 _ambientLightColor { 0.5f }; uint32_t _textureId { 0 }; bool _updateRoots { true }; graphics::ShaderUniforms _uniformsPrototype; - // Shadows + // Lighting and shadows + glm::vec3 _ambientLightColor { 0.5f }; + std::shared_ptr _lightingRefNode; /**< reference node to use when selecting closest light sources */ + std::vector _closestLights; const LightSceneNode *_shadowLight { nullptr }; - std::shared_ptr _shadowReference; float _shadowStrength { 1.0f }; bool _shadowFading { false }; - // END Shadows + // END Lighting and shadows // Fog