Skip to content

Commit b6b04ca

Browse files
committed
Merge branch 'luaaddvfxoffset' into 'master'
addVfx ability to provide additional local offset See merge request OpenMW/openmw!4591
2 parents 6eae103 + 2f2dd95 commit b6b04ca

5 files changed

Lines changed: 43 additions & 10 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...")
8282
set(OPENMW_VERSION_MAJOR 0)
8383
set(OPENMW_VERSION_MINOR 52)
8484
set(OPENMW_VERSION_RELEASE 0)
85-
set(OPENMW_LUA_API_REVISION 133)
85+
set(OPENMW_LUA_API_REVISION 134)
8686
set(OPENMW_POSTPROCESSING_API_REVISION 5)
8787

8888
set(OPENMW_VERSION_COMMITHASH "")

apps/openmw/mwlua/animationbindings.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "animationbindings.hpp"
22

33
#include <components/lua/luastate.hpp>
4+
#include <components/lua/utilpackage.hpp>
45
#include <components/misc/finitevalues.hpp>
56

67
#include "../mwbase/environment.hpp"
@@ -243,15 +244,26 @@ namespace MWLua
243244
api["addVfx"] = [context](const SelfObject& object, std::string_view model, sol::optional<sol::table> options) {
244245
if (options)
245246
{
247+
sol::object transformObject = options->get<sol::object>("transform");
248+
std::optional<osg::Matrix> transform;
249+
if (transformObject.is<LuaUtil::TransformM>())
250+
transform = LuaUtil::cast<LuaUtil::TransformM>(transformObject).mM;
251+
else if (transformObject.is<LuaUtil::TransformQ>())
252+
transform = osg::Matrix(LuaUtil::cast<LuaUtil::TransformQ>(transformObject).mQ);
253+
if (transform.has_value() && !transform->valid())
254+
throw std::runtime_error("Transform provided for 'addVfx' is invalid");
255+
246256
context.mLuaManager->addAction(
247257
[object = Object(object), model = std::string(model),
248258
effectId = options->get_or<std::string>("vfxId", ""), loop = options->get_or("loop", false),
249259
boneName = options->get_or<std::string>("boneName", ""),
250260
particleTexture = options->get_or<std::string>("particleTextureOverride", ""),
251-
useAmbientLight = options->get_or("useAmbientLight", true)] {
261+
useAmbientLight = options->get_or("useAmbientLight", true),
262+
autoTransform = options->get_or("autoTransform", true), transform] {
252263
MWRender::Animation* anim = getMutableAnimationOrThrow(object);
253264

254-
anim->addEffect(model, effectId, loop, boneName, particleTexture, useAmbientLight);
265+
anim->addEffect(model, effectId, loop, boneName, particleTexture, useAmbientLight,
266+
autoTransform, transform);
255267
},
256268
"addVfxAction");
257269
}

apps/openmw/mwrender/animation.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <osg/BlendFunc>
88
#include <osg/LightModel>
99
#include <osg/Material>
10+
#include <osg/Matrix>
1011
#include <osg/MatrixTransform>
1112
#include <osg/Switch>
1213

@@ -1704,7 +1705,7 @@ namespace MWRender
17041705
}
17051706

17061707
void Animation::addEffect(std::string_view model, std::string_view effectId, bool loop, std::string_view bonename,
1707-
std::string_view texture, bool useAmbientLight)
1708+
std::string_view texture, bool useAmbientLight, bool autoTransform, const std::optional<osg::Matrix>& transform)
17081709
{
17091710
if (!mObjectRoot.get())
17101711
return;
@@ -1737,21 +1738,35 @@ namespace MWRender
17371738
}
17381739

17391740
osg::ref_ptr<SceneUtil::PositionAttitudeTransform> trans = new SceneUtil::PositionAttitudeTransform;
1740-
if (!mPtr.getClass().isNpc())
1741+
1742+
osg::Matrix finalTransform;
1743+
1744+
if (!mPtr.getClass().isNpc() && autoTransform)
17411745
{
17421746
osg::Vec3f bounds(MWBase::Environment::get().getWorld()->getHalfExtents(mPtr) * 2.f);
17431747
float scale = std::max({ bounds.x(), bounds.y(), bounds.z() / 2.f }) / 64.f;
17441748
if (scale > 1.f)
1745-
trans->setScale(osg::Vec3f(scale, scale, scale));
1749+
finalTransform = osg::Matrix::scale(scale, scale, scale);
17461750
float offset = 0.f;
17471751
if (bounds.z() < 128.f)
17481752
offset = bounds.z() - 128.f;
17491753
else if (bounds.z() < bounds.x() + bounds.y())
17501754
offset = 128.f - bounds.z();
17511755
if (MWBase::Environment::get().getWorld()->isFlying(mPtr))
17521756
offset /= 20.f;
1753-
trans->setPosition(osg::Vec3f(0.f, 0.f, offset * scale));
1757+
1758+
finalTransform.setTrans(osg::Vec3f(0.f, 0.f, offset * scale));
1759+
}
1760+
1761+
if (transform)
1762+
{
1763+
finalTransform *= (*transform);
17541764
}
1765+
1766+
trans->setScale(finalTransform.getScale());
1767+
trans->setAttitude(finalTransform.getRotate());
1768+
trans->setPosition(finalTransform.getTrans());
1769+
17551770
parentNode->addChild(trans);
17561771

17571772
osg::ref_ptr<osg::Node> node

apps/openmw/mwrender/animation.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <components/vfs/pathutil.hpp>
1919

2020
#include <map>
21+
#include <optional>
2122
#include <span>
2223
#include <string>
2324
#include <unordered_map>
@@ -347,12 +348,14 @@ namespace MWRender
347348
* you need to remove it manually using removeEffect when the effect should end.
348349
* @param bonename Bone to attach to, or empty string to use the scene node instead
349350
* @param texture override the texture specified in the model's materials - if empty, do not override
350-
* @param useAmbientLight attach white ambient light to the root VFX node of the scenegraph (Morrowind
351-
* default)
351+
* @param useAmbientLight attach white ambient light to the root VFX node of the scenegraph (Morrowind default)
352+
* @param autoTransform auto-calculate vfx transform
353+
* @param transform apply a relative transform
352354
* @note Will not add an effect twice.
353355
*/
354356
void addEffect(std::string_view model, std::string_view effectId, bool loop = false,
355-
std::string_view bonename = {}, std::string_view texture = {}, bool useAmbientLight = true);
357+
std::string_view bonename = {}, std::string_view texture = {}, bool useAmbientLight = true,
358+
bool autoTransform = true, const std::optional<osg::Matrix>& transform = std::nullopt);
356359

357360
void removeEffect(std::string_view effectId);
358361
void removeEffects();

files/lua_api/openmw/animation.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@
230230
-- * `particleTextureOverride` - name of the particle texture to use. (default: "")
231231
-- * `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: "").
232232
-- * `useAmbientLight` - boolean, vfx get a white ambient light attached in Morrowind. If false don't attach this. (default: true)
233+
-- * `autoTransform` - boolean, if true, the engine will auto-calculate the transform. (default: true)
234+
-- * `transform` - relative transform (openmw.util#Transform) applied to the vfx. If autoTransform is true this will be applied on top of it.
233235
--
234236
-- @usage local mgef = core.magic.effects.records[myEffectName]
235237
-- anim.addVfx(self, 'VFX_Hands', {boneName = 'Bip01 L Hand', particleTextureOverride = mgef.particle, loop = mgef.continuousVfx, vfxId = mgef.id..'_myuniquenamehere'})
@@ -244,6 +246,7 @@
244246
-- vfxId = mgef.id,
245247
-- particleTextureOverride = mgef.particle,
246248
-- loop = false,
249+
-- transform = util.transform.move(100, 0, 0)
247250
-- }
248251
-- })
249252
--

0 commit comments

Comments
 (0)