Merge branch 'swimming' into 'master'

Swimming-related fixes

See merge request OpenMW/openmw!247

(cherry picked from commit 8be328ef80f29e9692e29d24beefa8ced16537a7)

738c71fd Extend the "turn to movement direction" mode for swimming up and down.
10d3e82b New setting "swim upward coef"
pull/578/head
psi29a 5 years ago
parent e335dc8b8a
commit 46db69a349

@ -1914,6 +1914,7 @@ void CharacterController::update(float duration, bool animationOnly)
mTimeUntilWake -= duration;
bool isPlayer = mPtr == MWMechanics::getPlayer();
bool isFirstPersonPlayer = isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson();
bool godmode = isPlayer && MWBase::Environment::get().getWorld()->getGodModeState();
float scale = mPtr.getCellRef().getScale();
@ -1977,7 +1978,7 @@ void CharacterController::update(float duration, bool animationOnly)
float effectiveRotation = rot.z();
static const bool turnToMovementDirection = Settings::Manager::getBool("turn to movement direction", "Game");
if (turnToMovementDirection && !(isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson()))
if (turnToMovementDirection && !isFirstPersonPlayer)
{
float targetMovementAngle = vec.y() >= 0 ? std::atan2(-vec.x(), vec.y()) : std::atan2(vec.x(), -vec.y());
movementSettings.mIsStrafing = (stats.getDrawState() != MWMechanics::DrawState_Nothing || inwater)
@ -2206,8 +2207,7 @@ void CharacterController::update(float duration, bool animationOnly)
// It seems only bipedal actors use turning animations.
// Also do not use turning animations in the first-person view and when sneaking.
bool isFirstPlayer = isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson();
if (!sneak && jumpstate == JumpState_None && !isFirstPlayer && mPtr.getClass().isBipedal(mPtr))
if (!sneak && jumpstate == JumpState_None && !isFirstPersonPlayer && mPtr.getClass().isBipedal(mPtr))
{
if(effectiveRotation > rotationThreshold)
movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight;
@ -2231,6 +2231,26 @@ void CharacterController::update(float duration, bool animationOnly)
sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal);
}
if (turnToMovementDirection)
{
float targetSwimmingPitch;
if (inwater && vec.y() != 0 && !isFirstPersonPlayer && !movementSettings.mIsStrafing)
targetSwimmingPitch = -mPtr.getRefData().getPosition().rot[0];
else
targetSwimmingPitch = 0;
float maxSwimPitchDelta = 3.0f * duration;
float swimmingPitch = mAnimation->getBodyPitchRadians();
swimmingPitch += osg::clampBetween(targetSwimmingPitch - swimmingPitch, -maxSwimPitchDelta, maxSwimPitchDelta);
mAnimation->setBodyPitchRadians(swimmingPitch);
}
if (inwater && isPlayer && !isFirstPersonPlayer)
{
static const float swimUpwardCoef = Settings::Manager::getFloat("swim upward coef", "Game");
static const float swimForwardCoef = sqrtf(1.0f - swimUpwardCoef * swimUpwardCoef);
vec.z() = std::abs(vec.y()) * swimUpwardCoef;
vec.y() *= swimForwardCoef;
}
// Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering
if (isPlayer)
{

@ -623,6 +623,7 @@ namespace MWRender
, mHeadPitchRadians(0.f)
, mUpperBodyYawRadians(0.f)
, mLegsYawRadians(0.f)
, mBodyPitchRadians(0.f)
, mHasMagicEffects(false)
, mAlpha(1.f)
{
@ -1340,11 +1341,11 @@ namespace MWRender
float yawOffset = 0;
if (mRootController)
{
bool enable = std::abs(mLegsYawRadians) > epsilon;
bool enable = std::abs(mLegsYawRadians) > epsilon || std::abs(mBodyPitchRadians) > epsilon;
mRootController->setEnabled(enable);
if (enable)
{
mRootController->setRotate(osg::Quat(mLegsYawRadians, osg::Vec3f(0,0,1)));
mRootController->setRotate(osg::Quat(mLegsYawRadians, osg::Vec3f(0,0,1)) * osg::Quat(mBodyPitchRadians, osg::Vec3f(1,0,0)));
yawOffset = mLegsYawRadians;
}
}

@ -273,6 +273,7 @@ protected:
float mHeadPitchRadians;
float mUpperBodyYawRadians;
float mLegsYawRadians;
float mBodyPitchRadians;
RotateController* addRotateController(std::string bone);
@ -489,6 +490,8 @@ public:
virtual void setLegsYawRadians(float v) { mLegsYawRadians = v; }
virtual float getUpperBodyYawRadians() const { return mUpperBodyYawRadians; }
virtual float getLegsYawRadians() const { return mLegsYawRadians; }
virtual void setBodyPitchRadians(float v) { mBodyPitchRadians = v; }
virtual float getBodyPitchRadians() const { return mBodyPitchRadians; }
virtual void setAccurateAiming(bool enabled) {}
virtual bool canBeHarvested() const { return false; }

@ -273,7 +273,7 @@ osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration)
{
osg::Vec3f ret = Animation::runAnimation(duration);
WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0]);
WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians());
return ret;
}

@ -747,7 +747,7 @@ osg::Vec3f NpcAnimation::runAnimation(float timepassed)
mFirstPersonNeckController->setOffset(mFirstPersonOffset);
}
WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0]);
WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians());
return ret;
}

@ -331,8 +331,19 @@ If enabled then the character turns lower body to the direction of movement. Upp
This setting can only be configured by editing the settings configuration file.
swim upward coef
----------------
:Type: floating point
:Range: -1.0 to 1.0
:Default: 0.0
Makes player swim a bit upward (or downward in case of negative value) from the line of sight. Intended to make simpler swimming without diving. Recommened range of values is from 0.0 to 0.2.
This setting can only be configured by editing the settings configuration file.
trainers training skills based on base skill
-----------------------
--------------------------------------------
:Type: boolean
:Range: True/False

@ -310,6 +310,9 @@ uncapped damage fatigue = false
# Turn lower body to movement direction. 'true' makes diagonal movement more realistic.
turn to movement direction = false
# Makes player swim a bit upward (or downward in case of negative value) from the line of sight.
swim upward coef = 0.0
# Make the training skills proposed by a trainer based on its base attribute instead of its modified ones
trainers training skills based on base skill = false

Loading…
Cancel
Save