diff --git a/code/BlenderLoader.cpp b/code/BlenderLoader.cpp index c5071cc26..e09bdbc5f 100644 --- a/code/BlenderLoader.cpp +++ b/code/BlenderLoader.cpp @@ -554,10 +554,8 @@ void BlenderImporter::ResolveTexture(aiMaterial* out, const Material* mat, const } // ------------------------------------------------------------------------------------------------ -void BlenderImporter::BuildMaterials(ConversionData& conv_data) +void BlenderImporter::BuildDefaultMaterial(Blender::ConversionData& conv_data) { - conv_data.materials->reserve(conv_data.materials_raw.size()); - // add a default material if necessary unsigned int index = static_cast( -1 ); for( aiMesh* mesh : conv_data.meshes.get() ) { @@ -588,6 +586,124 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data) mesh->mMaterialIndex = index; } } +} + +void BlenderImporter::AddBlendParams(aiMaterial* result, const Material* source) +{ + aiColor3D diffuseColor(source->r, source->g, source->b); + result->AddProperty(&diffuseColor, 1, "$mat.blend.diffuse.color", 0, 0); + + float diffuseIntensity = source->ref; + result->AddProperty(&diffuseIntensity, 1, "$mat.blend.diffuse.intensity", 0, 0); + + int diffuseShader = source->diff_shader; + result->AddProperty(&diffuseShader, 1, "$mat.blend.diffuse.shader", 0, 0); + + int diffuseRamp = 0; + result->AddProperty(&diffuseRamp, 1, "$mat.blend.diffuse.ramp", 0, 0); + + + aiColor3D specularColor(source->specr, source->specg, source->specb); + result->AddProperty(&specularColor, 1, "$mat.blend.specular.color", 0, 0); + + float specularIntensity = source->spec; + result->AddProperty(&specularIntensity, 1, "$mat.blend.specular.intensity", 0, 0); + + int specularShader = source->spec_shader; + result->AddProperty(&specularShader, 1, "$mat.blend.specular.shader", 0, 0); + + int specularRamp = 0; + result->AddProperty(&specularRamp, 1, "$mat.blend.specular.ramp", 0, 0); + + int specularHardness = source->har; + result->AddProperty(&specularHardness, 1, "$mat.blend.specular.hardness", 0, 0); + + + int transparencyUse = source->mode & MA_TRANSPARENCY ? 1 : 0; + result->AddProperty(&transparencyUse, 1, "$mat.blend.transparency.use", 0, 0); + + int transparencyMethod = source->mode & MA_RAYTRANSP ? 2 : (source->mode & MA_ZTRANSP ? 1 : 0); + result->AddProperty(&transparencyMethod, 1, "$mat.blend.transparency.method", 0, 0); + + float transparencyAlpha = source->alpha; + result->AddProperty(&transparencyAlpha, 1, "$mat.blend.transparency.alpha", 0, 0); + + float transparencySpecular = source->spectra; + result->AddProperty(&transparencySpecular, 1, "$mat.blend.transparency.specular", 0, 0); + + float transparencyFresnel = source->fresnel_tra; + result->AddProperty(&transparencyFresnel, 1, "$mat.blend.transparency.fresnel", 0, 0); + + float transparencyBlend = source->fresnel_tra_i; + result->AddProperty(&transparencyBlend, 1, "$mat.blend.transparency.blend", 0, 0); + + float transparencyIor = source->ang; + result->AddProperty(&transparencyIor, 1, "$mat.blend.transparency.ior", 0, 0); + + float transparencyFilter = source->filter; + result->AddProperty(&transparencyFilter, 1, "$mat.blend.transparency.filter", 0, 0); + + float transparencyFalloff = source->tx_falloff; + result->AddProperty(&transparencyFalloff, 1, "$mat.blend.transparency.falloff", 0, 0); + + float transparencyLimit = source->tx_limit; + result->AddProperty(&transparencyLimit, 1, "$mat.blend.transparency.limit", 0, 0); + + int transparencyDepth = source->ray_depth_tra; + result->AddProperty(&transparencyDepth, 1, "$mat.blend.transparency.depth", 0, 0); + + float transparencyGlossAmount = source->gloss_tra; + result->AddProperty(&transparencyGlossAmount, 1, "$mat.blend.transparency.glossAmount", 0, 0); + + float transparencyGlossThreshold = source->adapt_thresh_tra; + result->AddProperty(&transparencyGlossThreshold, 1, "$mat.blend.transparency.glossThreshold", 0, 0); + + int transparencyGlossSamples = source->samp_gloss_tra; + result->AddProperty(&transparencyGlossSamples, 1, "$mat.blend.transparency.glossSamples", 0, 0); + + + int mirrorUse = source->mode & MA_RAYMIRROR ? 1 : 0; + result->AddProperty(&mirrorUse, 1, "$mat.blend.mirror.use", 0, 0); + + float mirrorReflectivity = source->ray_mirror; + result->AddProperty(&mirrorReflectivity, 1, "$mat.blend.mirror.reflectivity", 0, 0); + + aiColor3D mirrorColor(source->mirr, source->mirg, source->mirb); + result->AddProperty(&mirrorColor, 1, "$mat.blend.mirror.color", 0, 0); + + float mirrorFresnel = source->fresnel_mir; + result->AddProperty(&mirrorFresnel, 1, "$mat.blend.mirror.fresnel", 0, 0); + + float mirrorBlend = source->fresnel_mir_i; + result->AddProperty(&mirrorBlend, 1, "$mat.blend.mirror.blend", 0, 0); + + int mirrorDepth = source->ray_depth; + result->AddProperty(&mirrorDepth, 1, "$mat.blend.mirror.depth", 0, 0); + + float mirrorMaxDist = source->dist_mir; + result->AddProperty(&mirrorMaxDist, 1, "$mat.blend.mirror.maxDist", 0, 0); + + int mirrorFadeTo = source->fadeto_mir; + result->AddProperty(&mirrorFadeTo, 1, "$mat.blend.mirror.fadeTo", 0, 0); + + float mirrorGlossAmount = source->gloss_mir; + result->AddProperty(&mirrorGlossAmount, 1, "$mat.blend.mirror.glossAmount", 0, 0); + + float mirrorGlossThreshold = source->adapt_thresh_mir; + result->AddProperty(&mirrorGlossThreshold, 1, "$mat.blend.mirror.glossThreshold", 0, 0); + + int mirrorGlossSamples = source->samp_gloss_mir; + result->AddProperty(&mirrorGlossSamples, 1, "$mat.blend.mirror.glossSamples", 0, 0); + + float mirrorGlossAnisotropic = source->aniso_gloss_mir; + result->AddProperty(&mirrorGlossAnisotropic, 1, "$mat.blend.mirror.glossAnisotropic", 0, 0); +} + +void BlenderImporter::BuildMaterials(ConversionData& conv_data) +{ + conv_data.materials->reserve(conv_data.materials_raw.size()); + + BuildDefaultMaterial(conv_data); for(std::shared_ptr mat : conv_data.materials_raw) { @@ -604,7 +720,6 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data) aiString name = aiString(mat->id.name+2); // skip over the name prefix 'MA' mout->AddProperty(&name,AI_MATKEY_NAME); - // basic material colors aiColor3D col(mat->r,mat->g,mat->b); if (mat->r || mat->g || mat->b ) { @@ -647,6 +762,8 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data) ResolveTexture(mout,mat.get(),mat->mtex[i].get(),conv_data); } + + AddBlendParams(mout, mat.get()); } } diff --git a/code/BlenderLoader.h b/code/BlenderLoader.h index ff13517f3..c964eee32 100644 --- a/code/BlenderLoader.h +++ b/code/BlenderLoader.h @@ -179,9 +179,18 @@ private: ); // -------------------- + void BuildDefaultMaterial( + Blender::ConversionData& conv_data + ); + + void AddBlendParams( + aiMaterial* result, + const Blender::Material* source + ); + void BuildMaterials( Blender::ConversionData& conv_data - ) ; + ); // -------------------- void ResolveTexture( diff --git a/code/BlenderScene.cpp b/code/BlenderScene.cpp index cb0245fce..f4d07662e 100644 --- a/code/BlenderScene.cpp +++ b/code/BlenderScene.cpp @@ -301,7 +301,6 @@ template <> void Structure :: Convert ( const FileDatabase& db ) const { - ReadField(dest.id,"id",db); ReadField(dest.r,"r",db); ReadField(dest.g,"g",db); @@ -330,6 +329,91 @@ template <> void Structure :: Convert ( ReadField(dest.spec_shader,"spec_shader",db); ReadFieldPtr(dest.mtex,"*mtex",db); + + ReadField(dest.amb, "amb", db); + ReadField(dest.ang, "ang", db); + ReadField(dest.spectra, "spectra", db); + ReadField(dest.spec, "spec", db); + ReadField(dest.zoffs, "zoffs", db); + ReadField(dest.add, "add", db); + ReadField(dest.fresnel_mir, "fresnel_mir", db); + ReadField(dest.fresnel_mir_i, "fresnel_mir_i", db); + ReadField(dest.fresnel_tra, "fresnel_tra", db); + ReadField(dest.fresnel_tra_i, "fresnel_tra_i", db); + ReadField(dest.filter, "filter", db); + ReadField(dest.tx_limit, "tx_limit", db); + ReadField(dest.tx_falloff, "tx_falloff", db); + ReadField(dest.gloss_mir, "gloss_mir", db); + ReadField(dest.gloss_tra, "gloss_tra", db); + ReadField(dest.adapt_thresh_mir, "adapt_thresh_mir", db); + ReadField(dest.adapt_thresh_tra, "adapt_thresh_tra", db); + ReadField(dest.aniso_gloss_mir, "aniso_gloss_mir", db); + ReadField(dest.dist_mir, "dist_mir", db); + ReadField(dest.hasize, "hasize", db); + ReadField(dest.flaresize, "flaresize", db); + ReadField(dest.subsize, "subsize", db); + ReadField(dest.flareboost, "flareboost", db); + ReadField(dest.strand_sta, "strand_sta", db); + ReadField(dest.strand_end, "strand_end", db); + ReadField(dest.strand_ease, "strand_ease", db); + ReadField(dest.strand_surfnor, "strand_surfnor", db); + ReadField(dest.strand_min, "strand_min", db); + ReadField(dest.strand_widthfade, "strand_widthfade", db); + ReadField(dest.sbias, "sbias", db); + ReadField(dest.lbias, "lbias", db); + ReadField(dest.shad_alpha, "shad_alpha", db); + ReadField(dest.param, "param", db); + ReadField(dest.rms, "rms", db); + ReadField(dest.rampfac_col, "rampfac_col", db); + ReadField(dest.rampfac_spec, "rampfac_spec", db); + ReadField(dest.friction, "friction", db); + ReadField(dest.fh, "fh", db); + ReadField(dest.reflect, "reflect", db); + ReadField(dest.fhdist, "fhdist", db); + ReadField(dest.xyfrict, "xyfrict", db); + ReadField(dest.sss_radius, "sss_radius", db); + ReadField(dest.sss_col, "sss_col", db); + ReadField(dest.sss_error, "sss_error", db); + ReadField(dest.sss_scale, "sss_scale", db); + ReadField(dest.sss_ior, "sss_ior", db); + ReadField(dest.sss_colfac, "sss_colfac", db); + ReadField(dest.sss_texfac, "sss_texfac", db); + ReadField(dest.sss_front, "sss_front", db); + ReadField(dest.sss_back, "sss_back", db); + + ReadField(dest.material_type, "material_type", db); + ReadField(dest.flag, "flag", db); + ReadField(dest.ray_depth, "ray_depth", db); + ReadField(dest.ray_depth_tra, "ray_depth_tra", db); + ReadField(dest.samp_gloss_mir, "samp_gloss_mir", db); + ReadField(dest.samp_gloss_tra, "samp_gloss_tra", db); + ReadField(dest.fadeto_mir, "fadeto_mir", db); + ReadField(dest.shade_flag, "shade_flag", db); + ReadField(dest.flarec, "flarec", db); + ReadField(dest.starc, "starc", db); + ReadField(dest.linec, "linec", db); + ReadField(dest.ringc, "ringc", db); + ReadField(dest.pr_lamp, "pr_lamp", db); + ReadField(dest.pr_texture, "pr_texture", db); + ReadField(dest.ml_flag, "ml_flag", db); + ReadField(dest.diff_shader, "diff_shader", db); + ReadField(dest.spec_shader, "spec_shader", db); + ReadField(dest.texco, "texco", db); + ReadField(dest.mapto, "mapto", db); + ReadField(dest.ramp_show, "ramp_show", db); + ReadField(dest.pad3, "pad3", db); + ReadField(dest.dynamode, "dynamode", db); + ReadField(dest.pad2, "pad2", db); + ReadField(dest.sss_flag, "sss_flag", db); + ReadField(dest.sss_preset, "sss_preset", db); + ReadField(dest.shadowonly_flag, "shadowonly_flag", db); + ReadField(dest.index, "index", db); + ReadField(dest.vcol_alpha, "vcol_alpha", db); + ReadField(dest.pad4, "pad4", db); + + ReadField(dest.seed1, "seed1", db); + ReadField(dest.seed2, "seed2", db); + db.reader->IncPtr(size); } diff --git a/code/BlenderScene.h b/code/BlenderScene.h index 5305789b7..9de0fcb39 100644 --- a/code/BlenderScene.h +++ b/code/BlenderScene.h @@ -242,6 +242,9 @@ struct MDeformVert : ElemBase { // ------------------------------------------------------------------------------- #define MA_RAYMIRROR 0x40000 +#define MA_TRANSPARENCY 0x10000 +#define MA_RAYTRANSP 0x20000 +#define MA_ZTRANSP 0x00040 struct Material : ElemBase { ID id FAIL; @@ -261,6 +264,89 @@ struct Material : ElemBase { float darkness; float refrac; + + float amb; + float ang; + float spectra; + float spec; + float zoffs; + float add; + float fresnel_mir; + float fresnel_mir_i; + float fresnel_tra; + float fresnel_tra_i; + float filter; + float tx_limit; + float tx_falloff; + float gloss_mir; + float gloss_tra; + float adapt_thresh_mir; + float adapt_thresh_tra; + float aniso_gloss_mir; + float dist_mir; + float hasize; + float flaresize; + float subsize; + float flareboost; + float strand_sta; + float strand_end; + float strand_ease; + float strand_surfnor; + float strand_min; + float strand_widthfade; + float sbias; + float lbias; + float shad_alpha; + float param; + float rms; + float rampfac_col; + float rampfac_spec; + float friction; + float fh; + float reflect; + float fhdist; + float xyfrict; + float sss_radius; + float sss_col; + float sss_error; + float sss_scale; + float sss_ior; + float sss_colfac; + float sss_texfac; + float sss_front; + float sss_back; + + short material_type; + short flag; + short ray_depth; + short ray_depth_tra; + short samp_gloss_mir; + short samp_gloss_tra; + short fadeto_mir; + short shade_flag; + short flarec; + short starc; + short linec; + short ringc; + short pr_lamp; + short pr_texture; + short ml_flag; + short texco; + short mapto; + short ramp_show; + short pad3; + short dynamode; + short pad2; + short sss_flag; + short sss_preset; + short shadowonly_flag; + short index; + short vcol_alpha; + short pad4; + + char seed1; + char seed2; + std::shared_ptr group; short diff_shader WARN; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0a9e10e40..33ad8460a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,6 @@ # Open Asset Import Library (assimp) # ---------------------------------------------------------------------- -# +# # Copyright (c) 2006-2016, assimp team # All rights reserved. # @@ -55,6 +55,9 @@ SOURCE_GROUP( unit FILES SET( TEST_SRCS unit/AssimpAPITest.cpp unit/utBlendImportAreaLight.cpp + unit/utBlendImportMaterials.cpp + unit/utColladaExportCamera.cpp + unit/utColladaExportLight.cpp unit/utFastAtof.cpp unit/utFindDegenerates.cpp unit/utFindInvalidData.cpp @@ -63,6 +66,7 @@ SET( TEST_SRCS unit/utImporter.cpp unit/utImproveCacheLocality.cpp unit/utIOSystem.cpp + unit/utIssues.cpp unit/utJoinVertices.cpp unit/utLimitBoneWeights.cpp unit/utMaterialSystem.cpp @@ -80,9 +84,6 @@ SET( TEST_SRCS unit/utTextureTransform.cpp unit/utTriangulate.cpp unit/utVertexTriangleAdjacency.cpp - unit/utColladaExportCamera.cpp - unit/utColladaExportLight.cpp - unit/utIssues.cpp ) SOURCE_GROUP( tests FILES ${TEST_SRCS} ) diff --git a/test/models/BLEND/BlenderMaterial_269.blend b/test/models/BLEND/BlenderMaterial_269.blend new file mode 100644 index 000000000..4c00fec9d Binary files /dev/null and b/test/models/BLEND/BlenderMaterial_269.blend differ diff --git a/test/unit/utBlendImportMaterials.cpp b/test/unit/utBlendImportMaterials.cpp new file mode 100644 index 000000000..f45c2a219 --- /dev/null +++ b/test/unit/utBlendImportMaterials.cpp @@ -0,0 +1,124 @@ +/* +--------------------------------------------------------------------------- +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 +#include +#include + +class BlendImportMaterials : public ::testing::Test { +public: + + virtual void SetUp() + { + im = new Assimp::Importer(); + } + + virtual void TearDown() + { + delete im; + } + +protected: + + Assimp::Importer* im; +}; + +// ------------------------------------------------------------------------------------------------ +TEST_F(BlendImportMaterials, testImportMaterial) +{ + const aiScene* pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/BlenderMaterial_269.blend", 0); + ASSERT_TRUE(pTest != NULL); + ASSERT_TRUE(pTest->HasMaterials()); + + ASSERT_EQ(1, pTest->mNumMaterials); + + auto alpha = pTest->mMaterials[0]; + + #define ASSERT_PROPERTY_EQ(expected, key, var) \ + auto var = expected; \ + ASSERT_EQ(aiReturn_SUCCESS, alpha->Get("$mat.blend." key, 0, 0, var)); \ + ASSERT_EQ(expected, var); + + #define ASSERT_PROPERTY_FLOAT_EQ(expected, key, var) \ + auto var = expected; \ + ASSERT_EQ(aiReturn_SUCCESS, alpha->Get("$mat.blend." key, 0, 0, var)); \ + ASSERT_FLOAT_EQ(expected, var); + + ASSERT_PROPERTY_EQ(aiColor3D(0.1f, 0.2f, 0.3f), "diffuse.color", diffuseColor); + ASSERT_PROPERTY_EQ(0.4f, "diffuse.intensity", diffuseIntensity); + ASSERT_PROPERTY_EQ(1, "diffuse.shader", diffuseShader); + ASSERT_PROPERTY_EQ(0, "diffuse.ramp", diffuseRamp); + + ASSERT_PROPERTY_EQ(aiColor3D(0.5f, 0.6f, 0.7f), "specular.color", specularColor); + ASSERT_PROPERTY_EQ(0.8f, "specular.intensity", specularIntensity); + ASSERT_PROPERTY_EQ(1, "specular.shader", specularShader); + ASSERT_PROPERTY_EQ(0, "specular.ramp", specularRamp); + ASSERT_PROPERTY_EQ(9, "specular.hardness", specularHardness); + + ASSERT_PROPERTY_EQ(1, "transparency.use", transparencyUse); + ASSERT_PROPERTY_EQ(2, "transparency.method", transparencyMethod); + ASSERT_PROPERTY_EQ(0.01f, "transparency.alpha", transparencyAlpha); + ASSERT_PROPERTY_EQ(0.02f, "transparency.specular", transparencySpecular); + ASSERT_PROPERTY_EQ(0.03f, "transparency.fresnel", transparencyFresnel); + ASSERT_PROPERTY_EQ(3.14f, "transparency.blend", transparencyBlend); + ASSERT_PROPERTY_EQ(0.85f, "transparency.ior", transparencyIor); + ASSERT_PROPERTY_FLOAT_EQ(0.128f, "transparency.filter", transparencyFilter); + ASSERT_PROPERTY_FLOAT_EQ(1.298f, "transparency.falloff", transparencyFalloff); + ASSERT_PROPERTY_FLOAT_EQ(0.2376f, "transparency.limit", transparencyLimit); + ASSERT_PROPERTY_EQ(7, "transparency.depth", transparencyDepth); + ASSERT_PROPERTY_FLOAT_EQ(0.678f, "transparency.glossAmount", transparencyGlossAmount); + ASSERT_PROPERTY_FLOAT_EQ(0.208f, "transparency.glossThreshold", transparencyGlossThreshold); + ASSERT_PROPERTY_EQ(17, "transparency.glossSamples", transparencyGlossSamples); + + ASSERT_PROPERTY_EQ(1, "mirror.use", mirrorUse); + ASSERT_PROPERTY_FLOAT_EQ(0.28f, "mirror.reflectivity", mirrorReflectivity); + ASSERT_PROPERTY_EQ(aiColor3D(0.25f, 0.5f, 0.128f), "mirror.color", mirrorColor); + ASSERT_PROPERTY_FLOAT_EQ(0.256f, "mirror.fresnel", mirrorFresnel); + ASSERT_PROPERTY_FLOAT_EQ(1.61f, "mirror.blend", mirrorBlend); + ASSERT_PROPERTY_EQ(12, "mirror.depth", mirrorDepth); + ASSERT_PROPERTY_FLOAT_EQ(0.4f, "mirror.maxDist", mirrorMaxDist); + ASSERT_PROPERTY_EQ(1, "mirror.fadeTo", mirrorFadeTo); + ASSERT_PROPERTY_FLOAT_EQ(0.512f, "mirror.glossAmount", mirrorGlossAmount); + ASSERT_PROPERTY_FLOAT_EQ(0.18f, "mirror.glossThreshold", mirrorGlossThreshold); + ASSERT_PROPERTY_EQ(61, "mirror.glossSamples", mirrorGlossSamples); + ASSERT_PROPERTY_FLOAT_EQ(0.87f, "mirror.glossAnisotropic", mirrorGlossAnisotropic); +}