Files
OpenSceneGraph/src/osgPlugins/OpenFlight/Pools.cpp
Robert Osfield c8aec2a07d Fixed warnings.
2006-07-04 11:24:36 +00:00

122 lines
3.6 KiB
C++

//
// OpenFlight® loader for OpenSceneGraph
//
// Copyright (C) 2005-2006 Brede Johansen
//
#include <cassert>
#include "Pools.h"
#include "Document.h"
using namespace flt;
osg::Vec4 ColorPool::getColor(int indexIntensity) const
{
if (_old) // version <= 13
{
// bit 0-6: intensity
// bit 7-11 color index
// bit 12 fixed intensity bit
bool fixedIntensity = (indexIntensity & 0x1000) ? true : false;
unsigned int index = (fixedIntensity) ? (indexIntensity & 0x0fff)+(4096>>7) : indexIntensity >> 7;
assert(index<size());
osg::Vec4 col = at(index);
if (!fixedIntensity)
{
float intensity = (float)(indexIntensity & 0x7f)/127.f;
col[0] *= intensity;
col[1] *= intensity;
col[2] *= intensity;
}
return col;
}
else // version > 13
{
// bit 0-6: intensity
// bit 7-15 color index
int index = indexIntensity >> 7;
if (index<0 || index>=(int)size())
{
// color index not available.
return osg::Vec4(1,1,1,1);
}
osg::Vec4 col = at(index);
float intensity = (float)(indexIntensity & 0x7f)/127.f;
col[0] *= intensity;
col[1] *= intensity;
col[2] *= intensity;
return col;
}
}
MaterialPool::MaterialPool()
{
// Default material.
// http://www.multigen-paradigm.com/ubb/Forum1/HTML/000228.html
_defaultMaterial = new osg::Material;
_defaultMaterial->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(1,1,1,1));
_defaultMaterial->setDiffuse (osg::Material::FRONT_AND_BACK,osg::Vec4(1,1,1,1));
_defaultMaterial->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(0,0,0,1));
_defaultMaterial->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(0,0,0,1));
_defaultMaterial->setShininess(osg::Material::FRONT_AND_BACK,0);
}
osg::Material* MaterialPool::get(int index)
{
iterator itr = find(index);
if (itr != end())
return (*itr).second.get();
// Use default material if not found in material palette.
return _defaultMaterial.get();
}
namespace {
osg::Vec4 finalColor(const osg::Vec4& materialColor, const osg::Vec4& faceColor)
{
return osg::Vec4(
materialColor.r() * faceColor.r(),
materialColor.g() * faceColor.g(),
materialColor.b() * faceColor.b(),
materialColor.a() * faceColor.a());
}
} // end namespace
osg::Material* MaterialPool::getOrCreateMaterial(int index, const osg::Vec4& faceColor)
{
MaterialParameters materialParam(index,faceColor);
// Look for final material.
FinalMaterialMap::iterator itr = _finalMaterialMap.find(materialParam);
if (itr != _finalMaterialMap.end())
{
// Final material found.
return (*itr).second.get();
}
osg::Material* poolMaterial = get(index);
// Create final material.
osg::Material* material = dynamic_cast<osg::Material*>(poolMaterial->clone(osg::CopyOp::SHALLOW_COPY));
osg::Vec4 materialPaletteAmbient = poolMaterial->getAmbient(osg::Material::FRONT);
osg::Vec4 materialPaletteDiffuse = poolMaterial->getDiffuse(osg::Material::FRONT);
material->setAmbient(osg::Material::FRONT_AND_BACK, finalColor(materialPaletteAmbient, faceColor));
material->setDiffuse(osg::Material::FRONT_AND_BACK, finalColor(materialPaletteDiffuse, faceColor));
material->setAlpha(osg::Material::FRONT_AND_BACK, materialPaletteAmbient.a()*faceColor.a());
// Set final material so it can be reused.
_finalMaterialMap[materialParam] = material;
return material;
}