Files
OpenSceneGraph/src/osgPlugins/fbx/fbxRLight.cpp

100 lines
3.2 KiB
C++

#include <osg/LightSource>
#include <osgDB/ReadFile>
#if defined(_MSC_VER)
#pragma warning( disable : 4505 )
#pragma warning( default : 4996 )
#endif
#include <fbxsdk.h>
#include "fbxReader.h"
osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxLight(FbxNode* pNode, int& nLightCount)
{
const FbxLight* fbxLight = FbxCast<FbxLight>(pNode->GetNodeAttribute());
if (!fbxLight)
{
return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;
}
osg::Light* osgLight = new osg::Light;
osgLight->setLightNum(nLightCount++);
osg::LightSource* osgLightSource = new osg::LightSource;
osgLightSource->setLight(osgLight);
FbxLight::EType fbxLightType = fbxLight->LightType.IsValid() ?
fbxLight->LightType.Get() : FbxLight::ePoint;
osgLight->setPosition(osg::Vec4(0,0,0,fbxLightType != FbxLight::eDirectional));
if (fbxLightType == FbxLight::eSpot)
{
double coneAngle = fbxLight->OuterAngle.Get();
double hotSpot = fbxLight->InnerAngle.Get();
const float MIN_HOTSPOT = 0.467532f;
osgLight->setSpotCutoff(static_cast<float>(coneAngle));
//Approximate the hotspot using the GL light exponent.
// This formula maps a hotspot of 180 to exponent 0 (uniform light
// distribution) and a hotspot of 45 to exponent 1 (effective light
// intensity is attenuated by the cosine of the angle between the
// direction of the light and the direction from the light to the vertex
// being lighted). A hotspot close to 0 maps to exponent 128 (maximum).
float exponent = (180.0f / (std::max)(static_cast<float>(hotSpot),
MIN_HOTSPOT) - 1.0f) / 3.0f;
osgLight->setSpotExponent(exponent);
}
if (fbxLight->DecayType.IsValid() &&
fbxLight->DecayStart.IsValid())
{
double fbxDecayStart = fbxLight->DecayStart.Get();
switch (fbxLight->DecayType.Get())
{
case FbxLight::eNone:
break;
case FbxLight::eLinear:
osgLight->setLinearAttenuation(fbxDecayStart);
break;
case FbxLight::eQuadratic:
case FbxLight::eCubic:
osgLight->setQuadraticAttenuation(fbxDecayStart);
break;
}
}
osg::Vec3f osgDiffuseSpecular(1.0f, 1.0f, 1.0f);
osg::Vec3f osgAmbient(0.0f, 0.0f, 0.0f);
if (fbxLight->Color.IsValid())
{
FbxDouble3 fbxColor = fbxLight->Color.Get();
osgDiffuseSpecular.set(
static_cast<float>(fbxColor[0]),
static_cast<float>(fbxColor[1]),
static_cast<float>(fbxColor[2]));
}
if (fbxLight->Intensity.IsValid())
{
osgDiffuseSpecular *= static_cast<float>(fbxLight->Intensity.Get()) * 0.01f;
}
if (fbxLight->ShadowColor.IsValid())
{
FbxDouble3 fbxShadowColor = fbxLight->ShadowColor.Get();
osgAmbient.set(
static_cast<float>(fbxShadowColor[0]),
static_cast<float>(fbxShadowColor[1]),
static_cast<float>(fbxShadowColor[2]));
}
osgLight->setDiffuse(osg::Vec4f(osgDiffuseSpecular, 1.0f));
osgLight->setSpecular(osg::Vec4f(osgDiffuseSpecular, 1.0f));
osgLight->setAmbient(osg::Vec4f(osgAmbient, 1.0f));
return osgDB::ReaderWriter::ReadResult(osgLightSource);
}