Preliminary handling for overflowing light lists

c++11
scrawl 10 years ago
parent acf9fc2d37
commit 18f4eaa8dc

@ -179,7 +179,7 @@ namespace SceneUtil
// possible optimization: return a StateSet containing all requested lights plus some extra lights (if a suitable one exists) // possible optimization: return a StateSet containing all requested lights plus some extra lights (if a suitable one exists)
size_t hash = 0; size_t hash = 0;
for (unsigned int i=0; i<lightList.size();++i) for (unsigned int i=0; i<lightList.size();++i)
boost::hash_combine(hash, lightList[i]->getId()); boost::hash_combine(hash, lightList[i]->mLightSource->getId());
LightStateSetMap::iterator found = mStateSetCache.find(hash); LightStateSetMap::iterator found = mStateSetCache.find(hash);
if (found != mStateSetCache.end()) if (found != mStateSetCache.end())
@ -189,7 +189,7 @@ namespace SceneUtil
std::vector<osg::ref_ptr<osg::Light> > lights; std::vector<osg::ref_ptr<osg::Light> > lights;
for (unsigned int i=0; i<lightList.size();++i) for (unsigned int i=0; i<lightList.size();++i)
lights.push_back(lightList[i]->getLight()); lights.push_back(lightList[i]->mLightSource->getLight());
osg::ref_ptr<LightStateAttribute> attr = new LightStateAttribute(mStartLight, lights); osg::ref_ptr<LightStateAttribute> attr = new LightStateAttribute(mStartLight, lights);
@ -237,6 +237,12 @@ namespace SceneUtil
mId = sLightId++; mId = sLightId++;
} }
bool sortLights (const LightManager::LightSourceTransform* left, const LightManager::LightSourceTransform* right)
{
return left->mViewBound.center().length2() < right->mViewBound.center().length2();
}
void LightListCallback::operator()(osg::Node *node, osg::NodeVisitor *nv) void LightListCallback::operator()(osg::Node *node, osg::NodeVisitor *nv)
{ {
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv); osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
@ -279,12 +285,12 @@ namespace SceneUtil
osg::Matrixf mat = *cv->getModelViewMatrix(); osg::Matrixf mat = *cv->getModelViewMatrix();
transformBoundingSphere(mat, nodeBound); transformBoundingSphere(mat, nodeBound);
std::vector<LightSource*> lightList; std::vector<const LightManager::LightSourceTransform*> lightList;
for (unsigned int i=0; i<lights.size(); ++i) for (unsigned int i=0; i<lights.size(); ++i)
{ {
const LightManager::LightSourceTransform& l = lights[i]; const LightManager::LightSourceTransform& l = lights[i];
if (l.mViewBound.intersects(nodeBound)) if (l.mViewBound.intersects(nodeBound))
lightList.push_back(l.mLightSource); lightList.push_back(&l);
} }
if (lightList.empty()) if (lightList.empty())
@ -297,12 +303,27 @@ namespace SceneUtil
if (lightList.size() > maxLights) if (lightList.size() > maxLights)
{ {
//std::cerr << "More than 8 lights!" << std::endl; // remove lights culled by this camera
for (LightManager::LightList::iterator it = lightList.begin(); it != lightList.end();)
{
osg::CullStack::CullingStack& stack = cv->getProjectionCullingStack();
// TODO: sort lights by certain criteria if (stack.back().isCulled(osg::BoundingSphere((*it)->mViewBound.center(), (*it)->mViewBound.radius()*2)))
{
it = lightList.erase(it);
continue;
}
else
++it;
}
while (lightList.size() > maxLights) if (lightList.size() > maxLights)
lightList.pop_back(); {
// sort by proximity to camera, then get rid of furthest away lights
std::sort(lightList.begin(), lightList.end(), sortLights);
while (lightList.size() > maxLights)
lightList.pop_back();
}
} }
osg::StateSet* stateset = mLightManager->getLightListStateSet(lightList); osg::StateSet* stateset = mLightManager->getLightListStateSet(lightList);

@ -85,7 +85,7 @@ namespace SceneUtil
const std::vector<LightSourceTransform>& getLights() const; const std::vector<LightSourceTransform>& getLights() const;
typedef std::vector<LightSource*> LightList; typedef std::vector<const LightSourceTransform*> LightList;
osg::ref_ptr<osg::StateSet> getLightListStateSet(const LightList& lightList); osg::ref_ptr<osg::StateSet> getLightListStateSet(const LightList& lightList);

Loading…
Cancel
Save