#include #include #if defined(_MSC_VER) #pragma warning( disable : 4505 ) #pragma warning( default : 4996 ) #endif #include #include "fbxReader.h" osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxLight(KFbxNode* pNode, int& nLightCount) { const KFbxLight* fbxLight = KFbxCast(pNode->GetNodeAttribute()); if (!fbxLight) { return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE; } osg::Light* osgLight = new osg::Light; osg::LightSource* osgLightSource = new osg::LightSource; osgLightSource->setLight(osgLight); osgLight->setLightNum(nLightCount++); KFbxLight::ELightType fbxLightType = fbxLight->LightType.IsValid() ? fbxLight->LightType.Get() : KFbxLight::ePOINT; osgLight->setPosition(osg::Vec4(0,0,0,fbxLightType != KFbxLight::eDIRECTIONAL)); if (fbxLightType == KFbxLight::eSPOT) { double coneAngle = fbxLight->ConeAngle.IsValid() ? fbxLight->ConeAngle.Get() : 45.0; double hotSpot = fbxLight->HotSpot.IsValid() ? fbxLight->HotSpot.Get() : 45.0; 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 KFbxLight::eLINEAR: osgLight->setLinearAttenuation(fbxDecayStart); break; case KFbxLight::eQUADRATIC: case KFbxLight::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); }