Use node masks and shared state sets to manage ground lights
Do away with the switch in each terrain tile for the ground lights. They are turned on by node masks now. Share state sets among all the light nodes and manage the fog values through a "GroundLightManager" instead of having separate state sets and callback functions for each group in each tile.
This commit is contained in:
73
simgear/scene/tgdb/GroundLightManager.cxx
Normal file
73
simgear/scene/tgdb/GroundLightManager.cxx
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <osg/Fog>
|
||||
|
||||
#include <simgear/scene/util/RenderConstants.hxx>
|
||||
#include "GroundLightManager.hxx"
|
||||
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
namespace
|
||||
{
|
||||
StateSet* makeLightSS()
|
||||
{
|
||||
StateSet* ss = new StateSet;
|
||||
Fog* fog = new Fog;
|
||||
fog->setMode(Fog::EXP2);
|
||||
ss->setAttribute(fog);
|
||||
ss->setDataVariance(Object::DYNAMIC);
|
||||
return ss;
|
||||
}
|
||||
}
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
GroundLightManager::GroundLightManager()
|
||||
{
|
||||
osg::Fog* fog;
|
||||
runwayLightSS = makeLightSS();
|
||||
taxiLightSS = makeLightSS();
|
||||
groundLightSS = makeLightSS();
|
||||
}
|
||||
|
||||
GroundLightManager* GroundLightManager::instance()
|
||||
{
|
||||
static ref_ptr<GroundLightManager> manager = new GroundLightManager;
|
||||
return manager.get();
|
||||
}
|
||||
|
||||
void GroundLightManager::update(const SGUpdateVisitor* updateVisitor)
|
||||
{
|
||||
osg::Fog* fog;
|
||||
SGVec4f fogColor = updateVisitor->getFogColor();
|
||||
fog = static_cast<osg::Fog*>(runwayLightSS
|
||||
->getAttribute(StateAttribute::FOG));
|
||||
fog->setColor(fogColor.osg());
|
||||
fog->setDensity(updateVisitor->getRunwayFogExp2Density());
|
||||
fog = static_cast<osg::Fog*>(taxiLightSS
|
||||
->getAttribute(StateAttribute::FOG));
|
||||
fog->setColor(fogColor.osg());
|
||||
fog->setDensity(updateVisitor->getTaxiFogExp2Density());
|
||||
fog = static_cast<osg::Fog*>(groundLightSS
|
||||
->getAttribute(StateAttribute::FOG));
|
||||
fog->setColor(fogColor.osg());
|
||||
fog->setDensity(updateVisitor->getGroundLightsFogExp2Density());
|
||||
}
|
||||
|
||||
unsigned GroundLightManager::getLightNodeMask(const SGUpdateVisitor* updateVisitor)
|
||||
{
|
||||
unsigned mask = 0;
|
||||
// The current sun angle in degree
|
||||
float sun_angle = updateVisitor->getSunAngleDeg();
|
||||
if (sun_angle > 85 || updateVisitor->getVisibility() < 5000)
|
||||
mask |= RUNWAYLIGHTS_BIT;
|
||||
// ground lights
|
||||
if ( sun_angle > 95 )
|
||||
mask |= GROUNDLIGHTS2_BIT;
|
||||
if ( sun_angle > 92 )
|
||||
mask |= GROUNDLIGHTS1_BIT;
|
||||
if ( sun_angle > 89 )
|
||||
mask |= GROUNDLIGHTS0_BIT;
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
45
simgear/scene/tgdb/GroundLightManager.hxx
Normal file
45
simgear/scene/tgdb/GroundLightManager.hxx
Normal file
@@ -0,0 +1,45 @@
|
||||
// GroundLightManager.hxx - manage StateSets for point lights
|
||||
//
|
||||
// Copyright (C) 2007 Tim Moore timoore@redhat.com
|
||||
// Copyright (C) 2006-2007 Mathias Froehlich
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/Referenced>
|
||||
#include <osg/StateSet>
|
||||
#include <simgear/scene/util/SGUpdateVisitor.hxx>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
class GroundLightManager : public osg::Referenced {
|
||||
public:
|
||||
GroundLightManager();
|
||||
osg::StateSet* getRunwayLightStateSet() { return runwayLightSS.get(); }
|
||||
osg::StateSet* getTaxiLightStateSet() { return taxiLightSS.get(); }
|
||||
osg::StateSet* getGroundLightStateSet() { return groundLightSS.get(); }
|
||||
// The SGUpdateVisitor manages various environmental properties,
|
||||
// so use it.
|
||||
void update (const SGUpdateVisitor* updateVisitor);
|
||||
unsigned getLightNodeMask(const SGUpdateVisitor* updateVisitor);
|
||||
static GroundLightManager* instance();
|
||||
protected:
|
||||
osg::ref_ptr<osg::StateSet> runwayLightSS;
|
||||
osg::ref_ptr<osg::StateSet> taxiLightSS;
|
||||
osg::ref_ptr<osg::StateSet> groundLightSS;
|
||||
};
|
||||
}
|
||||
@@ -17,7 +17,8 @@ include_HEADERS = \
|
||||
SGReaderWriterBTGOptions.hxx \
|
||||
SGTexturedTriangleBin.hxx \
|
||||
SGTriangleBin.hxx \
|
||||
SGVertexArrayBin.hxx
|
||||
SGVertexArrayBin.hxx \
|
||||
GroundLightManager.hxx
|
||||
|
||||
libsgtgdb_a_SOURCES = \
|
||||
apt_signs.cxx \
|
||||
@@ -26,6 +27,7 @@ libsgtgdb_a_SOURCES = \
|
||||
userdata.cxx \
|
||||
SGOceanTile.cxx \
|
||||
SGReaderWriterBTG.cxx \
|
||||
SGVasiDrawable.cxx
|
||||
SGVasiDrawable.cxx \
|
||||
GroundLightManager.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -55,9 +55,13 @@
|
||||
#include "SGTexturedTriangleBin.hxx"
|
||||
#include "SGLightBin.hxx"
|
||||
#include "SGDirectionalLightBin.hxx"
|
||||
#include "GroundLightManager.hxx"
|
||||
|
||||
|
||||
#include "pt_lights.hxx"
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
typedef std::map<std::string,SGTexturedTriangleBin> SGMaterialTriangleMap;
|
||||
typedef std::list<SGLightBin> SGLightListBin;
|
||||
typedef std::list<SGDirectionalLightBin> SGDirectionalLightListBin;
|
||||
@@ -449,92 +453,6 @@ struct SGTileGeometryBin {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class SGTileUpdateCallback : public osg::NodeCallback {
|
||||
public:
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
assert(dynamic_cast<osg::Switch*>(node));
|
||||
assert(dynamic_cast<SGUpdateVisitor*>(nv));
|
||||
|
||||
osg::Switch* lightSwitch = static_cast<osg::Switch*>(node);
|
||||
SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
|
||||
|
||||
// The current sun angle in degree
|
||||
float sun_angle = updateVisitor->getSunAngleDeg();
|
||||
|
||||
// vasi is always on
|
||||
lightSwitch->setValue(0, true);
|
||||
if (sun_angle > 85 || updateVisitor->getVisibility() < 5000) {
|
||||
// runway and taxi
|
||||
lightSwitch->setValue(1, true);
|
||||
lightSwitch->setValue(2, true);
|
||||
} else {
|
||||
// runway and taxi
|
||||
lightSwitch->setValue(1, false);
|
||||
lightSwitch->setValue(2, false);
|
||||
}
|
||||
|
||||
// ground lights
|
||||
if ( sun_angle > 95 )
|
||||
lightSwitch->setValue(5, true);
|
||||
else
|
||||
lightSwitch->setValue(5, false);
|
||||
if ( sun_angle > 92 )
|
||||
lightSwitch->setValue(4, true);
|
||||
else
|
||||
lightSwitch->setValue(4, false);
|
||||
if ( sun_angle > 89 )
|
||||
lightSwitch->setValue(3, true);
|
||||
else
|
||||
lightSwitch->setValue(3, false);
|
||||
|
||||
traverse(node, nv);
|
||||
}
|
||||
};
|
||||
|
||||
class SGRunwayLightFogUpdateCallback : public osg::StateAttribute::Callback {
|
||||
public:
|
||||
virtual void operator () (osg::StateAttribute* sa, osg::NodeVisitor* nv)
|
||||
{
|
||||
assert(dynamic_cast<SGUpdateVisitor*>(nv));
|
||||
assert(dynamic_cast<osg::Fog*>(sa));
|
||||
SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
|
||||
osg::Fog* fog = static_cast<osg::Fog*>(sa);
|
||||
fog->setMode(osg::Fog::EXP2);
|
||||
fog->setColor(updateVisitor->getFogColor().osg());
|
||||
fog->setDensity(updateVisitor->getRunwayFogExp2Density());
|
||||
}
|
||||
};
|
||||
|
||||
class SGTaxiLightFogUpdateCallback : public osg::StateAttribute::Callback {
|
||||
public:
|
||||
virtual void operator () (osg::StateAttribute* sa, osg::NodeVisitor* nv)
|
||||
{
|
||||
assert(dynamic_cast<SGUpdateVisitor*>(nv));
|
||||
assert(dynamic_cast<osg::Fog*>(sa));
|
||||
SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
|
||||
osg::Fog* fog = static_cast<osg::Fog*>(sa);
|
||||
fog->setMode(osg::Fog::EXP2);
|
||||
fog->setColor(updateVisitor->getFogColor().osg());
|
||||
fog->setDensity(updateVisitor->getTaxiFogExp2Density());
|
||||
}
|
||||
};
|
||||
|
||||
class SGGroundLightFogUpdateCallback : public osg::StateAttribute::Callback {
|
||||
public:
|
||||
virtual void operator () (osg::StateAttribute* sa, osg::NodeVisitor* nv)
|
||||
{
|
||||
assert(dynamic_cast<SGUpdateVisitor*>(nv));
|
||||
assert(dynamic_cast<osg::Fog*>(sa));
|
||||
SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
|
||||
osg::Fog* fog = static_cast<osg::Fog*>(sa);
|
||||
fog->setMode(osg::Fog::EXP2);
|
||||
fog->setColor(updateVisitor->getFogColor().osg());
|
||||
fog->setDensity(updateVisitor->getGroundLightsFogExp2Density());
|
||||
}
|
||||
};
|
||||
|
||||
osg::Node*
|
||||
SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool use_random_objects)
|
||||
{
|
||||
@@ -550,67 +468,9 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
|
||||
SGGeod geodPos = SGGeod::fromCart(center);
|
||||
SGQuatd hlOr = SGQuatd::fromLonLat(geodPos);
|
||||
SGVec3f up = toVec3f(hlOr.backTransform(SGVec3d(0, 0, -1)));
|
||||
GroundLightManager* lightManager = GroundLightManager::instance();
|
||||
|
||||
osg::Group* vasiLights = new osg::Group;
|
||||
vasiLights->setCullCallback(new SGPointSpriteLightCullCallback(osg::Vec3(1, 0.0001, 0.000001), 6));
|
||||
osg::StateSet* stateSet = vasiLights->getOrCreateStateSet();
|
||||
osg::Fog* fog = new osg::Fog;
|
||||
fog->setUpdateCallback(new SGRunwayLightFogUpdateCallback);
|
||||
stateSet->setAttribute(fog);
|
||||
|
||||
osg::Group* rwyLights = new osg::Group;
|
||||
rwyLights->setCullCallback(new SGPointSpriteLightCullCallback);
|
||||
stateSet = rwyLights->getOrCreateStateSet();
|
||||
fog = new osg::Fog;
|
||||
fog->setUpdateCallback(new SGRunwayLightFogUpdateCallback);
|
||||
stateSet->setAttribute(fog);
|
||||
|
||||
osg::Group* taxiLights = new osg::Group;
|
||||
taxiLights->setCullCallback(new SGPointSpriteLightCullCallback);
|
||||
stateSet = taxiLights->getOrCreateStateSet();
|
||||
fog = new osg::Fog;
|
||||
fog->setUpdateCallback(new SGTaxiLightFogUpdateCallback);
|
||||
stateSet->setAttribute(fog);
|
||||
|
||||
osg::Group* groundLights0 = new osg::Group;
|
||||
stateSet = groundLights0->getOrCreateStateSet();
|
||||
fog = new osg::Fog;
|
||||
fog->setUpdateCallback(new SGGroundLightFogUpdateCallback);
|
||||
stateSet->setAttribute(fog);
|
||||
|
||||
osg::Group* groundLights1 = new osg::Group;
|
||||
stateSet = groundLights1->getOrCreateStateSet();
|
||||
fog = new osg::Fog;
|
||||
fog->setUpdateCallback(new SGGroundLightFogUpdateCallback);
|
||||
stateSet->setAttribute(fog);
|
||||
|
||||
osg::Group* groundLights2 = new osg::Group;
|
||||
stateSet = groundLights2->getOrCreateStateSet();
|
||||
fog = new osg::Fog;
|
||||
fog->setUpdateCallback(new SGGroundLightFogUpdateCallback);
|
||||
stateSet->setAttribute(fog);
|
||||
|
||||
osg::Switch* lightSwitch = new osg::Switch;
|
||||
lightSwitch->setUpdateCallback(new SGTileUpdateCallback);
|
||||
lightSwitch->addChild(vasiLights, true);
|
||||
lightSwitch->addChild(rwyLights, true);
|
||||
lightSwitch->addChild(taxiLights, true);
|
||||
lightSwitch->addChild(groundLights0, true);
|
||||
lightSwitch->addChild(groundLights1, true);
|
||||
lightSwitch->addChild(groundLights2, true);
|
||||
|
||||
osg::Group* lightGroup = new SGOffsetTransform(0.94);
|
||||
lightGroup->addChild(lightSwitch);
|
||||
|
||||
osg::LOD* lightLOD = new osg::LOD;
|
||||
lightLOD->addChild(lightGroup, 0, 30000);
|
||||
unsigned nodeMask = ~0u;
|
||||
nodeMask &= ~SG_NODEMASK_CASTSHADOW_BIT;
|
||||
nodeMask &= ~SG_NODEMASK_RECIEVESHADOW_BIT;
|
||||
nodeMask &= ~SG_NODEMASK_PICK_BIT;
|
||||
nodeMask &= ~SG_NODEMASK_TERRAIN_BIT;
|
||||
lightLOD->setNodeMask(nodeMask);
|
||||
|
||||
osg::ref_ptr<osg::Group> lightGroup = new SGOffsetTransform(0.94);
|
||||
osg::Group* terrainGroup = new osg::Group;
|
||||
osg::Node* node = tileGeometryBin.getSurfaceGeometry(matlib);
|
||||
if (node)
|
||||
@@ -620,21 +480,36 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
|
||||
// FIXME: ugly, has a side effect
|
||||
tileGeometryBin.computeRandomSurfaceLights(matlib);
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
groundLights0->addChild(geode);
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.tileLights));
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.randomTileLights, 4, -0.3f));
|
||||
|
||||
geode = new osg::Geode;
|
||||
groundLights1->addChild(geode);
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.randomTileLights, 2, -0.15f));
|
||||
|
||||
geode = new osg::Geode;
|
||||
groundLights2->addChild(geode);
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.randomTileLights));
|
||||
if (tileGeometryBin.tileLights.getNumLights() > 0
|
||||
|| tileGeometryBin.randomTileLights.getNumLights() > 0) {
|
||||
osg::Group* groundLights0 = new osg::Group;
|
||||
groundLights0->setStateSet(lightManager->getGroundLightStateSet());
|
||||
groundLights0->setNodeMask(GROUNDLIGHTS0_BIT);
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.tileLights));
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.randomTileLights, 4, -0.3f));
|
||||
groundLights0->addChild(geode);
|
||||
lightGroup->addChild(groundLights0);
|
||||
}
|
||||
if (tileGeometryBin.randomTileLights.getNumLights() > 0) {
|
||||
osg::Group* groundLights1 = new osg::Group;
|
||||
groundLights1->setStateSet(lightManager->getGroundLightStateSet());
|
||||
groundLights1->setNodeMask(GROUNDLIGHTS1_BIT);
|
||||
osg::Group* groundLights2 = new osg::Group;
|
||||
groundLights2->setStateSet(lightManager->getGroundLightStateSet());
|
||||
groundLights2->setNodeMask(GROUNDLIGHTS2_BIT);
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.randomTileLights, 2, -0.15f));
|
||||
groundLights1->addChild(geode);
|
||||
lightGroup->addChild(groundLights1);
|
||||
geode = new osg::Geode;
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.randomTileLights));
|
||||
groundLights2->addChild(geode);
|
||||
lightGroup->addChild(groundLights2);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (!tileGeometryBin.vasiLights.empty()) {
|
||||
SGVec4f red(1, 0, 0, 1);
|
||||
SGMaterial* mat = matlib->find("RWY_RED_LIGHTS");
|
||||
if (mat)
|
||||
@@ -643,18 +518,35 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
|
||||
mat = matlib->find("RWY_WHITE_LIGHTS");
|
||||
if (mat)
|
||||
white = mat->get_light_color();
|
||||
osg::Geode* geode;
|
||||
geode = new osg::Geode;
|
||||
vasiLights->addChild(geode);
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
SGDirectionalLightListBin::const_iterator i;
|
||||
for (i = tileGeometryBin.vasiLights.begin();
|
||||
i != tileGeometryBin.vasiLights.end(); ++i) {
|
||||
geode->addDrawable(SGLightFactory::getVasi(up, *i, red, white));
|
||||
}
|
||||
|
||||
geode = new osg::Geode;
|
||||
rwyLights->addChild(geode);
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.runwayLights));
|
||||
osg::Group* vasiLights = new osg::Group;
|
||||
vasiLights->setCullCallback(new SGPointSpriteLightCullCallback(osg::Vec3(1, 0.0001, 0.000001), 6));
|
||||
vasiLights->setStateSet(lightManager->getRunwayLightStateSet());
|
||||
vasiLights->addChild(geode);
|
||||
lightGroup->addChild(vasiLights);
|
||||
}
|
||||
|
||||
if (tileGeometryBin.runwayLights.getNumLights() > 0
|
||||
|| !tileGeometryBin.rabitLights.empty()
|
||||
|| !tileGeometryBin.reilLights.empty()
|
||||
|| !tileGeometryBin.odalLights.empty()) {
|
||||
osg::Group* rwyLights = new osg::Group;
|
||||
rwyLights->setCullCallback(new SGPointSpriteLightCullCallback);
|
||||
rwyLights->setStateSet(lightManager->getRunwayLightStateSet());
|
||||
rwyLights->setNodeMask(RUNWAYLIGHTS_BIT);
|
||||
if (tileGeometryBin.runwayLights.getNumLights() != 0) {
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin
|
||||
.runwayLights));
|
||||
rwyLights->addChild(geode);
|
||||
}
|
||||
SGDirectionalLightListBin::const_iterator i;
|
||||
for (i = tileGeometryBin.rabitLights.begin();
|
||||
i != tileGeometryBin.rabitLights.end(); ++i) {
|
||||
rwyLights->addChild(SGLightFactory::getSequenced(*i));
|
||||
@@ -663,16 +555,23 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
|
||||
i != tileGeometryBin.reilLights.end(); ++i) {
|
||||
rwyLights->addChild(SGLightFactory::getSequenced(*i));
|
||||
}
|
||||
|
||||
SGLightListBin::const_iterator j;
|
||||
for (j = tileGeometryBin.odalLights.begin();
|
||||
j != tileGeometryBin.odalLights.end(); ++j) {
|
||||
rwyLights->addChild(SGLightFactory::getOdal(*j));
|
||||
}
|
||||
lightGroup->addChild(rwyLights);
|
||||
}
|
||||
|
||||
geode = new osg::Geode;
|
||||
taxiLights->addChild(geode);
|
||||
if (tileGeometryBin.taxiLights.getNumLights() > 0) {
|
||||
osg::Group* taxiLights = new osg::Group;
|
||||
taxiLights->setCullCallback(new SGPointSpriteLightCullCallback);
|
||||
taxiLights->setStateSet(lightManager->getTaxiLightStateSet());
|
||||
taxiLights->setNodeMask(RUNWAYLIGHTS_BIT);
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.taxiLights));
|
||||
taxiLights->addChild(geode);
|
||||
lightGroup->addChild(taxiLights);
|
||||
}
|
||||
|
||||
// The toplevel transform for that tile.
|
||||
@@ -680,7 +579,16 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
|
||||
transform->setName(path);
|
||||
transform->setMatrix(osg::Matrix::translate(center.osg()));
|
||||
transform->addChild(terrainGroup);
|
||||
transform->addChild(lightLOD);
|
||||
|
||||
if (lightGroup->getNumChildren() > 0) {
|
||||
osg::LOD* lightLOD = new osg::LOD;
|
||||
lightLOD->addChild(lightGroup.get(), 0, 30000);
|
||||
unsigned nodeMask = ~0u;
|
||||
nodeMask &= ~SG_NODEMASK_CASTSHADOW_BIT;
|
||||
nodeMask &= ~SG_NODEMASK_RECIEVESHADOW_BIT;
|
||||
nodeMask &= ~SG_NODEMASK_PICK_BIT;
|
||||
nodeMask &= ~SG_NODEMASK_TERRAIN_BIT;
|
||||
lightLOD->setNodeMask(nodeMask);
|
||||
transform->addChild(lightLOD);
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
@@ -31,8 +31,14 @@ enum NodeMask {
|
||||
RECEIVESHADOW_BIT = (1 << 3),
|
||||
GUI_BIT = (1 << 4),
|
||||
PANEL2D_BIT = (1 << 5),
|
||||
PICK_BIT = (1 << 6)
|
||||
PICK_BIT = (1 << 6),
|
||||
// Different classes of lights turned on by node masks
|
||||
GROUNDLIGHTS0_BIT = (1 << 7),
|
||||
GROUNDLIGHTS1_BIT = (1 << 8),
|
||||
GROUNDLIGHTS2_BIT = (1 << 9),
|
||||
RUNWAYLIGHTS_BIT = (1 << 10),
|
||||
LIGHTS_BITS = (GROUNDLIGHTS0_BIT | GROUNDLIGHTS1_BIT | GROUNDLIGHTS2_BIT
|
||||
| RUNWAYLIGHTS_BIT)
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user