- fbx: DOM Material -> aiMaterial converter (WIP!).
parent
131008cea1
commit
3f811f4a62
|
@ -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;
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue