Răsfoiți Sursa

Adds support for area lights.

ciechowoj 9 ani în urmă
părinte
comite
25d84a6aff

+ 1 - 1
code/AssxmlExporter.cpp

@@ -179,7 +179,7 @@ static std::string encodeXML(const std::string& data) {
 
 // -----------------------------------------------------------------------------------
 // Write a text model dump
-static 
+static
 void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
     time_t tt = ::time( NULL );
     tm* p     = ::gmtime( &tt );

+ 17 - 0
code/BlenderLoader.cpp

@@ -1049,7 +1049,24 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
 
             // blender orients directional lights as facing toward -z
             out->mDirection = aiVector3D(0.f, 0.f, -1.f);
+            out->mUp = aiVector3D(0.f, 1.f, 0.f);
             break;
+
+        case Lamp::Type_Area:
+            out->mType = aiLightSource_AREA;
+
+            if (lamp->area_shape == 0) {
+                out->mSize = aiVector2D(lamp->area_size, lamp->area_size);
+            }
+            else {
+                out->mSize = aiVector2D(lamp->area_size, lamp->area_sizey);
+            }
+
+            // blender orients directional lights as facing toward -z
+            out->mDirection = aiVector3D(0.f, 0.f, -1.f);
+            out->mUp = aiVector3D(0.f, 1.f, 0.f);
+            break;
+
         default:
             break;
     }

+ 4 - 0
code/BlenderScene.cpp

@@ -206,6 +206,10 @@ template <> void Structure :: Convert<Lamp> (
     ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
     ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
     ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
+    ReadField<ErrorPolicy_Igno>(dest.area_size,"area_size",db);
+    ReadField<ErrorPolicy_Igno>(dest.area_sizey,"area_sizey",db);
+    ReadField<ErrorPolicy_Igno>(dest.area_sizez,"area_sizez",db);
+    ReadField<ErrorPolicy_Igno>(dest.area_shape,"area_shape",db);
 
     db.reader->IncPtr(size);
 }

+ 2 - 2
code/BlenderScene.h

@@ -371,8 +371,8 @@ struct Lamp : ElemBase {
 
       //short ray_samp, ray_sampy, ray_sampz;
       //short ray_samp_type;
-      //short area_shape;
-      //float area_size, area_sizey, area_sizez;
+      short area_shape;
+      float area_size, area_sizey, area_sizez;
       //float adapt_thresh;
       //short ray_samp_method;
 

+ 1 - 0
code/PretransformVertices.cpp

@@ -618,6 +618,7 @@ void PretransformVertices::Execute( aiScene* pScene)
         // transformation of the corresponding node
         l->mPosition   = nd->mTransformation * l->mPosition;
         l->mDirection  = aiMatrix3x3( nd->mTransformation ) * l->mDirection;
+        l->mUp         = aiMatrix3x3( nd->mTransformation ) * l->mUp;
     }
 
     if( !configKeepHierarchy ) {

+ 16 - 0
include/assimp/light.h

@@ -82,6 +82,10 @@ enum aiLightSourceType
     //! other properties, just a color.
     aiLightSource_AMBIENT       = 0x4,
 
+    //! An area light is a rectangle with predefined size that uniformly
+    //! emits light from one of its sides. The position is center of the
+    //! rectangle and direction is its normal vector.
+    aiLightSource_AREA          = 0x5,
 
     /** This value is not used. It is just there to force the
      *  compiler to map this enum to a 32 Bit integer.
@@ -135,6 +139,14 @@ struct aiLight
      */
     C_STRUCT aiVector3D mDirection;
 
+    /** Up direction of the light source in space. Relative to the
+     *  transformation of the node corresponding to the light.
+     *
+     *  The direction is undefined for point lights. The vector
+     *  may be normalized, but it needn't.
+     */
+    C_STRUCT aiVector3D mUp;
+
     /** Constant light attenuation factor.
      *
      *  The intensity of the light source at a given distance 'd' from
@@ -217,6 +229,9 @@ struct aiLight
      */
     float mAngleOuterCone;
 
+    /** Size of area light source. */
+    C_STRUCT aiVector2D mSize;
+
 #ifdef __cplusplus
 
     aiLight()
@@ -226,6 +241,7 @@ struct aiLight
         ,   mAttenuationQuadratic (0.f)
         ,   mAngleInnerCone       ((float)AI_MATH_TWO_PI)
         ,   mAngleOuterCone       ((float)AI_MATH_TWO_PI)
+        ,   mSize                 (0.f, 0.f)
     {
     }
 

+ 1 - 0
test/CMakeLists.txt

@@ -54,6 +54,7 @@ SOURCE_GROUP( unit FILES
 
 SET( TEST_SRCS
   unit/AssimpAPITest.cpp
+  unit/utBlendImportAreaLight.cpp
   unit/utFastAtof.cpp
   unit/utFindDegenerates.cpp
   unit/utFindInvalidData.cpp

BIN
test/models/BLEND/AreaLight_269.blend


+ 113 - 0
test/unit/utBlendImportAreaLight.cpp

@@ -0,0 +1,113 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2016, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+#include "UnitTestPCH.h"
+
+#include <assimp/cexport.h>
+#include <assimp/Exporter.hpp>
+#include <assimp/Importer.hpp>
+#include <assimp/scene.h>
+
+class BlendImportAreaLight : public ::testing::Test {
+public:
+
+    virtual void SetUp()
+    {
+        im = new Assimp::Importer();
+    }
+
+    virtual void TearDown()
+    {
+        delete im;
+    }
+
+protected:
+
+    Assimp::Importer* im;
+};
+
+// ------------------------------------------------------------------------------------------------
+TEST_F(BlendImportAreaLight, testImportLight)
+{
+    const aiScene* pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/AreaLight_269.blend",0);
+    ASSERT_TRUE(pTest != NULL);
+    ASSERT_TRUE(pTest->HasLights());
+
+    std::vector< std::pair<std::string, size_t> > lightNames;
+
+    for (size_t i = 0; i < pTest->mNumLights; i++) {
+        lightNames.push_back(std::make_pair(pTest->mLights[i]->mName.C_Str(), i));
+    }
+
+    std::sort(lightNames.begin(), lightNames.end());
+
+    std::vector<aiLight> lights;
+
+    for (size_t i = 0; i < pTest->mNumLights; ++i) {
+        lights.push_back(*pTest->mLights[lightNames[i].second]);
+    }
+
+    ASSERT_STREQ(lights[0].mName.C_Str(), "Bar");
+    ASSERT_STREQ(lights[1].mName.C_Str(), "Baz");
+    ASSERT_STREQ(lights[2].mName.C_Str(), "Foo");
+
+    ASSERT_EQ(lights[0].mType, aiLightSource_AREA);
+    ASSERT_EQ(lights[1].mType, aiLightSource_POINT);
+    ASSERT_EQ(lights[2].mType, aiLightSource_AREA);
+
+    EXPECT_FLOAT_EQ(lights[0].mSize.x, 0.5f);
+    EXPECT_FLOAT_EQ(lights[0].mSize.y, 2.0f);
+    EXPECT_FLOAT_EQ(lights[2].mSize.x, 1.0f);
+    EXPECT_FLOAT_EQ(lights[2].mSize.y, 1.0f);
+
+    EXPECT_FLOAT_EQ(lights[0].mColorDiffuse.r, 42.0f);
+    EXPECT_FLOAT_EQ(lights[0].mColorDiffuse.g, 42.0f);
+    EXPECT_FLOAT_EQ(lights[0].mColorDiffuse.b, 42.0f);
+    EXPECT_FLOAT_EQ(lights[2].mColorDiffuse.r, 1.0f);
+    EXPECT_FLOAT_EQ(lights[2].mColorDiffuse.g, 1.0f);
+    EXPECT_FLOAT_EQ(lights[2].mColorDiffuse.b, 1.0f);
+
+    EXPECT_FLOAT_EQ(lights[0].mDirection.x, 0.0f);
+    EXPECT_FLOAT_EQ(lights[0].mDirection.y, 0.0f);
+    EXPECT_FLOAT_EQ(lights[0].mDirection.z, -1.0f);
+    EXPECT_FLOAT_EQ(lights[2].mDirection.x, 0.0f);
+    EXPECT_FLOAT_EQ(lights[2].mDirection.y, 0.0f);
+    EXPECT_FLOAT_EQ(lights[2].mDirection.z, -1.0f);
+}