#include #include #if defined(_MSC_VER) #pragma warning( disable : 4505 ) #pragma warning( default : 4996 ) #endif #include #include "fbxReader.h" osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxLight(FbxNode* pNode, int& nLightCount) { const FbxLight* fbxLight = FbxCast(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(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(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(fbxColor[0]), static_cast(fbxColor[1]), static_cast(fbxColor[2])); } if (fbxLight->Intensity.IsValid()) { osgDiffuseSpecular *= static_cast(fbxLight->Intensity.Get()) * 0.01f; } if (fbxLight->ShadowColor.IsValid()) { FbxDouble3 fbxShadowColor = fbxLight->ShadowColor.Get(); osgAmbient.set( static_cast(fbxShadowColor[0]), static_cast(fbxShadowColor[1]), static_cast(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); }