瀏覽代碼

Merge pull request #703 from terziman/master

Improvement of collada transparency handling
Alexander Gessler 9 年之前
父節點
當前提交
5847576f41
共有 5 個文件被更改,包括 25 次插入23 次删除
  1. 3 1
      code/ColladaHelper.h
  2. 14 8
      code/ColladaLoader.cpp
  3. 0 1
      code/ColladaLoader.h
  4. 8 3
      code/ColladaParser.cpp
  5. 0 10
      include/assimp/config.h

+ 3 - 1
code/ColladaHelper.h

@@ -517,6 +517,7 @@ struct Effect
     float mTransparency;
     bool mHasTransparency;
     bool mRGBTransparency;
+    bool mInvertTransparency;
 
     // local params referring to each other by their SID
     typedef std::map<std::string, Collada::EffectParam> ParamLibrary;
@@ -536,10 +537,11 @@ struct Effect
         , mTransparent  ( 0, 0, 0, 1)
         , mShininess    (10.0f)
         , mRefractIndex (1.f)
-        , mReflectivity (1.f)
+        , mReflectivity (0.f)
         , mTransparency (1.f)
         , mHasTransparency (false)
         , mRGBTransparency(false)
+        , mInvertTransparency(false)
         , mDoubleSided  (false)
         , mWireframe    (false)
         , mFaceted      (false)

+ 14 - 8
code/ColladaLoader.cpp

@@ -83,7 +83,6 @@ static const aiImporterDesc desc = {
 ColladaLoader::ColladaLoader()
     : noSkeletonMesh()
     , ignoreUpDirection(false)
-    , invertTransparency(false)
     , mNodeNameCounter()
 {}
 
@@ -120,7 +119,6 @@ void ColladaLoader::SetupProperties(const Importer* pImp)
 {
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
     ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION,0) != 0;
-    invertTransparency = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_INVERT_TRANSPARENCY,0) != 0;
 }
 
 
@@ -1341,7 +1339,6 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
         mat.AddProperty( &effect.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
         mat.AddProperty( &effect.mSpecular, 1,AI_MATKEY_COLOR_SPECULAR);
         mat.AddProperty( &effect.mEmissive, 1,  AI_MATKEY_COLOR_EMISSIVE);
-        mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT);
         mat.AddProperty( &effect.mReflective, 1, AI_MATKEY_COLOR_REFLECTIVE);
 
         // scalar properties
@@ -1354,20 +1351,29 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
         // therefore, we let the opportunity for the user to manually invert
         // the transparency if necessary and we add preliminary support for RGB_ZERO mode
         if(effect.mTransparency >= 0.f && effect.mTransparency <= 1.f) {
-            // Trying some support for RGB_ZERO mode
+            // handle RGB transparency completely, cf Collada specs 1.5.0 pages 249 and 304
             if(effect.mRGBTransparency) {
-                effect.mTransparency = 1.f - effect.mTransparent.a;
+				// use luminance as defined by ISO/CIE color standards (see ITU-R Recommendation BT.709-4)
+                effect.mTransparency *= (
+                    0.212671f * effect.mTransparent.r +
+                    0.715160f * effect.mTransparent.g +
+                    0.072169 * effect.mTransparent.b
+                );
+
+                effect.mTransparent.a = 1.f;
+
+                mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
+            } else {
+                effect.mTransparency *=  effect.mTransparent.a;
             }
 
-            // Global option
-            if(invertTransparency) {
+            if(effect.mInvertTransparency) {
                 effect.mTransparency = 1.f - effect.mTransparency;
             }
 
             // Is the material finally transparent ?
             if (effect.mHasTransparency || effect.mTransparency < 1.f) {
                 mat.AddProperty( &effect.mTransparency, 1, AI_MATKEY_OPACITY );
-                mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
             }
         }
 

+ 0 - 1
code/ColladaLoader.h

@@ -241,7 +241,6 @@ protected:
 
     bool noSkeletonMesh;
     bool ignoreUpDirection;
-    bool invertTransparency;
 
     /** Used by FindNameForNode() to generate unique node names */
     unsigned int mNodeNameCounter;

+ 8 - 3
code/ColladaParser.cpp

@@ -1256,12 +1256,17 @@ void ColladaParser::ReadEffectProfileCommon( Collada::Effect& pEffect)
             else if( IsElement( "transparent")) {
                 pEffect.mHasTransparency = true;
 
-                // In RGB_ZERO mode, the transparency is interpreted in reverse, go figure...
-                if(::strcmp(mReader->getAttributeValueSafe("opaque"), "RGB_ZERO") == 0) {
-                    // TODO: handle RGB_ZERO mode completely
+                const char* opaque = mReader->getAttributeValueSafe("opaque");
+ 
+                if(::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "RGB_ONE") == 0) {
                     pEffect.mRGBTransparency = true;
                 }
 
+                // In RGB_ZERO mode, the transparency is interpreted in reverse, go figure...
+				if(::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "A_ZERO") == 0) {
+					pEffect.mInvertTransparency = true;
+				}
+
                 ReadEffectColor( pEffect.mTransparent,pEffect.mTexTransparent);
             }
             else if( IsElement( "shininess"))

+ 0 - 10
include/assimp/config.h

@@ -895,16 +895,6 @@ enum aiComponent
  */
 #define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
 
-// ---------------------------------------------------------------------------
-/** @brief Specifies whether the Collada loader will invert the transparency value.
- *
- * If this property is set to true, the transparency value will be interpreted as the
- * inverse of the usual transparency. This is useful because lots of exporters does
- * not respect the standard and do the opposite of what is normally expected.
- * Property type: Bool. Default value: false.
- */
-#define AI_CONFIG_IMPORT_COLLADA_INVERT_TRANSPARENCY "IMPORT_COLLADA_INVERT_TRANSPARENCY"
-
 // ---------- All the Export defines ------------
 
 /** @brief Specifies the xfile use double for real values of float