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);
    }
}
Example #2
0
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;
}
Example #3
0
    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);
        }
    }
Example #4
0
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());
    }
}
Example #5
0
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);
}