Various math code ported to osg

c++11
scrawl 10 years ago
parent 0cc9b1bb40
commit 7bacb9418d

@ -11,14 +11,6 @@
#include "../mwrender/rendermode.hpp"
namespace Ogre
{
class Vector2;
class Vector3;
class Quaternion;
class Image;
}
namespace osg
{
class Vec3f;
@ -423,7 +415,7 @@ namespace MWBase
virtual bool getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor) = 0;
///< 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;
@ -497,7 +489,7 @@ namespace MWBase
// Are we in an exterior or pseudo-exterior cell and it's night?
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)
/// @note id must be lower case

@ -580,10 +580,10 @@ namespace MWClass
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);
Ogre::Vector3 vec(movement.mRotation);
osg::Vec3f vec(movement.mRotation[0], movement.mRotation[1], movement.mRotation[2]);
movement.mRotation[0] = 0.0f;
movement.mRotation[1] = 0.0f;
movement.mRotation[2] = 0.0f;

@ -113,7 +113,7 @@ namespace MWClass
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
///< 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.
float getSpeed (const MWWorld::Ptr& ptr) const;

@ -961,10 +961,10 @@ namespace MWClass
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);
Ogre::Vector3 vec(movement.mRotation);
osg::Vec3f vec(movement.mRotation[0], movement.mRotation[1], movement.mRotation[2]);
movement.mRotation[0] = 0.0f;
movement.mRotation[1] = 0.0f;
movement.mRotation[2] = 0.0f;

@ -105,7 +105,7 @@ namespace MWClass
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
///< 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.
virtual float getCapacity (const MWWorld::Ptr& ptr) const;

@ -394,7 +394,7 @@ namespace MWGui
}
if (mIsDrowning)
mDrowningFlashTheta += dt * Ogre::Math::TWO_PI;
mDrowningFlashTheta += dt * osg::PI*2;
}
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)

@ -169,8 +169,7 @@ namespace MWGui
if (!interior)
{
ESM::Position playerPos = player.getRefData().getPosition();
float d = Ogre::Vector3(pos.pos[0], pos.pos[1], 0).distance(
Ogre::Vector3(playerPos.pos[0], playerPos.pos[1], 0));
float d = (osg::Vec3f(pos.pos[0], pos.pos[1], 0) - osg::Vec3f(playerPos.pos[0], playerPos.pos[1], 0)).length();
int hours = static_cast<int>(d /MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTravelTimeMult")->getFloat());
for(int i = 0;i < hours;i++)
{

@ -992,12 +992,12 @@ namespace MWGui
mMap->setCellPrefix (cell->getCell()->mName );
mHud->setCellPrefix (cell->getCell()->mName );
Ogre::Vector3 worldPos;
osg::Vec3f worldPos;
if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos))
worldPos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition();
else
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& 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)
return;
@ -1081,7 +1081,7 @@ namespace MWMechanics
// AI and magic effects update
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;
iter->second->getCharacterController()->setActive(inProcessingRange);
@ -1151,7 +1151,7 @@ namespace MWMechanics
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
{
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)
continue;
@ -1236,7 +1236,7 @@ namespace MWMechanics
continue;
// 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))
{
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);
// 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;
else
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;

@ -35,18 +35,18 @@ namespace
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 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();
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;
// 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;
dir.z = 0;
dir.normalise();
osg::Vec3f dir = to - from;
dir.z() = 0;
dir.normalize();
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
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;
}
@ -95,7 +95,7 @@ namespace MWMechanics
bool mAttack;
bool mFollowTarget;
bool mCombatMove;
Ogre::Vector3 mLastTargetPos;
osg::Vec3f mLastTargetPos;
const MWWorld::CellStore* mCell;
boost::shared_ptr<Action> mCurrentAction;
float mActionCooldown;
@ -104,7 +104,7 @@ namespace MWMechanics
bool mMinMaxAttackDurationInitialised;
bool mForceNoShortcut;
ESM::Position mShortcutFailPos;
Ogre::Vector3 mLastActorPos;
osg::Vec3f mLastActorPos;
MWMechanics::Movement mMovement;
AiCombatStorage():
@ -231,12 +231,12 @@ namespace MWMechanics
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(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;
@ -450,12 +450,12 @@ namespace MWMechanics
*/
ESM::Position pos = actor.getRefData().getPosition();
Ogre::Vector3 vActorPos(pos.pos);
Ogre::Vector3 vTargetPos(target.getRefData().getPosition().pos);
Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos;
osg::Vec3f vActorPos(pos.asVec3());
osg::Vec3f vTargetPos(target.getRefData().getPosition().asVec3());
osg::Vec3f vDirToTarget = vTargetPos - vActorPos;
float distToTarget = vDirToTarget.length();
Ogre::Vector3& lastActorPos = storage.mLastActorPos;
osg::Vec3f& lastActorPos = storage.mLastActorPos;
bool& followTarget = storage.mFollowTarget;
bool isStuck = false;
@ -496,8 +496,8 @@ namespace MWMechanics
// note: in getZAngleToDir if we preserve dir.z then horizontal angle can be inaccurate
if (distantCombat)
{
Ogre::Vector3& lastTargetPos = storage.mLastTargetPos;
Ogre::Vector3 vAimDir = AimDirToMovingTarget(actor, target, lastTargetPos, tReaction, weaptype, strength);
osg::Vec3f& lastTargetPos = storage.mLastTargetPos;
osg::Vec3f vAimDir = AimDirToMovingTarget(actor, target, lastTargetPos, tReaction, weaptype, strength);
lastTargetPos = vTargetPos;
movement.mRotation[0] = getXAngleToDir(vAimDir);
movement.mRotation[2] = getZAngleToDir(vAimDir);
@ -553,12 +553,12 @@ namespace MWMechanics
ESM::Position& shortcutFailPos = storage.mShortcutFailPos;
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);
// 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
preferShortcut = checkWayIsClear(vActorPos, vTargetPos, Ogre::Vector3(vDirToTarget.x, vDirToTarget.y, 0).length() > maxAvoidDist*1.5? maxAvoidDist : maxAvoidDist/2);
float maxAvoidDist = tReaction * speed + speed / MAX_VEL_ANGULAR_RADIANS * 2; // *2 - for reliability
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
@ -594,7 +594,7 @@ namespace MWMechanics
// get point just before target
std::list<ESM::Pathgrid::Point>::const_iterator pntIter = --mPathFinder.getPath().end();
--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(distToTarget <= (vTargetPos - vBeforeTarget).length())
@ -668,7 +668,7 @@ namespace MWMechanics
actor.getClass().getMovementSettings(actor).mPosition[1] = 0.1f;
// change the angle a bit, too
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)
followTarget = false;
@ -680,14 +680,14 @@ namespace MWMechanics
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;
if(!mPathFinder.getPath().empty())
{
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
Ogre::Vector3 currPathTarget(PathFinder::MakeOgreVector3(lastPt));
osg::Vec3f currPathTarget(PathFinder::MakeOsgVec3(lastPt));
dist = (newPathTarget - currPathTarget).length();
}
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 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
Ogre::Vector3 vActorPos = Ogre::Vector3(actor.getRefData().getPosition().pos);
Ogre::Vector3 vTargetPos = Ogre::Vector3(target.getRefData().getPosition().pos);
Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos;
osg::Vec3f vActorPos = actor.getRefData().getPosition().asVec3();
osg::Vec3f vTargetPos = target.getRefData().getPosition().asVec3();
osg::Vec3f vDirToTarget = vTargetPos - vActorPos;
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
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());
float velDir = vTargetMoveDir.dotProduct(vDirToTarget.normalisedCopy());
vPerpToDir.normalize();
osg::Vec3f vDirToTargetNormalized = vDirToTarget;
vDirToTargetNormalized.normalize();
// dot product
float velPerp = vTargetMoveDir * vPerpToDir;
float velDir = vTargetMoveDir * vDirToTargetNormalized;
// time to collision between target and projectile
float t_collision;
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)
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
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 (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
&& MWBase::Environment::get().getWorld()->getLOS(actor, target))
mActive = true;
@ -137,7 +137,7 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, AiState& state, float duratio
// turn towards target anyway
float directionX = target.getRefData().getPosition().pos[0] - actor.getRefData().getPosition().pos[0];
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
{

@ -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[1] = 1;
// 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
@ -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
}
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;
}

@ -165,7 +165,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, AiState& state,float durati
std::list<AiPackage *>::iterator itActualCombat;
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();)
{
@ -183,7 +183,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, AiState& state,float durati
{
const ESM::Position &targetPos = target.getRefData().getPosition();
float distTo = (Ogre::Vector3(targetPos.pos) - vActorPos).length();
float distTo = (targetPos.asVec3() - vActorPos).length();
if (distTo < nearestDist)
{
nearestDist = distTo;
@ -258,7 +258,7 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor)
return; // already in combat with this actor
}
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
{
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.
// 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.
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;
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
@ -106,7 +106,7 @@ namespace MWMechanics
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;
return false;
@ -119,7 +119,7 @@ namespace MWMechanics
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;
// does not do any validation on the travel target (whether it's in air, inside collision geometry, etc),
// that is the user's responsibility

@ -48,7 +48,7 @@ namespace MWMechanics
{
// the z rotation angle (degrees) we want to reach
// used every frame when mRotate is true
Ogre::Radian mTargetAngle;
float mTargetAngleRadians;
bool mRotate;
float mReaction; // update some actions infrequently
@ -69,7 +69,7 @@ namespace MWMechanics
PathFinder mPathFinder;
AiWanderStorage():
mTargetAngle(0),
mTargetAngleRadians(0),
mRotate(false),
mReaction(0),
mSaidGreeting(AiWander::Greet_None),
@ -101,7 +101,7 @@ namespace MWMechanics
mTrimCurrentNode = false;
mHasReturnPosition = false;
mReturnPosition = Ogre::Vector3(0,0,0);
mReturnPosition = osg::Vec3f(0,0,0);
if(mDistance < 0)
mDistance = 0;
@ -231,7 +231,7 @@ namespace MWMechanics
if(walking) // have not yet reached the destination
{
// 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;
// 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[1] = 0.1f;
// 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
}
@ -275,14 +275,14 @@ namespace MWMechanics
}
Ogre::Radian& targetAngle = storage.mTargetAngle;
float& targetAngleRadians = storage.mTargetAngleRadians;
bool& rotate = storage.mRotate;
if (rotate)
{
// Reduce the turning animation glitch by using a *HUGE* value of
// epsilon... TODO: a proper fix might be in either the physics or the
// animation subsystem
if (zTurn(actor, targetAngle, Ogre::Degree(5)))
if (zTurn(actor, targetAngleRadians, osg::DegreesToRadians(5.f)))
rotate = false;
}
@ -340,7 +340,7 @@ namespace MWMechanics
// Only say Idle voices when player is in LOS
// A bit counterintuitive, likely vanilla did this to reduce the appearance of
// 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
&& MWBase::Environment::get().getWorld()->getLOS(player, actor))
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
if (cellChange)
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;
idleNow = false;
@ -435,9 +435,9 @@ namespace MWMechanics
helloDistance *= iGreetDistanceMultiplier;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
Ogre::Vector3 playerPos(player.getRefData().getPosition().pos);
Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos);
float playerDistSqr = playerPos.squaredDistance(actorPos);
osg::Vec3f playerPos(player.getRefData().getPosition().asVec3());
osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
float playerDistSqr = (playerPos - actorPos).length2();
int& greetingTimer = storage.mGreetingTimer;
if (greetingState == Greet_None)
@ -471,10 +471,10 @@ namespace MWMechanics
if(!rotate)
{
Ogre::Vector3 dir = playerPos - actorPos;
osg::Vec3f dir = playerPos - actorPos;
float faceAngleRadians = std::atan2(dir.x, dir.y);
targetAngle = faceAngleRadians;
float faceAngleRadians = std::atan2(dir.x(), dir.y());
targetAngleRadians = faceAngleRadians;
rotate = true;
}
@ -501,10 +501,8 @@ namespace MWMechanics
assert(mAllowedNodes.size());
unsigned int randNode = Misc::Rng::rollDice(mAllowedNodes.size());
// NOTE: initially constructed with local (i.e. cell) co-ordinates
Ogre::Vector3 destNodePos(PathFinder::MakeOgreVector3(mAllowedNodes[randNode]));
// convert dest to use world co-ordinates
ESM::Pathgrid::Point dest(PathFinder::MakePathgridPoint(destNodePos));
ESM::Pathgrid::Point dest(mAllowedNodes[randNode]);
if (currentCell->getCell()->isExterior())
{
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)
{
@ -652,8 +650,8 @@ namespace MWMechanics
ESM::Pathgrid::Point dest = mAllowedNodes[index];
// apply a slight offset to prevent overcrowding
dest.mX += static_cast<int>(Ogre::Math::RangeRandom(-64, 64));
dest.mY += static_cast<int>(Ogre::Math::RangeRandom(-64, 64));
dest.mX += static_cast<int>(Misc::Rng::rollProbability() * 128 - 64);
dest.mY += static_cast<int>(Misc::Rng::rollProbability() * 128 - 64);
if (actor.getCell()->isExterior())
{
@ -670,7 +668,7 @@ namespace MWMechanics
{
if (!mStoredInitialActorPosition)
{
mInitialActorPosition = Ogre::Vector3(actor.getRefData().getPosition().pos);
mInitialActorPosition = actor.getRefData().getPosition().asVec3();
mStoredInitialActorPosition = true;
}
@ -700,7 +698,7 @@ namespace MWMechanics
}
// convert npcPos to local (i.e. cell) co-ordinates
Ogre::Vector3 npcPos(mInitialActorPosition);
osg::Vec3f npcPos(mInitialActorPosition);
npcPos[0] = npcPos[0] - cellXOffset;
npcPos[1] = npcPos[1] - cellYOffset;
@ -708,19 +706,19 @@ namespace MWMechanics
// NOTE: mPoints and mAllowedNodes are in local co-ordinates
for(unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++)
{
Ogre::Vector3 nodePos(PathFinder::MakeOgreVector3(pathgrid->mPoints[counter]));
if(npcPos.squaredDistance(nodePos) <= mDistance * mDistance)
osg::Vec3f nodePos(PathFinder::MakeOsgVec3(pathgrid->mPoints[counter]));
if((npcPos - nodePos).length2() <= mDistance * mDistance)
mAllowedNodes.push_back(pathgrid->mPoints[counter]);
}
if(!mAllowedNodes.empty())
{
Ogre::Vector3 firstNodePos(PathFinder::MakeOgreVector3(mAllowedNodes[0]));
float closestNode = npcPos.squaredDistance(firstNodePos);
osg::Vec3f firstNodePos(PathFinder::MakeOsgVec3(mAllowedNodes[0]));
float closestNode = (npcPos - firstNodePos).length2();
unsigned int index = 0;
for(unsigned int counterThree = 1; counterThree < mAllowedNodes.size(); counterThree++)
{
Ogre::Vector3 nodePos(PathFinder::MakeOgreVector3(mAllowedNodes[counterThree]));
float tempDist = npcPos.squaredDistance(nodePos);
osg::Vec3f nodePos(PathFinder::MakeOsgVec3(mAllowedNodes[counterThree]));
float tempDist = (npcPos - nodePos).length2();
if(tempDist < closestNode)
index = counterThree;
}
@ -737,7 +735,7 @@ namespace MWMechanics
std::vector<PathDistance> nodeDistances;
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)));
}
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
/** 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;
@ -83,9 +83,9 @@ namespace MWMechanics
bool mHasReturnPosition; // NOTE: Could be removed if mReturnPosition was initialized to actor position,
// if we had the actor in the AiWander constructor...
Ogre::Vector3 mReturnPosition;
osg::Vec3f mReturnPosition;
Ogre::Vector3 mInitialActorPosition;
osg::Vec3f mInitialActorPosition;
bool mStoredInitialActorPosition;

@ -1531,7 +1531,7 @@ void CharacterController::update(float duration)
if(mHitState != CharState_None && mJumpState == JumpState_None)
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);
@ -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.
// 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.
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;
else if(rot.z < 0.0f)
else if(rot.z() < 0.0f)
movestate = CharState_TurnLeft;
}
}
@ -1782,18 +1782,18 @@ void CharacterController::update(float duration)
if (mMovementState == CharState_TurnLeft || mMovementState == CharState_TurnRight)
{
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)
{
rot *= Ogre::Math::RadiansToDegrees(1.0f);
rot *= osg::RadiansToDegrees(1.0f);
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
world->rotateObject(mPtr, rot.x, rot.y, 0.0f, true);
world->rotateObject(mPtr, rot.x(), rot.y(), 0.0f, true);
if (!mMovementAnimationControlled)
world->queueMovement(mPtr, vec);

@ -15,9 +15,9 @@ namespace
// 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
//
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
@ -26,7 +26,7 @@ namespace
//
// 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())
return -1;
@ -52,7 +52,7 @@ namespace
// Chooses a reachable end pathgrid point. start is assumed reachable.
std::pair<int, bool> getClosestReachablePoint(const ESM::Pathgrid* grid,
const MWWorld::CellStore *cell,
Ogre::Vector3 pos, int start)
const osg::Vec3f pos, int start)
{
if(!grid || grid->mPoints.empty())
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 outside the wall
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
if(startNode != -1)
{
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);
// this shouldn't really happen, but just in case
@ -279,7 +279,7 @@ namespace MWMechanics
float directionX = nextPoint.mX - x;
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)

@ -44,6 +44,7 @@ namespace MWMechanics
bool checkPathCompleted(float x, float y, float tolerance=32.f);
///< \Returns true if we are within \a tolerance units of the last path point.
/// In degrees
float getZAngleToNext(float x, float y) 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]));
}
/// 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
static ESM::Pathgrid::Point MakePathgridPoint(const ESM::Position& p)
{

@ -10,37 +10,37 @@
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]);
Ogre::Radian diff (targetAngle - currentAngle);
if (diff >= Ogre::Degree(180))
float currentAngle (actor.getRefData().getPosition().rot[axis]);
float diff (targetAngleRadians - currentAngle);
if (diff >= osg::DegreesToRadians(180.f))
{
// 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.
// Use epsilon to prevent jerkiness.
if (absDiff < epsilon)
if (absDiff < epsilonRadians)
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)
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;
}
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
#include <OgreMath.h>
#include <osg/Math>
namespace MWWorld
{
@ -11,15 +11,15 @@ namespace MWMechanics
{
// 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)
/// @return have we reached the target angle?
bool zTurn(const MWWorld::Ptr& actor, Ogre::Radian targetAngle,
Ogre::Degree epsilon = Ogre::Degree(0.5));
bool zTurn(const MWWorld::Ptr& actor, float targetAngleRadians,
float epsilonRadians = osg::DegreesToRadians(0.5));
bool smoothTurn(const MWWorld::Ptr& actor, Ogre::Radian targetAngle, int axis,
Ogre::Degree epsilon = Ogre::Degree(0.5));
bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis,
float epsilonRadians = osg::DegreesToRadians(0.5));
}

@ -186,9 +186,9 @@ namespace MWWorld
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

@ -192,7 +192,7 @@ namespace MWWorld
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
///< 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.
virtual std::pair<std::vector<int>, bool> getEquipmentSlots (const Ptr& ptr) const;

@ -206,9 +206,9 @@ namespace MWWorld
player.mBirthsign = mSign;
player.mLastKnownExteriorPosition[0] = mLastKnownExteriorPosition.x;
player.mLastKnownExteriorPosition[1] = mLastKnownExteriorPosition.y;
player.mLastKnownExteriorPosition[2] = mLastKnownExteriorPosition.z;
player.mLastKnownExteriorPosition[0] = mLastKnownExteriorPosition.x();
player.mLastKnownExteriorPosition[1] = mLastKnownExteriorPosition.y();
player.mLastKnownExteriorPosition[2] = mLastKnownExteriorPosition.z();
if (mMarkedCell)
{
@ -279,9 +279,9 @@ namespace MWWorld
mSign = player.mBirthsign;
mLastKnownExteriorPosition.x = player.mLastKnownExteriorPosition[0];
mLastKnownExteriorPosition.y = player.mLastKnownExteriorPosition[1];
mLastKnownExteriorPosition.z = player.mLastKnownExteriorPosition[2];
mLastKnownExteriorPosition.x() = player.mLastKnownExteriorPosition[0];
mLastKnownExteriorPosition.y() = player.mLastKnownExteriorPosition[1];
mLastKnownExteriorPosition.z() = player.mLastKnownExteriorPosition[2];
if (player.mHasMark && !player.mMarkedCell.mPaged)
{

@ -37,7 +37,7 @@ namespace MWWorld
MWWorld::CellStore *mCellStore;
std::string mSign;
Ogre::Vector3 mLastKnownExteriorPosition;
osg::Vec3f mLastKnownExteriorPosition;
ESM::Position mMarkedPosition;
// 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
/// world position is still required for divine / almsivi magic effects
/// and the player arrow on the global map.
/// TODO: This should be stored in the savegame, too.
void setLastKnownExteriorPosition (const Ogre::Vector3& position) { mLastKnownExteriorPosition = position; }
Ogre::Vector3 getLastKnownExteriorPosition() const { return mLastKnownExteriorPosition; }
void setLastKnownExteriorPosition (const osg::Vec3f& position) { mLastKnownExteriorPosition = position; }
osg::Vec3f getLastKnownExteriorPosition() const { return mLastKnownExteriorPosition; }
void set (const ESM::NPC *player);

@ -1585,7 +1585,7 @@ namespace MWWorld
if (player.getCell()->isExterior())
{
ESM::Position pos = player.getRefData().getPosition();
mPlayer->setLastKnownExteriorPosition(Ogre::Vector3(pos.pos));
mPlayer->setLastKnownExteriorPosition(pos.asVec3());
}
if (player.getClass().getNpcStats(player).isWerewolf())
@ -2324,20 +2324,19 @@ namespace MWWorld
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.x, dir.y, dir.z);
to_.normalize();
to_ = from_ + (to_ * maxDist);
osg::Vec3f to (dir);
to.normalize();
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);
if (!result.mHit)
return maxDist;
else
return (result.mHitPos - from_).length();
return (result.mHitPos - from).length();
}
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())
return false;
@ -2762,7 +2761,7 @@ namespace MWWorld
if (ref.mRef.getDestCell().empty())
{
ESM::Position pos = ref.mRef.getDoorDest();
result = Ogre::Vector3(pos.pos);
result = pos.asVec3();
return true;
}
else
@ -2822,7 +2821,7 @@ namespace MWWorld
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);
}
else
@ -2838,7 +2837,7 @@ namespace MWWorld
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;
float closestDistance = FLT_MAX;
@ -2847,8 +2846,8 @@ namespace MWWorld
for (std::vector<MWWorld::Ptr>::iterator it2 = markers.begin(); it2 != markers.end(); ++it2)
{
ESM::Position pos = it2->getRefData().getPosition();
Ogre::Vector3 markerPos = Ogre::Vector3(pos.pos);
float distance = worldPos.squaredDistance(markerPos);
osg::Vec3f markerPos = pos.asVec3();
float distance = (worldPos - markerPos).length2();
if (distance < closestDistance)
{
closestDistance = distance;

@ -156,7 +156,7 @@ namespace MWWorld
float feetToGameUnits(float feet);
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:
@ -508,7 +508,7 @@ namespace MWWorld
virtual bool getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor);
///< 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);
@ -583,7 +583,7 @@ namespace MWWorld
// Are we in an exterior or pseudo-exterior cell and it's night?
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)
/// @note id must be lower case

Loading…
Cancel
Save