mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-31 06:32:39 +00:00
Rendering raycasts in Lua
This commit is contained in:
parent
a65f8ebbc6
commit
51845e9553
@ -57,6 +57,7 @@ namespace ESM
|
||||
|
||||
namespace MWPhysics
|
||||
{
|
||||
class RayCastingResult;
|
||||
class RayCastingInterface;
|
||||
}
|
||||
|
||||
@ -331,6 +332,9 @@ namespace MWBase
|
||||
|
||||
virtual bool castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore) = 0;
|
||||
|
||||
virtual bool castRenderingRay(MWPhysics::RayCastingResult& res, const osg::Vec3f& from, const osg::Vec3f& to,
|
||||
bool ignorePlayer, bool ignoreActors) = 0;
|
||||
|
||||
virtual void setActorCollisionMode(const MWWorld::Ptr& ptr, bool internal, bool external) = 0;
|
||||
virtual bool isActorCollisionEnabled(const MWWorld::Ptr& ptr) = 0;
|
||||
|
||||
|
@ -41,7 +41,7 @@ namespace MWLua
|
||||
{
|
||||
auto* lua = context.mLua;
|
||||
sol::table api(lua->sol(), sol::create);
|
||||
api["API_REVISION"] = 20;
|
||||
api["API_REVISION"] = 21;
|
||||
api["quit"] = [lua]()
|
||||
{
|
||||
Log(Debug::Warning) << "Quit requested by a Lua script.\n" << lua->debugTraceback();
|
||||
|
@ -226,6 +226,7 @@ namespace MWLua
|
||||
return; // The game is not started yet.
|
||||
|
||||
// We apply input events in `synchronizedUpdate` rather than in `update` in order to reduce input latency.
|
||||
mProcessingInputEvents = true;
|
||||
PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
|
||||
if (playerScripts && !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu))
|
||||
{
|
||||
@ -235,6 +236,7 @@ namespace MWLua
|
||||
mInputEvents.clear();
|
||||
if (playerScripts && !mWorldView.isPaused())
|
||||
playerScripts->inputUpdate(MWBase::Environment::get().getFrameDuration());
|
||||
mProcessingInputEvents = false;
|
||||
|
||||
MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager();
|
||||
for (const std::string& message : mUIMessages)
|
||||
|
@ -111,12 +111,15 @@ namespace MWLua
|
||||
|
||||
LuaUi::ResourceManager* uiResourceManager() { return &mUiResourceManager; }
|
||||
|
||||
bool isProcessingInputEvents() const { return mProcessingInputEvents; }
|
||||
|
||||
private:
|
||||
void initConfiguration();
|
||||
LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr, ESM::LuaScriptCfg::Flags);
|
||||
|
||||
bool mInitialized = false;
|
||||
bool mGlobalScriptsStarted = false;
|
||||
bool mProcessingInputEvents = false;
|
||||
LuaUtil::ScriptsConfiguration mConfiguration;
|
||||
LuaUtil::LuaState mLua;
|
||||
LuaUi::ResourceManager mUiResourceManager;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwphysics/raycasting.hpp"
|
||||
|
||||
#include "luamanagerimp.hpp"
|
||||
#include "worldview.hpp"
|
||||
|
||||
namespace sol
|
||||
@ -91,6 +92,27 @@ namespace MWLua
|
||||
// and use this callback from the main thread at the beginning of the next frame processing.
|
||||
rayCasting->asyncCastRay(callback, from, to, ignore, std::vector<MWWorld::Ptr>(), collisionType);
|
||||
};*/
|
||||
api["castRenderingRay"] = [manager=context.mLuaManager](const osg::Vec3f& from, const osg::Vec3f& to)
|
||||
{
|
||||
if (!manager->isProcessingInputEvents())
|
||||
{
|
||||
throw std::logic_error("castRenderingRay can be used only in player scripts during processing of input events; "
|
||||
"use asyncCastRenderingRay instead.");
|
||||
}
|
||||
MWPhysics::RayCastingResult res;
|
||||
MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false);
|
||||
return res;
|
||||
};
|
||||
api["asyncCastRenderingRay"] =
|
||||
[manager=context.mLuaManager](const LuaUtil::Callback& callback, const osg::Vec3f& from, const osg::Vec3f& to)
|
||||
{
|
||||
manager->addAction([manager, callback, from, to]
|
||||
{
|
||||
MWPhysics::RayCastingResult res;
|
||||
MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false);
|
||||
manager->queueCallback(callback, sol::make_object(callback.mFunc.lua_state(), res));
|
||||
});
|
||||
};
|
||||
|
||||
api["activators"] = LObjectList{worldView->getActivatorsInScene()};
|
||||
api["actors"] = LObjectList{worldView->getActorsInScene()};
|
||||
|
@ -9,12 +9,13 @@
|
||||
|
||||
namespace MWPhysics
|
||||
{
|
||||
struct RayCastingResult
|
||||
class RayCastingResult
|
||||
{
|
||||
bool mHit;
|
||||
osg::Vec3f mHitPos;
|
||||
osg::Vec3f mHitNormal;
|
||||
MWWorld::Ptr mHitObject;
|
||||
public:
|
||||
bool mHit;
|
||||
osg::Vec3f mHitPos;
|
||||
osg::Vec3f mHitNormal;
|
||||
MWWorld::Ptr mHitObject;
|
||||
};
|
||||
|
||||
class RayCastingInterface
|
||||
|
@ -2042,6 +2042,25 @@ namespace MWWorld
|
||||
return facedObject;
|
||||
}
|
||||
|
||||
bool World::castRenderingRay(MWPhysics::RayCastingResult& res, const osg::Vec3f& from, const osg::Vec3f& to,
|
||||
bool ignorePlayer, bool ignoreActors)
|
||||
{
|
||||
MWRender::RenderingManager::RayResult rayRes = mRendering->castRay(from, to, ignorePlayer, ignoreActors);
|
||||
res.mHit = rayRes.mHit;
|
||||
res.mHitPos = rayRes.mHitPointWorld;
|
||||
res.mHitNormal = rayRes.mHitNormalWorld;
|
||||
res.mHitObject = rayRes.mHitObject;
|
||||
if (res.mHitObject.isEmpty() && rayRes.mHitRefnum.isSet())
|
||||
{
|
||||
for (CellStore* cellstore : mWorldScene->getActiveCells())
|
||||
{
|
||||
res.mHitObject = cellstore->searchViaRefNum(rayRes.mHitRefnum);
|
||||
if (!res.mHitObject.isEmpty()) break;
|
||||
}
|
||||
}
|
||||
return res.mHit;
|
||||
}
|
||||
|
||||
bool World::isCellExterior() const
|
||||
{
|
||||
const CellStore *currentCell = mWorldScene->getCurrentCell();
|
||||
|
@ -421,6 +421,9 @@ namespace MWWorld
|
||||
|
||||
bool castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore) override;
|
||||
|
||||
bool castRenderingRay(MWPhysics::RayCastingResult& res, const osg::Vec3f& from, const osg::Vec3f& to,
|
||||
bool ignorePlayer, bool ignoreActors) override;
|
||||
|
||||
void setActorCollisionMode(const Ptr& ptr, bool internal, bool external) override;
|
||||
bool isActorCollisionEnabled(const Ptr& ptr) override;
|
||||
|
||||
|
@ -68,5 +68,22 @@
|
||||
-- radius = 10,
|
||||
-- })
|
||||
|
||||
---
|
||||
-- Cast ray from one point to another and find the first visual intersection with anything in the scene.
|
||||
-- As opposite to `castRay` can find an intersection with an object without collisions.
|
||||
-- In order to avoid threading issues can be used only in player scripts only in `onInputUpdate` or
|
||||
-- in engine handlers for user input. In other cases use `asyncCastRenderingRay` instead.
|
||||
-- @function [parent=#nearby] castRenderingRay
|
||||
-- @param openmw.util#Vector3 from Start point of the ray.
|
||||
-- @param openmw.util#Vector3 to End point of the ray.
|
||||
-- @return #RayCastingResult
|
||||
|
||||
---
|
||||
-- Asynchronously cast ray from one point to another and find the first visual intersection with anything in the scene.
|
||||
-- @function [parent=#nearby] asyncCastRenderingRay
|
||||
-- @param openmw.async#Callback callback The callback to pass the result to (should accept a single argument @{openmw.nearby#RayCastingResult}).
|
||||
-- @param openmw.util#Vector3 from Start point of the ray.
|
||||
-- @param openmw.util#Vector3 to End point of the ray.
|
||||
|
||||
return nil
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user