Esempio n. 1
0
void CreatureWeaponAnimation::updatePart(NifOgre::ObjectScenePtr& scene, int slot)
{
    MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
    MWWorld::ContainerStoreIterator it = inv.getSlot(slot);

    if (it == inv.end())
    {
        scene.setNull();
        return;
    }
    MWWorld::Ptr item = *it;

    std::string bonename;
    if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
        bonename = "Weapon Bone";
    else
        bonename = "Shield Bone";

    scene = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, item.getClass().getModel(item));
    Ogre::Vector3 glowColor = getEnchantmentColor(item);

    setRenderProperties(scene, RV_Actors, RQG_Main, RQG_Alpha, 0,
                        !item.getClass().getEnchantment(item).empty(), &glowColor);

    if(scene->mSkelBase)
    {
        Ogre::SkeletonInstance *skel = scene->mSkelBase->getSkeleton();
        if(scene->mSkelBase->isParentTagPoint())
        {
            Ogre::Node *root = scene->mSkelBase->getParentNode();
            if(skel->hasBone("BoneOffset"))
            {
                Ogre::Bone *offset = skel->getBone("BoneOffset");

                root->translate(offset->getPosition());

                // It appears that the BoneOffset rotation is completely bogus, at least for light models.
                //root->rotate(offset->getOrientation());
                root->pitch(Ogre::Degree(-90.0f));

                root->scale(offset->getScale());
                root->setInitialState();
            }
        }
        updateSkeletonInstance(mSkelBase->getSkeleton(), skel);
    }

    // TODO:
    // type == ESM::PRT_Weapon should get an animation source based on the current offset
    // of the weapon attack animation (from its beginning, or start marker?)
    std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(scene->mControllers.begin());
    for(;ctrl != scene->mControllers.end();ctrl++)
    {
        if(ctrl->getSource().isNull())
            ctrl->setSource(Ogre::SharedPtr<NullAnimationTime>(new NullAnimationTime()));
    }
}
void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot)
{
    if (!mObjectRoot)
        return;

    MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
    MWWorld::ContainerStoreIterator it = inv.getSlot(slot);

    if (it == inv.end())
    {
        scene.reset();
        return;
    }
    MWWorld::Ptr item = *it;

    std::string bonename;
    if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
        bonename = "Weapon Bone";
    else
        bonename = "Shield Bone";

    osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(item.getClass().getModel(item));
    osg::ref_ptr<osg::Node> attached = SceneUtil::attach(node, mObjectRoot, bonename, bonename);
    mResourceSystem->getSceneManager()->notifyAttached(attached);
    if (mSkeleton)
        mSkeleton->markDirty();

    scene.reset(new PartHolder(attached));

    if (!item.getClass().getEnchantment(item).empty())
        addGlow(attached, getEnchantmentColor(item));

    // Crossbows start out with a bolt attached
    // FIXME: code duplicated from NpcAnimation
    if (slot == MWWorld::InventoryStore::Slot_CarriedRight &&
            item.getTypeName() == typeid(ESM::Weapon).name() &&
            item.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow)
    {
        MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
        if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt)
            attachArrow();
        else
            mAmmunition.reset();
    }
    else
        mAmmunition.reset();

    boost::shared_ptr<SceneUtil::ControllerSource> source;

    if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
        source = mWeaponAnimationTime;
    else
        source.reset(new NullAnimationTime);

    SceneUtil::AssignControllerSourcesVisitor assignVisitor(source);
    attached->accept(assignVisitor);
}
Esempio n. 3
0
ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model)
  : Animation(ptr, ptr.getRefData().getBaseNode())
{
    setObjectRoot(model, false);

    Ogre::Vector3 extents = getWorldBounds().getSize();
    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;

    float dist = small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0.0f;
    Ogre::Vector3 col = getEnchantmentColor(ptr);
    setRenderProperties(mObjectRoot, (mPtr.getTypeName() == typeid(ESM::Static).name()) ?
                                     (small ? RV_StaticsSmall : RV_Statics) : RV_Misc,
                        RQG_Main, RQG_Alpha, dist, !ptr.getClass().getEnchantment(ptr).empty(), &col);
}