1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 16:59:56 +00:00

add overwriteLighting a toggle option for addVfx

This commit is contained in:
Sebastian Fieber 2024-12-31 01:57:09 +00:00 committed by Alexei Kotov
parent 63b8e636f3
commit 5cb6da4b02
15 changed files with 63 additions and 38 deletions

View file

@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...")
set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 49)
set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_LUA_API_REVISION 68)
set(OPENMW_LUA_API_REVISION 69)
set(OPENMW_POSTPROCESSING_API_REVISION 2)
set(OPENMW_VERSION_COMMITHASH "")

View file

@ -516,7 +516,7 @@ namespace MWBase
virtual void spawnBloodEffect(const MWWorld::Ptr& ptr, const osg::Vec3f& worldPosition) = 0;
virtual void spawnEffect(VFS::Path::NormalizedView model, const std::string& textureOverride,
const osg::Vec3f& worldPos, float scale = 1.f, bool isMagicVFX = true)
const osg::Vec3f& worldPos, float scale = 1.f, bool isMagicVFX = true, bool useAmbientLight = false)
= 0;
/// @see MWWorld::WeatherManager::isInStorm

View file

@ -267,10 +267,11 @@ namespace MWLua
[object = ObjectVariant(object), model = std::string(model),
effectId = options->get_or<std::string>("vfxId", ""), loop = options->get_or("loop", false),
boneName = options->get_or<std::string>("boneName", ""),
particleTexture = options->get_or<std::string>("particleTextureOverride", "")] {
particleTexture = options->get_or<std::string>("particleTextureOverride", ""),
useAmbientLight = options->get_or("useAmbientLight", true)] {
MWRender::Animation* anim = getMutableAnimationOrThrow(ObjectVariant(object));
anim->addEffect(model, effectId, loop, boneName, particleTexture);
anim->addEffect(model, effectId, loop, boneName, particleTexture, useAmbientLight);
},
"addVfxAction");
}
@ -318,15 +319,20 @@ namespace MWLua
bool magicVfx = options->get_or("mwMagicVfx", true);
std::string texture = options->get_or<std::string>("particleTextureOverride", "");
float scale = options->get_or("scale", 1.f);
bool useAmbientLight = options->get_or("useAmbientLight", true);
context.mLuaManager->addAction(
[world, model = VFS::Path::Normalized(model), texture = std::move(texture), worldPos, scale,
magicVfx]() { world->spawnEffect(model, texture, worldPos, scale, magicVfx); },
magicVfx, useAmbientLight]() {
world->spawnEffect(model, texture, worldPos, scale, magicVfx, useAmbientLight);
},
"openmw.vfx.spawn");
}
else
{
context.mLuaManager->addAction([world, model = VFS::Path::Normalized(model),
worldPos]() { world->spawnEffect(model, "", worldPos); },
context.mLuaManager->addAction(
[world, model = VFS::Path::Normalized(model), worldPos]() {
world->spawnEffect(model, "", worldPos, 1.f, true, true);
},
"openmw.vfx.spawn");
}
};

View file

@ -389,22 +389,6 @@ namespace
std::string_view mEffectId;
};
namespace
{
osg::ref_ptr<osg::LightModel> makeVFXLightModelInstance()
{
osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel;
lightModel->setAmbientIntensity({ 1, 1, 1, 1 });
return lightModel;
}
const osg::ref_ptr<osg::LightModel>& getVFXLightModelInstance()
{
static const osg::ref_ptr<osg::LightModel> lightModel = makeVFXLightModelInstance();
return lightModel;
}
}
void assignBoneBlendCallbackRecursive(MWRender::BoneAnimBlendController* controller, osg::Node* parent, bool isRoot)
{
// Attempt to cast node to an osgAnimation::Bone
@ -1725,7 +1709,7 @@ namespace MWRender
}
void Animation::addEffect(std::string_view model, std::string_view effectId, bool loop, std::string_view bonename,
std::string_view texture)
std::string_view texture, bool useAmbientLight)
{
if (!mObjectRoot.get())
return;
@ -1778,10 +1762,15 @@ namespace MWRender
osg::ref_ptr<osg::Node> node
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(model), trans);
// Morrowind has a white ambient light attached to the root VFX node of the scenegraph
node->getOrCreateStateSet()->setAttributeAndModes(
getVFXLightModelInstance(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
if (useAmbientLight)
{
// Morrowind has a white ambient light attached to the root VFX node of the scenegraph
node->getOrCreateStateSet()->setAttributeAndModes(
getVFXLightModelInstance(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
}
mResourceSystem->getSceneManager()->setUpNormalsRTForStateSet(node->getOrCreateStateSet(), false);
SceneUtil::FindMaxControllerLengthVisitor findMaxLengthVisitor;
node->accept(findMaxLengthVisitor);

View file

@ -342,10 +342,13 @@ namespace MWRender
* you need to remove it manually using removeEffect when the effect should end.
* @param bonename Bone to attach to, or empty string to use the scene node instead
* @param texture override the texture specified in the model's materials - if empty, do not override
* @param useAmbientLight attach white ambient light to the root VFX node of the scenegraph (Morrowind
* default)
* @note Will not add an effect twice.
*/
void addEffect(std::string_view model, std::string_view effectId, bool loop = false,
std::string_view bonename = {}, std::string_view texture = {});
std::string_view bonename = {}, std::string_view texture = {}, bool useAmbientLight = true);
void removeEffect(std::string_view effectId);
void removeEffects();
std::vector<std::string_view> getLoopingEffects() const;

View file

@ -28,7 +28,7 @@ namespace MWRender
}
void EffectManager::addEffect(VFS::Path::NormalizedView model, std::string_view textureOverride,
const osg::Vec3f& worldPosition, float scale, bool isMagicVFX)
const osg::Vec3f& worldPosition, float scale, bool isMagicVFX, bool useAmbientLight)
{
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(model);
@ -58,6 +58,15 @@ namespace MWRender
mParentNode->addChild(trans);
if (useAmbientLight)
{
// Morrowind has a white ambient light attached to the root VFX node of the scenegraph
node->getOrCreateStateSet()->setAttributeAndModes(
getVFXLightModelInstance(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
}
mResourceSystem->getSceneManager()->setUpNormalsRTForStateSet(node->getOrCreateStateSet(), false);
mEffects.push_back(std::move(effect));
}

View file

@ -35,7 +35,7 @@ namespace MWRender
/// Add an effect. When it's finished playing, it will be removed automatically.
void addEffect(VFS::Path::NormalizedView model, std::string_view textureOverride,
const osg::Vec3f& worldPosition, float scale, bool isMagicVFX = true);
const osg::Vec3f& worldPosition, float scale, bool isMagicVFX = true, bool useAmbientLight = false);
void update(float dt);

View file

@ -1248,9 +1248,9 @@ namespace MWRender
}
void RenderingManager::spawnEffect(VFS::Path::NormalizedView model, std::string_view texture,
const osg::Vec3f& worldPosition, float scale, bool isMagicVFX)
const osg::Vec3f& worldPosition, float scale, bool isMagicVFX, bool useAmbientLight)
{
mEffectManager->addEffect(model, texture, worldPosition, scale, isMagicVFX);
mEffectManager->addEffect(model, texture, worldPosition, scale, isMagicVFX, useAmbientLight);
}
void RenderingManager::notifyWorldSpaceChanged()

View file

@ -195,7 +195,7 @@ namespace MWRender
SkyManager* getSkyManager();
void spawnEffect(VFS::Path::NormalizedView model, std::string_view texture, const osg::Vec3f& worldPosition,
float scale = 1.f, bool isMagicVFX = true);
float scale = 1.f, bool isMagicVFX = true, bool useAmbientLight = false);
/// Clear all savegame-specific data
void clear();

View file

@ -74,4 +74,16 @@ namespace MWRender
return Settings::shaders().mAntialiasAlphaTest && Settings::video().mAntialiasing > 1;
}
osg::ref_ptr<osg::LightModel> makeVFXLightModelInstance()
{
osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel;
lightModel->setAmbientIntensity({ 1, 1, 1, 1 });
return lightModel;
}
const osg::ref_ptr<osg::LightModel>& getVFXLightModelInstance()
{
static const osg::ref_ptr<osg::LightModel> lightModel = makeVFXLightModelInstance();
return lightModel;
}
}

View file

@ -1,6 +1,7 @@
#ifndef OPENMW_MWRENDER_UTIL_H
#define OPENMW_MWRENDER_UTIL_H
#include <osg/LightModel>
#include <osg/NodeCallback>
#include <string_view>
@ -35,6 +36,8 @@ namespace MWRender
};
bool shouldAddMSAAIntermediateTarget();
const osg::ref_ptr<osg::LightModel>& getVFXLightModelInstance();
}
#endif

View file

@ -3689,9 +3689,9 @@ namespace MWWorld
}
void World::spawnEffect(VFS::Path::NormalizedView model, const std::string& textureOverride,
const osg::Vec3f& worldPos, float scale, bool isMagicVFX)
const osg::Vec3f& worldPos, float scale, bool isMagicVFX, bool useAmbientLight)
{
mRendering->spawnEffect(model, textureOverride, worldPos, scale, isMagicVFX);
mRendering->spawnEffect(model, textureOverride, worldPos, scale, isMagicVFX, useAmbientLight);
}
struct ResetActorsVisitor

View file

@ -603,7 +603,8 @@ namespace MWWorld
void spawnBloodEffect(const MWWorld::Ptr& ptr, const osg::Vec3f& worldPosition) override;
void spawnEffect(VFS::Path::NormalizedView model, const std::string& textureOverride,
const osg::Vec3f& worldPos, float scale = 1.f, bool isMagicVFX = true) override;
const osg::Vec3f& worldPos, float scale = 1.f, bool isMagicVFX = true,
bool useAmbientLight = false) override;
/// @see MWWorld::WeatherManager::isInStorm
bool isInStorm() const override;

View file

@ -227,8 +227,9 @@
-- * `loop` - boolean, if true the effect will loop until removed (default: 0).
-- * `boneName` - name of the bone to attach the vfx to. (default: "")
-- * `particleTextureOverride` - name of the particle texture to use. (default: "")
-- * `vfxId` - a string ID that can be used to remove the effect later, using #removeVfx, and to avoid duplicate effects. The default value of "" can have duplicates. To avoid interaction with the engine, use unique identifiers unrelated to magic effect IDs. The engine uses this identifier to add and remove magic effects based on what effects are active on the actor. If this is set equal to the @{openmw.core#MagicEffectId} identifier of the magic effect being added, for example core.magic.EFFECT_TYPE.FireDamage, then the engine will remove it once the fire damage effect on the actor reaches 0. (Default: "").
--
-- * `vfxId` - a string ID that can be used to remove the effect later, using #removeVfx, and to avoid duplicate effects. The default value of "" can have duplicates. To avoid interaction with the engine, use unique identifiers unrelated to magic effect IDs. The engine uses this identifier to add and remove magic effects based on what effects are active on the actor. If this is set equal to the @{openmw.core#MagicEffectId} identifier of the magic effect being added, for example core.magic.EFFECT_TYPE.FireDamage, then the engine will remove it once the fire damage effect on the actor reaches 0. (Default: "").
-- * `useAmbientLighting` - boolean, vfx get a white ambient light attached in Morrowind. If false don't attach this. (default: 1)
--
-- @usage local mgef = core.magic.effects.records[myEffectName]
-- anim.addVfx(self, 'VFX_Hands', {boneName = 'Bip01 L Hand', particleTextureOverride = mgef.particle, loop = mgef.continuousVfx, vfxId = mgef.id..'_myuniquenamehere'})
-- -- later:

View file

@ -193,6 +193,7 @@
-- * `mwMagicVfx` - Boolean that if true causes the textureOverride parameter to only affect nodes with the Nif::RC_NiTexturingProperty property set. (default: true).
-- * `particleTextureOverride` - Name of a particle texture that should override this effect's default texture. (default: "")
-- * `scale` - A number that scales the size of the vfx (Default: 1)
-- * `useAmbientLighting` - boolean, vfx get a white ambient light attached in Morrowind. If false don't attach this. (default: 1)
--
-- @usage -- Spawn a sanctuary effect near the player
-- local effect = core.magic.effects.records[core.magic.EFFECT_TYPE.Sanctuary]