forked from mirror/openmw-tes3mp
Various math code ported to osg
This commit is contained in:
parent
0cc9b1bb40
commit
7bacb9418d
28 changed files with 180 additions and 177 deletions
|
@ -11,14 +11,6 @@
|
||||||
|
|
||||||
#include "../mwrender/rendermode.hpp"
|
#include "../mwrender/rendermode.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
|
||||||
{
|
|
||||||
class Vector2;
|
|
||||||
class Vector3;
|
|
||||||
class Quaternion;
|
|
||||||
class Image;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Vec3f;
|
class Vec3f;
|
||||||
|
@ -423,7 +415,7 @@ namespace MWBase
|
||||||
virtual bool getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor) = 0;
|
virtual bool getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor) = 0;
|
||||||
///< get Line of Sight (morrowind stupid implementation)
|
///< get Line of Sight (morrowind stupid implementation)
|
||||||
|
|
||||||
virtual float getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist) = 0;
|
virtual float getDistToNearestRayHit(const osg::Vec3f& from, const osg::Vec3f& dir, float maxDist) = 0;
|
||||||
|
|
||||||
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
||||||
|
|
||||||
|
@ -497,7 +489,7 @@ namespace MWBase
|
||||||
// Are we in an exterior or pseudo-exterior cell and it's night?
|
// Are we in an exterior or pseudo-exterior cell and it's night?
|
||||||
virtual bool isDark() const = 0;
|
virtual bool isDark() const = 0;
|
||||||
|
|
||||||
virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result) = 0;
|
virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, osg::Vec3f& result) = 0;
|
||||||
|
|
||||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||||
/// @note id must be lower case
|
/// @note id must be lower case
|
||||||
|
|
|
@ -580,10 +580,10 @@ namespace MWClass
|
||||||
return dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
return dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector3 Creature::getRotationVector (const MWWorld::Ptr& ptr) const
|
osg::Vec3f Creature::getRotationVector (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
||||||
Ogre::Vector3 vec(movement.mRotation);
|
osg::Vec3f vec(movement.mRotation[0], movement.mRotation[1], movement.mRotation[2]);
|
||||||
movement.mRotation[0] = 0.0f;
|
movement.mRotation[0] = 0.0f;
|
||||||
movement.mRotation[1] = 0.0f;
|
movement.mRotation[1] = 0.0f;
|
||||||
movement.mRotation[2] = 0.0f;
|
movement.mRotation[2] = 0.0f;
|
||||||
|
|
|
@ -113,7 +113,7 @@ namespace MWClass
|
||||||
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return desired movement.
|
///< Return desired movement.
|
||||||
|
|
||||||
virtual Ogre::Vector3 getRotationVector (const MWWorld::Ptr& ptr) const;
|
virtual osg::Vec3f getRotationVector (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return desired rotations, as euler angles.
|
///< Return desired rotations, as euler angles.
|
||||||
|
|
||||||
float getSpeed (const MWWorld::Ptr& ptr) const;
|
float getSpeed (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
|
@ -961,10 +961,10 @@ namespace MWClass
|
||||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector3 Npc::getRotationVector (const MWWorld::Ptr& ptr) const
|
osg::Vec3f Npc::getRotationVector (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
||||||
Ogre::Vector3 vec(movement.mRotation);
|
osg::Vec3f vec(movement.mRotation[0], movement.mRotation[1], movement.mRotation[2]);
|
||||||
movement.mRotation[0] = 0.0f;
|
movement.mRotation[0] = 0.0f;
|
||||||
movement.mRotation[1] = 0.0f;
|
movement.mRotation[1] = 0.0f;
|
||||||
movement.mRotation[2] = 0.0f;
|
movement.mRotation[2] = 0.0f;
|
||||||
|
|
|
@ -105,7 +105,7 @@ namespace MWClass
|
||||||
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return desired movement.
|
///< Return desired movement.
|
||||||
|
|
||||||
virtual Ogre::Vector3 getRotationVector (const MWWorld::Ptr& ptr) const;
|
virtual osg::Vec3f getRotationVector (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return desired rotations, as euler angles.
|
///< Return desired rotations, as euler angles.
|
||||||
|
|
||||||
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
|
@ -394,7 +394,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsDrowning)
|
if (mIsDrowning)
|
||||||
mDrowningFlashTheta += dt * Ogre::Math::TWO_PI;
|
mDrowningFlashTheta += dt * osg::PI*2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
|
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
|
||||||
|
|
|
@ -169,8 +169,7 @@ namespace MWGui
|
||||||
if (!interior)
|
if (!interior)
|
||||||
{
|
{
|
||||||
ESM::Position playerPos = player.getRefData().getPosition();
|
ESM::Position playerPos = player.getRefData().getPosition();
|
||||||
float d = Ogre::Vector3(pos.pos[0], pos.pos[1], 0).distance(
|
float d = (osg::Vec3f(pos.pos[0], pos.pos[1], 0) - osg::Vec3f(playerPos.pos[0], playerPos.pos[1], 0)).length();
|
||||||
Ogre::Vector3(playerPos.pos[0], playerPos.pos[1], 0));
|
|
||||||
int hours = static_cast<int>(d /MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTravelTimeMult")->getFloat());
|
int hours = static_cast<int>(d /MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTravelTimeMult")->getFloat());
|
||||||
for(int i = 0;i < hours;i++)
|
for(int i = 0;i < hours;i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -992,12 +992,12 @@ namespace MWGui
|
||||||
mMap->setCellPrefix (cell->getCell()->mName );
|
mMap->setCellPrefix (cell->getCell()->mName );
|
||||||
mHud->setCellPrefix (cell->getCell()->mName );
|
mHud->setCellPrefix (cell->getCell()->mName );
|
||||||
|
|
||||||
Ogre::Vector3 worldPos;
|
osg::Vec3f worldPos;
|
||||||
if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos))
|
if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos))
|
||||||
worldPos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition();
|
worldPos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition();
|
||||||
else
|
else
|
||||||
MWBase::Environment::get().getWorld()->getPlayer().setLastKnownExteriorPosition(worldPos);
|
MWBase::Environment::get().getWorld()->getPlayer().setLastKnownExteriorPosition(worldPos);
|
||||||
mMap->setGlobalMapPlayerPosition(worldPos.x, worldPos.y);
|
mMap->setGlobalMapPlayerPosition(worldPos.x(), worldPos.y());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -316,7 +316,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
const ESM::Position& actor1Pos = actor1.getRefData().getPosition();
|
const ESM::Position& actor1Pos = actor1.getRefData().getPosition();
|
||||||
const ESM::Position& actor2Pos = actor2.getRefData().getPosition();
|
const ESM::Position& actor2Pos = actor2.getRefData().getPosition();
|
||||||
float sqrDist = Ogre::Vector3(actor1Pos.pos).squaredDistance(Ogre::Vector3(actor2Pos.pos));
|
float sqrDist = (actor1Pos.asVec3() - actor2Pos.asVec3()).length2();
|
||||||
if (sqrDist > 7168*7168)
|
if (sqrDist > 7168*7168)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1081,7 +1081,7 @@ namespace MWMechanics
|
||||||
// AI and magic effects update
|
// AI and magic effects update
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
||||||
{
|
{
|
||||||
bool inProcessingRange = Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(iter->first.getRefData().getPosition().pos))
|
bool inProcessingRange = (player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
|
||||||
<= sqrProcessingDistance;
|
<= sqrProcessingDistance;
|
||||||
|
|
||||||
iter->second->getCharacterController()->setActive(inProcessingRange);
|
iter->second->getCharacterController()->setActive(inProcessingRange);
|
||||||
|
@ -1151,7 +1151,7 @@ namespace MWMechanics
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (iter->first != player &&
|
if (iter->first != player &&
|
||||||
Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(iter->first.getRefData().getPosition().pos))
|
(player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
|
||||||
> sqrProcessingDistance)
|
> sqrProcessingDistance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1236,7 +1236,7 @@ namespace MWMechanics
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// is the player in range and can they be detected
|
// is the player in range and can they be detected
|
||||||
if (Ogre::Vector3(iter->first.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(player.getRefData().getPosition().pos)) <= radius*radius
|
if ((iter->first.getRefData().getPosition().asVec3() - player.getRefData().getPosition().asVec3()).length2() <= radius*radius
|
||||||
&& MWBase::Environment::get().getWorld()->getLOS(player, iter->first))
|
&& MWBase::Environment::get().getWorld()->getLOS(player, iter->first))
|
||||||
{
|
{
|
||||||
if (MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, iter->first))
|
if (MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, iter->first))
|
||||||
|
|
|
@ -56,7 +56,7 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, AiState& stat
|
||||||
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
|
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
|
||||||
|
|
||||||
// Turn away from the door and move when turn completed
|
// Turn away from the door and move when turn completed
|
||||||
if (zTurn(actor, Ogre::Radian(std::atan2(x,y) + mAdjAngle), Ogre::Degree(5)))
|
if (zTurn(actor, std::atan2(x,y) + mAdjAngle, osg::DegreesToRadians(5.f)))
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 1;
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 1;
|
||||||
else
|
else
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
||||||
|
|
|
@ -35,18 +35,18 @@ namespace
|
||||||
|
|
||||||
void getMinMaxAttackDuration(const MWWorld::Ptr& actor, float (*fMinMaxDurations)[2]);
|
void getMinMaxAttackDuration(const MWWorld::Ptr& actor, float (*fMinMaxDurations)[2]);
|
||||||
|
|
||||||
Ogre::Vector3 AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, const Ogre::Vector3& vLastTargetPos,
|
osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, const osg::Vec3f& vLastTargetPos,
|
||||||
float duration, int weapType, float strength);
|
float duration, int weapType, float strength);
|
||||||
|
|
||||||
float getZAngleToDir(const Ogre::Vector3& dir)
|
float getZAngleToDir(const osg::Vec3f& dir)
|
||||||
{
|
{
|
||||||
return Ogre::Math::ATan2(dir.x,dir.y).valueDegrees();
|
return osg::RadiansToDegrees(std::atan2(dir.x(), dir.y()));
|
||||||
}
|
}
|
||||||
|
|
||||||
float getXAngleToDir(const Ogre::Vector3& dir, float dirLen = 0.0f)
|
float getXAngleToDir(const osg::Vec3f& dir, float dirLen = 0.0f)
|
||||||
{
|
{
|
||||||
float len = (dirLen > 0.0f)? dirLen : dir.length();
|
float len = (dirLen > 0.0f)? dirLen : dir.length();
|
||||||
return -Ogre::Math::ASin(dir.z / len).valueDegrees();
|
return osg::RadiansToDegrees(-std::asin(dir.z() / len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,20 +58,20 @@ namespace
|
||||||
|
|
||||||
// cast up-down ray with some offset from actor position to check for pits/obstacles on the way to target;
|
// cast up-down ray with some offset from actor position to check for pits/obstacles on the way to target;
|
||||||
// magnitude of pits/obstacles is defined by PATHFIND_Z_REACH
|
// magnitude of pits/obstacles is defined by PATHFIND_Z_REACH
|
||||||
bool checkWayIsClear(const Ogre::Vector3& from, const Ogre::Vector3& to, float offsetXY)
|
bool checkWayIsClear(const osg::Vec3f& from, const osg::Vec3f& to, float offsetXY)
|
||||||
{
|
{
|
||||||
if((to - from).length() >= PATHFIND_CAUTION_DIST || std::abs(from.z - to.z) <= PATHFIND_Z_REACH)
|
if((to - from).length() >= PATHFIND_CAUTION_DIST || std::abs(from.z() - to.z()) <= PATHFIND_Z_REACH)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 dir = to - from;
|
osg::Vec3f dir = to - from;
|
||||||
dir.z = 0;
|
dir.z() = 0;
|
||||||
dir.normalise();
|
dir.normalize();
|
||||||
float verticalOffset = 200; // instead of '200' here we want the height of the actor
|
float verticalOffset = 200; // instead of '200' here we want the height of the actor
|
||||||
Ogre::Vector3 _from = from + dir*offsetXY + Ogre::Vector3::UNIT_Z * verticalOffset;
|
osg::Vec3f _from = from + dir*offsetXY + osg::Vec3f(0,0,1) * verticalOffset;
|
||||||
|
|
||||||
// cast up-down ray and find height in world space of hit
|
// cast up-down ray and find height in world space of hit
|
||||||
float h = _from.z - MWBase::Environment::get().getWorld()->getDistToNearestRayHit(_from, -Ogre::Vector3::UNIT_Z, verticalOffset + PATHFIND_Z_REACH + 1);
|
float h = _from.z() - MWBase::Environment::get().getWorld()->getDistToNearestRayHit(_from, osg::Vec3f(0,0,-1), verticalOffset + PATHFIND_Z_REACH + 1);
|
||||||
|
|
||||||
if(std::abs(from.z - h) <= PATHFIND_Z_REACH)
|
if(std::abs(from.z() - h) <= PATHFIND_Z_REACH)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ namespace MWMechanics
|
||||||
bool mAttack;
|
bool mAttack;
|
||||||
bool mFollowTarget;
|
bool mFollowTarget;
|
||||||
bool mCombatMove;
|
bool mCombatMove;
|
||||||
Ogre::Vector3 mLastTargetPos;
|
osg::Vec3f mLastTargetPos;
|
||||||
const MWWorld::CellStore* mCell;
|
const MWWorld::CellStore* mCell;
|
||||||
boost::shared_ptr<Action> mCurrentAction;
|
boost::shared_ptr<Action> mCurrentAction;
|
||||||
float mActionCooldown;
|
float mActionCooldown;
|
||||||
|
@ -104,7 +104,7 @@ namespace MWMechanics
|
||||||
bool mMinMaxAttackDurationInitialised;
|
bool mMinMaxAttackDurationInitialised;
|
||||||
bool mForceNoShortcut;
|
bool mForceNoShortcut;
|
||||||
ESM::Position mShortcutFailPos;
|
ESM::Position mShortcutFailPos;
|
||||||
Ogre::Vector3 mLastActorPos;
|
osg::Vec3f mLastActorPos;
|
||||||
MWMechanics::Movement mMovement;
|
MWMechanics::Movement mMovement;
|
||||||
|
|
||||||
AiCombatStorage():
|
AiCombatStorage():
|
||||||
|
@ -231,12 +231,12 @@ namespace MWMechanics
|
||||||
|
|
||||||
if(movement.mRotation[2] != 0)
|
if(movement.mRotation[2] != 0)
|
||||||
{
|
{
|
||||||
if(zTurn(actor, Ogre::Degree(movement.mRotation[2]))) movement.mRotation[2] = 0;
|
if(zTurn(actor, osg::DegreesToRadians(movement.mRotation[2]))) movement.mRotation[2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(movement.mRotation[0] != 0)
|
if(movement.mRotation[0] != 0)
|
||||||
{
|
{
|
||||||
if(smoothTurn(actor, Ogre::Degree(movement.mRotation[0]), 0)) movement.mRotation[0] = 0;
|
if(smoothTurn(actor, osg::DegreesToRadians(movement.mRotation[0]), 0)) movement.mRotation[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float attacksPeriod = 1.0f;
|
float attacksPeriod = 1.0f;
|
||||||
|
@ -450,12 +450,12 @@ namespace MWMechanics
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ESM::Position pos = actor.getRefData().getPosition();
|
ESM::Position pos = actor.getRefData().getPosition();
|
||||||
Ogre::Vector3 vActorPos(pos.pos);
|
osg::Vec3f vActorPos(pos.asVec3());
|
||||||
Ogre::Vector3 vTargetPos(target.getRefData().getPosition().pos);
|
osg::Vec3f vTargetPos(target.getRefData().getPosition().asVec3());
|
||||||
Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos;
|
osg::Vec3f vDirToTarget = vTargetPos - vActorPos;
|
||||||
float distToTarget = vDirToTarget.length();
|
float distToTarget = vDirToTarget.length();
|
||||||
|
|
||||||
Ogre::Vector3& lastActorPos = storage.mLastActorPos;
|
osg::Vec3f& lastActorPos = storage.mLastActorPos;
|
||||||
bool& followTarget = storage.mFollowTarget;
|
bool& followTarget = storage.mFollowTarget;
|
||||||
|
|
||||||
bool isStuck = false;
|
bool isStuck = false;
|
||||||
|
@ -496,8 +496,8 @@ namespace MWMechanics
|
||||||
// note: in getZAngleToDir if we preserve dir.z then horizontal angle can be inaccurate
|
// note: in getZAngleToDir if we preserve dir.z then horizontal angle can be inaccurate
|
||||||
if (distantCombat)
|
if (distantCombat)
|
||||||
{
|
{
|
||||||
Ogre::Vector3& lastTargetPos = storage.mLastTargetPos;
|
osg::Vec3f& lastTargetPos = storage.mLastTargetPos;
|
||||||
Ogre::Vector3 vAimDir = AimDirToMovingTarget(actor, target, lastTargetPos, tReaction, weaptype, strength);
|
osg::Vec3f vAimDir = AimDirToMovingTarget(actor, target, lastTargetPos, tReaction, weaptype, strength);
|
||||||
lastTargetPos = vTargetPos;
|
lastTargetPos = vTargetPos;
|
||||||
movement.mRotation[0] = getXAngleToDir(vAimDir);
|
movement.mRotation[0] = getXAngleToDir(vAimDir);
|
||||||
movement.mRotation[2] = getZAngleToDir(vAimDir);
|
movement.mRotation[2] = getZAngleToDir(vAimDir);
|
||||||
|
@ -553,12 +553,12 @@ namespace MWMechanics
|
||||||
ESM::Position& shortcutFailPos = storage.mShortcutFailPos;
|
ESM::Position& shortcutFailPos = storage.mShortcutFailPos;
|
||||||
|
|
||||||
if(inLOS && (!isStuck || readyToAttack)
|
if(inLOS && (!isStuck || readyToAttack)
|
||||||
&& (!forceNoShortcut || (Ogre::Vector3(shortcutFailPos.pos) - vActorPos).length() >= PATHFIND_SHORTCUT_RETRY_DIST))
|
&& (!forceNoShortcut || (shortcutFailPos.asVec3() - vActorPos).length() >= PATHFIND_SHORTCUT_RETRY_DIST))
|
||||||
{
|
{
|
||||||
if(speed == 0.0f) speed = actorClass.getSpeed(actor);
|
if(speed == 0.0f) speed = actorClass.getSpeed(actor);
|
||||||
// maximum dist before pit/obstacle for actor to avoid them depending on his speed
|
// maximum dist before pit/obstacle for actor to avoid them depending on his speed
|
||||||
float maxAvoidDist = tReaction * speed + speed / MAX_VEL_ANGULAR.valueRadians() * 2; // *2 - for reliability
|
float maxAvoidDist = tReaction * speed + speed / MAX_VEL_ANGULAR_RADIANS * 2; // *2 - for reliability
|
||||||
preferShortcut = checkWayIsClear(vActorPos, vTargetPos, Ogre::Vector3(vDirToTarget.x, vDirToTarget.y, 0).length() > maxAvoidDist*1.5? maxAvoidDist : maxAvoidDist/2);
|
preferShortcut = checkWayIsClear(vActorPos, vTargetPos, osg::Vec3f(vDirToTarget.x(), vDirToTarget.y(), 0).length() > maxAvoidDist*1.5? maxAvoidDist : maxAvoidDist/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't use pathgrid when actor can move in 3 dimensions
|
// don't use pathgrid when actor can move in 3 dimensions
|
||||||
|
@ -594,7 +594,7 @@ namespace MWMechanics
|
||||||
// get point just before target
|
// get point just before target
|
||||||
std::list<ESM::Pathgrid::Point>::const_iterator pntIter = --mPathFinder.getPath().end();
|
std::list<ESM::Pathgrid::Point>::const_iterator pntIter = --mPathFinder.getPath().end();
|
||||||
--pntIter;
|
--pntIter;
|
||||||
Ogre::Vector3 vBeforeTarget(PathFinder::MakeOgreVector3(*pntIter));
|
osg::Vec3f vBeforeTarget(PathFinder::MakeOsgVec3(*pntIter));
|
||||||
|
|
||||||
// if current actor pos is closer to target then last point of path (excluding target itself) then go straight on target
|
// if current actor pos is closer to target then last point of path (excluding target itself) then go straight on target
|
||||||
if(distToTarget <= (vTargetPos - vBeforeTarget).length())
|
if(distToTarget <= (vTargetPos - vBeforeTarget).length())
|
||||||
|
@ -668,7 +668,7 @@ namespace MWMechanics
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0.1f;
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 0.1f;
|
||||||
// change the angle a bit, too
|
// change the angle a bit, too
|
||||||
if(mPathFinder.isPathConstructed())
|
if(mPathFinder.isPathConstructed())
|
||||||
zTurn(actor, Ogre::Degree(mPathFinder.getZAngleToNext(pos.pos[0] + 1, pos.pos[1])));
|
zTurn(actor, osg::DegreesToRadians(mPathFinder.getZAngleToNext(pos.pos[0] + 1, pos.pos[1])));
|
||||||
|
|
||||||
if(followTarget)
|
if(followTarget)
|
||||||
followTarget = false;
|
followTarget = false;
|
||||||
|
@ -680,14 +680,14 @@ namespace MWMechanics
|
||||||
|
|
||||||
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
|
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 newPathTarget = Ogre::Vector3(target.getRefData().getPosition().pos);
|
osg::Vec3f newPathTarget = target.getRefData().getPosition().asVec3();
|
||||||
|
|
||||||
float dist;
|
float dist;
|
||||||
|
|
||||||
if(!mPathFinder.getPath().empty())
|
if(!mPathFinder.getPath().empty())
|
||||||
{
|
{
|
||||||
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
|
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
|
||||||
Ogre::Vector3 currPathTarget(PathFinder::MakeOgreVector3(lastPt));
|
osg::Vec3f currPathTarget(PathFinder::MakeOsgVec3(lastPt));
|
||||||
dist = (newPathTarget - currPathTarget).length();
|
dist = (newPathTarget - currPathTarget).length();
|
||||||
}
|
}
|
||||||
else dist = 1e+38F; // necessarily construct a new path
|
else dist = 1e+38F; // necessarily construct a new path
|
||||||
|
@ -876,7 +876,7 @@ void getMinMaxAttackDuration(const MWWorld::Ptr& actor, float (*fMinMaxDurations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector3 AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, const Ogre::Vector3& vLastTargetPos,
|
osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, const osg::Vec3f& vLastTargetPos,
|
||||||
float duration, int weapType, float strength)
|
float duration, int weapType, float strength)
|
||||||
{
|
{
|
||||||
float projSpeed;
|
float projSpeed;
|
||||||
|
@ -905,28 +905,37 @@ Ogre::Vector3 AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr
|
||||||
|
|
||||||
// idea: perpendicular to dir to target speed components of target move vector and projectile vector should be the same
|
// idea: perpendicular to dir to target speed components of target move vector and projectile vector should be the same
|
||||||
|
|
||||||
Ogre::Vector3 vActorPos = Ogre::Vector3(actor.getRefData().getPosition().pos);
|
osg::Vec3f vActorPos = actor.getRefData().getPosition().asVec3();
|
||||||
Ogre::Vector3 vTargetPos = Ogre::Vector3(target.getRefData().getPosition().pos);
|
osg::Vec3f vTargetPos = target.getRefData().getPosition().asVec3();
|
||||||
Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos;
|
osg::Vec3f vDirToTarget = vTargetPos - vActorPos;
|
||||||
float distToTarget = vDirToTarget.length();
|
float distToTarget = vDirToTarget.length();
|
||||||
|
|
||||||
Ogre::Vector3 vTargetMoveDir = vTargetPos - vLastTargetPos;
|
osg::Vec3f vTargetMoveDir = vTargetPos - vLastTargetPos;
|
||||||
vTargetMoveDir /= duration; // |vTargetMoveDir| is target real speed in units/sec now
|
vTargetMoveDir /= duration; // |vTargetMoveDir| is target real speed in units/sec now
|
||||||
|
|
||||||
Ogre::Vector3 vPerpToDir = vDirToTarget.crossProduct(Ogre::Vector3::UNIT_Z);
|
osg::Vec3f vPerpToDir = vDirToTarget ^ osg::Vec3f(0,0,1); // cross product
|
||||||
|
|
||||||
float velPerp = vTargetMoveDir.dotProduct(vPerpToDir.normalisedCopy());
|
vPerpToDir.normalize();
|
||||||
float velDir = vTargetMoveDir.dotProduct(vDirToTarget.normalisedCopy());
|
osg::Vec3f vDirToTargetNormalized = vDirToTarget;
|
||||||
|
vDirToTargetNormalized.normalize();
|
||||||
|
|
||||||
|
// dot product
|
||||||
|
float velPerp = vTargetMoveDir * vPerpToDir;
|
||||||
|
float velDir = vTargetMoveDir * vDirToTargetNormalized;
|
||||||
|
|
||||||
// time to collision between target and projectile
|
// time to collision between target and projectile
|
||||||
float t_collision;
|
float t_collision;
|
||||||
|
|
||||||
float projVelDirSquared = projSpeed * projSpeed - velPerp * velPerp;
|
float projVelDirSquared = projSpeed * projSpeed - velPerp * velPerp;
|
||||||
float projDistDiff = vDirToTarget.dotProduct(vTargetMoveDir.normalisedCopy());
|
|
||||||
projDistDiff = sqrt(distToTarget * distToTarget - projDistDiff * projDistDiff);
|
osg::Vec3f vTargetMoveDirNormalized = vTargetMoveDir;
|
||||||
|
vTargetMoveDirNormalized.normalize();
|
||||||
|
|
||||||
|
float projDistDiff = vDirToTarget * vTargetMoveDirNormalized; // dot product
|
||||||
|
projDistDiff = std::sqrt(distToTarget * distToTarget - projDistDiff * projDistDiff);
|
||||||
|
|
||||||
if (projVelDirSquared > 0)
|
if (projVelDirSquared > 0)
|
||||||
t_collision = projDistDiff / (sqrt(projVelDirSquared) - velDir);
|
t_collision = projDistDiff / (std::sqrt(projVelDirSquared) - velDir);
|
||||||
else t_collision = 0; // speed of projectile is not enough to reach moving target
|
else t_collision = 0; // speed of projectile is not enough to reach moving target
|
||||||
|
|
||||||
return vTargetPos + vTargetMoveDir * t_collision - vActorPos;
|
return vTargetPos + vTargetMoveDir * t_collision - vActorPos;
|
||||||
|
|
|
@ -76,7 +76,7 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, AiState& state, float duratio
|
||||||
|
|
||||||
if (storage.mTimer < 0)
|
if (storage.mTimer < 0)
|
||||||
{
|
{
|
||||||
if (Ogre::Vector3(actor.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(target.getRefData().getPosition().pos))
|
if ((actor.getRefData().getPosition().asVec3() - target.getRefData().getPosition().asVec3()).length2()
|
||||||
< 500*500
|
< 500*500
|
||||||
&& MWBase::Environment::get().getWorld()->getLOS(actor, target))
|
&& MWBase::Environment::get().getWorld()->getLOS(actor, target))
|
||||||
mActive = true;
|
mActive = true;
|
||||||
|
@ -137,7 +137,7 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, AiState& state, float duratio
|
||||||
// turn towards target anyway
|
// turn towards target anyway
|
||||||
float directionX = target.getRefData().getPosition().pos[0] - actor.getRefData().getPosition().pos[0];
|
float directionX = target.getRefData().getPosition().pos[0] - actor.getRefData().getPosition().pos[0];
|
||||||
float directionY = target.getRefData().getPosition().pos[1] - actor.getRefData().getPosition().pos[1];
|
float directionY = target.getRefData().getPosition().pos[1] - actor.getRefData().getPosition().pos[1];
|
||||||
zTurn(actor, Ogre::Math::ATan2(directionX,directionY), Ogre::Degree(5));
|
zTurn(actor, std::atan2(directionX,directionY), osg::DegreesToRadians(5.f));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -106,7 +106,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[0] = 1;
|
actor.getClass().getMovementSettings(actor).mPosition[0] = 1;
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 1;
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 1;
|
||||||
// change the angle a bit, too
|
// change the angle a bit, too
|
||||||
zTurn(actor, Ogre::Degree(mPathFinder.getZAngleToNext(pos.pos[0] + 1, pos.pos[1])));
|
zTurn(actor, osg::DegreesToRadians(mPathFinder.getZAngleToNext(pos.pos[0] + 1, pos.pos[1])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { //Not stuck, so reset things
|
else { //Not stuck, so reset things
|
||||||
|
@ -119,7 +119,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 1; //Just run forward the rest of the time
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 1; //Just run forward the rest of the time
|
||||||
}
|
}
|
||||||
|
|
||||||
zTurn(actor, Ogre::Degree(mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
|
zTurn(actor, osg::DegreesToRadians(mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, AiState& state,float durati
|
||||||
std::list<AiPackage *>::iterator itActualCombat;
|
std::list<AiPackage *>::iterator itActualCombat;
|
||||||
|
|
||||||
float nearestDist = std::numeric_limits<float>::max();
|
float nearestDist = std::numeric_limits<float>::max();
|
||||||
Ogre::Vector3 vActorPos = Ogre::Vector3(actor.getRefData().getPosition().pos);
|
osg::Vec3f vActorPos = actor.getRefData().getPosition().asVec3();
|
||||||
|
|
||||||
for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end();)
|
for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end();)
|
||||||
{
|
{
|
||||||
|
@ -183,7 +183,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, AiState& state,float durati
|
||||||
{
|
{
|
||||||
const ESM::Position &targetPos = target.getRefData().getPosition();
|
const ESM::Position &targetPos = target.getRefData().getPosition();
|
||||||
|
|
||||||
float distTo = (Ogre::Vector3(targetPos.pos) - vActorPos).length();
|
float distTo = (targetPos.asVec3() - vActorPos).length();
|
||||||
if (distTo < nearestDist)
|
if (distTo < nearestDist)
|
||||||
{
|
{
|
||||||
nearestDist = distTo;
|
nearestDist = distTo;
|
||||||
|
@ -258,7 +258,7 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor)
|
||||||
return; // already in combat with this actor
|
return; // already in combat with this actor
|
||||||
}
|
}
|
||||||
else if ((*iter)->getTypeId() == AiPackage::TypeIdWander)
|
else if ((*iter)->getTypeId() == AiPackage::TypeIdWander)
|
||||||
static_cast<AiWander*>(*iter)->setReturnPosition(Ogre::Vector3(actor.getRefData().getPosition().pos));
|
static_cast<AiWander*>(*iter)->setReturnPosition(actor.getRefData().getPosition().asVec3());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
bool isWithinMaxRange(const Ogre::Vector3& pos1, const Ogre::Vector3& pos2)
|
bool isWithinMaxRange(const osg::Vec3f& pos1, const osg::Vec3f& pos2)
|
||||||
{
|
{
|
||||||
// Maximum travel distance for vanilla compatibility.
|
// Maximum travel distance for vanilla compatibility.
|
||||||
// Was likely meant to prevent NPCs walking into non-loaded exterior cells, but for some reason is used in interior cells as well.
|
// Was likely meant to prevent NPCs walking into non-loaded exterior cells, but for some reason is used in interior cells as well.
|
||||||
// We can make this configurable at some point, but the default *must* be the below value. Anything else will break shoddily-written content (*cough* MW *cough*) in bizarre ways.
|
// We can make this configurable at some point, but the default *must* be the below value. Anything else will break shoddily-written content (*cough* MW *cough*) in bizarre ways.
|
||||||
return (pos1.squaredDistance(pos2) <= 7168*7168);
|
return (pos1 - pos2).length2() <= 7168*7168;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isWithinMaxRange(Ogre::Vector3(mX, mY, mZ), Ogre::Vector3(pos.pos)))
|
if (!isWithinMaxRange(osg::Vec3f(mX, mY, mZ), pos.asVec3()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
|
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
|
||||||
|
@ -106,7 +106,7 @@ namespace MWMechanics
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
zTurn(actor, Ogre::Degree(mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
|
zTurn(actor, osg::DegreesToRadians(mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
|
||||||
movement.mPosition[1] = 1;
|
movement.mPosition[1] = 1;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -119,7 +119,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
void AiTravel::fastForward(const MWWorld::Ptr& actor, AiState& state)
|
void AiTravel::fastForward(const MWWorld::Ptr& actor, AiState& state)
|
||||||
{
|
{
|
||||||
if (!isWithinMaxRange(Ogre::Vector3(mX, mY, mZ), Ogre::Vector3(actor.getRefData().getPosition().pos)))
|
if (!isWithinMaxRange(osg::Vec3f(mX, mY, mZ), actor.getRefData().getPosition().asVec3()))
|
||||||
return;
|
return;
|
||||||
// does not do any validation on the travel target (whether it's in air, inside collision geometry, etc),
|
// does not do any validation on the travel target (whether it's in air, inside collision geometry, etc),
|
||||||
// that is the user's responsibility
|
// that is the user's responsibility
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
// the z rotation angle (degrees) we want to reach
|
// the z rotation angle (degrees) we want to reach
|
||||||
// used every frame when mRotate is true
|
// used every frame when mRotate is true
|
||||||
Ogre::Radian mTargetAngle;
|
float mTargetAngleRadians;
|
||||||
bool mRotate;
|
bool mRotate;
|
||||||
float mReaction; // update some actions infrequently
|
float mReaction; // update some actions infrequently
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ namespace MWMechanics
|
||||||
PathFinder mPathFinder;
|
PathFinder mPathFinder;
|
||||||
|
|
||||||
AiWanderStorage():
|
AiWanderStorage():
|
||||||
mTargetAngle(0),
|
mTargetAngleRadians(0),
|
||||||
mRotate(false),
|
mRotate(false),
|
||||||
mReaction(0),
|
mReaction(0),
|
||||||
mSaidGreeting(AiWander::Greet_None),
|
mSaidGreeting(AiWander::Greet_None),
|
||||||
|
@ -101,7 +101,7 @@ namespace MWMechanics
|
||||||
mTrimCurrentNode = false;
|
mTrimCurrentNode = false;
|
||||||
|
|
||||||
mHasReturnPosition = false;
|
mHasReturnPosition = false;
|
||||||
mReturnPosition = Ogre::Vector3(0,0,0);
|
mReturnPosition = osg::Vec3f(0,0,0);
|
||||||
|
|
||||||
if(mDistance < 0)
|
if(mDistance < 0)
|
||||||
mDistance = 0;
|
mDistance = 0;
|
||||||
|
@ -231,7 +231,7 @@ namespace MWMechanics
|
||||||
if(walking) // have not yet reached the destination
|
if(walking) // have not yet reached the destination
|
||||||
{
|
{
|
||||||
// turn towards the next point in mPath
|
// turn towards the next point in mPath
|
||||||
zTurn(actor, Ogre::Degree(storage.mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
|
zTurn(actor, osg::DegreesToRadians(storage.mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 1;
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 1;
|
||||||
|
|
||||||
// Returns true if evasive action needs to be taken
|
// Returns true if evasive action needs to be taken
|
||||||
|
@ -255,7 +255,7 @@ namespace MWMechanics
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[0] = 1;
|
actor.getClass().getMovementSettings(actor).mPosition[0] = 1;
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0.1f;
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 0.1f;
|
||||||
// change the angle a bit, too
|
// change the angle a bit, too
|
||||||
zTurn(actor, Ogre::Degree(storage.mPathFinder.getZAngleToNext(pos.pos[0] + 1, pos.pos[1])));
|
zTurn(actor, osg::DegreesToRadians(storage.mPathFinder.getZAngleToNext(pos.pos[0] + 1, pos.pos[1])));
|
||||||
}
|
}
|
||||||
mStuckCount++; // TODO: maybe no longer needed
|
mStuckCount++; // TODO: maybe no longer needed
|
||||||
}
|
}
|
||||||
|
@ -275,14 +275,14 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ogre::Radian& targetAngle = storage.mTargetAngle;
|
float& targetAngleRadians = storage.mTargetAngleRadians;
|
||||||
bool& rotate = storage.mRotate;
|
bool& rotate = storage.mRotate;
|
||||||
if (rotate)
|
if (rotate)
|
||||||
{
|
{
|
||||||
// Reduce the turning animation glitch by using a *HUGE* value of
|
// Reduce the turning animation glitch by using a *HUGE* value of
|
||||||
// epsilon... TODO: a proper fix might be in either the physics or the
|
// epsilon... TODO: a proper fix might be in either the physics or the
|
||||||
// animation subsystem
|
// animation subsystem
|
||||||
if (zTurn(actor, targetAngle, Ogre::Degree(5)))
|
if (zTurn(actor, targetAngleRadians, osg::DegreesToRadians(5.f)))
|
||||||
rotate = false;
|
rotate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ namespace MWMechanics
|
||||||
// Only say Idle voices when player is in LOS
|
// Only say Idle voices when player is in LOS
|
||||||
// A bit counterintuitive, likely vanilla did this to reduce the appearance of
|
// A bit counterintuitive, likely vanilla did this to reduce the appearance of
|
||||||
// voices going through walls?
|
// voices going through walls?
|
||||||
if (roll < x && Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(pos.pos))
|
if (roll < x && (player.getRefData().getPosition().asVec3() - pos.asVec3()).length2()
|
||||||
< 3000*3000 // maybe should be fAudioVoiceDefaultMaxDistance*fAudioMaxDistanceMult instead
|
< 3000*3000 // maybe should be fAudioVoiceDefaultMaxDistance*fAudioMaxDistanceMult instead
|
||||||
&& MWBase::Environment::get().getWorld()->getLOS(player, actor))
|
&& MWBase::Environment::get().getWorld()->getLOS(player, actor))
|
||||||
MWBase::Environment::get().getDialogueManager()->say(actor, "idle");
|
MWBase::Environment::get().getDialogueManager()->say(actor, "idle");
|
||||||
|
@ -400,7 +400,7 @@ namespace MWMechanics
|
||||||
// For stationary NPCs, move back to the starting location if another AiPackage moved us elsewhere
|
// For stationary NPCs, move back to the starting location if another AiPackage moved us elsewhere
|
||||||
if (cellChange)
|
if (cellChange)
|
||||||
mHasReturnPosition = false;
|
mHasReturnPosition = false;
|
||||||
if (mDistance == 0 && mHasReturnPosition && Ogre::Vector3(pos.pos).squaredDistance(mReturnPosition) > 20*20)
|
if (mDistance == 0 && mHasReturnPosition && (pos.asVec3() - mReturnPosition).length2() > 20*20)
|
||||||
{
|
{
|
||||||
chooseAction = false;
|
chooseAction = false;
|
||||||
idleNow = false;
|
idleNow = false;
|
||||||
|
@ -435,9 +435,9 @@ namespace MWMechanics
|
||||||
helloDistance *= iGreetDistanceMultiplier;
|
helloDistance *= iGreetDistanceMultiplier;
|
||||||
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
Ogre::Vector3 playerPos(player.getRefData().getPosition().pos);
|
osg::Vec3f playerPos(player.getRefData().getPosition().asVec3());
|
||||||
Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos);
|
osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
|
||||||
float playerDistSqr = playerPos.squaredDistance(actorPos);
|
float playerDistSqr = (playerPos - actorPos).length2();
|
||||||
|
|
||||||
int& greetingTimer = storage.mGreetingTimer;
|
int& greetingTimer = storage.mGreetingTimer;
|
||||||
if (greetingState == Greet_None)
|
if (greetingState == Greet_None)
|
||||||
|
@ -471,10 +471,10 @@ namespace MWMechanics
|
||||||
|
|
||||||
if(!rotate)
|
if(!rotate)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 dir = playerPos - actorPos;
|
osg::Vec3f dir = playerPos - actorPos;
|
||||||
|
|
||||||
float faceAngleRadians = std::atan2(dir.x, dir.y);
|
float faceAngleRadians = std::atan2(dir.x(), dir.y());
|
||||||
targetAngle = faceAngleRadians;
|
targetAngleRadians = faceAngleRadians;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,10 +501,8 @@ namespace MWMechanics
|
||||||
assert(mAllowedNodes.size());
|
assert(mAllowedNodes.size());
|
||||||
unsigned int randNode = Misc::Rng::rollDice(mAllowedNodes.size());
|
unsigned int randNode = Misc::Rng::rollDice(mAllowedNodes.size());
|
||||||
// NOTE: initially constructed with local (i.e. cell) co-ordinates
|
// NOTE: initially constructed with local (i.e. cell) co-ordinates
|
||||||
Ogre::Vector3 destNodePos(PathFinder::MakeOgreVector3(mAllowedNodes[randNode]));
|
|
||||||
|
|
||||||
// convert dest to use world co-ordinates
|
// convert dest to use world co-ordinates
|
||||||
ESM::Pathgrid::Point dest(PathFinder::MakePathgridPoint(destNodePos));
|
ESM::Pathgrid::Point dest(mAllowedNodes[randNode]);
|
||||||
if (currentCell->getCell()->isExterior())
|
if (currentCell->getCell()->isExterior())
|
||||||
{
|
{
|
||||||
dest.mX += currentCell->getCell()->mData.mX * ESM::Land::REAL_SIZE;
|
dest.mX += currentCell->getCell()->mData.mX * ESM::Land::REAL_SIZE;
|
||||||
|
@ -607,7 +605,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiWander::setReturnPosition(const Ogre::Vector3& position)
|
void AiWander::setReturnPosition(const osg::Vec3f& position)
|
||||||
{
|
{
|
||||||
if (!mHasReturnPosition)
|
if (!mHasReturnPosition)
|
||||||
{
|
{
|
||||||
|
@ -652,8 +650,8 @@ namespace MWMechanics
|
||||||
ESM::Pathgrid::Point dest = mAllowedNodes[index];
|
ESM::Pathgrid::Point dest = mAllowedNodes[index];
|
||||||
|
|
||||||
// apply a slight offset to prevent overcrowding
|
// apply a slight offset to prevent overcrowding
|
||||||
dest.mX += static_cast<int>(Ogre::Math::RangeRandom(-64, 64));
|
dest.mX += static_cast<int>(Misc::Rng::rollProbability() * 128 - 64);
|
||||||
dest.mY += static_cast<int>(Ogre::Math::RangeRandom(-64, 64));
|
dest.mY += static_cast<int>(Misc::Rng::rollProbability() * 128 - 64);
|
||||||
|
|
||||||
if (actor.getCell()->isExterior())
|
if (actor.getCell()->isExterior())
|
||||||
{
|
{
|
||||||
|
@ -670,7 +668,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
if (!mStoredInitialActorPosition)
|
if (!mStoredInitialActorPosition)
|
||||||
{
|
{
|
||||||
mInitialActorPosition = Ogre::Vector3(actor.getRefData().getPosition().pos);
|
mInitialActorPosition = actor.getRefData().getPosition().asVec3();
|
||||||
mStoredInitialActorPosition = true;
|
mStoredInitialActorPosition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,7 +698,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert npcPos to local (i.e. cell) co-ordinates
|
// convert npcPos to local (i.e. cell) co-ordinates
|
||||||
Ogre::Vector3 npcPos(mInitialActorPosition);
|
osg::Vec3f npcPos(mInitialActorPosition);
|
||||||
npcPos[0] = npcPos[0] - cellXOffset;
|
npcPos[0] = npcPos[0] - cellXOffset;
|
||||||
npcPos[1] = npcPos[1] - cellYOffset;
|
npcPos[1] = npcPos[1] - cellYOffset;
|
||||||
|
|
||||||
|
@ -708,19 +706,19 @@ namespace MWMechanics
|
||||||
// NOTE: mPoints and mAllowedNodes are in local co-ordinates
|
// NOTE: mPoints and mAllowedNodes are in local co-ordinates
|
||||||
for(unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++)
|
for(unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 nodePos(PathFinder::MakeOgreVector3(pathgrid->mPoints[counter]));
|
osg::Vec3f nodePos(PathFinder::MakeOsgVec3(pathgrid->mPoints[counter]));
|
||||||
if(npcPos.squaredDistance(nodePos) <= mDistance * mDistance)
|
if((npcPos - nodePos).length2() <= mDistance * mDistance)
|
||||||
mAllowedNodes.push_back(pathgrid->mPoints[counter]);
|
mAllowedNodes.push_back(pathgrid->mPoints[counter]);
|
||||||
}
|
}
|
||||||
if(!mAllowedNodes.empty())
|
if(!mAllowedNodes.empty())
|
||||||
{
|
{
|
||||||
Ogre::Vector3 firstNodePos(PathFinder::MakeOgreVector3(mAllowedNodes[0]));
|
osg::Vec3f firstNodePos(PathFinder::MakeOsgVec3(mAllowedNodes[0]));
|
||||||
float closestNode = npcPos.squaredDistance(firstNodePos);
|
float closestNode = (npcPos - firstNodePos).length2();
|
||||||
unsigned int index = 0;
|
unsigned int index = 0;
|
||||||
for(unsigned int counterThree = 1; counterThree < mAllowedNodes.size(); counterThree++)
|
for(unsigned int counterThree = 1; counterThree < mAllowedNodes.size(); counterThree++)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 nodePos(PathFinder::MakeOgreVector3(mAllowedNodes[counterThree]));
|
osg::Vec3f nodePos(PathFinder::MakeOsgVec3(mAllowedNodes[counterThree]));
|
||||||
float tempDist = npcPos.squaredDistance(nodePos);
|
float tempDist = (npcPos - nodePos).length2();
|
||||||
if(tempDist < closestNode)
|
if(tempDist < closestNode)
|
||||||
index = counterThree;
|
index = counterThree;
|
||||||
}
|
}
|
||||||
|
@ -737,7 +735,7 @@ namespace MWMechanics
|
||||||
std::vector<PathDistance> nodeDistances;
|
std::vector<PathDistance> nodeDistances;
|
||||||
for (unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++)
|
for (unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++)
|
||||||
{
|
{
|
||||||
float distance = npcPos.squaredDistance(PathFinder::MakeOgreVector3(pathgrid->mPoints[counter]));
|
float distance = (npcPos - PathFinder::MakeOsgVec3(pathgrid->mPoints[counter])).length2();
|
||||||
nodeDistances.push_back(std::make_pair(distance, &pathgrid->mPoints.at(counter)));
|
nodeDistances.push_back(std::make_pair(distance, &pathgrid->mPoints.at(counter)));
|
||||||
}
|
}
|
||||||
std::sort(nodeDistances.begin(), nodeDistances.end(), sortByDistance);
|
std::sort(nodeDistances.begin(), nodeDistances.end(), sortByDistance);
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
/// Set the position to return to for a stationary (non-wandering) actor
|
/// Set the position to return to for a stationary (non-wandering) actor
|
||||||
/** In case another AI package moved the actor elsewhere **/
|
/** In case another AI package moved the actor elsewhere **/
|
||||||
void setReturnPosition (const Ogre::Vector3& position);
|
void setReturnPosition (const osg::Vec3f& position);
|
||||||
|
|
||||||
virtual void writeState(ESM::AiSequence::AiSequence &sequence) const;
|
virtual void writeState(ESM::AiSequence::AiSequence &sequence) const;
|
||||||
|
|
||||||
|
@ -83,9 +83,9 @@ namespace MWMechanics
|
||||||
|
|
||||||
bool mHasReturnPosition; // NOTE: Could be removed if mReturnPosition was initialized to actor position,
|
bool mHasReturnPosition; // NOTE: Could be removed if mReturnPosition was initialized to actor position,
|
||||||
// if we had the actor in the AiWander constructor...
|
// if we had the actor in the AiWander constructor...
|
||||||
Ogre::Vector3 mReturnPosition;
|
osg::Vec3f mReturnPosition;
|
||||||
|
|
||||||
Ogre::Vector3 mInitialActorPosition;
|
osg::Vec3f mInitialActorPosition;
|
||||||
bool mStoredInitialActorPosition;
|
bool mStoredInitialActorPosition;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1531,7 +1531,7 @@ void CharacterController::update(float duration)
|
||||||
|
|
||||||
if(mHitState != CharState_None && mJumpState == JumpState_None)
|
if(mHitState != CharState_None && mJumpState == JumpState_None)
|
||||||
vec = osg::Vec3f(0.f, 0.f, 0.f);
|
vec = osg::Vec3f(0.f, 0.f, 0.f);
|
||||||
Ogre::Vector3 rot = cls.getRotationVector(mPtr);
|
osg::Vec3f rot = cls.getRotationVector(mPtr);
|
||||||
|
|
||||||
mMovementSpeed = cls.getSpeed(mPtr);
|
mMovementSpeed = cls.getSpeed(mPtr);
|
||||||
|
|
||||||
|
@ -1728,11 +1728,11 @@ void CharacterController::update(float duration)
|
||||||
// Don't play turning animations during attack. It would break positioning of the arrow bone when releasing a shot.
|
// Don't play turning animations during attack. It would break positioning of the arrow bone when releasing a shot.
|
||||||
// Actually, in vanilla the turning animation is not even played when merely having equipped the weapon,
|
// Actually, in vanilla the turning animation is not even played when merely having equipped the weapon,
|
||||||
// but I don't think we need to go as far as that.
|
// but I don't think we need to go as far as that.
|
||||||
else if(rot.z != 0.0f && !inwater && !sneak && mUpperBodyState < UpperCharState_StartToMinAttack)
|
else if(rot.z() != 0.0f && !inwater && !sneak && mUpperBodyState < UpperCharState_StartToMinAttack)
|
||||||
{
|
{
|
||||||
if(rot.z > 0.0f)
|
if(rot.z() > 0.0f)
|
||||||
movestate = CharState_TurnRight;
|
movestate = CharState_TurnRight;
|
||||||
else if(rot.z < 0.0f)
|
else if(rot.z() < 0.0f)
|
||||||
movestate = CharState_TurnLeft;
|
movestate = CharState_TurnLeft;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1782,18 +1782,18 @@ void CharacterController::update(float duration)
|
||||||
if (mMovementState == CharState_TurnLeft || mMovementState == CharState_TurnRight)
|
if (mMovementState == CharState_TurnLeft || mMovementState == CharState_TurnRight)
|
||||||
{
|
{
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
mAnimation->adjustSpeedMult(mCurrentMovement, std::min(1.5f, std::abs(rot.z) / duration / Ogre::Math::PI));
|
mAnimation->adjustSpeedMult(mCurrentMovement, std::min(1.5f, std::abs(rot.z()) / duration / Ogre::Math::PI));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mSkipAnim)
|
if (!mSkipAnim)
|
||||||
{
|
{
|
||||||
rot *= Ogre::Math::RadiansToDegrees(1.0f);
|
rot *= osg::RadiansToDegrees(1.0f);
|
||||||
if(mHitState != CharState_KnockDown && mHitState != CharState_KnockOut)
|
if(mHitState != CharState_KnockDown && mHitState != CharState_KnockOut)
|
||||||
{
|
{
|
||||||
world->rotateObject(mPtr, rot.x, rot.y, rot.z, true);
|
world->rotateObject(mPtr, rot.x(), rot.y(), rot.z(), true);
|
||||||
}
|
}
|
||||||
else //avoid z-rotating for knockdown
|
else //avoid z-rotating for knockdown
|
||||||
world->rotateObject(mPtr, rot.x, rot.y, 0.0f, true);
|
world->rotateObject(mPtr, rot.x(), rot.y(), 0.0f, true);
|
||||||
|
|
||||||
if (!mMovementAnimationControlled)
|
if (!mMovementAnimationControlled)
|
||||||
world->queueMovement(mPtr, vec);
|
world->queueMovement(mPtr, vec);
|
||||||
|
|
|
@ -15,9 +15,9 @@ namespace
|
||||||
// Caller needs to be careful for very short distances (i.e. less than 1)
|
// Caller needs to be careful for very short distances (i.e. less than 1)
|
||||||
// or when accumuating the results i.e. (a + b)^2 != a^2 + b^2
|
// or when accumuating the results i.e. (a + b)^2 != a^2 + b^2
|
||||||
//
|
//
|
||||||
float distanceSquared(ESM::Pathgrid::Point point, Ogre::Vector3 pos)
|
float distanceSquared(ESM::Pathgrid::Point point, const osg::Vec3f& pos)
|
||||||
{
|
{
|
||||||
return MWMechanics::PathFinder::MakeOgreVector3(point).squaredDistance(pos);
|
return (MWMechanics::PathFinder::MakeOsgVec3(point) - pos).length2();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the closest pathgrid point index from the specified position co
|
// Return the closest pathgrid point index from the specified position co
|
||||||
|
@ -26,7 +26,7 @@ namespace
|
||||||
//
|
//
|
||||||
// NOTE: pos is expected to be in local co-ordinates, as is grid->mPoints
|
// NOTE: pos is expected to be in local co-ordinates, as is grid->mPoints
|
||||||
//
|
//
|
||||||
int getClosestPoint(const ESM::Pathgrid* grid, Ogre::Vector3 pos)
|
int getClosestPoint(const ESM::Pathgrid* grid, const osg::Vec3f& pos)
|
||||||
{
|
{
|
||||||
if(!grid || grid->mPoints.empty())
|
if(!grid || grid->mPoints.empty())
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -52,7 +52,7 @@ namespace
|
||||||
// Chooses a reachable end pathgrid point. start is assumed reachable.
|
// Chooses a reachable end pathgrid point. start is assumed reachable.
|
||||||
std::pair<int, bool> getClosestReachablePoint(const ESM::Pathgrid* grid,
|
std::pair<int, bool> getClosestReachablePoint(const ESM::Pathgrid* grid,
|
||||||
const MWWorld::CellStore *cell,
|
const MWWorld::CellStore *cell,
|
||||||
Ogre::Vector3 pos, int start)
|
const osg::Vec3f pos, int start)
|
||||||
{
|
{
|
||||||
if(!grid || grid->mPoints.empty())
|
if(!grid || grid->mPoints.empty())
|
||||||
return std::pair<int, bool> (-1, false);
|
return std::pair<int, bool> (-1, false);
|
||||||
|
@ -216,12 +216,12 @@ namespace MWMechanics
|
||||||
// point right behind the wall that is closer than any pathgrid
|
// point right behind the wall that is closer than any pathgrid
|
||||||
// point outside the wall
|
// point outside the wall
|
||||||
int startNode = getClosestPoint(mPathgrid,
|
int startNode = getClosestPoint(mPathgrid,
|
||||||
Ogre::Vector3(startPoint.mX - xCell, startPoint.mY - yCell, static_cast<float>(startPoint.mZ)));
|
osg::Vec3f(startPoint.mX - xCell, startPoint.mY - yCell, static_cast<float>(startPoint.mZ)));
|
||||||
// Some cells don't have any pathgrids at all
|
// Some cells don't have any pathgrids at all
|
||||||
if(startNode != -1)
|
if(startNode != -1)
|
||||||
{
|
{
|
||||||
std::pair<int, bool> endNode = getClosestReachablePoint(mPathgrid, cell,
|
std::pair<int, bool> endNode = getClosestReachablePoint(mPathgrid, cell,
|
||||||
Ogre::Vector3(endPoint.mX - xCell, endPoint.mY - yCell, static_cast<float>(endPoint.mZ)),
|
osg::Vec3f(endPoint.mX - xCell, endPoint.mY - yCell, static_cast<float>(endPoint.mZ)),
|
||||||
startNode);
|
startNode);
|
||||||
|
|
||||||
// this shouldn't really happen, but just in case
|
// this shouldn't really happen, but just in case
|
||||||
|
@ -279,7 +279,7 @@ namespace MWMechanics
|
||||||
float directionX = nextPoint.mX - x;
|
float directionX = nextPoint.mX - x;
|
||||||
float directionY = nextPoint.mY - y;
|
float directionY = nextPoint.mY - y;
|
||||||
|
|
||||||
return Ogre::Math::ATan2(directionX,directionY).valueDegrees();
|
return osg::RadiansToDegrees(std::atan2(directionX, directionY));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PathFinder::checkPathCompleted(float x, float y, float tolerance)
|
bool PathFinder::checkPathCompleted(float x, float y, float tolerance)
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace MWMechanics
|
||||||
bool checkPathCompleted(float x, float y, float tolerance=32.f);
|
bool checkPathCompleted(float x, float y, float tolerance=32.f);
|
||||||
///< \Returns true if we are within \a tolerance units of the last path point.
|
///< \Returns true if we are within \a tolerance units of the last path point.
|
||||||
|
|
||||||
|
/// In degrees
|
||||||
float getZAngleToNext(float x, float y) const;
|
float getZAngleToNext(float x, float y) const;
|
||||||
|
|
||||||
bool isPathConstructed() const
|
bool isPathConstructed() const
|
||||||
|
@ -82,6 +83,12 @@ namespace MWMechanics
|
||||||
return ESM::Pathgrid::Point(static_cast<int>(v[0]), static_cast<int>(v[1]), static_cast<int>(v[2]));
|
return ESM::Pathgrid::Point(static_cast<int>(v[0]), static_cast<int>(v[1]), static_cast<int>(v[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// utility function to convert a osg::Vec3f to a Pathgrid::Point
|
||||||
|
static ESM::Pathgrid::Point MakePathgridPoint(const osg::Vec3f& v)
|
||||||
|
{
|
||||||
|
return ESM::Pathgrid::Point(static_cast<int>(v[0]), static_cast<int>(v[1]), static_cast<int>(v[2]));
|
||||||
|
}
|
||||||
|
|
||||||
/// utility function to convert an ESM::Position to a Pathgrid::Point
|
/// utility function to convert an ESM::Position to a Pathgrid::Point
|
||||||
static ESM::Pathgrid::Point MakePathgridPoint(const ESM::Position& p)
|
static ESM::Pathgrid::Point MakePathgridPoint(const ESM::Position& p)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,37 +10,37 @@
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
|
||||||
bool smoothTurn(const MWWorld::Ptr& actor, Ogre::Radian targetAngle, int axis, Ogre::Degree epsilon)
|
bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, float epsilonRadians)
|
||||||
{
|
{
|
||||||
Ogre::Radian currentAngle (actor.getRefData().getPosition().rot[axis]);
|
float currentAngle (actor.getRefData().getPosition().rot[axis]);
|
||||||
Ogre::Radian diff (targetAngle - currentAngle);
|
float diff (targetAngleRadians - currentAngle);
|
||||||
if (diff >= Ogre::Degree(180))
|
if (diff >= osg::DegreesToRadians(180.f))
|
||||||
{
|
{
|
||||||
// Turning the other way would be a better idea
|
// Turning the other way would be a better idea
|
||||||
diff = diff-Ogre::Degree(360);
|
diff = diff-osg::DegreesToRadians(360.f);
|
||||||
}
|
}
|
||||||
else if (diff <= Ogre::Degree(-180))
|
else if (diff <= osg::DegreesToRadians(-180.f))
|
||||||
{
|
{
|
||||||
diff = Ogre::Degree(360)-diff;
|
diff = osg::DegreesToRadians(360.f)-diff;
|
||||||
}
|
}
|
||||||
Ogre::Radian absDiff = Ogre::Math::Abs(diff);
|
float absDiff = std::abs(diff);
|
||||||
|
|
||||||
// The turning animation actually moves you slightly, so the angle will be wrong again.
|
// The turning animation actually moves you slightly, so the angle will be wrong again.
|
||||||
// Use epsilon to prevent jerkiness.
|
// Use epsilon to prevent jerkiness.
|
||||||
if (absDiff < epsilon)
|
if (absDiff < epsilonRadians)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Ogre::Radian limit = MAX_VEL_ANGULAR * MWBase::Environment::get().getFrameDuration();
|
float limit = MAX_VEL_ANGULAR_RADIANS * MWBase::Environment::get().getFrameDuration();
|
||||||
if (absDiff > limit)
|
if (absDiff > limit)
|
||||||
diff = Ogre::Math::Sign(diff) * limit;
|
diff = osg::sign(diff) * limit;
|
||||||
|
|
||||||
actor.getClass().getMovementSettings(actor).mRotation[axis] = diff.valueRadians();
|
actor.getClass().getMovementSettings(actor).mRotation[axis] = diff;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool zTurn(const MWWorld::Ptr& actor, Ogre::Radian targetAngle, Ogre::Degree epsilon)
|
bool zTurn(const MWWorld::Ptr& actor, float targetAngleRadians, float epsilonRadians)
|
||||||
{
|
{
|
||||||
return smoothTurn(actor, targetAngle, 2, epsilon);
|
return smoothTurn(actor, targetAngleRadians, 2, epsilonRadians);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef OPENMW_MECHANICS_STEERING_H
|
#ifndef OPENMW_MECHANICS_STEERING_H
|
||||||
|
|
||||||
#include <OgreMath.h>
|
#include <osg/Math>
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -11,15 +11,15 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
|
||||||
// Max rotating speed, radian/sec
|
// Max rotating speed, radian/sec
|
||||||
const Ogre::Radian MAX_VEL_ANGULAR(10);
|
const float MAX_VEL_ANGULAR_RADIANS(10);
|
||||||
|
|
||||||
/// configure rotation settings for an actor to reach this target angle (eventually)
|
/// configure rotation settings for an actor to reach this target angle (eventually)
|
||||||
/// @return have we reached the target angle?
|
/// @return have we reached the target angle?
|
||||||
bool zTurn(const MWWorld::Ptr& actor, Ogre::Radian targetAngle,
|
bool zTurn(const MWWorld::Ptr& actor, float targetAngleRadians,
|
||||||
Ogre::Degree epsilon = Ogre::Degree(0.5));
|
float epsilonRadians = osg::DegreesToRadians(0.5));
|
||||||
|
|
||||||
bool smoothTurn(const MWWorld::Ptr& actor, Ogre::Radian targetAngle, int axis,
|
bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis,
|
||||||
Ogre::Degree epsilon = Ogre::Degree(0.5));
|
float epsilonRadians = osg::DegreesToRadians(0.5));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,9 +186,9 @@ namespace MWWorld
|
||||||
throw std::runtime_error ("movement settings not supported by class");
|
throw std::runtime_error ("movement settings not supported by class");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector3 Class::getRotationVector (const Ptr& ptr) const
|
osg::Vec3f Class::getRotationVector (const Ptr& ptr) const
|
||||||
{
|
{
|
||||||
return Ogre::Vector3 (0, 0, 0);
|
return osg::Vec3f (0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::vector<int>, bool> Class::getEquipmentSlots (const Ptr& ptr) const
|
std::pair<std::vector<int>, bool> Class::getEquipmentSlots (const Ptr& ptr) const
|
||||||
|
|
|
@ -192,7 +192,7 @@ namespace MWWorld
|
||||||
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
|
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
|
||||||
///< Return desired movement.
|
///< Return desired movement.
|
||||||
|
|
||||||
virtual Ogre::Vector3 getRotationVector (const Ptr& ptr) const;
|
virtual osg::Vec3f getRotationVector (const Ptr& ptr) const;
|
||||||
///< Return desired rotations, as euler angles.
|
///< Return desired rotations, as euler angles.
|
||||||
|
|
||||||
virtual std::pair<std::vector<int>, bool> getEquipmentSlots (const Ptr& ptr) const;
|
virtual std::pair<std::vector<int>, bool> getEquipmentSlots (const Ptr& ptr) const;
|
||||||
|
|
|
@ -206,9 +206,9 @@ namespace MWWorld
|
||||||
|
|
||||||
player.mBirthsign = mSign;
|
player.mBirthsign = mSign;
|
||||||
|
|
||||||
player.mLastKnownExteriorPosition[0] = mLastKnownExteriorPosition.x;
|
player.mLastKnownExteriorPosition[0] = mLastKnownExteriorPosition.x();
|
||||||
player.mLastKnownExteriorPosition[1] = mLastKnownExteriorPosition.y;
|
player.mLastKnownExteriorPosition[1] = mLastKnownExteriorPosition.y();
|
||||||
player.mLastKnownExteriorPosition[2] = mLastKnownExteriorPosition.z;
|
player.mLastKnownExteriorPosition[2] = mLastKnownExteriorPosition.z();
|
||||||
|
|
||||||
if (mMarkedCell)
|
if (mMarkedCell)
|
||||||
{
|
{
|
||||||
|
@ -279,9 +279,9 @@ namespace MWWorld
|
||||||
|
|
||||||
mSign = player.mBirthsign;
|
mSign = player.mBirthsign;
|
||||||
|
|
||||||
mLastKnownExteriorPosition.x = player.mLastKnownExteriorPosition[0];
|
mLastKnownExteriorPosition.x() = player.mLastKnownExteriorPosition[0];
|
||||||
mLastKnownExteriorPosition.y = player.mLastKnownExteriorPosition[1];
|
mLastKnownExteriorPosition.y() = player.mLastKnownExteriorPosition[1];
|
||||||
mLastKnownExteriorPosition.z = player.mLastKnownExteriorPosition[2];
|
mLastKnownExteriorPosition.z() = player.mLastKnownExteriorPosition[2];
|
||||||
|
|
||||||
if (player.mHasMark && !player.mMarkedCell.mPaged)
|
if (player.mHasMark && !player.mMarkedCell.mPaged)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace MWWorld
|
||||||
MWWorld::CellStore *mCellStore;
|
MWWorld::CellStore *mCellStore;
|
||||||
std::string mSign;
|
std::string mSign;
|
||||||
|
|
||||||
Ogre::Vector3 mLastKnownExteriorPosition;
|
osg::Vec3f mLastKnownExteriorPosition;
|
||||||
|
|
||||||
ESM::Position mMarkedPosition;
|
ESM::Position mMarkedPosition;
|
||||||
// If no position was marked, this is NULL
|
// If no position was marked, this is NULL
|
||||||
|
@ -61,9 +61,8 @@ namespace MWWorld
|
||||||
/// Interiors can not always be mapped to a world position. However
|
/// Interiors can not always be mapped to a world position. However
|
||||||
/// world position is still required for divine / almsivi magic effects
|
/// world position is still required for divine / almsivi magic effects
|
||||||
/// and the player arrow on the global map.
|
/// and the player arrow on the global map.
|
||||||
/// TODO: This should be stored in the savegame, too.
|
void setLastKnownExteriorPosition (const osg::Vec3f& position) { mLastKnownExteriorPosition = position; }
|
||||||
void setLastKnownExteriorPosition (const Ogre::Vector3& position) { mLastKnownExteriorPosition = position; }
|
osg::Vec3f getLastKnownExteriorPosition() const { return mLastKnownExteriorPosition; }
|
||||||
Ogre::Vector3 getLastKnownExteriorPosition() const { return mLastKnownExteriorPosition; }
|
|
||||||
|
|
||||||
void set (const ESM::NPC *player);
|
void set (const ESM::NPC *player);
|
||||||
|
|
||||||
|
|
|
@ -1585,7 +1585,7 @@ namespace MWWorld
|
||||||
if (player.getCell()->isExterior())
|
if (player.getCell()->isExterior())
|
||||||
{
|
{
|
||||||
ESM::Position pos = player.getRefData().getPosition();
|
ESM::Position pos = player.getRefData().getPosition();
|
||||||
mPlayer->setLastKnownExteriorPosition(Ogre::Vector3(pos.pos));
|
mPlayer->setLastKnownExteriorPosition(pos.asVec3());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.getClass().getNpcStats(player).isWerewolf())
|
if (player.getClass().getNpcStats(player).isWerewolf())
|
||||||
|
@ -2324,20 +2324,19 @@ namespace MWWorld
|
||||||
return mPhysics->getLineOfSight(actor, targetActor);
|
return mPhysics->getLineOfSight(actor, targetActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
float World::getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist)
|
float World::getDistToNearestRayHit(const osg::Vec3f& from, const osg::Vec3f& dir, float maxDist)
|
||||||
{
|
{
|
||||||
osg::Vec3f from_ (from.x, from.y, from.z);
|
osg::Vec3f to (dir);
|
||||||
osg::Vec3f to_ (dir.x, dir.y, dir.z);
|
to.normalize();
|
||||||
to_.normalize();
|
to = from + (to * maxDist);
|
||||||
to_ = from_ + (to_ * maxDist);
|
|
||||||
|
|
||||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(from_, to_, MWWorld::Ptr(),
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(from, to, MWWorld::Ptr(),
|
||||||
MWPhysics::CollisionType_World|MWPhysics::CollisionType_HeightMap);
|
MWPhysics::CollisionType_World|MWPhysics::CollisionType_HeightMap);
|
||||||
|
|
||||||
if (!result.mHit)
|
if (!result.mHit)
|
||||||
return maxDist;
|
return maxDist;
|
||||||
else
|
else
|
||||||
return (result.mHitPos - from_).length();
|
return (result.mHitPos - from).length();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::enableActorCollision(const MWWorld::Ptr& actor, bool enable)
|
void World::enableActorCollision(const MWWorld::Ptr& actor, bool enable)
|
||||||
|
@ -2731,7 +2730,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result)
|
bool World::findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, osg::Vec3f& result)
|
||||||
{
|
{
|
||||||
if (cell->isExterior())
|
if (cell->isExterior())
|
||||||
return false;
|
return false;
|
||||||
|
@ -2762,7 +2761,7 @@ namespace MWWorld
|
||||||
if (ref.mRef.getDestCell().empty())
|
if (ref.mRef.getDestCell().empty())
|
||||||
{
|
{
|
||||||
ESM::Position pos = ref.mRef.getDoorDest();
|
ESM::Position pos = ref.mRef.getDoorDest();
|
||||||
result = Ogre::Vector3(pos.pos);
|
result = pos.asVec3();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2822,7 +2821,7 @@ namespace MWWorld
|
||||||
|
|
||||||
if (ref.mRef.getDestCell().empty())
|
if (ref.mRef.getDestCell().empty())
|
||||||
{
|
{
|
||||||
Ogre::Vector3 worldPos = Ogre::Vector3(ref.mRef.getDoorDest().pos);
|
osg::Vec3f worldPos = ref.mRef.getDoorDest().asVec3();
|
||||||
return getClosestMarkerFromExteriorPosition(worldPos, id);
|
return getClosestMarkerFromExteriorPosition(worldPos, id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2838,7 +2837,7 @@ namespace MWWorld
|
||||||
return MWWorld::Ptr();
|
return MWWorld::Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr World::getClosestMarkerFromExteriorPosition( const Ogre::Vector3 worldPos, const std::string &id ) {
|
MWWorld::Ptr World::getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ) {
|
||||||
MWWorld::Ptr closestMarker;
|
MWWorld::Ptr closestMarker;
|
||||||
float closestDistance = FLT_MAX;
|
float closestDistance = FLT_MAX;
|
||||||
|
|
||||||
|
@ -2847,8 +2846,8 @@ namespace MWWorld
|
||||||
for (std::vector<MWWorld::Ptr>::iterator it2 = markers.begin(); it2 != markers.end(); ++it2)
|
for (std::vector<MWWorld::Ptr>::iterator it2 = markers.begin(); it2 != markers.end(); ++it2)
|
||||||
{
|
{
|
||||||
ESM::Position pos = it2->getRefData().getPosition();
|
ESM::Position pos = it2->getRefData().getPosition();
|
||||||
Ogre::Vector3 markerPos = Ogre::Vector3(pos.pos);
|
osg::Vec3f markerPos = pos.asVec3();
|
||||||
float distance = worldPos.squaredDistance(markerPos);
|
float distance = (worldPos - markerPos).length2();
|
||||||
if (distance < closestDistance)
|
if (distance < closestDistance)
|
||||||
{
|
{
|
||||||
closestDistance = distance;
|
closestDistance = distance;
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace MWWorld
|
||||||
float feetToGameUnits(float feet);
|
float feetToGameUnits(float feet);
|
||||||
|
|
||||||
MWWorld::Ptr getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id );
|
MWWorld::Ptr getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id );
|
||||||
MWWorld::Ptr getClosestMarkerFromExteriorPosition( const Ogre::Vector3 worldPos, const std::string &id );
|
MWWorld::Ptr getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -508,7 +508,7 @@ namespace MWWorld
|
||||||
virtual bool getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor);
|
virtual bool getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor);
|
||||||
///< get Line of Sight (morrowind stupid implementation)
|
///< get Line of Sight (morrowind stupid implementation)
|
||||||
|
|
||||||
virtual float getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist);
|
virtual float getDistToNearestRayHit(const osg::Vec3f& from, const osg::Vec3f& dir, float maxDist);
|
||||||
|
|
||||||
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable);
|
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable);
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ namespace MWWorld
|
||||||
// Are we in an exterior or pseudo-exterior cell and it's night?
|
// Are we in an exterior or pseudo-exterior cell and it's night?
|
||||||
virtual bool isDark() const;
|
virtual bool isDark() const;
|
||||||
|
|
||||||
virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result);
|
virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, osg::Vec3f& result);
|
||||||
|
|
||||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||||
/// @note id must be lower case
|
/// @note id must be lower case
|
||||||
|
|
Loading…
Reference in a new issue