mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-28 23:06:41 +00:00
Merge branch 'camera_refactoring' into 'master'
Camera refactoring See merge request OpenMW/openmw!271
This commit is contained in:
commit
80e23536cb
15 changed files with 170 additions and 230 deletions
|
@ -73,7 +73,7 @@ add_openmw_dir (mwworld
|
|||
add_openmw_dir (mwphysics
|
||||
physicssystem trace collisiontype actor convert object heightfield closestnotmerayresultcallback
|
||||
contacttestresultcallback deepestnotmecontacttestresultcallback stepper movementsolver
|
||||
closestnotmeconvexresultcallback
|
||||
closestnotmeconvexresultcallback raycasting
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
|
|
|
@ -51,6 +51,11 @@ namespace ESM
|
|||
struct TimeStamp;
|
||||
}
|
||||
|
||||
namespace MWPhysics
|
||||
{
|
||||
class RayCastingInterface;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class Animation;
|
||||
|
@ -303,6 +308,8 @@ namespace MWBase
|
|||
|
||||
virtual void updateAnimatedCollisionShape(const MWWorld::Ptr &ptr) = 0;
|
||||
|
||||
virtual const MWPhysics::RayCastingInterface* getRayCasting() const = 0;
|
||||
|
||||
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) = 0;
|
||||
///< cast a Ray and return true if there is an object in the ray path.
|
||||
|
||||
|
@ -420,9 +427,8 @@ namespace MWBase
|
|||
virtual void togglePreviewMode(bool enable) = 0;
|
||||
virtual bool toggleVanityMode(bool enable) = 0;
|
||||
virtual void allowVanityMode(bool allow) = 0;
|
||||
virtual void changeVanityModeScale(float factor) = 0;
|
||||
virtual bool vanityRotateCamera(float * rot) = 0;
|
||||
virtual void setCameraDistance(float dist, bool adjust = false, bool override = true)=0;
|
||||
virtual void adjustCameraDistance(float dist) = 0;
|
||||
virtual void applyDeferredPreviewRotationToPlayer(float dt) = 0;
|
||||
virtual void disableDeferredPreviewRotation() = 0;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
namespace MWInput
|
||||
{
|
||||
const float ZOOM_SCALE = 120.f; /// Used for scrolling camera in and out
|
||||
const float ZOOM_SCALE = 10.f; /// Used for scrolling camera in and out
|
||||
|
||||
ActionManager::ActionManager(BindingsManager* bindingsManager,
|
||||
osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation,
|
||||
|
@ -195,6 +195,8 @@ namespace MWInput
|
|||
|
||||
void ActionManager::executeAction(int action)
|
||||
{
|
||||
auto* inputManager = MWBase::Environment::get().getInputManager();
|
||||
auto* windowManager = MWBase::Environment::get().getWindowManager();
|
||||
// trigger action activated
|
||||
switch (action)
|
||||
{
|
||||
|
@ -211,7 +213,7 @@ namespace MWInput
|
|||
toggleConsole ();
|
||||
break;
|
||||
case A_Activate:
|
||||
MWBase::Environment::get().getInputManager()->resetIdleTime();
|
||||
inputManager->resetIdleTime();
|
||||
activate();
|
||||
break;
|
||||
case A_MoveLeft:
|
||||
|
@ -272,18 +274,18 @@ namespace MWInput
|
|||
showQuickKeysMenu();
|
||||
break;
|
||||
case A_ToggleHUD:
|
||||
MWBase::Environment::get().getWindowManager()->toggleHud();
|
||||
windowManager->toggleHud();
|
||||
break;
|
||||
case A_ToggleDebug:
|
||||
MWBase::Environment::get().getWindowManager()->toggleDebugWindow();
|
||||
windowManager->toggleDebugWindow();
|
||||
break;
|
||||
case A_ZoomIn:
|
||||
if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch") && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") && !MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
MWBase::Environment::get().getWorld()->setCameraDistance(ZOOM_SCALE, true, true);
|
||||
if (inputManager->getControlSwitch("playerviewswitch") && inputManager->getControlSwitch("playercontrols") && !windowManager->isGuiMode())
|
||||
MWBase::Environment::get().getWorld()->adjustCameraDistance(-ZOOM_SCALE);
|
||||
break;
|
||||
case A_ZoomOut:
|
||||
if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch") && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") && !MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
MWBase::Environment::get().getWorld()->setCameraDistance(-ZOOM_SCALE, true, true);
|
||||
if (inputManager->getControlSwitch("playerviewswitch") && inputManager->getControlSwitch("playercontrols") && !windowManager->isGuiMode())
|
||||
MWBase::Environment::get().getWorld()->adjustCameraDistance(ZOOM_SCALE);
|
||||
break;
|
||||
case A_QuickSave:
|
||||
quickSave();
|
||||
|
@ -292,19 +294,19 @@ namespace MWInput
|
|||
quickLoad();
|
||||
break;
|
||||
case A_CycleSpellLeft:
|
||||
if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic))
|
||||
if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic))
|
||||
MWBase::Environment::get().getWindowManager()->cycleSpell(false);
|
||||
break;
|
||||
case A_CycleSpellRight:
|
||||
if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic))
|
||||
if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic))
|
||||
MWBase::Environment::get().getWindowManager()->cycleSpell(true);
|
||||
break;
|
||||
case A_CycleWeaponLeft:
|
||||
if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory))
|
||||
if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory))
|
||||
MWBase::Environment::get().getWindowManager()->cycleWeapon(false);
|
||||
break;
|
||||
case A_CycleWeaponRight:
|
||||
if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory))
|
||||
if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory))
|
||||
MWBase::Environment::get().getWindowManager()->cycleWeapon(true);
|
||||
break;
|
||||
case A_Sneak:
|
||||
|
|
|
@ -190,10 +190,7 @@ namespace MWInput
|
|||
mGamepadZoom = 0;
|
||||
|
||||
if (mGamepadZoom)
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->changeVanityModeScale(mGamepadZoom);
|
||||
MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true);
|
||||
}
|
||||
MWBase::Environment::get().getWorld()->adjustCameraDistance(-mGamepadZoom);
|
||||
}
|
||||
|
||||
return triedToMove;
|
||||
|
@ -291,12 +288,12 @@ namespace MWInput
|
|||
{
|
||||
if (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
|
||||
{
|
||||
mGamepadZoom = arg.value * 0.85f / 1000.f;
|
||||
mGamepadZoom = arg.value * 0.85f / 1000.f / 12.f;
|
||||
return; // Do not propagate event.
|
||||
}
|
||||
else if (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)
|
||||
{
|
||||
mGamepadZoom = -arg.value * 0.85f / 1000.f;
|
||||
mGamepadZoom = -arg.value * 0.85f / 1000.f / 12.f;
|
||||
return; // Do not propagate event.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ namespace MWInput
|
|||
mBindingsManager->mouseMoved(arg);
|
||||
|
||||
MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
input->setJoystickLastUsed(false);
|
||||
input->resetIdleTime();
|
||||
|
||||
|
@ -102,19 +103,14 @@ namespace MWInput
|
|||
rot[2] = -x;
|
||||
|
||||
// Only actually turn player when we're not in vanity mode
|
||||
if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && input->getControlSwitch("playerlooking"))
|
||||
if (!world->vanityRotateCamera(rot) && input->getControlSwitch("playerlooking"))
|
||||
{
|
||||
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
|
||||
MWWorld::Player& player = world->getPlayer();
|
||||
player.yaw(x);
|
||||
player.pitch(y);
|
||||
}
|
||||
else if (!input->getControlSwitch("playerlooking"))
|
||||
MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation();
|
||||
|
||||
if (arg.zrel && input->getControlSwitch("playerviewswitch") && input->getControlSwitch("playercontrols")) //Check to make sure you are allowed to zoomout and there is a change
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->changeVanityModeScale(static_cast<float>(arg.zrel));
|
||||
}
|
||||
world->disableDeferredPreviewRotation();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ namespace MWPhysics
|
|||
{
|
||||
// First of all, try to hit where you aim to
|
||||
int hitmask = CollisionType_World | CollisionType_Door | CollisionType_HeightMap | CollisionType_Actor;
|
||||
RayResult result = castRay(origin, origin + (orient * osg::Vec3f(0.0f, queryDistance, 0.0f)), actor, targets, hitmask, CollisionType_Actor);
|
||||
RayCastingResult result = castRay(origin, origin + (orient * osg::Vec3f(0.0f, queryDistance, 0.0f)), actor, targets, hitmask, CollisionType_Actor);
|
||||
|
||||
if (result.mHit)
|
||||
{
|
||||
|
@ -262,7 +262,7 @@ namespace MWPhysics
|
|||
return (point - Misc::Convert::toOsg(cb.m_hitPointWorld)).length();
|
||||
}
|
||||
|
||||
PhysicsSystem::RayResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore, std::vector<MWWorld::Ptr> targets, int mask, int group) const
|
||||
RayCastingResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore, std::vector<MWWorld::Ptr> targets, int mask, int group) const
|
||||
{
|
||||
btVector3 btFrom = Misc::Convert::toBullet(from);
|
||||
btVector3 btTo = Misc::Convert::toBullet(to);
|
||||
|
@ -299,7 +299,7 @@ namespace MWPhysics
|
|||
|
||||
mCollisionWorld->rayTest(btFrom, btTo, resultCallback);
|
||||
|
||||
RayResult result;
|
||||
RayCastingResult result;
|
||||
result.mHit = resultCallback.hasHit();
|
||||
if (resultCallback.hasHit())
|
||||
{
|
||||
|
@ -311,7 +311,7 @@ namespace MWPhysics
|
|||
return result;
|
||||
}
|
||||
|
||||
PhysicsSystem::RayResult PhysicsSystem::castSphere(const osg::Vec3f &from, const osg::Vec3f &to, float radius)
|
||||
RayCastingResult PhysicsSystem::castSphere(const osg::Vec3f &from, const osg::Vec3f &to, float radius) const
|
||||
{
|
||||
btCollisionWorld::ClosestConvexResultCallback callback(Misc::Convert::toBullet(from), Misc::Convert::toBullet(to));
|
||||
callback.m_collisionFilterGroup = 0xff;
|
||||
|
@ -325,7 +325,7 @@ namespace MWPhysics
|
|||
|
||||
mCollisionWorld->convexSweepTest(&shape, from_, to_, callback);
|
||||
|
||||
RayResult result;
|
||||
RayCastingResult result;
|
||||
result.mHit = callback.hasHit();
|
||||
if (result.mHit)
|
||||
{
|
||||
|
@ -346,7 +346,7 @@ namespace MWPhysics
|
|||
osg::Vec3f pos1 (physactor1->getCollisionObjectPosition() + osg::Vec3f(0,0,physactor1->getHalfExtents().z() * 0.9)); // eye level
|
||||
osg::Vec3f pos2 (physactor2->getCollisionObjectPosition() + osg::Vec3f(0,0,physactor2->getHalfExtents().z() * 0.9));
|
||||
|
||||
RayResult result = castRay(pos1, pos2, MWWorld::ConstPtr(), std::vector<MWWorld::Ptr>(), CollisionType_World|CollisionType_HeightMap|CollisionType_Door);
|
||||
RayCastingResult result = castRay(pos1, pos2, MWWorld::ConstPtr(), std::vector<MWWorld::Ptr>(), CollisionType_World|CollisionType_HeightMap|CollisionType_Door);
|
||||
|
||||
return !result.mHit;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "collisiontype.hpp"
|
||||
#include "raycasting.hpp"
|
||||
|
||||
namespace osg
|
||||
{
|
||||
|
@ -52,7 +53,7 @@ namespace MWPhysics
|
|||
class Object;
|
||||
class Actor;
|
||||
|
||||
class PhysicsSystem
|
||||
class PhysicsSystem : public RayCastingInterface
|
||||
{
|
||||
public:
|
||||
PhysicsSystem (Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> parentNode);
|
||||
|
@ -108,25 +109,17 @@ namespace MWPhysics
|
|||
/// target vector hits the collision shape and then calculates distance from the intersection point.
|
||||
/// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful.
|
||||
/// \note Only Actor targets are supported at the moment.
|
||||
float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const;
|
||||
|
||||
struct RayResult
|
||||
{
|
||||
bool mHit;
|
||||
osg::Vec3f mHitPos;
|
||||
osg::Vec3f mHitNormal;
|
||||
MWWorld::Ptr mHitObject;
|
||||
};
|
||||
float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const final;
|
||||
|
||||
/// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all other actors.
|
||||
RayResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(),
|
||||
RayCastingResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(),
|
||||
std::vector<MWWorld::Ptr> targets = std::vector<MWWorld::Ptr>(),
|
||||
int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const;
|
||||
int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const final;
|
||||
|
||||
RayResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius);
|
||||
RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const final;
|
||||
|
||||
/// Return true if actor1 can see actor2.
|
||||
bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const;
|
||||
bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const final;
|
||||
|
||||
bool isOnGround (const MWWorld::Ptr& actor);
|
||||
|
||||
|
|
41
apps/openmw/mwphysics/raycasting.hpp
Normal file
41
apps/openmw/mwphysics/raycasting.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef OPENMW_MWPHYSICS_RAYCASTING_H
|
||||
#define OPENMW_MWPHYSICS_RAYCASTING_H
|
||||
|
||||
#include <osg/Vec3f>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "collisiontype.hpp"
|
||||
|
||||
namespace MWPhysics
|
||||
{
|
||||
struct RayCastingResult
|
||||
{
|
||||
bool mHit;
|
||||
osg::Vec3f mHitPos;
|
||||
osg::Vec3f mHitNormal;
|
||||
MWWorld::Ptr mHitObject;
|
||||
};
|
||||
|
||||
class RayCastingInterface
|
||||
{
|
||||
public:
|
||||
/// Get distance from \a point to the collision shape of \a target. Uses a raycast to find where the
|
||||
/// target vector hits the collision shape and then calculates distance from the intersection point.
|
||||
/// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful.
|
||||
/// \note Only Actor targets are supported at the moment.
|
||||
virtual float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const = 0;
|
||||
|
||||
/// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all other actors.
|
||||
virtual RayCastingResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(),
|
||||
std::vector<MWWorld::Ptr> targets = std::vector<MWWorld::Ptr>(),
|
||||
int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const = 0;
|
||||
|
||||
virtual RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const = 0;
|
||||
|
||||
/// Return true if actor1 can see actor2.
|
||||
virtual bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
@ -16,6 +17,8 @@
|
|||
#include "../mwmechanics/movement.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "../mwphysics/raycasting.hpp"
|
||||
|
||||
#include "npcanimation.hpp"
|
||||
|
||||
namespace
|
||||
|
@ -195,6 +198,7 @@ namespace MWRender
|
|||
rotateCamera(0.f, osg::DegreesToRadians(3.f * duration), true);
|
||||
|
||||
updateFocalPointOffset(duration);
|
||||
updatePosition();
|
||||
|
||||
float speed = mTrackingPtr.getClass().getSpeed(mTrackingPtr);
|
||||
speed /= (1.f + speed / 500.f);
|
||||
|
@ -205,6 +209,42 @@ namespace MWRender
|
|||
updateStandingPreviewMode();
|
||||
}
|
||||
|
||||
void Camera::updatePosition()
|
||||
{
|
||||
mFocalPointAdjustment = osg::Vec3d();
|
||||
if (isFirstPerson())
|
||||
return;
|
||||
|
||||
const float cameraObstacleLimit = 5.0f;
|
||||
const float focalObstacleLimit = 10.f;
|
||||
|
||||
const auto* rayCasting = MWBase::Environment::get().getWorld()->getRayCasting();
|
||||
|
||||
// Adjust focal point to prevent clipping.
|
||||
osg::Vec3d focal = getFocalPoint();
|
||||
osg::Vec3d focalOffset = getFocalPointOffset();
|
||||
float offsetLen = focalOffset.length();
|
||||
if (offsetLen > 0)
|
||||
{
|
||||
MWPhysics::RayCastingResult result = rayCasting->castSphere(focal - focalOffset, focal, focalObstacleLimit);
|
||||
if (result.mHit)
|
||||
{
|
||||
double adjustmentCoef = -(result.mHitPos + result.mHitNormal * focalObstacleLimit - focal).length() / offsetLen;
|
||||
mFocalPointAdjustment = focalOffset * std::max(-1.0, adjustmentCoef);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate camera distance.
|
||||
mCameraDistance = mBaseCameraDistance + getCameraDistanceCorrection();
|
||||
if (mDynamicCameraDistanceEnabled)
|
||||
mCameraDistance = std::min(mCameraDistance, mMaxNextCameraDistance);
|
||||
osg::Vec3d cameraPos;
|
||||
getPosition(focal, cameraPos);
|
||||
MWPhysics::RayCastingResult result = rayCasting->castSphere(focal, cameraPos, cameraObstacleLimit);
|
||||
if (result.mHit)
|
||||
mCameraDistance = (result.mHitPos + result.mHitNormal * cameraObstacleLimit - focal).length();
|
||||
}
|
||||
|
||||
void Camera::updateStandingPreviewMode()
|
||||
{
|
||||
if (!mStandingPreviewAllowed)
|
||||
|
@ -378,27 +418,24 @@ namespace MWRender
|
|||
return mCameraDistance;
|
||||
}
|
||||
|
||||
void Camera::updateBaseCameraDistance(float dist, bool adjust)
|
||||
void Camera::adjustCameraDistance(float delta)
|
||||
{
|
||||
if (isFirstPerson())
|
||||
return;
|
||||
|
||||
if (adjust)
|
||||
dist += std::min(mCameraDistance - getCameraDistanceCorrection(), mBaseCameraDistance);
|
||||
|
||||
mIsNearest = dist <= mNearest;
|
||||
mBaseCameraDistance = osg::clampBetween(dist, mNearest, mFurthest);
|
||||
Settings::Manager::setFloat("third person camera distance", "Camera", mBaseCameraDistance);
|
||||
setCameraDistance();
|
||||
if (!isFirstPerson())
|
||||
{
|
||||
if(isNearest() && delta < 0.f && getMode() != Mode::Preview && getMode() != Mode::Vanity)
|
||||
toggleViewMode();
|
||||
else
|
||||
mBaseCameraDistance = std::min(mCameraDistance - getCameraDistanceCorrection(), mBaseCameraDistance) + delta;
|
||||
}
|
||||
else if (delta > 0.f)
|
||||
{
|
||||
toggleViewMode();
|
||||
mBaseCameraDistance = 0;
|
||||
}
|
||||
|
||||
void Camera::setCameraDistance(float dist, bool adjust)
|
||||
{
|
||||
if (isFirstPerson())
|
||||
return;
|
||||
if (adjust)
|
||||
dist += mCameraDistance;
|
||||
mCameraDistance = osg::clampBetween(dist, 10.f, mFurthest);
|
||||
mIsNearest = mBaseCameraDistance <= mNearest;
|
||||
mBaseCameraDistance = osg::clampBetween(mBaseCameraDistance, mNearest, mFurthest);
|
||||
Settings::Manager::setFloat("third person camera distance", "Camera", mBaseCameraDistance);
|
||||
}
|
||||
|
||||
float Camera::getCameraDistanceCorrection() const
|
||||
|
@ -414,16 +451,6 @@ namespace MWRender
|
|||
return pitchCorrection + speedCorrection;
|
||||
}
|
||||
|
||||
void Camera::setCameraDistance()
|
||||
{
|
||||
mFocalPointAdjustment = osg::Vec3d();
|
||||
if (isFirstPerson())
|
||||
return;
|
||||
mCameraDistance = mBaseCameraDistance + getCameraDistanceCorrection();
|
||||
if (mDynamicCameraDistanceEnabled)
|
||||
mCameraDistance = std::min(mCameraDistance, mMaxNextCameraDistance);
|
||||
}
|
||||
|
||||
void Camera::setAnimation(NpcAnimation *anim)
|
||||
{
|
||||
mAnimation = anim;
|
||||
|
|
|
@ -73,6 +73,7 @@ namespace MWRender
|
|||
bool mShowCrosshairInThirdPersonMode;
|
||||
|
||||
void updateFocalPointOffset(float duration);
|
||||
void updatePosition();
|
||||
float getCameraDistanceCorrection() const;
|
||||
|
||||
osg::ref_ptr<osg::NodeCallback> mUpdateCallback;
|
||||
|
@ -135,17 +136,8 @@ namespace MWRender
|
|||
|
||||
void update(float duration, bool paused=false);
|
||||
|
||||
/// Set base camera distance for current mode. Don't work on 1st person view.
|
||||
/// \param adjust Indicates should distance be adjusted or set.
|
||||
void updateBaseCameraDistance(float dist, bool adjust = false);
|
||||
|
||||
/// Set camera distance for current mode. Don't work on 1st person view.
|
||||
/// \param adjust Indicates should distance be adjusted or set.
|
||||
/// Default distance can be restored with setCameraDistance().
|
||||
void setCameraDistance(float dist, bool adjust = false);
|
||||
|
||||
/// Restore default camera distance and offset for current mode.
|
||||
void setCameraDistance();
|
||||
/// Adds distDelta to the camera distance. Switches 3rd/1st person view if distance is less than limit.
|
||||
void adjustCameraDistance(float distDelta);
|
||||
|
||||
float getCameraDistance() const;
|
||||
|
||||
|
@ -153,7 +145,6 @@ namespace MWRender
|
|||
|
||||
osg::Vec3d getFocalPoint() const;
|
||||
osg::Vec3d getFocalPointOffset() const;
|
||||
void adjustFocalPoint(osg::Vec3d adjustment) { mFocalPointAdjustment = adjustment; }
|
||||
|
||||
/// Stores focal and camera world positions in passed arguments
|
||||
void getPosition(osg::Vec3d &focal, osg::Vec3d &camera) const;
|
||||
|
|
|
@ -1316,82 +1316,6 @@ namespace MWRender
|
|||
return mTerrain->getHeightAt(pos);
|
||||
}
|
||||
|
||||
bool RenderingManager::vanityRotateCamera(const float *rot)
|
||||
{
|
||||
if(!mCamera->isVanityOrPreviewModeEnabled())
|
||||
return false;
|
||||
|
||||
mCamera->rotateCamera(rot[0], rot[2], true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderingManager::setCameraDistance(float dist, bool adjust, bool override)
|
||||
{
|
||||
if(!mCamera->isVanityOrPreviewModeEnabled() && !mCamera->isFirstPerson())
|
||||
{
|
||||
if(mCamera->isNearest() && dist > 0.f)
|
||||
mCamera->toggleViewMode();
|
||||
else if (override)
|
||||
mCamera->updateBaseCameraDistance(-dist / 120.f * 10, adjust);
|
||||
else
|
||||
mCamera->setCameraDistance(-dist / 120.f * 10, adjust);
|
||||
}
|
||||
else if(mCamera->isFirstPerson() && dist < 0.f)
|
||||
{
|
||||
mCamera->toggleViewMode();
|
||||
if (override)
|
||||
mCamera->updateBaseCameraDistance(0.f, false);
|
||||
else
|
||||
mCamera->setCameraDistance(0.f, false);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingManager::resetCamera()
|
||||
{
|
||||
mCamera->reset();
|
||||
}
|
||||
|
||||
float RenderingManager::getCameraDistance() const
|
||||
{
|
||||
return mCamera->getCameraDistance();
|
||||
}
|
||||
|
||||
Camera* RenderingManager::getCamera()
|
||||
{
|
||||
return mCamera.get();
|
||||
}
|
||||
|
||||
const osg::Vec3f &RenderingManager::getCameraPosition() const
|
||||
{
|
||||
return mCurrentCameraPos;
|
||||
}
|
||||
|
||||
void RenderingManager::togglePOV(bool force)
|
||||
{
|
||||
mCamera->toggleViewMode(force);
|
||||
}
|
||||
|
||||
void RenderingManager::togglePreviewMode(bool enable)
|
||||
{
|
||||
mCamera->togglePreviewMode(enable);
|
||||
}
|
||||
|
||||
bool RenderingManager::toggleVanityMode(bool enable)
|
||||
{
|
||||
return mCamera->toggleVanityMode(enable);
|
||||
}
|
||||
|
||||
void RenderingManager::allowVanityMode(bool allow)
|
||||
{
|
||||
mCamera->allowVanityMode(allow);
|
||||
}
|
||||
|
||||
void RenderingManager::changeVanityModeScale(float factor)
|
||||
{
|
||||
if(mCamera->isVanityOrPreviewModeEnabled())
|
||||
mCamera->updateBaseCameraDistance(-factor/120.f*10, true);
|
||||
}
|
||||
|
||||
void RenderingManager::overrideFieldOfView(float val)
|
||||
{
|
||||
if (mFieldOfViewOverridden != true || mFieldOfViewOverride != val)
|
||||
|
|
|
@ -209,17 +209,8 @@ namespace MWRender
|
|||
float getTerrainHeightAt(const osg::Vec3f& pos);
|
||||
|
||||
// camera stuff
|
||||
bool vanityRotateCamera(const float *rot);
|
||||
void setCameraDistance(float dist, bool adjust, bool override);
|
||||
void resetCamera();
|
||||
float getCameraDistance() const;
|
||||
Camera* getCamera();
|
||||
const osg::Vec3f& getCameraPosition() const;
|
||||
void togglePOV(bool force = false);
|
||||
void togglePreviewMode(bool enable);
|
||||
bool toggleVanityMode(bool enable);
|
||||
void allowVanityMode(bool allow);
|
||||
void changeVanityModeScale(float factor);
|
||||
Camera* getCamera() { return mCamera.get(); }
|
||||
const osg::Vec3f& getCameraPosition() const { return mCurrentCameraPos; }
|
||||
|
||||
/// temporarily override the field of view with given value.
|
||||
void overrideFieldOfView(float val);
|
||||
|
|
|
@ -424,7 +424,7 @@ namespace MWWorld
|
|||
|
||||
// Check for impact
|
||||
// TODO: use a proper btRigidBody / btGhostObject?
|
||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(pos, newPos, caster, targetActors, 0xff, MWPhysics::CollisionType_Projectile);
|
||||
MWPhysics::RayCastingResult result = mPhysics->castRay(pos, newPos, caster, targetActors, 0xff, MWPhysics::CollisionType_Projectile);
|
||||
|
||||
bool hit = false;
|
||||
if (result.mHit)
|
||||
|
@ -500,7 +500,7 @@ namespace MWWorld
|
|||
|
||||
// Check for impact
|
||||
// TODO: use a proper btRigidBody / btGhostObject?
|
||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(pos, newPos, caster, targetActors, 0xff, MWPhysics::CollisionType_Projectile);
|
||||
MWPhysics::RayCastingResult result = mPhysics->castRay(pos, newPos, caster, targetActors, 0xff, MWPhysics::CollisionType_Projectile);
|
||||
|
||||
bool underwater = MWBase::Environment::get().getWorld()->isUnderwater(MWMechanics::getPlayer().getCell(), newPos);
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ namespace MWWorld
|
|||
setupPlayer();
|
||||
|
||||
renderPlayer();
|
||||
mRendering->resetCamera();
|
||||
mRendering->getCamera()->reset();
|
||||
|
||||
// we don't want old weather to persist on a new game
|
||||
// Note that if reset later, the initial ChangeWeather that the chargen script calls will be lost.
|
||||
|
@ -1542,6 +1542,11 @@ namespace MWWorld
|
|||
return mNavigator->updateObject(DetourNavigator::ObjectId(object), shapes, object->getCollisionObject()->getWorldTransform());
|
||||
}
|
||||
|
||||
const MWPhysics::RayCastingInterface* World::getRayCasting() const
|
||||
{
|
||||
return mPhysics.get();
|
||||
}
|
||||
|
||||
bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
{
|
||||
int mask = MWPhysics::CollisionType_World | MWPhysics::CollisionType_Door;
|
||||
|
@ -1554,7 +1559,7 @@ namespace MWWorld
|
|||
osg::Vec3f a(x1,y1,z1);
|
||||
osg::Vec3f b(x2,y2,z2);
|
||||
|
||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), mask);
|
||||
MWPhysics::RayCastingResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), mask);
|
||||
return result.mHit;
|
||||
}
|
||||
|
||||
|
@ -1863,37 +1868,6 @@ namespace MWWorld
|
|||
|
||||
int nightEye = static_cast<int>(player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye).getMagnitude());
|
||||
mRendering->setNightEyeFactor(std::min(1.f, (nightEye/100.f)));
|
||||
|
||||
auto* camera = mRendering->getCamera();
|
||||
camera->setCameraDistance();
|
||||
if(!mRendering->getCamera()->isFirstPerson())
|
||||
{
|
||||
float cameraObstacleLimit = mRendering->getNearClipDistance() * 2.5f;
|
||||
float focalObstacleLimit = std::max(cameraObstacleLimit, 10.0f);
|
||||
|
||||
// Adjust focal point.
|
||||
osg::Vec3d focal = camera->getFocalPoint();
|
||||
osg::Vec3d focalOffset = camera->getFocalPointOffset();
|
||||
float offsetLen = focalOffset.length();
|
||||
if (offsetLen > 0)
|
||||
{
|
||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castSphere(focal - focalOffset, focal, focalObstacleLimit);
|
||||
if (result.mHit)
|
||||
{
|
||||
double adjustmentCoef = -(result.mHitPos + result.mHitNormal * focalObstacleLimit - focal).length() / offsetLen;
|
||||
if (adjustmentCoef < -1)
|
||||
adjustmentCoef = -1;
|
||||
camera->adjustFocalPoint(focalOffset * adjustmentCoef);
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust camera position.
|
||||
osg::Vec3d cameraPos;
|
||||
camera->getPosition(focal, cameraPos);
|
||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castSphere(focal, cameraPos, cameraObstacleLimit);
|
||||
if (result.mHit)
|
||||
mRendering->getCamera()->setCameraDistance((result.mHitPos + result.mHitNormal * cameraObstacleLimit - focal).length(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void World::preloadSpells()
|
||||
|
@ -1984,7 +1958,7 @@ namespace MWWorld
|
|||
|
||||
MWWorld::Ptr World::getFacedObject(float maxDistance, bool ignorePlayer)
|
||||
{
|
||||
const float camDist = mRendering->getCameraDistance();
|
||||
const float camDist = mRendering->getCamera()->getCameraDistance();
|
||||
maxDistance += camDist;
|
||||
MWWorld::Ptr facedObject;
|
||||
MWRender::RenderingManager::RayResult rayToObject;
|
||||
|
@ -2387,7 +2361,7 @@ namespace MWWorld
|
|||
|
||||
void World::togglePOV(bool force)
|
||||
{
|
||||
mRendering->togglePOV(force);
|
||||
mRendering->getCamera()->toggleViewMode(force);
|
||||
}
|
||||
|
||||
bool World::isFirstPerson() const
|
||||
|
@ -2402,12 +2376,12 @@ namespace MWWorld
|
|||
|
||||
void World::togglePreviewMode(bool enable)
|
||||
{
|
||||
mRendering->togglePreviewMode(enable);
|
||||
mRendering->getCamera()->togglePreviewMode(enable);
|
||||
}
|
||||
|
||||
bool World::toggleVanityMode(bool enable)
|
||||
{
|
||||
return mRendering->toggleVanityMode(enable);
|
||||
return mRendering->getCamera()->toggleVanityMode(enable);
|
||||
}
|
||||
|
||||
void World::disableDeferredPreviewRotation()
|
||||
|
@ -2422,22 +2396,21 @@ namespace MWWorld
|
|||
|
||||
void World::allowVanityMode(bool allow)
|
||||
{
|
||||
mRendering->allowVanityMode(allow);
|
||||
}
|
||||
|
||||
void World::changeVanityModeScale(float factor)
|
||||
{
|
||||
mRendering->changeVanityModeScale(factor);
|
||||
mRendering->getCamera()->allowVanityMode(allow);
|
||||
}
|
||||
|
||||
bool World::vanityRotateCamera(float * rot)
|
||||
{
|
||||
return mRendering->vanityRotateCamera(rot);
|
||||
if(!mRendering->getCamera()->isVanityOrPreviewModeEnabled())
|
||||
return false;
|
||||
|
||||
mRendering->getCamera()->rotateCamera(rot[0], rot[2], true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void World::setCameraDistance(float dist, bool adjust, bool override_)
|
||||
void World::adjustCameraDistance(float dist)
|
||||
{
|
||||
mRendering->setCameraDistance(dist, adjust, override_);
|
||||
mRendering->getCamera()->adjustCameraDistance(dist);
|
||||
}
|
||||
|
||||
void World::setupPlayer()
|
||||
|
@ -2760,7 +2733,7 @@ namespace MWWorld
|
|||
if (includeWater) {
|
||||
collisionTypes |= MWPhysics::CollisionType_Water;
|
||||
}
|
||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(from, to, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), collisionTypes);
|
||||
MWPhysics::RayCastingResult result = mPhysics->castRay(from, to, MWWorld::Ptr(), std::vector<MWWorld::Ptr>(), collisionTypes);
|
||||
|
||||
if (!result.mHit)
|
||||
return maxDist;
|
||||
|
@ -3123,7 +3096,7 @@ namespace MWWorld
|
|||
actor.getClass().getCreatureStats(actor).getAiSequence().getCombatTargets(targetActors);
|
||||
|
||||
// Check for impact, if yes, handle hit, if not, launch projectile
|
||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(sourcePos, worldPos, actor, targetActors, 0xff, MWPhysics::CollisionType_Projectile);
|
||||
MWPhysics::RayCastingResult result = mPhysics->castRay(sourcePos, worldPos, actor, targetActors, 0xff, MWPhysics::CollisionType_Projectile);
|
||||
if (result.mHit)
|
||||
MWMechanics::projectileHit(actor, result.mHitObject, bow, projectile, result.mHitPos, attackStrength);
|
||||
else
|
||||
|
|
|
@ -410,6 +410,8 @@ namespace MWWorld
|
|||
|
||||
void updateAnimatedCollisionShape(const Ptr &ptr) override;
|
||||
|
||||
const MWPhysics::RayCastingInterface* getRayCasting() const override;
|
||||
|
||||
bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) override;
|
||||
///< cast a Ray and return true if there is an object in the ray path.
|
||||
|
||||
|
@ -531,11 +533,8 @@ namespace MWWorld
|
|||
bool toggleVanityMode(bool enable) override;
|
||||
|
||||
void allowVanityMode(bool allow) override;
|
||||
|
||||
void changeVanityModeScale(float factor) override;
|
||||
|
||||
bool vanityRotateCamera(float * rot) override;
|
||||
void setCameraDistance(float dist, bool adjust = false, bool override = true) override;
|
||||
void adjustCameraDistance(float dist) override;
|
||||
|
||||
void applyDeferredPreviewRotationToPlayer(float dt) override;
|
||||
void disableDeferredPreviewRotation() override;
|
||||
|
|
Loading…
Reference in a new issue