mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-10-16 13:16:36 +00:00
Touch input of activation now makes character point forward.
This commit is contained in:
parent
0840d2dd92
commit
287886d545
8 changed files with 198 additions and 78 deletions
|
@ -48,6 +48,10 @@
|
||||||
#include "actorutil.hpp"
|
#include "actorutil.hpp"
|
||||||
#include "spellcasting.hpp"
|
#include "spellcasting.hpp"
|
||||||
|
|
||||||
|
#ifdef USE_OPENXR
|
||||||
|
#include "../mwvr/openxranimation.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1666,6 +1670,7 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
||||||
animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete);
|
animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete);
|
||||||
if(mUpperBodyState == UpperCharState_MinAttackToMaxAttack && !isKnockedDown())
|
if(mUpperBodyState == UpperCharState_MinAttackToMaxAttack && !isKnockedDown())
|
||||||
mAttackStrength = complete;
|
mAttackStrength = complete;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1876,6 +1881,18 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
||||||
|
|
||||||
mAnimation->setAccurateAiming(mUpperBodyState > UpperCharState_WeapEquiped);
|
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;
|
return forcestateupdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,37 +55,36 @@
|
||||||
namespace MWVR
|
namespace MWVR
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// This will work for a prototype. But finger/arm control might be better implemented using the
|
||||||
|
// existing animation system, implementing this as an animation source.
|
||||||
|
// But I'm not sure it would be since these are not classical animations.
|
||||||
|
// It would make it easier to control priority, and later allow for users to add their own stuff to animations based on VR/touch input.
|
||||||
|
// But openmw doesn't really have any concepts for user animation overrides.
|
||||||
|
|
||||||
|
|
||||||
/// Implements dummy control of the forearm, to control mesh/bone deformation of the hand.
|
/// Implements dummy control of the forearm, to control mesh/bone deformation of the hand.
|
||||||
class ForearmController : public osg::NodeCallback
|
class ForearmController : public osg::NodeCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ForearmController(osg::Node* relativeTo, SceneUtil::PositionAttitudeTransform* tracker);
|
ForearmController(osg::Node* relativeTo, SceneUtil::PositionAttitudeTransform* tracker);
|
||||||
void setEnabled(bool enabled);
|
void setEnabled(bool enabled) { mEnabled = enabled; };
|
||||||
void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mEnabled;
|
bool mEnabled = true;
|
||||||
osg::Quat mRotate;
|
osg::Quat mRotate{};
|
||||||
osg::Node* mRelativeTo;
|
osg::Node* mRelativeTo;
|
||||||
osg::Matrix mOffset;
|
osg::Matrix mOffset{ osg::Matrix::identity() };
|
||||||
bool mOffsetInitialized;
|
bool mOffsetInitialized = false;
|
||||||
SceneUtil::PositionAttitudeTransform* mTracker;
|
SceneUtil::PositionAttitudeTransform* mTracker;
|
||||||
};
|
};
|
||||||
|
|
||||||
ForearmController::ForearmController(osg::Node* relativeTo, SceneUtil::PositionAttitudeTransform* tracker)
|
ForearmController::ForearmController(osg::Node* relativeTo, SceneUtil::PositionAttitudeTransform* tracker)
|
||||||
: mEnabled(true)
|
: mRelativeTo(relativeTo)
|
||||||
, mRelativeTo(relativeTo)
|
|
||||||
, mOffset(osg::Matrix::identity())
|
|
||||||
, mOffsetInitialized(false)
|
|
||||||
, mTracker(tracker)
|
, mTracker(tracker)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForearmController::setEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
mEnabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ForearmController::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
void ForearmController::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
if (!mEnabled)
|
if (!mEnabled)
|
||||||
|
@ -117,11 +116,47 @@ void ForearmController::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
transform->setMatrix(mOffset * worldReference * osg::Matrix::inverse(worldToLimb) * transform->getMatrix());
|
transform->setMatrix(mOffset * worldReference * osg::Matrix::inverse(worldToLimb) * transform->getMatrix());
|
||||||
|
|
||||||
|
|
||||||
// TODO: Continued traversal is necessary to allow update of new hand poses such as gribbing a weapon.
|
// TODO: Continued traversal is necessary to allow update of new hand poses such as gripping a weapon.
|
||||||
// But I want to disable idle animations.
|
// But I want to disable idle animations.
|
||||||
traverse(node, nv);
|
traverse(node, nv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements control of a finger by overriding rotation
|
||||||
|
class FingerController : public osg::NodeCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FingerController(osg::Quat rotate) : mRotate(rotate) {};
|
||||||
|
void setEnabled(bool enabled) { mEnabled = enabled; };
|
||||||
|
void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mEnabled = true;
|
||||||
|
osg::Quat mRotate{};
|
||||||
|
};
|
||||||
|
|
||||||
|
void FingerController::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
if (!mEnabled)
|
||||||
|
{
|
||||||
|
traverse(node, nv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto matrixTransform = node->asTransform()->asMatrixTransform();
|
||||||
|
auto matrix = matrixTransform->getMatrix();
|
||||||
|
matrix.setRotate(mRotate);
|
||||||
|
matrixTransform->setMatrix(matrix);
|
||||||
|
|
||||||
|
auto tip = matrixTransform->getChild(0);
|
||||||
|
auto tipMatrixTransform = tip->asTransform()->asMatrixTransform();
|
||||||
|
matrix = tipMatrixTransform->getMatrix();
|
||||||
|
matrix.setRotate(mRotate);
|
||||||
|
tipMatrixTransform->setMatrix(matrix);
|
||||||
|
|
||||||
|
//traverse(node, nv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
OpenXRAnimation::OpenXRAnimation(
|
OpenXRAnimation::OpenXRAnimation(
|
||||||
const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
||||||
bool disableSounds, std::shared_ptr<OpenXRSession> xrSession)
|
bool disableSounds, std::shared_ptr<OpenXRSession> xrSession)
|
||||||
|
@ -129,8 +164,14 @@ OpenXRAnimation::OpenXRAnimation(
|
||||||
// when OpenMW sets the view mode of the camera object.
|
// when OpenMW sets the view mode of the camera object.
|
||||||
: MWRender::NpcAnimation(ptr, parentNode, resourceSystem, disableSounds, VM_Normal, 55.f)
|
: MWRender::NpcAnimation(ptr, parentNode, resourceSystem, disableSounds, VM_Normal, 55.f)
|
||||||
, mSession(xrSession)
|
, mSession(xrSession)
|
||||||
|
, mIndexFingerControllers{nullptr, nullptr}
|
||||||
{
|
{
|
||||||
|
mIndexFingerControllers[0] = osg::ref_ptr<FingerController> (new FingerController(osg::Quat(0, 0, 0, 1)));
|
||||||
|
mIndexFingerControllers[1] = osg::ref_ptr<FingerController> (new FingerController(osg::Quat(0, 0, 0, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenXRAnimation::~OpenXRAnimation() {};
|
||||||
|
|
||||||
void OpenXRAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
|
void OpenXRAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
|
||||||
{
|
{
|
||||||
if (viewMode != VM_VRHeadless)
|
if (viewMode != VM_VRHeadless)
|
||||||
|
@ -154,6 +195,16 @@ void OpenXRAnimation::updateParts()
|
||||||
removeIndividualPart(ESM::PartReferenceType::PRT_RUpperarm);
|
removeIndividualPart(ESM::PartReferenceType::PRT_RUpperarm);
|
||||||
removeIndividualPart(ESM::PartReferenceType::PRT_RWrist);
|
removeIndividualPart(ESM::PartReferenceType::PRT_RWrist);
|
||||||
}
|
}
|
||||||
|
void OpenXRAnimation::setPointForward(bool enabled)
|
||||||
|
{
|
||||||
|
auto found00 = mNodeMap.find("bip01 r finger1");
|
||||||
|
if (found00 != mNodeMap.end())
|
||||||
|
{
|
||||||
|
found00->second->removeUpdateCallback(mIndexFingerControllers[0]);
|
||||||
|
if (enabled)
|
||||||
|
found00->second->addUpdateCallback(mIndexFingerControllers[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
osg::Vec3f OpenXRAnimation::runAnimation(float timepassed)
|
osg::Vec3f OpenXRAnimation::runAnimation(float timepassed)
|
||||||
{
|
{
|
||||||
return NpcAnimation::runAnimation(timepassed);
|
return NpcAnimation::runAnimation(timepassed);
|
||||||
|
@ -187,7 +238,7 @@ void OpenXRAnimation::addControllers()
|
||||||
|
|
||||||
SceneUtil::PositionAttitudeTransform* tracker = dynamic_cast<SceneUtil::PositionAttitudeTransform*>(findTrackerVisitor.mFoundNode);
|
SceneUtil::PositionAttitudeTransform* tracker = dynamic_cast<SceneUtil::PositionAttitudeTransform*>(findTrackerVisitor.mFoundNode);
|
||||||
|
|
||||||
std::map<std::string, osg::ref_ptr<osg::MatrixTransform> >::const_iterator found = mNodeMap.find(i == 0 ? "bip01 l forearm" : "bip01 r forearm");
|
auto found = mNodeMap.find(i == 0 ? "bip01 l forearm" : "bip01 r forearm");
|
||||||
if (found != mNodeMap.end())
|
if (found != mNodeMap.end())
|
||||||
{
|
{
|
||||||
osg::Node* node = found->second;
|
osg::Node* node = found->second;
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace MWVR
|
||||||
{
|
{
|
||||||
|
|
||||||
class HandController;
|
class HandController;
|
||||||
|
class FingerController;
|
||||||
class ForearmController;
|
class ForearmController;
|
||||||
|
|
||||||
/// Subclassing NpcAnimation to override behaviours not compatible with VR
|
/// Subclassing NpcAnimation to override behaviours not compatible with VR
|
||||||
|
@ -29,7 +30,7 @@ public:
|
||||||
*/
|
*/
|
||||||
OpenXRAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
OpenXRAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
||||||
bool disableSounds, std::shared_ptr<OpenXRSession> xrSession );
|
bool disableSounds, std::shared_ptr<OpenXRSession> xrSession );
|
||||||
virtual ~OpenXRAnimation() {};
|
virtual ~OpenXRAnimation();
|
||||||
|
|
||||||
/// Overridden to always be false
|
/// Overridden to always be false
|
||||||
virtual void enableHeadAnimation(bool enable);
|
virtual void enableHeadAnimation(bool enable);
|
||||||
|
@ -50,11 +51,15 @@ public:
|
||||||
/// Overriden to include VR modifications
|
/// Overriden to include VR modifications
|
||||||
virtual void updateParts();
|
virtual void updateParts();
|
||||||
|
|
||||||
|
/// Overrides finger animations to point forward
|
||||||
|
/// (Used to visualize direction of activation action)
|
||||||
|
void setPointForward(bool enabled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<OpenXRSession> mSession;
|
std::shared_ptr<OpenXRSession> mSession;
|
||||||
ForearmController* mForearmControllers[2]{};
|
ForearmController* mForearmControllers[2]{};
|
||||||
HandController* mHandControllers[2]{};
|
HandController* mHandControllers[2]{};
|
||||||
|
osg::ref_ptr<FingerController> mIndexFingerControllers[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
#include "../mwmechanics/actorutil.hpp"
|
||||||
|
|
||||||
#include <openxr/openxr.h>
|
#include <openxr/openxr.h>
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ namespace MWVR
|
||||||
{
|
{
|
||||||
struct OpenXRActionEvent
|
struct OpenXRActionEvent
|
||||||
{
|
{
|
||||||
MWInput::InputManager::Actions action;
|
int action;
|
||||||
bool onPress;
|
bool onPress;
|
||||||
float value = 0.f;
|
float value = 0.f;
|
||||||
};
|
};
|
||||||
|
@ -116,10 +117,46 @@ namespace MWVR
|
||||||
float mValue = 0.f;
|
float mValue = 0.f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Wrapper around float type input actions, converting them to bools above a specified value
|
||||||
|
struct OpenXRAction_FloatToBool
|
||||||
|
{
|
||||||
|
OpenXRAction_FloatToBool(OpenXRAction action, float threshold);
|
||||||
|
operator XrAction() { return mAction; }
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
//! True if action changed to being pressed in the last update
|
||||||
|
bool actionOnPress() { return actionIsPressed() && actionChanged(); }
|
||||||
|
//! True if action changed to being released in the last update
|
||||||
|
bool actionOnRelease() { return actionIsReleased() && actionChanged(); };
|
||||||
|
//! True if the action is currently being pressed
|
||||||
|
bool actionIsPressed() { return mPressed; }
|
||||||
|
//! True if the action is currently not being pressed
|
||||||
|
bool actionIsReleased() { return !mPressed; }
|
||||||
|
//! True if the action changed state in the last update
|
||||||
|
bool actionChanged() { return mChanged; }
|
||||||
|
|
||||||
|
OpenXRAction_Float mAction;
|
||||||
|
float mThreshold;
|
||||||
|
bool mPressed = false;
|
||||||
|
bool mChanged = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct OpenXRInput
|
struct OpenXRInput
|
||||||
{
|
{
|
||||||
using Actions = MWInput::InputManager::Actions;
|
using Actions = MWInput::InputManager::Actions;
|
||||||
|
|
||||||
|
// The OpenMW input manager iterates from 0 to A_Last in its actions enum.
|
||||||
|
// I don't know that it would cause any ill effects, but i nonetheless do not
|
||||||
|
// want to contaminate the input manager with my OpenXR specific actions.
|
||||||
|
// Therefore i add them here to a separate enum whose values start past A_Last.
|
||||||
|
enum XrActions
|
||||||
|
{
|
||||||
|
A_XrFirst = MWInput::InputManager::A_Last,
|
||||||
|
A_ActivateTouch,
|
||||||
|
A_XrLast
|
||||||
|
};
|
||||||
|
|
||||||
enum SubAction : signed
|
enum SubAction : signed
|
||||||
{
|
{
|
||||||
NONE = -1, //!< Used to ignore subaction or when action has no subaction. Not a valid input to createAction().
|
NONE = -1, //!< Used to ignore subaction or when action has no subaction. Not a valid input to createAction().
|
||||||
|
@ -160,7 +197,6 @@ namespace MWVR
|
||||||
|
|
||||||
ControllerActionPaths mSelectPath;
|
ControllerActionPaths mSelectPath;
|
||||||
ControllerActionPaths mSqueezeValuePath;
|
ControllerActionPaths mSqueezeValuePath;
|
||||||
ControllerActionPaths mSqueezeClickPath;
|
|
||||||
ControllerActionPaths mPosePath;
|
ControllerActionPaths mPosePath;
|
||||||
ControllerActionPaths mHapticPath;
|
ControllerActionPaths mHapticPath;
|
||||||
ControllerActionPaths mMenuClickPath;
|
ControllerActionPaths mMenuClickPath;
|
||||||
|
@ -172,7 +208,6 @@ namespace MWVR
|
||||||
ControllerActionPaths mYPath;
|
ControllerActionPaths mYPath;
|
||||||
ControllerActionPaths mAPath;
|
ControllerActionPaths mAPath;
|
||||||
ControllerActionPaths mBPath;
|
ControllerActionPaths mBPath;
|
||||||
ControllerActionPaths mTriggerClickPath;
|
|
||||||
ControllerActionPaths mTriggerValuePath;
|
ControllerActionPaths mTriggerValuePath;
|
||||||
|
|
||||||
OpenXRAction_Bool mGameMenu;
|
OpenXRAction_Bool mGameMenu;
|
||||||
|
@ -191,46 +226,14 @@ namespace MWVR
|
||||||
OpenXRAction_Float mLookLeftRight;
|
OpenXRAction_Float mLookLeftRight;
|
||||||
OpenXRAction_Float mMoveForwardBackward;
|
OpenXRAction_Float mMoveForwardBackward;
|
||||||
OpenXRAction_Float mMoveLeftRight;
|
OpenXRAction_Float mMoveLeftRight;
|
||||||
//OpenXRAction mUnused;
|
|
||||||
//OpenXRAction mScreenshot;
|
|
||||||
//OpenXRAction mConsole;
|
|
||||||
//OpenXRAction mMoveLeft;
|
|
||||||
//OpenXRAction mMoveRight;
|
|
||||||
//OpenXRAction mMoveForward;
|
|
||||||
//OpenXRAction mMoveBackward;
|
|
||||||
//OpenXRAction mAutoMove;
|
|
||||||
//OpenXRAction mRest;
|
|
||||||
//OpenXRAction mJournal;
|
|
||||||
//OpenXRAction mRun;
|
|
||||||
//OpenXRAction mToggleSneak;
|
|
||||||
//OpenXRAction mAlwaysRun;
|
|
||||||
//OpenXRAction mQuickSave;
|
|
||||||
//OpenXRAction mQuickLoad;
|
|
||||||
//OpenXRAction mToggleWeapon;
|
|
||||||
//OpenXRAction mToggleSpell;
|
|
||||||
//OpenXRAction mTogglePOV;
|
|
||||||
//OpenXRAction mQuickKey1;
|
|
||||||
//OpenXRAction mQuickKey2;
|
|
||||||
//OpenXRAction mQuickKey3;
|
|
||||||
//OpenXRAction mQuickKey4;
|
|
||||||
//OpenXRAction mQuickKey5;
|
|
||||||
//OpenXRAction mQuickKey6;
|
|
||||||
//OpenXRAction mQuickKey7;
|
|
||||||
//OpenXRAction mQuickKey8;
|
|
||||||
//OpenXRAction mQuickKey9;
|
|
||||||
//OpenXRAction mQuickKey10;
|
|
||||||
//OpenXRAction mQuickKeysMenu;
|
|
||||||
//OpenXRAction mToggleHUD;
|
|
||||||
//OpenXRAction mToggleDebug;
|
|
||||||
//OpenXRAction mLookUpDown;
|
|
||||||
//OpenXRAction mZoomIn;
|
|
||||||
//OpenXRAction mZoomOut;
|
|
||||||
|
|
||||||
//! Needed to access all the actions that don't fit on the controllers
|
// Needed to access all the actions that don't fit on the controllers
|
||||||
OpenXRAction_Bool mActionsMenu;
|
OpenXRAction_Bool mActionsMenu;
|
||||||
//! Economize buttons by accessing spell actions and weapon actions on the same keys, but with/without this modifier
|
// Economize buttons by accessing spell actions and weapon actions on the same keys, but with/without this modifier
|
||||||
OpenXRAction_Bool mSpellModifier;
|
OpenXRAction_Bool mSpellModifier;
|
||||||
|
|
||||||
|
OpenXRAction_FloatToBool mActivateTouch;
|
||||||
|
|
||||||
// Hand tracking
|
// Hand tracking
|
||||||
OpenXRAction mHandPoseAction;
|
OpenXRAction mHandPoseAction;
|
||||||
OpenXRAction mHapticsAction;
|
OpenXRAction mHapticsAction;
|
||||||
|
@ -353,6 +356,23 @@ namespace MWVR
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OpenXRAction_FloatToBool::OpenXRAction_FloatToBool(
|
||||||
|
OpenXRAction action, float threshold)
|
||||||
|
: mAction(std::move(action))
|
||||||
|
, mThreshold(threshold)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenXRAction_FloatToBool::update()
|
||||||
|
{
|
||||||
|
mAction.update();
|
||||||
|
bool old = mPressed;
|
||||||
|
float value = mAction.value();
|
||||||
|
mPressed = value > mThreshold;
|
||||||
|
mChanged = mPressed != old;
|
||||||
|
}
|
||||||
|
|
||||||
OpenXRAction_Bool::OpenXRAction_Bool(
|
OpenXRAction_Bool::OpenXRAction_Bool(
|
||||||
OpenXRAction action)
|
OpenXRAction action)
|
||||||
: mAction(std::move(action))
|
: mAction(std::move(action))
|
||||||
|
@ -411,7 +431,6 @@ namespace MWVR
|
||||||
, mActionSet(createActionSet())
|
, mActionSet(createActionSet())
|
||||||
, mSelectPath(generateControllerActionPaths("/input/select/click"))
|
, mSelectPath(generateControllerActionPaths("/input/select/click"))
|
||||||
, mSqueezeValuePath(generateControllerActionPaths("/input/squeeze/value"))
|
, mSqueezeValuePath(generateControllerActionPaths("/input/squeeze/value"))
|
||||||
, mSqueezeClickPath(generateControllerActionPaths("/input/squeeze/click"))
|
|
||||||
, mPosePath(generateControllerActionPaths("/input/aim/pose"))
|
, mPosePath(generateControllerActionPaths("/input/aim/pose"))
|
||||||
, mHapticPath(generateControllerActionPaths("/output/haptic"))
|
, mHapticPath(generateControllerActionPaths("/output/haptic"))
|
||||||
, mMenuClickPath(generateControllerActionPaths("/input/menu/click"))
|
, mMenuClickPath(generateControllerActionPaths("/input/menu/click"))
|
||||||
|
@ -423,7 +442,6 @@ namespace MWVR
|
||||||
, mYPath(generateControllerActionPaths("/input/y/click"))
|
, mYPath(generateControllerActionPaths("/input/y/click"))
|
||||||
, mAPath(generateControllerActionPaths("/input/a/click"))
|
, mAPath(generateControllerActionPaths("/input/a/click"))
|
||||||
, mBPath(generateControllerActionPaths("/input/b/click"))
|
, mBPath(generateControllerActionPaths("/input/b/click"))
|
||||||
, mTriggerClickPath(generateControllerActionPaths("/input/trigger/click"))
|
|
||||||
, mTriggerValuePath(generateControllerActionPaths("/input/trigger/value"))
|
, mTriggerValuePath(generateControllerActionPaths("/input/trigger/value"))
|
||||||
, mGameMenu(std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "game_menu", "GameMenu", { })))
|
, mGameMenu(std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "game_menu", "GameMenu", { })))
|
||||||
, mInventory(std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "inventory", "Inventory", { })))
|
, mInventory(std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "inventory", "Inventory", { })))
|
||||||
|
@ -443,6 +461,7 @@ namespace MWVR
|
||||||
, mMoveLeftRight(std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "move_left_right", "MoveLeftRight", { })))
|
, mMoveLeftRight(std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "move_left_right", "MoveLeftRight", { })))
|
||||||
, mActionsMenu(std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "actions_menu", "Actions Menu", { })))
|
, mActionsMenu(std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "actions_menu", "Actions Menu", { })))
|
||||||
, mSpellModifier(std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "spell_modifier", "Spell Modifier", { })))
|
, mSpellModifier(std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "spell_modifier", "Spell Modifier", { })))
|
||||||
|
, mActivateTouch(std::move(createAction(XR_ACTION_TYPE_FLOAT_INPUT, "activate_touched", "Activate Touch", { RIGHT_HAND })), 0.01f)
|
||||||
, mHandPoseAction(std::move(createAction(XR_ACTION_TYPE_POSE_INPUT, "hand_pose", "Hand Pose", { LEFT_HAND, RIGHT_HAND })))
|
, mHandPoseAction(std::move(createAction(XR_ACTION_TYPE_POSE_INPUT, "hand_pose", "Hand Pose", { LEFT_HAND, RIGHT_HAND })))
|
||||||
, mHapticsAction(std::move(createAction(XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_hand", "Vibrate Hand", { LEFT_HAND, RIGHT_HAND })))
|
, mHapticsAction(std::move(createAction(XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_hand", "Vibrate Hand", { LEFT_HAND, RIGHT_HAND })))
|
||||||
{
|
{
|
||||||
|
@ -472,6 +491,7 @@ namespace MWVR
|
||||||
{mQuickMenu, mYPath[LEFT_HAND]},
|
{mQuickMenu, mYPath[LEFT_HAND]},
|
||||||
{mSpellModifier, mSqueezeValuePath[LEFT_HAND]},
|
{mSpellModifier, mSqueezeValuePath[LEFT_HAND]},
|
||||||
{mGameMenu, mMenuClickPath[LEFT_HAND]},
|
{mGameMenu, mMenuClickPath[LEFT_HAND]},
|
||||||
|
{mActivateTouch, mSqueezeValuePath[RIGHT_HAND]},
|
||||||
} };
|
} };
|
||||||
XrInteractionProfileSuggestedBinding suggestedBindings{ XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING };
|
XrInteractionProfileSuggestedBinding suggestedBindings{ XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING };
|
||||||
suggestedBindings.interactionProfile = oculusTouchInteractionProfilePath;
|
suggestedBindings.interactionProfile = oculusTouchInteractionProfilePath;
|
||||||
|
@ -483,10 +503,10 @@ namespace MWVR
|
||||||
mSpellModifier; // L-Squeeze
|
mSpellModifier; // L-Squeeze
|
||||||
mActivate; // R-Squeeze
|
mActivate; // R-Squeeze
|
||||||
mUse; // R-Trigger
|
mUse; // R-Trigger
|
||||||
mJump; // L-Trigger. L-trigger has value, can be used to make measured jumps
|
mJump; // L-Trigger. L-trigger has value, could use this to make measured jumps ?
|
||||||
mWeapon; // A
|
mToggleWeapon; // A
|
||||||
mSpell; // A + SpellModifier
|
mToggleSpell; // A + SpellModifier
|
||||||
mRun; // Based on movement thumbstick value: broken line ( 0 (stand), 0.5 (walk), 1.0 (run) ). Remember to scale fatigue use.
|
mRun; // Based on movement thumbstick value ?
|
||||||
mCycleSpellLeft; // L-ThumbstickClick + SpellModifier
|
mCycleSpellLeft; // L-ThumbstickClick + SpellModifier
|
||||||
mCycleSpellRight; // R-ThumbstickClick + SpellModifier
|
mCycleSpellRight; // R-ThumbstickClick + SpellModifier
|
||||||
mCycleWeaponLeft; // L-ThumbstickClick
|
mCycleWeaponLeft; // L-ThumbstickClick
|
||||||
|
@ -583,8 +603,9 @@ namespace MWVR
|
||||||
mMoveLeftRight.update();
|
mMoveLeftRight.update();
|
||||||
mActionsMenu.update();
|
mActionsMenu.update();
|
||||||
mSpellModifier.update();
|
mSpellModifier.update();
|
||||||
|
mActivateTouch.update();
|
||||||
|
|
||||||
// This set of actions only care about on-press
|
// Simple fire-and-forget on-press actions
|
||||||
if (mActionsMenu.actionOnPress())
|
if (mActionsMenu.actionOnPress())
|
||||||
{
|
{
|
||||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_QuickKeysMenu, true });
|
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_QuickKeysMenu, true });
|
||||||
|
@ -601,27 +622,29 @@ namespace MWVR
|
||||||
{
|
{
|
||||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Activate, true });
|
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Activate, true });
|
||||||
}
|
}
|
||||||
if (mUse.actionChanged())
|
|
||||||
{
|
|
||||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Use, mUse.actionOnPress() });
|
|
||||||
}
|
|
||||||
if (mJump.actionOnPress())
|
if (mJump.actionOnPress())
|
||||||
{
|
{
|
||||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Jump, true });
|
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Jump, true });
|
||||||
}
|
}
|
||||||
if (mSneak.actionOnPress())
|
|
||||||
{
|
|
||||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Sneak, true });
|
|
||||||
}
|
|
||||||
if (mSneak.actionOnRelease())
|
|
||||||
{
|
|
||||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Sneak, false });
|
|
||||||
}
|
|
||||||
if (mQuickMenu.actionOnPress())
|
if (mQuickMenu.actionOnPress())
|
||||||
{
|
{
|
||||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_QuickMenu, true });
|
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_QuickMenu, true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actions that hold with the button
|
||||||
|
if (mUse.actionChanged())
|
||||||
|
{
|
||||||
|
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Use, mUse.actionOnPress() });
|
||||||
|
}
|
||||||
|
if (mSneak.actionChanged())
|
||||||
|
{
|
||||||
|
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_Sneak, mSneak.actionOnPress() });
|
||||||
|
}
|
||||||
|
if (mActivateTouch.actionChanged())
|
||||||
|
{
|
||||||
|
mActionEvents.emplace_back(OpenXRActionEvent{ A_ActivateTouch, mActivateTouch.actionOnPress() });
|
||||||
|
}
|
||||||
|
|
||||||
// Weapon/Spell actions
|
// Weapon/Spell actions
|
||||||
if (mWeapon.actionOnPress() && !mSpellModifier.actionIsPressed())
|
if (mWeapon.actionOnPress() && !mSpellModifier.actionIsPressed())
|
||||||
{
|
{
|
||||||
|
@ -717,6 +740,11 @@ namespace MWVR
|
||||||
return mXRInput->getHandPoses(time, space);
|
return mXRInput->getHandPoses(time, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenXRInputManager::showActivationIndication(bool show)
|
||||||
|
{
|
||||||
|
mPlayer->setPointing(show);
|
||||||
|
}
|
||||||
|
|
||||||
OpenXRInputManager::OpenXRInputManager(
|
OpenXRInputManager::OpenXRInputManager(
|
||||||
SDL_Window* window,
|
SDL_Window* window,
|
||||||
osg::ref_ptr<OpenXRViewer> viewer,
|
osg::ref_ptr<OpenXRViewer> viewer,
|
||||||
|
@ -922,6 +950,9 @@ namespace MWVR
|
||||||
case A_Use:
|
case A_Use:
|
||||||
mInputBinder->getChannel(A_Use)->setValue(event.onPress);
|
mInputBinder->getChannel(A_Use)->setValue(event.onPress);
|
||||||
break;
|
break;
|
||||||
|
case OpenXRInput::A_ActivateTouch:
|
||||||
|
showActivationIndication(event.onPress);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Log(Debug::Warning) << "Unhandled XR action " << event.action;
|
Log(Debug::Warning) << "Unhandled XR action " << event.action;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ namespace MWVR
|
||||||
|
|
||||||
PoseSet getHandPoses(int64_t time, TrackedSpace space);
|
PoseSet getHandPoses(int64_t time, TrackedSpace space);
|
||||||
|
|
||||||
|
void showActivationIndication(bool show);
|
||||||
|
|
||||||
osg::ref_ptr<OpenXRViewer> mXRViewer;
|
osg::ref_ptr<OpenXRViewer> mXRViewer;
|
||||||
std::unique_ptr<OpenXRInput> mXRInput;
|
std::unique_ptr<OpenXRInput> mXRInput;
|
||||||
};
|
};
|
||||||
|
|
|
@ -185,8 +185,8 @@ namespace MWVR
|
||||||
mirror_width = mMirrorTextureSwapchain->width() / 2;
|
mirror_width = mMirrorTextureSwapchain->width() / 2;
|
||||||
|
|
||||||
|
|
||||||
mViews["LeftEye"]->swapchain().renderBuffer()->blit(gc, 0, 0, mirror_width, mMirrorTextureSwapchain->height());
|
mViews["RightEye"]->swapchain().renderBuffer()->blit(gc, 0, 0, mirror_width, mMirrorTextureSwapchain->height());
|
||||||
mViews["RightEye"]->swapchain().renderBuffer()->blit(gc, mirror_width, 0, 2 * mirror_width, mMirrorTextureSwapchain->height());
|
mViews["LeftEye"]->swapchain().renderBuffer()->blit(gc, mirror_width, 0, 2 * mirror_width, mMirrorTextureSwapchain->height());
|
||||||
|
|
||||||
if(includeMenu)
|
if(includeMenu)
|
||||||
mViews["MenuView"]->swapchain().renderBuffer()->blit(gc, 2 * mirror_width, 0, 3 * mirror_width, mMirrorTextureSwapchain->height());
|
mViews["MenuView"]->swapchain().renderBuffer()->blit(gc, 2 * mirror_width, 0, 3 * mirror_width, mMirrorTextureSwapchain->height());
|
||||||
|
|
|
@ -274,6 +274,16 @@ namespace MWWorld
|
||||||
return mJumping;
|
return mJumping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::setPointing(bool pointing)
|
||||||
|
{
|
||||||
|
mPointing = pointing;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Player::getPointing() const
|
||||||
|
{
|
||||||
|
return mPointing;
|
||||||
|
}
|
||||||
|
|
||||||
bool Player::isInCombat() {
|
bool Player::isInCombat() {
|
||||||
return MWBase::Environment::get().getMechanicsManager()->getActorsFighting(getPlayer()).size() != 0;
|
return MWBase::Environment::get().getMechanicsManager()->getActorsFighting(getPlayer()).size() != 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ namespace MWWorld
|
||||||
|
|
||||||
bool mAttackingOrSpell;
|
bool mAttackingOrSpell;
|
||||||
bool mJumping;
|
bool mJumping;
|
||||||
|
bool mPointing;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -117,6 +118,9 @@ namespace MWWorld
|
||||||
void setJumping(bool jumping);
|
void setJumping(bool jumping);
|
||||||
bool getJumping() const;
|
bool getJumping() const;
|
||||||
|
|
||||||
|
void setPointing(bool pointing);
|
||||||
|
bool getPointing(void) const;
|
||||||
|
|
||||||
///Checks all nearby actors to see if anyone has an aipackage against you
|
///Checks all nearby actors to see if anyone has an aipackage against you
|
||||||
bool isInCombat();
|
bool isInCombat();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue