mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 01:56:44 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			140 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef OPENMW_COMPONENTS_SCENEUTIL_LIGHTMANAGER_H
 | 
						|
#define OPENMW_COMPONENTS_SCENEUTIL_LIGHTMANAGER_H
 | 
						|
 | 
						|
#include <osg/Light>
 | 
						|
 | 
						|
#include <osg/Group>
 | 
						|
#include <osg/NodeVisitor>
 | 
						|
 | 
						|
namespace SceneUtil
 | 
						|
{
 | 
						|
 | 
						|
    // This mask should be included in the Cull and Update visitor's traversal mask if lighting is desired.
 | 
						|
    const int Mask_Lit = (1<<16);
 | 
						|
 | 
						|
    /// LightSource managed by a LightManager.
 | 
						|
    class LightSource : public osg::Node
 | 
						|
    {
 | 
						|
        osg::ref_ptr<osg::Light> mLight;
 | 
						|
 | 
						|
        // The activation radius
 | 
						|
        float mRadius;
 | 
						|
 | 
						|
        int mId;
 | 
						|
 | 
						|
    public:
 | 
						|
 | 
						|
        META_Node(SceneUtil, SceneUtil::LightSource)
 | 
						|
 | 
						|
        LightSource();
 | 
						|
 | 
						|
        LightSource(const LightSource& copy, const osg::CopyOp& copyop);
 | 
						|
 | 
						|
        float getRadius() const
 | 
						|
        {
 | 
						|
            return mRadius;
 | 
						|
        }
 | 
						|
 | 
						|
        void setRadius(float radius)
 | 
						|
        {
 | 
						|
            mRadius = radius;
 | 
						|
        }
 | 
						|
 | 
						|
        osg::Light* getLight()
 | 
						|
        {
 | 
						|
            return mLight;
 | 
						|
        }
 | 
						|
 | 
						|
        void setLight(osg::Light* light)
 | 
						|
        {
 | 
						|
            mLight = light;
 | 
						|
        }
 | 
						|
 | 
						|
        int getId()
 | 
						|
        {
 | 
						|
            return mId;
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    /// All light sources must be a child of the LightManager node. The LightManager can be anywhere in the scene graph,
 | 
						|
    /// but would be typically somewhere near the top.
 | 
						|
    class LightManager : public osg::Group
 | 
						|
    {
 | 
						|
    public:
 | 
						|
 | 
						|
        META_Node(SceneUtil, SceneUtil::LightManager)
 | 
						|
 | 
						|
        LightManager();
 | 
						|
 | 
						|
        LightManager(const LightManager& copy, const osg::CopyOp& copyop);
 | 
						|
 | 
						|
        // Called automatically by the UpdateCallback
 | 
						|
        void update();
 | 
						|
 | 
						|
        // Called automatically by the LightSource's UpdateCallback
 | 
						|
        void addLight(LightSource* lightSource, osg::Matrix worldMat);
 | 
						|
 | 
						|
        struct LightSourceTransform
 | 
						|
        {
 | 
						|
            osg::ref_ptr<LightSource> mLightSource;
 | 
						|
            osg::Matrix mWorldMatrix;
 | 
						|
        };
 | 
						|
 | 
						|
        const std::vector<LightSourceTransform>& getLights() const;
 | 
						|
 | 
						|
        struct LightSourceViewBound
 | 
						|
        {
 | 
						|
            osg::ref_ptr<LightSource> mLightSource;
 | 
						|
            osg::BoundingSphere mViewBound;
 | 
						|
        };
 | 
						|
 | 
						|
        const std::vector<LightSourceViewBound>& getLightsInViewSpace(osg::Camera* camera, const osg::RefMatrix* viewMatrix);
 | 
						|
 | 
						|
        typedef std::vector<const LightSourceViewBound*> LightList;
 | 
						|
 | 
						|
        osg::ref_ptr<osg::StateSet> getLightListStateSet(const LightList& lightList);
 | 
						|
 | 
						|
        /// Set the first light index that should be used by this manager, typically the number of directional lights in the scene.
 | 
						|
        void setStartLight(int start);
 | 
						|
 | 
						|
        int getStartLight() const;
 | 
						|
 | 
						|
    private:
 | 
						|
        // Lights collected from the scene graph. Only valid during the cull traversal.
 | 
						|
        std::vector<LightSourceTransform> mLights;
 | 
						|
 | 
						|
        typedef std::vector<LightSourceViewBound> LightSourceViewBoundCollection;
 | 
						|
        std::map<osg::observer_ptr<osg::Camera>, LightSourceViewBoundCollection> mLightsInViewSpace;
 | 
						|
 | 
						|
        // < Light list hash , StateSet >
 | 
						|
        typedef std::map<size_t, osg::ref_ptr<osg::StateSet> > LightStateSetMap;
 | 
						|
        LightStateSetMap mStateSetCache;
 | 
						|
 | 
						|
        int mStartLight;
 | 
						|
    };
 | 
						|
 | 
						|
    class LightListCallback : public osg::NodeCallback
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        LightListCallback()
 | 
						|
            : mLightManager(NULL)
 | 
						|
        {}
 | 
						|
        LightListCallback(const LightListCallback& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY)
 | 
						|
            : osg::Object(copy, copyop), osg::NodeCallback(copy, copyop), mLightManager(copy.mLightManager)
 | 
						|
        {}
 | 
						|
 | 
						|
        META_Object(NifOsg, LightListCallback)
 | 
						|
 | 
						|
        void operator()(osg::Node* node, osg::NodeVisitor* nv);
 | 
						|
 | 
						|
    private:
 | 
						|
        LightManager* mLightManager;
 | 
						|
    };
 | 
						|
 | 
						|
    /// @brief Configures a light's attenuation according to vanilla Morrowind attenuation settings.
 | 
						|
    void configureLight(osg::Light* light, float radius, bool isExterior, bool outQuadInLin, bool useQuadratic, float quadraticValue,
 | 
						|
                         float quadraticRadiusMult, bool useLinear, float linearRadiusMult, float linearValue);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |