mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-15 16:39:40 +00:00
Rudimentary menu interactions
This commit is contained in:
parent
2ae7255fac
commit
e573a260cb
12 changed files with 114 additions and 44 deletions
|
@ -7,7 +7,7 @@
|
|||
#include <map>
|
||||
#include <set>
|
||||
#include <deque>
|
||||
#include <osg/node>
|
||||
#include <tuple>
|
||||
|
||||
#include <components/esm/cellid.hpp>
|
||||
|
||||
|
@ -22,6 +22,7 @@ namespace osg
|
|||
class Matrixf;
|
||||
class Quat;
|
||||
class Image;
|
||||
class Node;
|
||||
}
|
||||
|
||||
namespace Loading
|
||||
|
@ -97,6 +98,12 @@ namespace MWBase
|
|||
ESM::CellId dest;
|
||||
};
|
||||
|
||||
using IntersectedObject = std::tuple<
|
||||
MWWorld::Ptr,
|
||||
osg::Node*,
|
||||
osg::Vec3f
|
||||
>;
|
||||
|
||||
World() {}
|
||||
|
||||
virtual ~World() {}
|
||||
|
@ -261,7 +268,7 @@ namespace MWBase
|
|||
virtual MWWorld::Ptr getFacedObject() = 0;
|
||||
///< Return pointer to the object the player is looking at, if it is within activation range
|
||||
|
||||
virtual std::pair<MWWorld::Ptr, osg::Node*> getPointedAtObject() = 0;
|
||||
virtual IntersectedObject getPointedAtObject() = 0;
|
||||
///< Return pointer to the object and/or node the player is currently pointing at
|
||||
|
||||
virtual float getDistanceToFacedObject() = 0;
|
||||
|
|
|
@ -1881,18 +1881,6 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||
|
||||
mAnimation->setAccurateAiming(mUpperBodyState > UpperCharState_WeapEquiped);
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
if (mPtr == getPlayer())
|
||||
{
|
||||
auto xrAnimation = dynamic_cast<MWVR::OpenXRAnimation*>(mAnimation);
|
||||
if (xrAnimation)
|
||||
{
|
||||
bool pointing = MWBase::Environment::get().getWorld()->getPlayer().getPointing();
|
||||
xrAnimation->setPointForward(pointing);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return forcestateupdate;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
|
||||
#ifdef USE_OPENXR
|
||||
#include "../mwvr/openxranimation.hpp"
|
||||
#include "../mwvr/openxrenvironment.hpp"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
|
@ -1025,6 +1026,7 @@ namespace MWRender
|
|||
result.mHit = true;
|
||||
osgUtil::LineSegmentIntersector::Intersection intersection = intersector->getFirstIntersection();
|
||||
|
||||
result.mHitPointLocal = intersection.getLocalIntersectPoint();
|
||||
result.mHitPointWorld = intersection.getWorldIntersectPoint();
|
||||
result.mHitNormalWorld = intersection.getWorldIntersectNormal();
|
||||
result.mRatio = intersection.ratio;
|
||||
|
@ -1163,7 +1165,8 @@ namespace MWRender
|
|||
void RenderingManager::renderPlayer(const MWWorld::Ptr &player)
|
||||
{
|
||||
#ifdef USE_OPENXR
|
||||
mPlayerAnimation = new MWVR::OpenXRAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, false, nullptr);
|
||||
MWVR::OpenXREnvironment::get().setPlayerAnimation(new MWVR::OpenXRAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, false, nullptr));
|
||||
mPlayerAnimation = MWVR::OpenXREnvironment::get().getPlayerAnimation();
|
||||
#else
|
||||
mPlayerAnimation = new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0, NpcAnimation::VM_Normal,
|
||||
mFirstPersonFieldOfView);
|
||||
|
|
|
@ -151,6 +151,7 @@ namespace MWRender
|
|||
bool mHit;
|
||||
osg::Vec3f mHitNormalWorld;
|
||||
osg::Vec3f mHitPointWorld;
|
||||
osg::Vec3f mHitPointLocal;
|
||||
MWWorld::Ptr mHitObject;
|
||||
osg::Node* mHitNode;
|
||||
float mRatio;
|
||||
|
|
|
@ -184,11 +184,17 @@ void FingerController::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
|||
{
|
||||
// Get distance to pointer intersection
|
||||
auto pat = pointerTransform->asTransform()->asPositionAttitudeTransform();
|
||||
// TODO: Using the cached value from the input manager makes this off by one frame
|
||||
float intersected_distance = MWBase::Environment::get().getWorld()->getDistanceToPointedAtObject();
|
||||
auto* world = MWBase::Environment::get().getWorld();
|
||||
if (world)
|
||||
{
|
||||
// TODO: Using the cached value from the input manager makes this off by one frame
|
||||
// So do one otherwise redundant intersection here.
|
||||
world->getPointedAtObject();
|
||||
float intersected_distance = world->getDistanceToPointedAtObject();
|
||||
|
||||
// Stretch beam to point of intersection.
|
||||
pat->setScale(osg::Vec3(1.f, 1.f, intersected_distance));
|
||||
// Stretch beam to point of intersection.
|
||||
pat->setScale(osg::Vec3(.25f, .25f, intersected_distance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
#include "openxranimation.hpp"
|
||||
#include "openxrinputmanager.hpp"
|
||||
#include "openxrsession.hpp"
|
||||
#include "openxrmenu.hpp"
|
||||
|
@ -31,6 +32,9 @@ void MWVR::OpenXREnvironment::cleanup()
|
|||
if (mMenuManager)
|
||||
delete mMenuManager;
|
||||
mMenuManager = nullptr;
|
||||
if (mPlayerAnimation)
|
||||
delete mPlayerAnimation;
|
||||
mPlayerAnimation = nullptr;
|
||||
if (mViewer)
|
||||
delete mViewer;
|
||||
mViewer = nullptr;
|
||||
|
@ -39,7 +43,7 @@ void MWVR::OpenXREnvironment::cleanup()
|
|||
mOpenXRManager = nullptr;
|
||||
}
|
||||
|
||||
const MWVR::OpenXREnvironment& MWVR::OpenXREnvironment::get()
|
||||
MWVR::OpenXREnvironment& MWVR::OpenXREnvironment::get()
|
||||
{
|
||||
assert (sThis);
|
||||
return *sThis;
|
||||
|
@ -74,6 +78,16 @@ void MWVR::OpenXREnvironment::setMenuManager(MWVR::OpenXRMenuManager* menuManage
|
|||
mMenuManager = menuManager;
|
||||
}
|
||||
|
||||
MWVR::OpenXRAnimation* MWVR::OpenXREnvironment::getPlayerAnimation() const
|
||||
{
|
||||
return mPlayerAnimation;
|
||||
}
|
||||
|
||||
void MWVR::OpenXREnvironment::setPlayerAnimation(MWVR::OpenXRAnimation* xrAnimation)
|
||||
{
|
||||
mPlayerAnimation = xrAnimation;
|
||||
}
|
||||
|
||||
|
||||
MWVR::OpenXRViewer* MWVR::OpenXREnvironment::getViewer() const
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
namespace MWVR
|
||||
{
|
||||
class OpenXRAnimation;
|
||||
class OpenXRInputManager;
|
||||
class OpenXRSession;
|
||||
class OpenXRMenuManager;
|
||||
|
@ -35,7 +36,7 @@ namespace MWVR
|
|||
void cleanup();
|
||||
///< Delete all mwvr-subsystems.
|
||||
|
||||
static const OpenXREnvironment& get();
|
||||
static OpenXREnvironment& get();
|
||||
///< Return instance of this class.
|
||||
|
||||
MWVR::OpenXRInputManager* getInputManager() const;
|
||||
|
@ -47,6 +48,9 @@ namespace MWVR
|
|||
MWVR::OpenXRMenuManager* getMenuManager() const;
|
||||
void setMenuManager(MWVR::OpenXRMenuManager* xrMenuManager);
|
||||
|
||||
MWVR::OpenXRAnimation* getPlayerAnimation() const;
|
||||
void setPlayerAnimation(MWVR::OpenXRAnimation* xrAnimation);
|
||||
|
||||
MWVR::OpenXRSession* getSession() const;
|
||||
void setSession(MWVR::OpenXRSession* xrSession);
|
||||
|
||||
|
@ -62,6 +66,7 @@ namespace MWVR
|
|||
private:
|
||||
MWVR::OpenXRSession* mSession{ nullptr };
|
||||
MWVR::OpenXRMenuManager* mMenuManager{ nullptr };
|
||||
MWVR::OpenXRAnimation* mPlayerAnimation{ nullptr };
|
||||
MWVR::OpenXRViewer* mViewer{ nullptr };
|
||||
MWVR::OpenXRManager* mOpenXRManager{ nullptr };
|
||||
float mUnitsPerMeter{ 1.f };
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "openxranimation.hpp"
|
||||
#include "openxrinputmanager.hpp"
|
||||
#include "openxrenvironment.hpp"
|
||||
#include "openxrmanager.hpp"
|
||||
|
@ -625,10 +626,6 @@ namespace MWVR
|
|||
{
|
||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Inventory, true });
|
||||
}
|
||||
if (mActivate.actionOnPress())
|
||||
{
|
||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Activate, true });
|
||||
}
|
||||
if (mJump.actionOnPress())
|
||||
{
|
||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Jump, true });
|
||||
|
@ -637,6 +634,12 @@ namespace MWVR
|
|||
{
|
||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_QuickMenu, true });
|
||||
}
|
||||
|
||||
// Actions that activate on release
|
||||
if (mActivate.actionChanged())
|
||||
{
|
||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Activate, mActivate.actionOnPress() });
|
||||
}
|
||||
|
||||
// Actions that hold with the button
|
||||
if (mUse.actionChanged())
|
||||
|
@ -749,9 +752,16 @@ namespace MWVR
|
|||
return mXRInput->getHandPoses(time, space);
|
||||
}
|
||||
|
||||
void OpenXRInputManager::showActivationIndication(bool show)
|
||||
void OpenXRInputManager::updateActivationIndication(void)
|
||||
{
|
||||
mPlayer->setPointing(show);
|
||||
bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode();
|
||||
bool show = guiMode | mActivationIndication;
|
||||
if (mPlayer)
|
||||
mPlayer->setPointing(show);
|
||||
|
||||
auto* playerAnimation = OpenXREnvironment::get().getPlayerAnimation();
|
||||
if (playerAnimation)
|
||||
playerAnimation->setPointForward(show);
|
||||
}
|
||||
|
||||
OpenXRInputManager::OpenXRInputManager(
|
||||
|
@ -801,11 +811,30 @@ namespace MWVR
|
|||
{
|
||||
mXRInput->updateControls();
|
||||
|
||||
|
||||
auto* world = MWBase::Environment::get().getWorld();
|
||||
if (world)
|
||||
{
|
||||
auto pointedAt = world->getPointedAtObject();
|
||||
// TODO: Left off here
|
||||
|
||||
auto* node = std::get<1>(pointedAt);
|
||||
if (node)
|
||||
{
|
||||
|
||||
int w, h;
|
||||
SDL_GetWindowSize(mWindow, &w, &h);
|
||||
|
||||
osg::Vec3 local = std::get<2>(pointedAt);
|
||||
local.x() = (local.x() + 1.f) / 2.f;
|
||||
local.y() = 1.f - (local.y() + 1.f) / 2.f;
|
||||
|
||||
|
||||
mGuiCursorX = mInvUiScalingFactor * (local.x() * w);
|
||||
mGuiCursorY = mInvUiScalingFactor * (local.y() * h);
|
||||
|
||||
MyGUI::InputManager::getInstance().injectMouseMove(int(mGuiCursorX), int(mGuiCursorY), 0);
|
||||
}
|
||||
}
|
||||
|
||||
OpenXRActionEvent event{};
|
||||
|
@ -814,6 +843,8 @@ namespace MWVR
|
|||
processEvent(event);
|
||||
}
|
||||
|
||||
updateActivationIndication();
|
||||
|
||||
MWInput::InputManager::update(dt, disableControls, disableEvents);
|
||||
|
||||
bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode();
|
||||
|
@ -831,7 +862,6 @@ namespace MWVR
|
|||
switch (event.action)
|
||||
{
|
||||
case A_GameMenu:
|
||||
Log(Debug::Verbose) << "A_GameMenu";
|
||||
toggleMainMenu();
|
||||
// Explicitly request position update here so that the player can move the menu
|
||||
// using the menu key when the menu can't be toggled.
|
||||
|
@ -848,7 +878,14 @@ namespace MWVR
|
|||
break;
|
||||
case A_Activate:
|
||||
resetIdleTime();
|
||||
activate();
|
||||
{
|
||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if(!event.onPress)
|
||||
activate();
|
||||
}
|
||||
break;
|
||||
// TODO: Movement
|
||||
//case A_MoveLeft:
|
||||
|
@ -964,10 +1001,19 @@ namespace MWVR
|
|||
mAttemptJump = true;
|
||||
break;
|
||||
case A_Use:
|
||||
mInputBinder->getChannel(A_Use)->setValue(event.onPress);
|
||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
{
|
||||
SDL_MouseButtonEvent arg;
|
||||
if (event.onPress)
|
||||
mousePressed(arg, SDL_BUTTON_LEFT);
|
||||
else
|
||||
mouseReleased(arg, SDL_BUTTON_LEFT);
|
||||
}
|
||||
else
|
||||
mInputBinder->getChannel(A_Use)->setValue(event.onPress);
|
||||
break;
|
||||
case OpenXRInput::A_ActivateTouch:
|
||||
showActivationIndication(event.onPress);
|
||||
mActivationIndication = event.onPress;
|
||||
break;
|
||||
default:
|
||||
Log(Debug::Warning) << "Unhandled XR action " << event.action;
|
||||
|
|
|
@ -43,12 +43,13 @@ namespace MWVR
|
|||
|
||||
PoseSet getHandPoses(int64_t time, TrackedSpace space);
|
||||
|
||||
void showActivationIndication(bool show);
|
||||
void updateActivationIndication(void);
|
||||
|
||||
std::unique_ptr<OpenXRInput> mXRInput;
|
||||
Pose mPreviousHeadPose{};
|
||||
osg::Vec3 mHeadOffset{ 0,0,0 };
|
||||
bool mRecenter{ true };
|
||||
bool mActivationIndication{ false };
|
||||
float mYaw{ 0.f };
|
||||
|
||||
float mVrAngles[3]{ 0.f,0.f,0.f };
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace MWVR
|
|||
createInfo.enabledExtensionCount = extensions.size();
|
||||
createInfo.enabledExtensionNames = extensions.data();
|
||||
|
||||
strcpy(createInfo.applicationInfo.applicationName, "Boo");
|
||||
strcpy(createInfo.applicationInfo.applicationName, "openmw_vr");
|
||||
createInfo.applicationInfo.apiVersion = XR_CURRENT_API_VERSION;
|
||||
CHECK_XRCMD(xrCreateInstance(&createInfo, &mInstance));
|
||||
assert(mInstance);
|
||||
|
@ -504,7 +504,7 @@ namespace MWVR
|
|||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(ref->mBase->mRace);
|
||||
bool isMale = ref->mBase->isMale();
|
||||
float charHeightFactor = isMale ? race->mData.mHeight.mMale : race->mData.mHeight.mFemale;
|
||||
float charHeightBase = 2.f;
|
||||
float charHeightBase = 1.8f;
|
||||
float charHeight = charHeightBase * charHeightFactor;
|
||||
// TODO: Player height should be configurable
|
||||
// For now i'm just using my own
|
||||
|
|
|
@ -1113,7 +1113,7 @@ namespace MWWorld
|
|||
return facedObject;
|
||||
}
|
||||
|
||||
std::pair<MWWorld::Ptr, osg::Node*> World::getPointedAtObject()
|
||||
World::IntersectedObject World::getPointedAtObject()
|
||||
{
|
||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode() &&
|
||||
MWBase::Environment::get().getWindowManager()->isConsoleMode())
|
||||
|
@ -1123,10 +1123,10 @@ namespace MWWorld
|
|||
else
|
||||
{
|
||||
auto pointedAtObject = getPointedAtObject(getActivationDistancePlusTelekinesis(), true);
|
||||
|
||||
if (!pointedAtObject.first.isEmpty() && !pointedAtObject.first.getClass().allowTelekinesis(pointedAtObject.first)
|
||||
auto ptr = std::get<0>(pointedAtObject);
|
||||
if (!ptr.isEmpty() && !ptr.getClass().allowTelekinesis(ptr)
|
||||
&& mDistanceToFacedObject > getMaxActivationDistance() && !MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
return std::pair<MWWorld::Ptr, osg::Node*>();
|
||||
return IntersectedObject();
|
||||
return pointedAtObject;
|
||||
}
|
||||
}
|
||||
|
@ -2070,7 +2070,7 @@ namespace MWWorld
|
|||
return facedObject;
|
||||
}
|
||||
|
||||
std::pair<MWWorld::Ptr, osg::Node*> World::getPointedAtObject(float maxDistance, bool ignorePlayer)
|
||||
World::IntersectedObject World::getPointedAtObject(float maxDistance, bool ignorePlayer)
|
||||
{
|
||||
auto sceneRoot = mRendering->getLightRoot();
|
||||
|
||||
|
@ -2103,11 +2103,10 @@ namespace MWWorld
|
|||
else
|
||||
// Leave a very large but not too large number to permit visualizing a beam going into "infinity"
|
||||
mDistanceToPointedAtObject = 10000.f;
|
||||
|
||||
return { rayToObject.mHitObject, rayToObject.mHitNode };
|
||||
return { rayToObject.mHitObject, rayToObject.mHitNode, rayToObject.mHitPointLocal };
|
||||
}
|
||||
|
||||
return std::pair<MWWorld::Ptr, osg::Node*>();
|
||||
return IntersectedObject();
|
||||
}
|
||||
|
||||
bool World::isCellExterior() const
|
||||
|
|
|
@ -140,7 +140,7 @@ namespace MWWorld
|
|||
|
||||
MWWorld::Ptr getFacedObject(float maxDistance, bool ignorePlayer=true);
|
||||
|
||||
std::pair<MWWorld::Ptr, osg::Node*> getPointedAtObject(float maxDistance, bool ignorePlayer=true);
|
||||
IntersectedObject getPointedAtObject(float maxDistance, bool ignorePlayer=true);
|
||||
|
||||
public: // FIXME
|
||||
void addContainerScripts(const Ptr& reference, CellStore* cell) override;
|
||||
|
@ -377,7 +377,7 @@ namespace MWWorld
|
|||
MWWorld::Ptr getFacedObject() override;
|
||||
///< Return pointer to the object the player is looking at, if it is within activation range
|
||||
|
||||
std::pair<MWWorld::Ptr, osg::Node*> getPointedAtObject() override;
|
||||
IntersectedObject getPointedAtObject() override;
|
||||
///< Return pointer to the object and/or node the player is currently pointing at
|
||||
|
||||
float getDistanceToFacedObject() override;
|
||||
|
|
Loading…
Reference in a new issue