1
0
Fork 1
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:
Mads Buvik Sandvei 2020-03-08 14:14:24 +01:00
parent 2ae7255fac
commit e573a260cb
12 changed files with 114 additions and 44 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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));
}
}
}

View file

@ -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
{

View file

@ -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 };

View file

@ -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;

View file

@ -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 };

View file

@ -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

View file

@ -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

View file

@ -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;