void operator()(Ogre::Entity *entity) const { if(mVisFlags != 0) entity->setVisibilityFlags(mVisFlags); entity->setRenderingDistance(mDist); unsigned int numsubs = entity->getNumSubEntities(); for(unsigned int i = 0;i < numsubs;++i) { Ogre::SubEntity* subEnt = entity->getSubEntity(i); sh::Factory::getInstance()._ensureMaterial(subEnt->getMaterial()->getName(), "Default"); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? mTransQueue : mSolidQueue); } }
// 设置模型的透明度 // 0 -- 完全透明。 // 1 -- 不透明。 void CEditDobject_NT::SetTransparence(float Transparence) { int iCount = m_EntityList.size(); Ogre::Entity* pEntity = NULL; for(int i = 0; i < iCount; i++) { pEntity = m_EntityList[i].pEntity; if(pEntity) { Ogre::SubEntity* pSubEntiy = pEntity->getSubEntity(0); if(pSubEntiy) { Ogre::MaterialPtr material1 = pSubEntiy->getMaterial(); Ogre::Technique* t1 = material1->getBestTechnique(); Ogre::Pass* p1 = t1->getPass(0); p1->setSceneBlending(Ogre::SBT_ADD ); p1->setSceneBlending(Ogre::SBF_SOURCE_ALPHA , Ogre::SBF_ONE_MINUS_SOURCE_ALPHA ); Ogre::TextureUnitState* pTextureState = p1->getTextureUnitState(0); pTextureState->setAlphaOperation(Ogre::LBX_MODULATE, Ogre::LBS_TEXTURE, Ogre::LBS_MANUAL, 1, Transparence, 1); //Ogre::ColourValue color(1,0.0,0.0,0.1) ; //pTextureState->setColourOperationEx(LBX_ADD , LBS_TEXTURE , LBS_MANUAL, color, color ); } } } }
ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr) : Animation(ptr) { MWWorld::LiveCellRef<ESM::Activator> *ref = mPtr.get<ESM::Activator>(); assert (ref->mBase != NULL); if(!ref->mBase->mModel.empty()) { std::string mesh = "meshes\\" + ref->mBase->mModel; createEntityList(mPtr.getRefData().getBaseNode(), mesh); for(size_t i = 0;i < mEntityList.mEntities.size();i++) { Ogre::Entity *ent = mEntityList.mEntities[i]; for(unsigned int j=0; j < ent->getNumSubEntities(); ++j) { Ogre::SubEntity* subEnt = ent->getSubEntity(j); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main); } ent->setVisibilityFlags(RV_Misc); } setAnimationSource(mesh); } }
NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int group, const std::string &bonename) { NifOgre::EntityList entities = NifOgre::Loader::createEntities(mEntityList.mSkelBase, bonename, mInsert, mesh); std::vector<Ogre::Entity*> &parts = entities.mEntities; for(size_t i = 0;i < parts.size();i++) { parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group)); if (mVisibilityFlags != 0) parts[i]->setVisibilityFlags(mVisibilityFlags); for(unsigned int j=0; j < parts[i]->getNumSubEntities(); ++j) { Ogre::SubEntity* subEnt = parts[i]->getSubEntity(j); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main); } } if(entities.mSkelBase) { Ogre::AnimationStateSet *aset = entities.mSkelBase->getAllAnimationStates(); Ogre::AnimationStateIterator asiter = aset->getAnimationStateIterator(); while(asiter.hasMoreElements()) { Ogre::AnimationState *state = asiter.getNext(); state->setEnabled(false); state->setLoop(false); } Ogre::SkeletonInstance *skelinst = entities.mSkelBase->getSkeleton(); Ogre::Skeleton::BoneIterator boneiter = skelinst->getBoneIterator(); while(boneiter.hasMoreElements()) boneiter.getNext()->setManuallyControlled(true); } return entities; }
void ShapeBase::extractMaterials( Ogre::Entity *entity, S_MaterialPtr &materials ) { uint32_t num_sub_entities = entity->getNumSubEntities(); for (uint32_t i = 0; i < num_sub_entities; ++i) { Ogre::SubEntity* sub = entity->getSubEntity(i); Ogre::MaterialPtr material = sub->getMaterial(); materials.insert( material ); } }
void LIRenAttachmentEntity::replace_texture_now (const Ogre::String& name, Ogre::TexturePtr& texture) { if (mesh.isNull () || entity == NULL) return; // Translate the name if already replaced before. std::map<Ogre::String, Ogre::String>::const_iterator iter; iter = applied_texture_replaces.find(name); Ogre::String real_name; if (iter != applied_texture_replaces.end()) real_name = iter->second; else real_name = name; // Save the replaced name for future translations. applied_texture_replaces[name] = texture->getName (); // Replace in each submesh. for (size_t subent_idx = 0 ; subent_idx < entity->getNumSubEntities () ; ++subent_idx) { // Get the material of the subent. Ogre::SubEntity* subent = entity->getSubEntity (subent_idx); Ogre::MaterialPtr submat = subent->getMaterial (); if (submat.isNull ()) continue; // Check if there are replaceable textures. if (!render->material_utils->has_overridable_texture (submat, real_name)) continue; // Create a modified version of the material. Ogre::String new_name = render->id.next (); Ogre::MaterialPtr material = submat->clone (new_name, true, LIREN_RESOURCES_TEMPORARY); render->material_utils->replace_texture (material, real_name, texture->getName ()); subent->setMaterial (material); } }
// 设置选中的外观颜色. void CEditDobject_NT::SetSelectLook(Ogre::ColourValue color) { if(0 == m_materialSelVector.size()) { // 选中材质的名字. Ogre::String strCloneName; int iCount = m_EntityList.size(); Ogre::Entity* pEntity = NULL; for(int i = 0; i < iCount; i++) { pEntity = m_EntityList[i].pEntity; if(pEntity) { Ogre::SubEntity* pSubEntiy = pEntity->getSubEntity(0); if(pSubEntiy) { Ogre::MaterialPtr pMaterial = pSubEntiy->getMaterial(); if(pMaterial.isNull()) { return; }// const Ogre::String& strName = pMaterial->getName(); if("BaseWhite" == strName) { continue; } strCloneName = strName; strCloneName += "_select"; Ogre::MaterialManager* pMaterialManager = (Ogre::MaterialManager*)(pMaterial->getCreator()); if(NULL == pMaterialManager) { return; } Ogre::MaterialPtr pMaterialClone = pMaterialManager->getByName(strCloneName); if(pMaterialClone.isNull()) { pMaterialClone = pMaterial->clone(strCloneName); } //if(!pMaterialClone) //{ // return; //}// Ogre::Technique* pTechnique = pMaterialClone->getBestTechnique(); Ogre::Pass* pPass = pTechnique->getPass(0); //pPass->setSceneBlending(SBT_ADD); //pPass->setSceneBlending(SBF_SOURCE_ALPHA , SBF_ONE_MINUS_SOURCE_ALPHA ); //pTextureState->setAlphaOperation(LBX_MODULATE, LBS_TEXTURE, LBS_MANUAL, 1, Transparence, 1);// Ogre::TextureUnitState* pTextureState = pPass->getTextureUnitState(0); pTextureState->setColourOperationEx(Ogre::LBX_ADD , Ogre::LBS_TEXTURE , Ogre::LBS_MANUAL, color, color ); pSubEntiy->setMaterialName(strCloneName); m_materialSelVector.push_back(pMaterialClone); m_materilaOldVector.push_back(pMaterial); } } } } else { int iIndex = 0; int iCount = m_EntityList.size(); Ogre::Entity* pEntity = NULL; for(int i = 0; i < iCount; i++) { pEntity = m_EntityList[i].pEntity; if(pEntity) { Ogre::SubEntity* pSubEntiy = pEntity->getSubEntity(0); if(pSubEntiy) { if(iIndex >= (int)m_materialSelVector.size()) { continue; } std::string strMaterialName = m_materialSelVector[iIndex]->getName(); pSubEntiy->setMaterialName(strMaterialName); iIndex++; } } } } }
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light) { Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); assert(insert); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; NifOgre::ObjectList objects = NifOgre::Loader::createObjects(insert, mesh); for(size_t i = 0;i < objects.mEntities.size();i++) bounds.merge(objects.mEntities[i]->getWorldBoundingBox(true)); Ogre::Vector3 extents = bounds.getSize(); extents *= insert->getScale(); float size = std::max(std::max(extents.x, extents.y), extents.z); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); // do not fade out doors. that will cause holes and look stupid if (ptr.getTypeName().find("Door") != std::string::npos) small = false; if (mBounds.find(ptr.getCell()) == mBounds.end()) mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()].merge(bounds); bool anyTransparency = false; for(size_t i = 0;!anyTransparency && i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0;!anyTransparency && i < ent->getNumSubEntities(); ++i) { anyTransparency = ent->getSubEntity(i)->getMaterial()->isTransparent(); } } if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || anyTransparency || objects.mParticles.size() > 0) { for(size_t i = 0;i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0; i < ent->getNumSubEntities(); ++i) { Ogre::SubEntity* subEnt = ent->getSubEntity(i); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main); } ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } for(size_t i = 0;i < objects.mParticles.size();i++) { Ogre::ParticleSystem *part = objects.mParticles[i]; // TODO: Check the particle system's material for actual transparency part->setRenderQueueGroup(RQG_Alpha); part->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); part->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } } else { Ogre::StaticGeometry* sg = 0; if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometrySmall[ptr.getCell()] = sg; sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); } else sg = mStaticGeometrySmall[ptr.getCell()]; } else { if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometry[ptr.getCell()] = sg; } else sg = mStaticGeometry[ptr.getCell()]; } // This specifies the size of a single batch region. // If it is set too high: // - there will be problems choosing the correct lights // - the culling will be more inefficient // If it is set too low: // - there will be too many batches. sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); sg->setCastShadows(true); sg->setRenderQueueGroup(RQG_Main); std::vector<Ogre::Entity*>::reverse_iterator iter = objects.mEntities.rbegin(); while(iter != objects.mEntities.rend()) { Ogre::Node *node = (*iter)->getParentNode(); sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale()); (*iter)->detachFromParent(); mRenderer.getScene()->destroyEntity(*iter); iter++; } } if (light) { insertLight(ptr, objects.mSkelBase, bounds.getCenter() - insert->_getDerivedPosition()); } }
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); }