diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 4a3344e22..c99e42662 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -60,7 +60,7 @@ namespace MWRender mNode = renderRoot->createChildSceneNode(); mAnimation = new NpcAnimation(mCharacter, mNode, - MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0); + MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0, renderHeadOnly()); mNode->setVisible (false); @@ -102,7 +102,7 @@ namespace MWRender delete mAnimation; mAnimation = new NpcAnimation(mCharacter, mNode, - MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0); + MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0, renderHeadOnly()); mNode->setVisible (false); @@ -161,7 +161,7 @@ namespace MWRender RaceSelectionPreview::RaceSelectionPreview() : CharacterPreview(MWBase::Environment::get().getWorld()->getPlayer().getPlayer(), - 512, 512, "CharacterHeadPreview", Ogre::Vector3(0, 120, -35), Ogre::Vector3(0,125,0)) + 512, 512, "CharacterHeadPreview", Ogre::Vector3(0, 6, -35), Ogre::Vector3(0,125,0)) , mRef(&mBase) { mBase = *mCharacter.get()->mBase; @@ -173,6 +173,8 @@ namespace MWRender mAnimation->runAnimation(0.0f); mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL); + updateCamera(); + mNode->setVisible (true); mRenderTarget->update(); mNode->setVisible (false); @@ -189,5 +191,17 @@ namespace MWRender void RaceSelectionPreview::onSetup () { mAnimation->play("idle", "start", "stop", false); + + updateCamera(); + } + + void RaceSelectionPreview::updateCamera() + { + Ogre::Vector3 scale = mNode->getScale(); + Ogre::Vector3 headOffset = mAnimation->getHeadNode()->_getDerivedPosition(); + headOffset = mNode->convertLocalToWorldPosition(headOffset); + + mCamera->setPosition(headOffset + mPosition * scale); + mCamera->lookAt(headOffset + mPosition*Ogre::Vector3(0,1,0) * scale); } } diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index cf1e25069..08cbd5108 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -36,6 +36,8 @@ namespace MWRender virtual void rebuild(); protected: + virtual bool renderHeadOnly() { return false; } + Ogre::TexturePtr mTexture; Ogre::RenderTarget* mRenderTarget; Ogre::Viewport* mViewport; @@ -82,6 +84,12 @@ namespace MWRender ESM::NPC mBase; MWWorld::LiveCellRef mRef; + protected: + + virtual bool renderHeadOnly() { return true; } + + void updateCamera(); + public: RaceSelectionPreview(); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index a7d5c22af..9da70beb4 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -54,7 +54,7 @@ NpcAnimation::~NpcAnimation() } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags) +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags, bool headOnly) : Animation(ptr), mStateID(-1), mTimeToChange(0), @@ -70,7 +70,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor mPants(inv.end()), mGloveL(inv.end()), mGloveR(inv.end()), - mSkirtIter(inv.end()) + mSkirtIter(inv.end()), + mHeadOnly(headOnly) { mNpc = mPtr.get()->mBase; @@ -215,7 +216,7 @@ void NpcAnimation::updateParts(bool forceupdate) if(!forceupdate) return; - for(size_t i = 0;i < slotlistsize;i++) + for(size_t i = 0;i < slotlistsize && !mHeadOnly;i++) { MWWorld::ContainerStoreIterator iter = inv.getSlot(slotlist[i].slot); @@ -252,6 +253,9 @@ void NpcAnimation::updateParts(bool forceupdate) if(mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1) addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1, mHairModel); + if (mHeadOnly) + return; + static const struct { ESM::PartReferenceType type; const char name[2][12]; @@ -449,4 +453,9 @@ void NpcAnimation::addPartGroup(int group, int priority, const std::vectorgetSkeleton()->getBone("Bip01 Head"); +} + } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index aed4868bd..5da4afef8 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -39,6 +39,7 @@ private: std::string mHeadModel; std::string mHairModel; std::string mBodyPrefix; + bool mHeadOnly; float mTimeToChange; MWWorld::ContainerStoreIterator mRobe; @@ -73,11 +74,13 @@ private: public: NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, - MWWorld::InventoryStore& inv, int visibilityFlags); + MWWorld::InventoryStore& inv, int visibilityFlags, bool headOnly=false); virtual ~NpcAnimation(); virtual Ogre::Vector3 runAnimation(float timepassed); + Ogre::Node* getHeadNode(); + void forceUpdate() { updateParts(true); } };