From 3f811f4a6264e3f5447017842effa6d40c9b6a00 Mon Sep 17 00:00:00 2001 From: acgessler Date: Mon, 2 Jul 2012 19:59:31 +0200 Subject: [PATCH] - fbx: DOM Material -> aiMaterial converter (WIP!). --- code/FBXConverter.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++ code/FBXDocument.h | 13 +++++- code/FBXProperties.h | 31 +++++++++++++-- 3 files changed, 131 insertions(+), 6 deletions(-) diff --git a/code/FBXConverter.cpp b/code/FBXConverter.cpp index 61a307ff6..0cb77aa9d 100644 --- a/code/FBXConverter.cpp +++ b/code/FBXConverter.cpp @@ -49,9 +49,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FBXConverter.h" #include "FBXDocument.h" #include "FBXUtil.h" +#include "FBXProperties.h" namespace Assimp { namespace FBX { + + using namespace Util; + namespace { /** Dummy class to encapsulate the conversion process */ @@ -94,6 +98,7 @@ public: ~Converter() { std::for_each(meshes.begin(),meshes.end(),Util::delete_fun()); + std::for_each(materials.begin(),materials.end(),Util::delete_fun()); } @@ -224,6 +229,87 @@ private: } + // ------------------------------------------------------------------------------------------------ + // Material -> aiMaterial + void ConvertMaterial(const Material& material) + { + const PropertyTable& props = material.Props(); + + // generate empty output material + aiMaterial* out_mat = new aiMaterial(); + materials.push_back(out_mat); + + aiString str; + + // set material name + str.Set(material.Name()); + out_mat->AddProperty(&str,AI_MATKEY_NAME); + + SetShadingPropertiesCommon(out_mat,props); + } + + // ------------------------------------------------------------------------------------------------ + void SetShadingPropertiesCommon(aiMaterial* out_mat, const PropertyTable& props) + { + // set shading properties. There are various, redundant ways in which FBX materials + // specify their shading settings (depending on shading models, prop + // template etc.). No idea which one is right in a particular context. + // Just try to make sense of it - there's no spec to verify this against, + // so why should we. + bool ok; + const aiVector3D& Diffuse = PropertyGet(props,"Diffuse",ok); + if(ok) { + out_mat->AddProperty(&Diffuse,1,AI_MATKEY_COLOR_DIFFUSE); + } + else { + aiVector3D DiffuseColor = PropertyGet(props,"DiffuseColor",ok); + if(ok) { + float DiffuseFactor = PropertyGet(props,"DiffuseFactor",ok); + if(ok) { + DiffuseColor *= DiffuseFactor; + } + + out_mat->AddProperty(&DiffuseColor,1,AI_MATKEY_COLOR_DIFFUSE); + } + } + + const aiVector3D& Emissive = PropertyGet(props,"Emissive",ok); + if(ok) { + out_mat->AddProperty(&Emissive,1,AI_MATKEY_COLOR_EMISSIVE); + } + + const aiVector3D& Ambient = PropertyGet(props,"Ambient",ok); + if(ok) { + out_mat->AddProperty(&Ambient,1,AI_MATKEY_COLOR_AMBIENT); + } + + const aiVector3D& Specular = PropertyGet(props,"Specular",ok); + if(ok) { + out_mat->AddProperty(&Specular,1,AI_MATKEY_COLOR_SPECULAR); + } + + const float Opacity = PropertyGet(props,"Opacity",ok); + if(ok) { + out_mat->AddProperty(&Opacity,1,AI_MATKEY_OPACITY); + } + + const float Reflectivity = PropertyGet(props,"Reflectivity",ok); + if(ok) { + out_mat->AddProperty(&Reflectivity,1,AI_MATKEY_REFLECTIVITY); + } + + const float Shininess = PropertyGet(props,"Shininess",ok); + if(ok) { + out_mat->AddProperty(&Shininess,1,AI_MATKEY_SHININESS_STRENGTH); + } + + const float ShininessExponent = PropertyGet(props,"ShininessExponent",ok); + if(ok) { + out_mat->AddProperty(&ShininessExponent,1,AI_MATKEY_SHININESS); + } + } + + // ------------------------------------------------------------------------------------------------ // copy generated meshes, animations, lights, cameras and textures to the output scene void TransferDataToScene() @@ -237,12 +323,19 @@ private: out->mNumMeshes = static_cast(meshes.size()); std::swap_ranges(meshes.begin(),meshes.end(),out->mMeshes); + + + out->mMaterials = new aiMaterial*[meshes.size()](); + out->mNumMaterials = static_cast(materials.size()); + + std::swap_ranges(materials.begin(),materials.end(),out->mMaterials); } private: std::vector meshes; + std::vector materials; aiScene* const out; const FBX::Document& doc; diff --git a/code/FBXDocument.h b/code/FBXDocument.h index 58837398c..7bbb4fcf8 100644 --- a/code/FBXDocument.h +++ b/code/FBXDocument.h @@ -98,6 +98,14 @@ public: public: + const Element& SourceElement() const { + return element; + } + + const std::string& Name() const { + return name; + } + protected: const Element& element; const std::string name; @@ -122,8 +130,9 @@ public: return multilayer; } - const PropertyTable* Props() const { - return props; + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); } private: diff --git a/code/FBXProperties.h b/code/FBXProperties.h index cf930c5b3..43e0bb82e 100644 --- a/code/FBXProperties.h +++ b/code/FBXProperties.h @@ -75,7 +75,7 @@ public: template const T* As() const { - return dynamic_cast(t); + return dynamic_cast(this); } }; @@ -141,7 +141,7 @@ private: template inline T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue, - bool ignoreTemplate /*= false*/) + bool ignoreTemplate = false) { const Property* const prop = PropertyGet(in,name); if(!prop) { @@ -151,14 +151,37 @@ inline T PropertyGet(const PropertyTable& in, const std::string& name, // strong typing, no need to be lenient const TypedProperty* const tprop = prop->As< TypedProperty >(); if(!tprop) { - // XXX print type name - DOMError("unexpected data type: property " + name,in.GetElement()); + return defaultValue; } return tprop->Value(); } +// ------------------------------------------------------------------------------------------------ +template +inline T PropertyGet(const PropertyTable& in, const std::string& name, + bool& result, + bool ignoreTemplate = false) +{ + const Property* const prop = in.Get(name); + if(!prop) { + result = false; + return T(); + } + + // strong typing, no need to be lenient + const TypedProperty* const tprop = prop->As< TypedProperty >(); + if(!tprop) { + result = false; + return T(); + } + + result = true; + return tprop->Value(); +} + + } //! FBX } //! Assimp