mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-15 22:19:54 +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 "spellcasting.hpp"
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
#include "../mwvr/openxranimation.hpp"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
@ -1666,6 +1670,7 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||
animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete);
|
||||
if(mUpperBodyState == UpperCharState_MinAttackToMaxAttack && !isKnockedDown())
|
||||
mAttackStrength = complete;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1876,6 +1881,18 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,37 +55,36 @@
|
|||
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.
|
||||
class ForearmController : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
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);
|
||||
|
||||
private:
|
||||
bool mEnabled;
|
||||
osg::Quat mRotate;
|
||||
bool mEnabled = true;
|
||||
osg::Quat mRotate{};
|
||||
osg::Node* mRelativeTo;
|
||||
osg::Matrix mOffset;
|
||||
bool mOffsetInitialized;
|
||||
osg::Matrix mOffset{ osg::Matrix::identity() };
|
||||
bool mOffsetInitialized = false;
|
||||
SceneUtil::PositionAttitudeTransform* mTracker;
|
||||
};
|
||||
|
||||
ForearmController::ForearmController(osg::Node* relativeTo, SceneUtil::PositionAttitudeTransform* tracker)
|
||||
: mEnabled(true)
|
||||
, mRelativeTo(relativeTo)
|
||||
, mOffset(osg::Matrix::identity())
|
||||
, mOffsetInitialized(false)
|
||||
: mRelativeTo(relativeTo)
|
||||
, mTracker(tracker)
|
||||
{
|
||||
}
|
||||
|
||||
void ForearmController::setEnabled(bool enabled)
|
||||
{
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
void ForearmController::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
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());
|
||||
|
||||
|
||||
// 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.
|
||||
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(
|
||||
const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
||||
bool disableSounds, std::shared_ptr<OpenXRSession> xrSession)
|
||||
|
@ -129,8 +164,14 @@ OpenXRAnimation::OpenXRAnimation(
|
|||
// when OpenMW sets the view mode of the camera object.
|
||||
: MWRender::NpcAnimation(ptr, parentNode, resourceSystem, disableSounds, VM_Normal, 55.f)
|
||||
, 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)
|
||||
{
|
||||
if (viewMode != VM_VRHeadless)
|
||||
|
@ -154,6 +195,16 @@ void OpenXRAnimation::updateParts()
|
|||
removeIndividualPart(ESM::PartReferenceType::PRT_RUpperarm);
|
||||
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)
|
||||
{
|
||||
return NpcAnimation::runAnimation(timepassed);
|
||||
|
@ -187,7 +238,7 @@ void OpenXRAnimation::addControllers()
|
|||
|
||||
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())
|
||||
{
|
||||
osg::Node* node = found->second;
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace MWVR
|
|||
{
|
||||
|
||||
class HandController;
|
||||
class FingerController;
|
||||
class ForearmController;
|
||||
|
||||
/// 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,
|
||||
bool disableSounds, std::shared_ptr<OpenXRSession> xrSession );
|
||||
virtual ~OpenXRAnimation() {};
|
||||
virtual ~OpenXRAnimation();
|
||||
|
||||
/// Overridden to always be false
|
||||
virtual void enableHeadAnimation(bool enable);
|
||||
|
@ -50,11 +51,15 @@ public:
|
|||
/// Overriden to include VR modifications
|
||||
virtual void updateParts();
|
||||
|
||||
/// Overrides finger animations to point forward
|
||||
/// (Used to visualize direction of activation action)
|
||||
void setPointForward(bool enabled);
|
||||
|
||||
private:
|
||||
std::shared_ptr<OpenXRSession> mSession;
|
||||
ForearmController* mForearmControllers[2]{};
|
||||
HandController* mHandControllers[2]{};
|
||||
|
||||
osg::ref_ptr<FingerController> mIndexFingerControllers[2];
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
||||
#include <openxr/openxr.h>
|
||||
|
||||
|
@ -42,7 +43,7 @@ namespace MWVR
|
|||
{
|
||||
struct OpenXRActionEvent
|
||||
{
|
||||
MWInput::InputManager::Actions action;
|
||||
int action;
|
||||
bool onPress;
|
||||
float value = 0.f;
|
||||
};
|
||||
|
@ -116,10 +117,46 @@ namespace MWVR
|
|||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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 mSqueezeValuePath;
|
||||
ControllerActionPaths mSqueezeClickPath;
|
||||
ControllerActionPaths mPosePath;
|
||||
ControllerActionPaths mHapticPath;
|
||||
ControllerActionPaths mMenuClickPath;
|
||||
|
@ -172,7 +208,6 @@ namespace MWVR
|
|||
ControllerActionPaths mYPath;
|
||||
ControllerActionPaths mAPath;
|
||||
ControllerActionPaths mBPath;
|
||||
ControllerActionPaths mTriggerClickPath;
|
||||
ControllerActionPaths mTriggerValuePath;
|
||||
|
||||
OpenXRAction_Bool mGameMenu;
|
||||
|
@ -191,46 +226,14 @@ namespace MWVR
|
|||
OpenXRAction_Float mLookLeftRight;
|
||||
OpenXRAction_Float mMoveForwardBackward;
|
||||
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;
|
||||
//! 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_FloatToBool mActivateTouch;
|
||||
|
||||
// Hand tracking
|
||||
OpenXRAction mHandPoseAction;
|
||||
OpenXRAction mHapticsAction;
|
||||
|
@ -353,6 +356,23 @@ namespace MWVR
|
|||
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 action)
|
||||
: mAction(std::move(action))
|
||||
|
@ -411,7 +431,6 @@ namespace MWVR
|
|||
, mActionSet(createActionSet())
|
||||
, mSelectPath(generateControllerActionPaths("/input/select/click"))
|
||||
, mSqueezeValuePath(generateControllerActionPaths("/input/squeeze/value"))
|
||||
, mSqueezeClickPath(generateControllerActionPaths("/input/squeeze/click"))
|
||||
, mPosePath(generateControllerActionPaths("/input/aim/pose"))
|
||||
, mHapticPath(generateControllerActionPaths("/output/haptic"))
|
||||
, mMenuClickPath(generateControllerActionPaths("/input/menu/click"))
|
||||
|
@ -423,7 +442,6 @@ namespace MWVR
|
|||
, mYPath(generateControllerActionPaths("/input/y/click"))
|
||||
, mAPath(generateControllerActionPaths("/input/a/click"))
|
||||
, mBPath(generateControllerActionPaths("/input/b/click"))
|
||||
, mTriggerClickPath(generateControllerActionPaths("/input/trigger/click"))
|
||||
, mTriggerValuePath(generateControllerActionPaths("/input/trigger/value"))
|
||||
, mGameMenu(std::move(createAction(XR_ACTION_TYPE_BOOLEAN_INPUT, "game_menu", "GameMenu", { })))
|
||||
, 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", { })))
|
||||
, 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", { })))
|
||||
, 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 })))
|
||||
, 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]},
|
||||
{mSpellModifier, mSqueezeValuePath[LEFT_HAND]},
|
||||
{mGameMenu, mMenuClickPath[LEFT_HAND]},
|
||||
{mActivateTouch, mSqueezeValuePath[RIGHT_HAND]},
|
||||
} };
|
||||
XrInteractionProfileSuggestedBinding suggestedBindings{ XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING };
|
||||
suggestedBindings.interactionProfile = oculusTouchInteractionProfilePath;
|
||||
|
@ -483,10 +503,10 @@ namespace MWVR
|
|||
mSpellModifier; // L-Squeeze
|
||||
mActivate; // R-Squeeze
|
||||
mUse; // R-Trigger
|
||||
mJump; // L-Trigger. L-trigger has value, can be used to make measured jumps
|
||||
mWeapon; // A
|
||||
mSpell; // A + SpellModifier
|
||||
mRun; // Based on movement thumbstick value: broken line ( 0 (stand), 0.5 (walk), 1.0 (run) ). Remember to scale fatigue use.
|
||||
mJump; // L-Trigger. L-trigger has value, could use this to make measured jumps ?
|
||||
mToggleWeapon; // A
|
||||
mToggleSpell; // A + SpellModifier
|
||||
mRun; // Based on movement thumbstick value ?
|
||||
mCycleSpellLeft; // L-ThumbstickClick + SpellModifier
|
||||
mCycleSpellRight; // R-ThumbstickClick + SpellModifier
|
||||
mCycleWeaponLeft; // L-ThumbstickClick
|
||||
|
@ -583,8 +603,9 @@ namespace MWVR
|
|||
mMoveLeftRight.update();
|
||||
mActionsMenu.update();
|
||||
mSpellModifier.update();
|
||||
mActivateTouch.update();
|
||||
|
||||
// This set of actions only care about on-press
|
||||
// Simple fire-and-forget on-press actions
|
||||
if (mActionsMenu.actionOnPress())
|
||||
{
|
||||
mActionEvents.emplace_back(OpenXRActionEvent{ MWInput::InputManager::A_QuickKeysMenu, true });
|
||||
|
@ -601,27 +622,29 @@ namespace MWVR
|
|||
{
|
||||
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())
|
||||
{
|
||||
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())
|
||||
{
|
||||
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
|
||||
if (mWeapon.actionOnPress() && !mSpellModifier.actionIsPressed())
|
||||
{
|
||||
|
@ -717,6 +740,11 @@ namespace MWVR
|
|||
return mXRInput->getHandPoses(time, space);
|
||||
}
|
||||
|
||||
void OpenXRInputManager::showActivationIndication(bool show)
|
||||
{
|
||||
mPlayer->setPointing(show);
|
||||
}
|
||||
|
||||
OpenXRInputManager::OpenXRInputManager(
|
||||
SDL_Window* window,
|
||||
osg::ref_ptr<OpenXRViewer> viewer,
|
||||
|
@ -922,6 +950,9 @@ namespace MWVR
|
|||
case A_Use:
|
||||
mInputBinder->getChannel(A_Use)->setValue(event.onPress);
|
||||
break;
|
||||
case OpenXRInput::A_ActivateTouch:
|
||||
showActivationIndication(event.onPress);
|
||||
break;
|
||||
default:
|
||||
Log(Debug::Warning) << "Unhandled XR action " << event.action;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ namespace MWVR
|
|||
|
||||
PoseSet getHandPoses(int64_t time, TrackedSpace space);
|
||||
|
||||
void showActivationIndication(bool show);
|
||||
|
||||
osg::ref_ptr<OpenXRViewer> mXRViewer;
|
||||
std::unique_ptr<OpenXRInput> mXRInput;
|
||||
};
|
||||
|
|
|
@ -185,8 +185,8 @@ namespace MWVR
|
|||
mirror_width = mMirrorTextureSwapchain->width() / 2;
|
||||
|
||||
|
||||
mViews["LeftEye"]->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["RightEye"]->swapchain().renderBuffer()->blit(gc, 0, 0, mirror_width, mMirrorTextureSwapchain->height());
|
||||
mViews["LeftEye"]->swapchain().renderBuffer()->blit(gc, mirror_width, 0, 2 * mirror_width, mMirrorTextureSwapchain->height());
|
||||
|
||||
if(includeMenu)
|
||||
mViews["MenuView"]->swapchain().renderBuffer()->blit(gc, 2 * mirror_width, 0, 3 * mirror_width, mMirrorTextureSwapchain->height());
|
||||
|
|
|
@ -274,6 +274,16 @@ namespace MWWorld
|
|||
return mJumping;
|
||||
}
|
||||
|
||||
void Player::setPointing(bool pointing)
|
||||
{
|
||||
mPointing = pointing;
|
||||
}
|
||||
|
||||
bool Player::getPointing() const
|
||||
{
|
||||
return mPointing;
|
||||
}
|
||||
|
||||
bool Player::isInCombat() {
|
||||
return MWBase::Environment::get().getMechanicsManager()->getActorsFighting(getPlayer()).size() != 0;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ namespace MWWorld
|
|||
|
||||
bool mAttackingOrSpell;
|
||||
bool mJumping;
|
||||
bool mPointing;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -117,6 +118,9 @@ namespace MWWorld
|
|||
void setJumping(bool jumping);
|
||||
bool getJumping() const;
|
||||
|
||||
void setPointing(bool pointing);
|
||||
bool getPointing(void) const;
|
||||
|
||||
///Checks all nearby actors to see if anyone has an aipackage against you
|
||||
bool isInCombat();
|
||||
|
||||
|
|
Loading…
Reference in a new issue