From 3089aeccc4f82aebd9d5ae1801b3d9adcf5621eb Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 6 Jan 2016 13:37:55 +0100 Subject: [PATCH] Factor out SceneUtil::addLight --- apps/openmw/mwrender/animation.cpp | 66 +------------------------- components/sceneutil/lightutil.cpp | 75 ++++++++++++++++++++++++++++++ components/sceneutil/lightutil.hpp | 21 +++++++-- 3 files changed, 94 insertions(+), 68 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 6300d28cf..549d0eb8e 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -31,8 +30,6 @@ #include #include #include -#include -#include #include #include @@ -1088,38 +1085,7 @@ namespace MWRender void Animation::addExtraLight(osg::ref_ptr parent, const ESM::Light *esmLight) { - SceneUtil::FindByNameVisitor visitor("AttachLight"); - parent->accept(visitor); - - osg::Group* attachTo = NULL; - if (visitor.mFoundNode) - { - attachTo = visitor.mFoundNode; - } - else - { - osg::ComputeBoundsVisitor computeBound; - computeBound.setTraversalMask(~Mask_ParticleSystem); - parent->accept(computeBound); - - // PositionAttitudeTransform seems to be slightly faster than MatrixTransform - osg::ref_ptr trans(new osg::PositionAttitudeTransform); - trans->setPosition(computeBound.getBoundingBox().center()); - - parent->addChild(trans); - - attachTo = trans; - } - - osg::ref_ptr lightSource = new SceneUtil::LightSource; - osg::ref_ptr light (new osg::Light); - lightSource->setNodeMask(Mask_Lighting); - const Fallback::Map* fallback = MWBase::Environment::get().getWorld()->getFallback(); - - float radius = esmLight->mData.mRadius; - lightSource->setRadius(radius); - static bool outQuadInLin = fallback->getFallbackBool("LightAttenuation_OutQuadInLin"); static bool useQuadratic = fallback->getFallbackBool("LightAttenuation_UseQuadratic"); static float quadraticValue = fallback->getFallbackFloat("LightAttenuation_QuadraticValue"); @@ -1127,38 +1093,10 @@ namespace MWRender static bool useLinear = fallback->getFallbackBool("LightAttenuation_UseLinear"); static float linearRadiusMult = fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult"); static float linearValue = fallback->getFallbackFloat("LightAttenuation_LinearValue"); - bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior(); - SceneUtil::configureLight(light, radius, exterior, outQuadInLin, useQuadratic, quadraticValue, - quadraticRadiusMult, useLinear, linearRadiusMult, linearValue); - - osg::Vec4f diffuse = SceneUtil::colourFromRGB(esmLight->mData.mColor); - if (esmLight->mData.mFlags & ESM::Light::Negative) - { - diffuse *= -1; - diffuse.a() = 1; - } - light->setDiffuse(diffuse); - light->setAmbient(osg::Vec4f(0,0,0,1)); - light->setSpecular(osg::Vec4f(0,0,0,0)); - - lightSource->setLight(light); - - osg::ref_ptr ctrl (new SceneUtil::LightController); - ctrl->setDiffuse(light->getDiffuse()); - if (esmLight->mData.mFlags & ESM::Light::Flicker) - ctrl->setType(SceneUtil::LightController::LT_Flicker); - if (esmLight->mData.mFlags & ESM::Light::FlickerSlow) - ctrl->setType(SceneUtil::LightController::LT_FlickerSlow); - if (esmLight->mData.mFlags & ESM::Light::Pulse) - ctrl->setType(SceneUtil::LightController::LT_Pulse); - if (esmLight->mData.mFlags & ESM::Light::PulseSlow) - ctrl->setType(SceneUtil::LightController::LT_PulseSlow); - - lightSource->addUpdateCallback(ctrl); - - attachTo->addChild(lightSource); + SceneUtil::addLight(parent, esmLight, Mask_ParticleSystem, Mask_Lighting, exterior, outQuadInLin, + useQuadratic, quadraticValue, quadraticRadiusMult, useLinear, linearRadiusMult, linearValue); } void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, std::string texture) diff --git a/components/sceneutil/lightutil.cpp b/components/sceneutil/lightutil.cpp index 711a94ba8..00f7f4d13 100644 --- a/components/sceneutil/lightutil.cpp +++ b/components/sceneutil/lightutil.cpp @@ -1,6 +1,16 @@ #include "lightutil.hpp" #include +#include +#include + +#include + +#include "lightmanager.hpp" +#include "lightcontroller.hpp" +#include "util.hpp" +#include "visitor.hpp" +#include "positionattitudetransform.hpp" namespace SceneUtil { @@ -29,4 +39,69 @@ namespace SceneUtil } + void addLight (osg::Group* node, const ESM::Light* esmLight, int partsysMask, int lightMask, bool isExterior, bool outQuadInLin, bool useQuadratic, + float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult, + float linearValue) + { + SceneUtil::FindByNameVisitor visitor("AttachLight"); + node->accept(visitor); + + osg::Group* attachTo = NULL; + if (visitor.mFoundNode) + { + attachTo = visitor.mFoundNode; + } + else + { + osg::ComputeBoundsVisitor computeBound; + computeBound.setTraversalMask(~partsysMask); + node->accept(computeBound); + + // PositionAttitudeTransform seems to be slightly faster than MatrixTransform + osg::ref_ptr trans(new SceneUtil::PositionAttitudeTransform); + trans->setPosition(computeBound.getBoundingBox().center()); + + node->addChild(trans); + + attachTo = trans; + } + + osg::ref_ptr lightSource (new SceneUtil::LightSource); + osg::ref_ptr light (new osg::Light); + lightSource->setNodeMask(lightMask); + + float radius = esmLight->mData.mRadius; + lightSource->setRadius(radius); + + configureLight(light, radius, isExterior, outQuadInLin, useQuadratic, quadraticValue, + quadraticRadiusMult, useLinear, linearRadiusMult, linearValue); + + osg::Vec4f diffuse = SceneUtil::colourFromRGB(esmLight->mData.mColor); + if (esmLight->mData.mFlags & ESM::Light::Negative) + { + diffuse *= -1; + diffuse.a() = 1; + } + light->setDiffuse(diffuse); + light->setAmbient(osg::Vec4f(0,0,0,1)); + light->setSpecular(osg::Vec4f(0,0,0,0)); + + lightSource->setLight(light); + + osg::ref_ptr ctrl (new SceneUtil::LightController); + ctrl->setDiffuse(light->getDiffuse()); + if (esmLight->mData.mFlags & ESM::Light::Flicker) + ctrl->setType(SceneUtil::LightController::LT_Flicker); + if (esmLight->mData.mFlags & ESM::Light::FlickerSlow) + ctrl->setType(SceneUtil::LightController::LT_FlickerSlow); + if (esmLight->mData.mFlags & ESM::Light::Pulse) + ctrl->setType(SceneUtil::LightController::LT_Pulse); + if (esmLight->mData.mFlags & ESM::Light::PulseSlow) + ctrl->setType(SceneUtil::LightController::LT_PulseSlow); + + lightSource->addUpdateCallback(ctrl); + + attachTo->addChild(lightSource); + } + } diff --git a/components/sceneutil/lightutil.hpp b/components/sceneutil/lightutil.hpp index 09d23d4a2..f7879cd72 100644 --- a/components/sceneutil/lightutil.hpp +++ b/components/sceneutil/lightutil.hpp @@ -2,6 +2,11 @@ #define OPENMW_COMPONENTS_LIGHTUTIL_H namespace osg +{ + class Group; +} + +namespace ESM { class Light; } @@ -9,10 +14,18 @@ namespace osg namespace SceneUtil { - /// @brief Configures a light's attenuation according to vanilla Morrowind attenuation settings. - void configureLight(osg::Light* light, float radius, bool isExterior, bool outQuadInLin, bool useQuadratic, - float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult, - float linearValue); + /// @brief Convert an ESM::Light to a SceneUtil::LightSource, and add it to a sub graph. + /// @note If the sub graph contains a node named "AttachLight" (case insensitive), then the light is added to that. + /// Otherwise, the light is added in the center of the node's bounds. + /// @param node The sub graph to add a light to + /// @param esmLight The light definition coming from the game files containing radius, color, flicker, etc. + /// @param partsysMask Node mask to ignore when computing the sub graph's bounding box. + /// @param lightMask Mask to assign to the newly created LightSource. + /// @param isExterior Is the light outside? May be used for deciding which attenuation settings to use. + /// @par Attenuation parameters come from the game INI file. + void addLight (osg::Group* node, const ESM::Light* esmLight, int partsysMask, int lightMask, bool isExterior, bool outQuadInLin, bool useQuadratic, + float quadraticValue, float quadraticRadiusMult, bool useLinear, float linearRadiusMult, + float linearValue); }