NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& _inv, int visibilityFlags) : Animation(), mStateID(-1), mInv(_inv), timeToChange(0), mVisibilityFlags(visibilityFlags), robe(mInv.end()), helmet(mInv.end()), shirt(mInv.end()), cuirass(mInv.end()), greaves(mInv.end()), leftpauldron(mInv.end()), rightpauldron(mInv.end()), boots(mInv.end()), leftglove(mInv.end()), rightglove(mInv.end()), skirtiter(mInv.end()), pants(mInv.end()) { MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>(); for (int init = 0; init < 27; init++) { mPartslots[init] = -1; //each slot is empty mPartPriorities[init] = 0; } const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const ESM::Race *race = store.races.find(ref->base->mRace); std::string hairID = ref->base->mHair; std::string headID = ref->base->mHead; headModel = "meshes\\" + store.bodyParts.find(headID)->mModel; hairModel = "meshes\\" + store.bodyParts.find(hairID)->mModel; npcName = ref->base->mName; isFemale = !!(ref->base->mFlags&ESM::NPC::Female); isBeast = !!(race->mData.mFlags&ESM::Race::Beast); bodyRaceID = "b_n_"+ref->base->mRace; std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower); mInsert = node; assert(mInsert); std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif"); mEntityList = NifOgre::NIFLoader::createEntities(mInsert, &mTextKeys, smodel); for(size_t i = 0;i < mEntityList.mEntities.size();i++) { Ogre::Entity *base = mEntityList.mEntities[i]; base->getUserObjectBindings ().setUserAny (Ogre::Any(-1)); base->setVisibilityFlags(mVisibilityFlags); bool transparent = false; for(unsigned int j=0;j < base->getNumSubEntities();++j) { Ogre::MaterialPtr mat = base->getSubEntity(j)->getMaterial(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); while (techIt.hasMoreElements()) { Ogre::Technique* tech = techIt.getNext(); Ogre::Technique::PassIterator passIt = tech->getPassIterator(); while (passIt.hasMoreElements()) { Ogre::Pass* pass = passIt.getNext(); if (pass->getDepthWriteEnabled() == false) transparent = true; } } } base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); } if(mEntityList.mSkelBase) { Ogre::AnimationStateSet *aset = mEntityList.mSkelBase->getAllAnimationStates(); Ogre::AnimationStateIterator as = aset->getAnimationStateIterator(); while(as.hasMoreElements()) { Ogre::AnimationState *state = as.getNext(); state->setEnabled(true); state->setLoop(false); } } float scale = race->mData.mHeight.mMale; if (isFemale) { scale = race->mData.mHeight.mFemale; } mInsert->scale(scale, scale, scale); updateParts(); }
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags, bool headOnly) : Animation(ptr), mStateID(-1), mTimeToChange(0), mVisibilityFlags(visibilityFlags), mRobe(inv.end()), mHelmet(inv.end()), mShirt(inv.end()), mCuirass(inv.end()), mGreaves(inv.end()), mPauldronL(inv.end()), mPauldronR(inv.end()), mBoots(inv.end()), mPants(inv.end()), mGloveL(inv.end()), mGloveR(inv.end()), mSkirtIter(inv.end()), mHeadOnly(headOnly) { mNpc = mPtr.get<ESM::NPC>()->mBase; for(size_t i = 0;i < sPartListSize;i++) { mPartslots[i] = -1; //each slot is empty mPartPriorities[i] = 0; } const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace); float scale = race->mData.mHeight.mMale; if(!mNpc->isMale()) scale = race->mData.mHeight.mFemale; node->scale(Ogre::Vector3(scale)); mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel; mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHair)->mModel; mBodyPrefix = "b_n_" + mNpc->mRace; Misc::StringUtils::toLower(mBodyPrefix); bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0; std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif"); createEntityList(node, smodel); for(size_t i = 0;i < mEntityList.mEntities.size();i++) { Ogre::Entity *base = mEntityList.mEntities[i]; base->getUserObjectBindings().setUserAny(Ogre::Any(-1)); if (mVisibilityFlags != 0) base->setVisibilityFlags(mVisibilityFlags); for(unsigned int j=0; j < base->getNumSubEntities(); ++j) { Ogre::SubEntity* subEnt = base->getSubEntity(j); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main); } } 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)); setAnimationSources(skelnames); updateParts(true); }