mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 00:26:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			124 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "statesetupdater.hpp"
 | 
						|
 | 
						|
#include <components/stereo/stereomanager.hpp>
 | 
						|
 | 
						|
#include <osg/Node>
 | 
						|
#include <osg/NodeVisitor>
 | 
						|
#include <osgUtil/CullVisitor>
 | 
						|
 | 
						|
namespace SceneUtil
 | 
						|
{
 | 
						|
 | 
						|
    void StateSetUpdater::operator()(osg::Node* node, osg::NodeVisitor* nv)
 | 
						|
    {
 | 
						|
        bool isCullVisitor = nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR;
 | 
						|
 | 
						|
        if (isCullVisitor)
 | 
						|
            return applyCull(node, static_cast<osgUtil::CullVisitor*>(nv));
 | 
						|
        else
 | 
						|
            return applyUpdate(node, nv);
 | 
						|
    }
 | 
						|
 | 
						|
    void StateSetUpdater::applyUpdate(osg::Node* node, osg::NodeVisitor* nv)
 | 
						|
    {
 | 
						|
        if (!mStateSetsUpdate[0])
 | 
						|
        {
 | 
						|
            for (int i = 0; i < 2; ++i)
 | 
						|
            {
 | 
						|
                mStateSetsUpdate[i] = new osg::StateSet(*node->getOrCreateStateSet(),
 | 
						|
                    osg::CopyOp::SHALLOW_COPY); // Using SHALLOW_COPY for StateAttributes, if users want to modify it is
 | 
						|
                                                // their responsibility to set a non-shared one first in setDefaults
 | 
						|
                setDefaults(mStateSetsUpdate[i]);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        osg::ref_ptr<osg::StateSet> stateset = mStateSetsUpdate[nv->getTraversalNumber() % 2];
 | 
						|
        apply(stateset, nv);
 | 
						|
        node->setStateSet(stateset);
 | 
						|
        traverse(node, nv);
 | 
						|
    }
 | 
						|
 | 
						|
    void StateSetUpdater::applyCull(osg::Node* node, osgUtil::CullVisitor* cv)
 | 
						|
    {
 | 
						|
        auto stateset = getCvDependentStateset(cv);
 | 
						|
        apply(stateset, cv);
 | 
						|
        auto* sm = &Stereo::Manager::instance();
 | 
						|
        if (sm != nullptr)
 | 
						|
        {
 | 
						|
            if (sm->getEye(cv) == Stereo::Eye::Left)
 | 
						|
                applyLeft(stateset, cv);
 | 
						|
            if (sm->getEye(cv) == Stereo::Eye::Right)
 | 
						|
                applyRight(stateset, cv);
 | 
						|
        }
 | 
						|
 | 
						|
        cv->pushStateSet(stateset);
 | 
						|
        traverse(node, cv);
 | 
						|
        cv->popStateSet();
 | 
						|
    }
 | 
						|
 | 
						|
    osg::StateSet* StateSetUpdater::getCvDependentStateset(osgUtil::CullVisitor* cv)
 | 
						|
    {
 | 
						|
        auto it = mStateSetsCull.find(cv);
 | 
						|
        if (it == mStateSetsCull.end())
 | 
						|
        {
 | 
						|
            osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
 | 
						|
            mStateSetsCull.emplace(cv, stateset);
 | 
						|
            setDefaults(stateset);
 | 
						|
            return stateset;
 | 
						|
        }
 | 
						|
        return it->second;
 | 
						|
    }
 | 
						|
 | 
						|
    void StateSetUpdater::reset()
 | 
						|
    {
 | 
						|
        mStateSetsUpdate[0] = nullptr;
 | 
						|
        mStateSetsUpdate[1] = nullptr;
 | 
						|
        mStateSetsCull.clear();
 | 
						|
    }
 | 
						|
 | 
						|
    StateSetUpdater::StateSetUpdater() {}
 | 
						|
 | 
						|
    StateSetUpdater::StateSetUpdater(const StateSetUpdater& copy, const osg::CopyOp& copyop)
 | 
						|
        : SceneUtil::NodeCallback<StateSetUpdater>(copy, copyop)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    // ----------------------------------------------------------------------------------
 | 
						|
 | 
						|
    void CompositeStateSetUpdater::apply(osg::StateSet* stateset, osg::NodeVisitor* nv)
 | 
						|
    {
 | 
						|
        for (unsigned int i = 0; i < mCtrls.size(); ++i)
 | 
						|
            mCtrls[i]->apply(stateset, nv);
 | 
						|
    }
 | 
						|
 | 
						|
    void CompositeStateSetUpdater::setDefaults(osg::StateSet* stateset)
 | 
						|
    {
 | 
						|
        for (unsigned int i = 0; i < mCtrls.size(); ++i)
 | 
						|
            mCtrls[i]->setDefaults(stateset);
 | 
						|
    }
 | 
						|
 | 
						|
    CompositeStateSetUpdater::CompositeStateSetUpdater() {}
 | 
						|
 | 
						|
    CompositeStateSetUpdater::CompositeStateSetUpdater(const CompositeStateSetUpdater& copy, const osg::CopyOp& copyop)
 | 
						|
        : StateSetUpdater(copy, copyop)
 | 
						|
    {
 | 
						|
        for (unsigned int i = 0; i < copy.mCtrls.size(); ++i)
 | 
						|
            mCtrls.emplace_back(osg::clone(copy.mCtrls[i].get(), copyop));
 | 
						|
    }
 | 
						|
 | 
						|
    unsigned int CompositeStateSetUpdater::getNumControllers()
 | 
						|
    {
 | 
						|
        return mCtrls.size();
 | 
						|
    }
 | 
						|
 | 
						|
    StateSetUpdater* CompositeStateSetUpdater::getController(int i)
 | 
						|
    {
 | 
						|
        return mCtrls[i];
 | 
						|
    }
 | 
						|
 | 
						|
    void CompositeStateSetUpdater::addController(StateSetUpdater* ctrl)
 | 
						|
    {
 | 
						|
        mCtrls.emplace_back(ctrl);
 | 
						|
    }
 | 
						|
 | 
						|
}
 |