1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-01 22:15:33 +00:00

Add a first-person view mode to NpcAnimation

And use it instead of showing/hiding the player.
This commit is contained in:
Chris Robinson 2013-04-09 15:10:14 -07:00
parent 029d565727
commit a700c50e84
4 changed files with 65 additions and 16 deletions

View file

@ -476,7 +476,7 @@ void Animation::play(const std::string &groupname, const std::string &start, con
Ogre::Vector3 Animation::runAnimation(float timepassed)
{
Ogre::Vector3 movement = Ogre::Vector3::ZERO;
Ogre::Vector3 movement(0.0f);
timepassed *= mAnimSpeedMult;
while(mCurrentAnim && mPlaying)

View file

@ -130,7 +130,40 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
skelnames.push_back("meshes\\"+Misc::StringUtils::lowerCase(mNpc->mModel));
setAnimationSources(skelnames);
updateParts(true);
forceUpdate();
}
void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
{
assert(viewMode != VM_HeadOnly);
mViewMode = viewMode;
/* FIXME: Enable this once first-person animations work. */
#if 0
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace);
bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0;
std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif");
std::vector<std::string> skelnames(1, smodel);
if(!mNpc->isMale() && !isBeast)
skelnames.push_back("meshes\\base_anim_female.nif");
else if(mBodyPrefix.find("argonian") != std::string::npos)
skelnames.push_back("meshes\\argonian_swimkna.nif");
if(mNpc->mModel.length() > 0)
skelnames.push_back("meshes\\"+Misc::StringUtils::lowerCase(mNpc->mModel));
if(mViewMode == VM_FirstPerson)
{
smodel = (!isBeast ? "meshes\\base_anim.1st.nif" : "meshes\\base_animkna.1st.nif");
skelnames.push_back(smodel);
}
setAnimationSources(skelnames);
#endif
for(size_t i = 0;i < sPartListSize;i++)
removeIndividualPart(i);
forceUpdate();
}
void NpcAnimation::updateParts(bool forceupdate)
@ -254,13 +287,18 @@ void NpcAnimation::updateParts(bool forceupdate)
reserveIndividualPart(slotlist[i].reserveParts[res], slotlist[i].slot, prio);
}
if(mPartPriorities[ESM::PRT_Head] < 1)
addOrReplaceIndividualPart(ESM::PRT_Head, -1,1, mHeadModel);
if(mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1)
addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1, mHairModel);
if(mViewMode != VM_FirstPerson)
{
if(mPartPriorities[ESM::PRT_Head] < 1)
addOrReplaceIndividualPart(ESM::PRT_Head, -1,1, mHeadModel);
if(mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1)
addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1, mHairModel);
}
if(mViewMode == VM_HeadOnly)
return;
/* FIXME: Remove this once we figure out how to show what in first-person */
if(mViewMode == VM_FirstPerson)
return;
static const struct {
ESM::PartReferenceType type;
@ -288,6 +326,7 @@ void NpcAnimation::updateParts(bool forceupdate)
{ ESM::PRT_Tail, { "tail", "" } }
};
const char *ext = (mViewMode == VM_FirstPerson) ? ".1st" : "";
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
for(size_t i = 0;i < sizeof(PartTypeList)/sizeof(PartTypeList[0]);i++)
{
@ -298,14 +337,14 @@ void NpcAnimation::updateParts(bool forceupdate)
if(!mNpc->isMale())
{
part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[0]);
part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[0]+ext);
if(part == 0)
part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[1]);
part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[1]+ext);
}
if(part == 0)
part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[0]);
part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[0]+ext);
if(part == 0)
part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[1]);
part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[1]+ext);
if(part)
addOrReplaceIndividualPart(PartTypeList[i].type, -1,1, "meshes\\"+part->mModel);
@ -431,6 +470,7 @@ bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority,
void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts)
{
const char *ext = (mViewMode == VM_FirstPerson) ? ".1st" : "";
for(std::size_t i = 0; i < parts.size(); i++)
{
const ESM::PartReference &part = parts[i];
@ -440,9 +480,9 @@ void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::
const ESM::BodyPart *bodypart = 0;
if(!mNpc->isMale())
bodypart = partStore.search(part.mFemale);
bodypart = partStore.search(part.mFemale+ext);
if(!bodypart)
bodypart = partStore.search(part.mMale);
bodypart = partStore.search(part.mMale+ext);
if(bodypart)
addOrReplaceIndividualPart(part.mPart, group, priority, "meshes\\"+bodypart->mModel);

View file

@ -28,6 +28,7 @@ struct PartInfo {
enum ViewMode {
VM_Normal,
VM_FirstPerson,
VM_HeadOnly
};
@ -84,6 +85,8 @@ public:
virtual Ogre::Vector3 runAnimation(float timepassed);
void setViewMode(ViewMode viewMode);
void forceUpdate()
{ updateParts(true); }
};

View file

@ -124,8 +124,6 @@ namespace MWRender
MWBase::Environment::get().getWindowManager ()->showCrosshair
(!MWBase::Environment::get().getWindowManager ()->isGuiMode () && (mFirstPersonView && !mVanity.enabled && !mPreviewMode));
/// \fixme We shouldn't hide the whole model, just certain components of the character (head, chest, feet, etc)
mPlayerNode->setVisible(mVanity.enabled || mPreviewMode || !mFirstPersonView);
if (mFirstPersonView && !mVanity.enabled) {
return;
}
@ -139,6 +137,8 @@ namespace MWRender
void Player::toggleViewMode()
{
mFirstPersonView = !mFirstPersonView;
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ?
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson);
if (mFirstPersonView) {
mCamera->setPosition(0.f, 0.f, 0.f);
setLowHeight(false);
@ -168,6 +168,9 @@ namespace MWRender
mVanity.enabled = enable;
mVanity.forced = force && enable;
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ?
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson);
float offset = mPreviewCam.offset;
Ogre::Vector3 rot(0.f, 0.f, 0.f);
if (mVanity.enabled) {
@ -194,6 +197,8 @@ namespace MWRender
return;
}
mPreviewMode = enable;
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ?
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson);
float offset = mCamera->getPosition().z;
if (mPreviewMode) {
mMainCam.offset = offset;
@ -305,7 +310,8 @@ namespace MWRender
delete mAnimation;
mAnimation = anim;
mPlayerNode->setVisible(mVanity.enabled || mPreviewMode || !mFirstPersonView);
mAnimation->setViewMode((mVanity.enabled || mPreviewMode || !mFirstPersonView) ?
NpcAnimation::VM_Normal : NpcAnimation::VM_FirstPerson);
}
void Player::setHeight(float height)