Use the actor's Head position for Say streams

openmw-38
Chris Robinson 9 years ago
parent a47bdecac7
commit 808f701013

@ -14,6 +14,7 @@
namespace osg namespace osg
{ {
class Vec3f; class Vec3f;
class Matrixf;
class Quat; class Quat;
class Image; class Image;
} }
@ -373,6 +374,8 @@ namespace MWBase
virtual bool isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const = 0; virtual bool isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const = 0;
virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0; virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0;
virtual osg::Matrixf getActorHeadTransform(const MWWorld::Ptr& actor) const = 0;
virtual void togglePOV() = 0; virtual void togglePOV() = 0;
virtual bool isFirstPerson() const = 0; virtual bool isFirstPerson() const = 0;
virtual void togglePreviewMode(bool enable) = 0; virtual void togglePreviewMode(bool enable) = 0;

@ -4,6 +4,8 @@
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <osg/Matrixf>
#include <components/misc/rng.hpp> #include <components/misc/rng.hpp>
#include <components/vfs/manager.hpp> #include <components/vfs/manager.hpp>
@ -397,8 +399,6 @@ namespace MWSound
try try
{ {
std::string voicefile = "Sound/"+filename; std::string voicefile = "Sound/"+filename;
const ESM::Position &pos = ptr.getRefData().getPosition();
const osg::Vec3f objpos(pos.asVec3());
Sound_Loudness *loudness; Sound_Loudness *loudness;
mVFS->normalizeFilename(voicefile); mVFS->normalizeFilename(voicefile);
@ -408,7 +408,9 @@ namespace MWSound
mPendingSaySounds[ptr] = std::make_pair(decoder, loudness); mPendingSaySounds[ptr] = std::make_pair(decoder, loudness);
else else
{ {
MWBase::SoundStreamPtr sound = playVoice(decoder, objpos, (ptr == MWMechanics::getPlayer())); MWBase::World *world = MWBase::Environment::get().getWorld();
const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans();
MWBase::SoundStreamPtr sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer()));
mActiveSaySounds[ptr] = std::make_pair(sound, loudness); mActiveSaySounds[ptr] = std::make_pair(sound, loudness);
} }
} }
@ -906,10 +908,10 @@ namespace MWSound
sound = playVoice(decoder, osg::Vec3f(), true); sound = playVoice(decoder, osg::Vec3f(), true);
else else
{ {
const ESM::Position &pos = ptr.getRefData().getPosition(); MWBase::World *world = MWBase::Environment::get().getWorld();
const osg::Vec3f objpos(pos.asVec3()); const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans();
sound = playVoice(decoder, objpos, (ptr == MWMechanics::getPlayer())); sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer()));
} }
mActiveSaySounds[ptr] = std::make_pair(sound, loudness); mActiveSaySounds[ptr] = std::make_pair(sound, loudness);
} }
@ -930,13 +932,13 @@ namespace MWSound
MWBase::SoundStreamPtr sound = sayiter->second.first; MWBase::SoundStreamPtr sound = sayiter->second.first;
if(!ptr.isEmpty() && sound->getIs3D()) if(!ptr.isEmpty() && sound->getIs3D())
{ {
const ESM::Position &pos = ptr.getRefData().getPosition(); MWBase::World *world = MWBase::Environment::get().getWorld();
const osg::Vec3f objpos(pos.asVec3()); const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans();
sound->setPosition(objpos); sound->setPosition(pos);
if(sound->getDistanceCull()) if(sound->getDistanceCull())
{ {
if((mListenerPos - objpos).length2() > 2000*2000) if((mListenerPos - pos).length2() > 2000*2000)
mOutput->stopStream(sound); mOutput->stopStream(sound);
} }
} }

@ -1038,32 +1038,30 @@ namespace MWWorld
return facedObject; return facedObject;
} }
osg::Vec3f getActorHeadPosition(const MWWorld::Ptr& actor, MWRender::RenderingManager* rendering) osg::Matrixf World::getActorHeadTransform(const MWWorld::Ptr& actor) const
{ {
osg::Vec3f origin(actor.getRefData().getPosition().asVec3()); MWRender::Animation *anim = mRendering->getAnimation(actor);
if(anim)
MWRender::Animation* anim = rendering->getAnimation(actor);
if (anim != NULL)
{ {
const osg::Node* node = anim->getNode("Head"); const osg::Node *node = anim->getNode("Head");
if (node == NULL) if(!node) node = anim->getNode("Bip01 Head");
node = anim->getNode("Bip01 Head"); if(node)
if (node != NULL)
{ {
osg::MatrixList mats = node->getWorldMatrices(); osg::MatrixList mats = node->getWorldMatrices();
if (mats.size()) if(!mats.empty())
origin = mats[0].getTrans(); return mats[0];
} }
} }
return origin; return osg::Matrixf::translate(actor.getRefData().getPosition().asVec3());
} }
std::pair<MWWorld::Ptr,osg::Vec3f> World::getHitContact(const MWWorld::Ptr &ptr, float distance) std::pair<MWWorld::Ptr,osg::Vec3f> World::getHitContact(const MWWorld::Ptr &ptr, float distance)
{ {
const ESM::Position &posdata = ptr.getRefData().getPosition(); const ESM::Position &posdata = ptr.getRefData().getPosition();
osg::Quat rot = osg::Quat(posdata.rot[0], osg::Vec3f(-1,0,0)) * osg::Quat(posdata.rot[2], osg::Vec3f(0,0,-1)); osg::Quat rot = osg::Quat(posdata.rot[0], osg::Vec3f(-1,0,0)) * osg::Quat(posdata.rot[2], osg::Vec3f(0,0,-1));
osg::Vec3f pos = getActorHeadPosition(ptr, mRendering); osg::Vec3f pos = getActorHeadTransform(ptr).getTrans();
std::pair<MWWorld::Ptr,osg::Vec3f> result = mPhysics->getHitContact(ptr, pos, rot, distance); std::pair<MWWorld::Ptr,osg::Vec3f> result = mPhysics->getHitContact(ptr, pos, rot, distance);
if(result.first.isEmpty()) if(result.first.isEmpty())
@ -2659,7 +2657,7 @@ namespace MWWorld
MWWorld::Ptr target; MWWorld::Ptr target;
float distance = 192.f; // ?? float distance = 192.f; // ??
osg::Vec3f hitPosition = actor.getRefData().getPosition().asVec3(); osg::Vec3f hitPosition = actor.getRefData().getPosition().asVec3();
osg::Vec3f origin = getActorHeadPosition(actor, mRendering); osg::Vec3f origin = getActorHeadTransform(actor).getTrans();
osg::Quat orient = osg::Quat(actor.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0)) osg::Quat orient = osg::Quat(actor.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0))
* osg::Quat(actor.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1)); * osg::Quat(actor.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1));
@ -3297,14 +3295,14 @@ namespace MWWorld
osg::Vec3f World::aimToTarget(const Ptr &actor, const MWWorld::Ptr& target) osg::Vec3f World::aimToTarget(const Ptr &actor, const MWWorld::Ptr& target)
{ {
osg::Vec3f weaponPos = getActorHeadPosition(actor, mRendering); osg::Vec3f weaponPos = getActorHeadTransform(actor).getTrans();
osg::Vec3f targetPos = mPhysics->getPosition(target); osg::Vec3f targetPos = mPhysics->getPosition(target);
return (targetPos - weaponPos); return (targetPos - weaponPos);
} }
float World::getHitDistance(const Ptr &actor, const Ptr &target) float World::getHitDistance(const Ptr &actor, const Ptr &target)
{ {
osg::Vec3f weaponPos = getActorHeadPosition(actor, mRendering); osg::Vec3f weaponPos = getActorHeadTransform(actor).getTrans();
return mPhysics->getHitDistance(weaponPos, target); return mPhysics->getHitDistance(weaponPos, target);
} }

@ -469,6 +469,8 @@ namespace MWWorld
virtual bool isWading(const MWWorld::Ptr &object) const; virtual bool isWading(const MWWorld::Ptr &object) const;
virtual bool isOnGround(const MWWorld::Ptr &ptr) const; virtual bool isOnGround(const MWWorld::Ptr &ptr) const;
virtual osg::Matrixf getActorHeadTransform(const MWWorld::Ptr& actor) const;
virtual void togglePOV(); virtual void togglePOV();
virtual bool isFirstPerson() const; virtual bool isFirstPerson() const;

Loading…
Cancel
Save