You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
6.5 KiB
C++
236 lines
6.5 KiB
C++
#include "vrcamera.hpp"
|
|
#include "vrgui.hpp"
|
|
#include "vrinputmanager.hpp"
|
|
#include "vrenvironment.hpp"
|
|
#include "vranimation.hpp"
|
|
|
|
#include <components/sceneutil/visitor.hpp>
|
|
|
|
#include <components/misc/constants.hpp>
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
#include "../mwbase/world.hpp"
|
|
#include "../mwbase/windowmanager.hpp"
|
|
|
|
#include "../mwworld/player.hpp"
|
|
#include "../mwworld/class.hpp"
|
|
|
|
#include "../mwmechanics/movement.hpp"
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Include additional headers for multiplayer purposes
|
|
*/
|
|
#include "../mwmp/Main.hpp"
|
|
#include "../mwmp/Networking.hpp"
|
|
#include "../mwmp/LocalPlayer.hpp"
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
#include <osg/Quat>
|
|
|
|
namespace MWVR
|
|
{
|
|
|
|
VRCamera::VRCamera(osg::Camera* camera)
|
|
: MWRender::Camera(camera)
|
|
{
|
|
mVanityAllowed = false;
|
|
mFirstPersonView = true;
|
|
|
|
auto vrTrackingManager = MWVR::Environment::get().getTrackingManager();
|
|
vrTrackingManager->bind(this, "pcworld");
|
|
}
|
|
|
|
VRCamera::~VRCamera()
|
|
{
|
|
}
|
|
|
|
void VRCamera::setShouldTrackPlayerCharacter(bool track)
|
|
{
|
|
mShouldTrackPlayerCharacter = track;
|
|
}
|
|
|
|
void VRCamera::recenter()
|
|
{
|
|
if (!mHasTrackingData)
|
|
return;
|
|
|
|
// Move position of head to center of character
|
|
// Z should not be affected
|
|
|
|
auto* session = Environment::get().getSession();
|
|
|
|
auto* tm = Environment::get().getTrackingManager();
|
|
auto* ws = static_cast<VRTrackingToWorldBinding*>(tm->getSource("pcworld"));
|
|
|
|
|
|
ws->setSeatedPlay(session->seatedPlay());
|
|
ws->setEyeLevel(session->eyeLevel() * Constants::UnitsPerMeter);
|
|
ws->recenter(mShouldResetZ);
|
|
|
|
|
|
|
|
mShouldRecenter = false;
|
|
Log(Debug::Verbose) << "Recentered";
|
|
}
|
|
|
|
void VRCamera::applyTracking()
|
|
{
|
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
|
|
auto& player = world->getPlayer();
|
|
auto playerPtr = player.getPlayer();
|
|
|
|
float yaw = 0.f;
|
|
float pitch = 0.f;
|
|
float roll = 0.f;
|
|
getEulerAngles(mHeadPose.orientation, yaw, pitch, roll);
|
|
|
|
if (!player.isDisabled() && mTrackingNode)
|
|
{
|
|
world->rotateObject(playerPtr, pitch, 0.f, yaw, MWBase::RotationFlag_none);
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Set the player's direction here, because VR doesn't do it from CharacterController::update()
|
|
*/
|
|
mwmp::LocalPlayer *localPlayer = mwmp::Main::get().getLocalPlayer();
|
|
localPlayer->direction.rot[0] = playerPtr.getRefData().getPosition().rot[0] - localPlayer->position.rot[0];
|
|
localPlayer->direction.rot[2] = playerPtr.getRefData().getPosition().rot[2] - localPlayer->position.rot[2];
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
}
|
|
}
|
|
|
|
void VRCamera::onTrackingUpdated(VRTrackingSource& source, DisplayTime predictedDisplayTime)
|
|
{
|
|
auto path = Environment::get().getTrackingManager()->stringToVRPath("/user/head/input/pose");
|
|
auto tp = source.getTrackingPose(predictedDisplayTime, path);
|
|
|
|
if (!!tp.status)
|
|
{
|
|
mHeadPose = tp.pose;
|
|
mHasTrackingData = true;
|
|
}
|
|
|
|
if (mShouldRecenter)
|
|
{
|
|
recenter();
|
|
Camera::updateCamera(mCamera);
|
|
auto* vrGuiManager = MWVR::Environment::get().getGUIManager();
|
|
vrGuiManager->updateTracking();
|
|
}
|
|
else
|
|
{
|
|
if (mShouldTrackPlayerCharacter && !MWBase::Environment::get().getWindowManager()->isGuiMode())
|
|
applyTracking();
|
|
|
|
Camera::updateCamera(mCamera);
|
|
}
|
|
}
|
|
|
|
void VRCamera::updateCamera(osg::Camera* cam)
|
|
{
|
|
// The regular update call should do nothing while tracking the player
|
|
}
|
|
|
|
void VRCamera::updateCamera()
|
|
{
|
|
Camera::updateCamera();
|
|
}
|
|
|
|
void VRCamera::reset()
|
|
{
|
|
Camera::reset();
|
|
}
|
|
|
|
void VRCamera::rotateCamera(float pitch, float roll, float yaw, bool adjust)
|
|
{
|
|
if (adjust)
|
|
{
|
|
pitch += getPitch();
|
|
yaw += getYaw();
|
|
}
|
|
setYaw(yaw);
|
|
setPitch(pitch);
|
|
}
|
|
|
|
void VRCamera::toggleViewMode(bool force)
|
|
{
|
|
mFirstPersonView = true;
|
|
}
|
|
bool VRCamera::toggleVanityMode(bool enable)
|
|
{
|
|
// Vanity mode makes no sense in VR
|
|
return Camera::toggleVanityMode(false);
|
|
}
|
|
void VRCamera::allowVanityMode(bool allow)
|
|
{
|
|
// Vanity mode makes no sense in VR
|
|
mVanityAllowed = false;
|
|
}
|
|
void VRCamera::getPosition(osg::Vec3d& focal, osg::Vec3d& camera) const
|
|
{
|
|
camera = focal = mHeadPose.position;
|
|
}
|
|
void VRCamera::getOrientation(osg::Quat& orientation) const
|
|
{
|
|
orientation = mHeadPose.orientation;
|
|
}
|
|
|
|
void VRCamera::processViewChange()
|
|
{
|
|
SceneUtil::FindByNameVisitor findRootVisitor("Player Root", osg::NodeVisitor::TRAVERSE_PARENTS);
|
|
mAnimation->getObjectRoot()->accept(findRootVisitor);
|
|
mTrackingNode = findRootVisitor.mFoundNode;
|
|
|
|
if (!mTrackingNode)
|
|
throw std::logic_error("Unable to find tracking node for VR camera");
|
|
mHeightScale = 1.f;
|
|
}
|
|
|
|
void VRCamera::instantTransition()
|
|
{
|
|
Camera::instantTransition();
|
|
|
|
// When the cell changes, openmw rotates the character.
|
|
// To make sure the player faces the same direction regardless of current orientation,
|
|
// compute the offset from character orientation to player orientation and reset yaw offset to this.
|
|
float yaw = 0.f;
|
|
float pitch = 0.f;
|
|
float roll = 0.f;
|
|
getEulerAngles(mHeadPose.orientation, yaw, pitch, roll);
|
|
yaw = - mYaw - yaw;
|
|
auto* tm = Environment::get().getTrackingManager();
|
|
auto* ws = static_cast<VRTrackingToWorldBinding*>(tm->getSource("pcworld"));
|
|
ws->setWorldOrientation(yaw, true);
|
|
}
|
|
|
|
void VRCamera::rotateStage(float yaw)
|
|
{
|
|
auto* tm = Environment::get().getTrackingManager();
|
|
auto* ws = static_cast<VRTrackingToWorldBinding*>(tm->getSource("pcworld"));
|
|
ws->setWorldOrientation(yaw, true);
|
|
}
|
|
|
|
osg::Quat VRCamera::stageRotation()
|
|
{
|
|
auto* tm = Environment::get().getTrackingManager();
|
|
auto* ws = static_cast<VRTrackingToWorldBinding*>(tm->getSource("pcworld"));
|
|
return ws->getWorldOrientation();
|
|
}
|
|
|
|
void VRCamera::requestRecenter(bool resetZ)
|
|
{
|
|
mShouldRecenter = true;
|
|
|
|
// Use OR so we don't negate a pending requests.
|
|
mShouldResetZ |= resetZ;
|
|
}
|
|
}
|