FBX: Add correct light locations and falloff values.
authorMatt Oliver <protogonoi@gmail.com>
Mon, 9 Jan 2017 05:07:40 +0000 (16:07 +1100)
committerMatt Oliver <protogonoi@gmail.com>
Mon, 9 Jan 2017 06:03:25 +0000 (17:03 +1100)
Fbx lights are stored in the scene graph as well as having separate light properties.
The separate light properties have a light position and direction that is already fully
transformed based on its position in the scene graph so this results in the assimp
light being transformed twice. Since the scene graph contains all the relevant
transformations the light position and direction can just use default values. Fbx
specifies lights along the negative y axis so the default light values have a up and
direction set accordingly.

The DecayStart value specifies the distance from the light that the light intensity
will drop to half. Using the default assimp falloff equation of f=1/c+lr+qr^2 then
the falloff coefficients can be calculated for either c,l or q accordingly by setting
r=DecayStart and f=0.5.

Fixes #851

code/FBXConverter.cpp
code/FBXDocument.h

index 5148f23..ee9ce29 100644 (file)
@@ -640,7 +640,7 @@ void Converter::ConvertLight( const Model& model, const Light& light )
 
     out_light->mName.Set( FixNodeName( model.Name() ) );
 
-    const float intensity = light.Intensity();
+    const float intensity = light.Intensity() / 100.0f;
     const aiVector3D& col = light.Color();
 
     out_light->mColorDiffuse = aiColor3D( col.x, col.y, col.z );
@@ -650,6 +650,11 @@ void Converter::ConvertLight( const Model& model, const Light& light )
 
     out_light->mColorSpecular = out_light->mColorDiffuse;
 
+    //lights are defined along negative y direction
+    out_light->mPosition = aiVector3D(0.0f);
+    out_light->mDirection = aiVector3D(0.0f, -1.0f, 0.0f);
+    out_light->mUp = aiVector3D(0.0f, 0.0f, -1.0f);
+
     switch ( light.LightType() )
     {
     case Light::Type_Point:
@@ -679,17 +684,23 @@ void Converter::ConvertLight( const Model& model, const Light& light )
         ai_assert( false );
     }
 
-    // XXX: how to best convert the near and far decay ranges?
+    float decay = light.DecayStart();
     switch ( light.DecayType() )
     {
     case Light::Decay_None:
-        out_light->mAttenuationConstant = 1.0f;
+        out_light->mAttenuationConstant = decay;
+        out_light->mAttenuationLinear = 0.0f;
+        out_light->mAttenuationQuadratic = 0.0f;
         break;
     case Light::Decay_Linear:
-        out_light->mAttenuationLinear = 1.0f;
+        out_light->mAttenuationConstant = 0.0f;
+        out_light->mAttenuationLinear = 2.0f / decay;
+        out_light->mAttenuationQuadratic = 0.0f;
         break;
     case Light::Decay_Quadratic:
-        out_light->mAttenuationQuadratic = 1.0f;
+        out_light->mAttenuationConstant = 0.0f;
+        out_light->mAttenuationLinear = 0.0f;
+        out_light->mAttenuationQuadratic = 2.0f / (decay * decay);
         break;
     case Light::Decay_Cubic:
         FBXImporter::LogWarn( "cannot represent cubic attenuation, set to Quadratic" );
index be67e32..0abcdcf 100644 (file)
@@ -302,12 +302,12 @@ public:
     fbx_simple_property(DrawVolumetricLight, bool, true)
     fbx_simple_property(DrawGroundProjection, bool, true)
     fbx_simple_property(DrawFrontFacingVolumetricLight, bool, false)
-    fbx_simple_property(Intensity, float, 1.0f)
+    fbx_simple_property(Intensity, float, 100.0f)
     fbx_simple_property(InnerAngle, float, 0.0f)
     fbx_simple_property(OuterAngle, float, 45.0f)
     fbx_simple_property(Fog, int, 50)
-    fbx_simple_enum_property(DecayType, Decay, 0)
-    fbx_simple_property(DecayStart, int, 0)
+    fbx_simple_enum_property(DecayType, Decay, 2)
+    fbx_simple_property(DecayStart, float, 1.0f)
     fbx_simple_property(FileName, std::string, "")
 
     fbx_simple_property(EnableNearAttenuation, bool, false)