- fbx: DOM Material -> aiMaterial converter (WIP!).

pull/14/head
acgessler 2012-07-02 19:59:31 +02:00
parent 131008cea1
commit 3f811f4a62
3 changed files with 131 additions and 6 deletions

View File

@ -49,9 +49,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXConverter.h" #include "FBXConverter.h"
#include "FBXDocument.h" #include "FBXDocument.h"
#include "FBXUtil.h" #include "FBXUtil.h"
#include "FBXProperties.h"
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
using namespace Util;
namespace { namespace {
/** Dummy class to encapsulate the conversion process */ /** Dummy class to encapsulate the conversion process */
@ -94,6 +98,7 @@ public:
~Converter() ~Converter()
{ {
std::for_each(meshes.begin(),meshes.end(),Util::delete_fun<aiMesh>()); std::for_each(meshes.begin(),meshes.end(),Util::delete_fun<aiMesh>());
std::for_each(materials.begin(),materials.end(),Util::delete_fun<aiMaterial>());
} }
@ -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<aiVector3D>(props,"Diffuse",ok);
if(ok) {
out_mat->AddProperty(&Diffuse,1,AI_MATKEY_COLOR_DIFFUSE);
}
else {
aiVector3D DiffuseColor = PropertyGet<aiVector3D>(props,"DiffuseColor",ok);
if(ok) {
float DiffuseFactor = PropertyGet<float>(props,"DiffuseFactor",ok);
if(ok) {
DiffuseColor *= DiffuseFactor;
}
out_mat->AddProperty(&DiffuseColor,1,AI_MATKEY_COLOR_DIFFUSE);
}
}
const aiVector3D& Emissive = PropertyGet<aiVector3D>(props,"Emissive",ok);
if(ok) {
out_mat->AddProperty(&Emissive,1,AI_MATKEY_COLOR_EMISSIVE);
}
const aiVector3D& Ambient = PropertyGet<aiVector3D>(props,"Ambient",ok);
if(ok) {
out_mat->AddProperty(&Ambient,1,AI_MATKEY_COLOR_AMBIENT);
}
const aiVector3D& Specular = PropertyGet<aiVector3D>(props,"Specular",ok);
if(ok) {
out_mat->AddProperty(&Specular,1,AI_MATKEY_COLOR_SPECULAR);
}
const float Opacity = PropertyGet<float>(props,"Opacity",ok);
if(ok) {
out_mat->AddProperty(&Opacity,1,AI_MATKEY_OPACITY);
}
const float Reflectivity = PropertyGet<float>(props,"Reflectivity",ok);
if(ok) {
out_mat->AddProperty(&Reflectivity,1,AI_MATKEY_REFLECTIVITY);
}
const float Shininess = PropertyGet<float>(props,"Shininess",ok);
if(ok) {
out_mat->AddProperty(&Shininess,1,AI_MATKEY_SHININESS_STRENGTH);
}
const float ShininessExponent = PropertyGet<float>(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 // copy generated meshes, animations, lights, cameras and textures to the output scene
void TransferDataToScene() void TransferDataToScene()
@ -237,12 +323,19 @@ private:
out->mNumMeshes = static_cast<unsigned int>(meshes.size()); out->mNumMeshes = static_cast<unsigned int>(meshes.size());
std::swap_ranges(meshes.begin(),meshes.end(),out->mMeshes); std::swap_ranges(meshes.begin(),meshes.end(),out->mMeshes);
out->mMaterials = new aiMaterial*[meshes.size()]();
out->mNumMaterials = static_cast<unsigned int>(materials.size());
std::swap_ranges(materials.begin(),materials.end(),out->mMaterials);
} }
private: private:
std::vector<aiMesh*> meshes; std::vector<aiMesh*> meshes;
std::vector<aiMaterial*> materials;
aiScene* const out; aiScene* const out;
const FBX::Document& doc; const FBX::Document& doc;

View File

@ -98,6 +98,14 @@ public:
public: public:
const Element& SourceElement() const {
return element;
}
const std::string& Name() const {
return name;
}
protected: protected:
const Element& element; const Element& element;
const std::string name; const std::string name;
@ -122,8 +130,9 @@ public:
return multilayer; return multilayer;
} }
const PropertyTable* Props() const { const PropertyTable& Props() const {
return props; ai_assert(props.get());
return *props.get();
} }
private: private:

View File

@ -75,7 +75,7 @@ public:
template <typename T> template <typename T>
const T* As() const { const T* As() const {
return dynamic_cast<const T*>(t); return dynamic_cast<const T*>(this);
} }
}; };
@ -141,7 +141,7 @@ private:
template <typename T> template <typename T>
inline T PropertyGet(const PropertyTable& in, const std::string& name, inline T PropertyGet(const PropertyTable& in, const std::string& name,
const T& defaultValue, const T& defaultValue,
bool ignoreTemplate /*= false*/) bool ignoreTemplate = false)
{ {
const Property* const prop = PropertyGet(in,name); const Property* const prop = PropertyGet(in,name);
if(!prop) { if(!prop) {
@ -151,14 +151,37 @@ inline T PropertyGet(const PropertyTable& in, const std::string& name,
// strong typing, no need to be lenient // strong typing, no need to be lenient
const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >(); const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
if(!tprop) { if(!tprop) {
// XXX print type name return defaultValue;
DOMError("unexpected data type: property " + name,in.GetElement());
} }
return tprop->Value(); return tprop->Value();
} }
// ------------------------------------------------------------------------------------------------
template <typename T>
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<T>* const tprop = prop->As< TypedProperty<T> >();
if(!tprop) {
result = false;
return T();
}
result = true;
return tprop->Value();
}
} //! FBX } //! FBX
} //! Assimp } //! Assimp