mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-09 12:25:17 -04:00
Prevent hard freeze when camera receives invalid inputs from Lua
This commit is contained in:
parent
8a10de5fed
commit
d2f1eeff98
@ -234,6 +234,7 @@
|
|||||||
Bug #8445: Launcher crashes on exit when cell name loading thread is still running
|
Bug #8445: Launcher crashes on exit when cell name loading thread is still running
|
||||||
Bug #8462: Crashes when resizing the window on macOS
|
Bug #8462: Crashes when resizing the window on macOS
|
||||||
Bug #8465: Blue screen w/ antialiasing and post-processing on macOS
|
Bug #8465: Blue screen w/ antialiasing and post-processing on macOS
|
||||||
|
Bug #8503: Camera does not handle NaN gracefully
|
||||||
Feature #1415: Infinite fall failsafe
|
Feature #1415: Infinite fall failsafe
|
||||||
Feature #2566: Handle NAM9 records for manual cell references
|
Feature #2566: Handle NAM9 records for manual cell references
|
||||||
Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking
|
Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <components/lua/luastate.hpp>
|
#include <components/lua/luastate.hpp>
|
||||||
#include <components/lua/utilpackage.hpp>
|
#include <components/lua/utilpackage.hpp>
|
||||||
|
#include <components/misc/finitenumbers.hpp>
|
||||||
#include <components/settings/values.hpp>
|
#include <components/settings/values.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
@ -11,11 +12,12 @@
|
|||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
|
||||||
using CameraMode = MWRender::Camera::Mode;
|
using CameraMode = MWRender::Camera::Mode;
|
||||||
|
|
||||||
sol::table initCameraPackage(sol::state_view lua)
|
sol::table initCameraPackage(sol::state_view lua)
|
||||||
{
|
{
|
||||||
|
using FiniteFloat = Misc::FiniteFloat;
|
||||||
|
|
||||||
MWRender::Camera* camera = MWBase::Environment::get().getWorld()->getCamera();
|
MWRender::Camera* camera = MWBase::Environment::get().getWorld()->getCamera();
|
||||||
MWRender::RenderingManager* renderingManager = MWBase::Environment::get().getWorld()->getRenderingManager();
|
MWRender::RenderingManager* renderingManager = MWBase::Environment::get().getWorld()->getRenderingManager();
|
||||||
|
|
||||||
@ -49,26 +51,27 @@ namespace MWLua
|
|||||||
api["getRoll"] = [camera]() { return -camera->getRoll(); };
|
api["getRoll"] = [camera]() { return -camera->getRoll(); };
|
||||||
|
|
||||||
api["setStaticPosition"] = [camera](const osg::Vec3f& pos) { camera->setStaticPosition(pos); };
|
api["setStaticPosition"] = [camera](const osg::Vec3f& pos) { camera->setStaticPosition(pos); };
|
||||||
api["setPitch"] = [camera](float v) {
|
api["setPitch"] = [camera](const FiniteFloat v) {
|
||||||
camera->setPitch(-v, true);
|
camera->setPitch(-v, true);
|
||||||
if (camera->getMode() == CameraMode::ThirdPerson)
|
if (camera->getMode() == CameraMode::ThirdPerson)
|
||||||
camera->calculateDeferredRotation();
|
camera->calculateDeferredRotation();
|
||||||
};
|
};
|
||||||
api["setYaw"] = [camera](float v) {
|
api["setYaw"] = [camera](const FiniteFloat v) {
|
||||||
camera->setYaw(-v, true);
|
camera->setYaw(-v, true);
|
||||||
if (camera->getMode() == CameraMode::ThirdPerson)
|
if (camera->getMode() == CameraMode::ThirdPerson)
|
||||||
camera->calculateDeferredRotation();
|
camera->calculateDeferredRotation();
|
||||||
};
|
};
|
||||||
api["setRoll"] = [camera](float v) { camera->setRoll(-v); };
|
api["setRoll"] = [camera](const FiniteFloat v) { camera->setRoll(-v); };
|
||||||
api["setExtraPitch"] = [camera](float v) { camera->setExtraPitch(-v); };
|
api["setExtraPitch"] = [camera](const FiniteFloat v) { camera->setExtraPitch(-v); };
|
||||||
api["setExtraYaw"] = [camera](float v) { camera->setExtraYaw(-v); };
|
api["setExtraYaw"] = [camera](const FiniteFloat v) { camera->setExtraYaw(-v); };
|
||||||
api["setExtraRoll"] = [camera](float v) { camera->setExtraRoll(-v); };
|
api["setExtraRoll"] = [camera](const FiniteFloat v) { camera->setExtraRoll(-v); };
|
||||||
api["getExtraPitch"] = [camera]() { return -camera->getExtraPitch(); };
|
api["getExtraPitch"] = [camera]() { return -camera->getExtraPitch(); };
|
||||||
api["getExtraYaw"] = [camera]() { return -camera->getExtraYaw(); };
|
api["getExtraYaw"] = [camera]() { return -camera->getExtraYaw(); };
|
||||||
api["getExtraRoll"] = [camera]() { return -camera->getExtraRoll(); };
|
api["getExtraRoll"] = [camera]() { return -camera->getExtraRoll(); };
|
||||||
|
|
||||||
api["getThirdPersonDistance"] = [camera]() { return camera->getCameraDistance(); };
|
api["getThirdPersonDistance"] = [camera]() { return camera->getCameraDistance(); };
|
||||||
api["setPreferredThirdPersonDistance"] = [camera](float v) { camera->setPreferredCameraDistance(v); };
|
api["setPreferredThirdPersonDistance"]
|
||||||
|
= [camera](const FiniteFloat v) { camera->setPreferredCameraDistance(v); };
|
||||||
|
|
||||||
api["getFirstPersonOffset"] = [camera]() { return camera->getFirstPersonOffset(); };
|
api["getFirstPersonOffset"] = [camera]() { return camera->getFirstPersonOffset(); };
|
||||||
api["setFirstPersonOffset"] = [camera](const osg::Vec3f& v) { camera->setFirstPersonOffset(v); };
|
api["setFirstPersonOffset"] = [camera](const osg::Vec3f& v) { camera->setFirstPersonOffset(v); };
|
||||||
@ -76,7 +79,7 @@ namespace MWLua
|
|||||||
api["getFocalPreferredOffset"] = [camera]() -> osg::Vec2f { return camera->getFocalPointTargetOffset(); };
|
api["getFocalPreferredOffset"] = [camera]() -> osg::Vec2f { return camera->getFocalPointTargetOffset(); };
|
||||||
api["setFocalPreferredOffset"] = [camera](const osg::Vec2f& v) { camera->setFocalPointTargetOffset(v); };
|
api["setFocalPreferredOffset"] = [camera](const osg::Vec2f& v) { camera->setFocalPointTargetOffset(v); };
|
||||||
api["getFocalTransitionSpeed"] = [camera]() { return camera->getFocalPointTransitionSpeed(); };
|
api["getFocalTransitionSpeed"] = [camera]() { return camera->getFocalPointTransitionSpeed(); };
|
||||||
api["setFocalTransitionSpeed"] = [camera](float v) { camera->setFocalPointTransitionSpeed(v); };
|
api["setFocalTransitionSpeed"] = [camera](const FiniteFloat v) { camera->setFocalPointTransitionSpeed(v); };
|
||||||
api["instantTransition"] = [camera]() { camera->instantTransition(); };
|
api["instantTransition"] = [camera]() { camera->instantTransition(); };
|
||||||
|
|
||||||
api["getCollisionType"] = [camera]() { return camera->getCollisionType(); };
|
api["getCollisionType"] = [camera]() { return camera->getCollisionType(); };
|
||||||
@ -86,11 +89,12 @@ namespace MWLua
|
|||||||
api["getFieldOfView"]
|
api["getFieldOfView"]
|
||||||
= [renderingManager]() { return osg::DegreesToRadians(renderingManager->getFieldOfView()); };
|
= [renderingManager]() { return osg::DegreesToRadians(renderingManager->getFieldOfView()); };
|
||||||
api["setFieldOfView"]
|
api["setFieldOfView"]
|
||||||
= [renderingManager](float v) { renderingManager->setFieldOfView(osg::RadiansToDegrees(v)); };
|
= [renderingManager](const FiniteFloat v) { renderingManager->setFieldOfView(osg::RadiansToDegrees(v)); };
|
||||||
|
|
||||||
api["getBaseViewDistance"] = [] { return Settings::camera().mViewingDistance.get(); };
|
api["getBaseViewDistance"] = [] { return Settings::camera().mViewingDistance.get(); };
|
||||||
api["getViewDistance"] = [renderingManager]() { return renderingManager->getViewDistance(); };
|
api["getViewDistance"] = [renderingManager]() { return renderingManager->getViewDistance(); };
|
||||||
api["setViewDistance"] = [renderingManager](float d) { renderingManager->setViewDistance(d, true); };
|
api["setViewDistance"]
|
||||||
|
= [renderingManager](const FiniteFloat d) { renderingManager->setViewDistance(d, true); };
|
||||||
|
|
||||||
api["getViewTransform"] = [camera]() { return LuaUtil::TransformM{ camera->getViewMatrix() }; };
|
api["getViewTransform"] = [camera]() { return LuaUtil::TransformM{ camera->getViewMatrix() }; };
|
||||||
|
|
||||||
|
45
components/misc/finitenumbers.hpp
Normal file
45
components/misc/finitenumbers.hpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef OPENMW_COMPONENTS_MISC_FINITENUMBERS_HPP
|
||||||
|
#define OPENMW_COMPONENTS_MISC_FINITENUMBERS_HPP
|
||||||
|
|
||||||
|
#include <components/lua/luastate.hpp>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace Misc
|
||||||
|
{
|
||||||
|
struct FiniteFloat
|
||||||
|
{
|
||||||
|
float mValue;
|
||||||
|
FiniteFloat(float v)
|
||||||
|
{
|
||||||
|
if (!std::isfinite(v))
|
||||||
|
throw std::invalid_argument("Value must be a finite number");
|
||||||
|
mValue = v;
|
||||||
|
}
|
||||||
|
operator float() const { return mValue; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace sol
|
||||||
|
{
|
||||||
|
using FiniteFloat = Misc::FiniteFloat;
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
bool sol_lua_check(
|
||||||
|
sol::types<FiniteFloat>, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking)
|
||||||
|
{
|
||||||
|
bool success = sol::stack::check<float>(L, lua_absindex(L, index), handler);
|
||||||
|
tracking.use(1);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FiniteFloat sol_lua_get(sol::types<FiniteFloat>, lua_State* L, int index, sol::stack::record& tracking)
|
||||||
|
{
|
||||||
|
float val = sol::stack::get<float>(L, lua_absindex(L, index));
|
||||||
|
tracking.use(1);
|
||||||
|
return FiniteFloat(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user