diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index c9226b8f3..ae77bcafb 100644 --- a/code/FBXDocument.cpp +++ b/code/FBXDocument.cpp @@ -332,8 +332,8 @@ void ReadVectorDataArray(std::vector& out, const Element& el) using namespace Util; // ------------------------------------------------------------------------------------------------ -LazyObject::LazyObject(const Element& element, const ImportSettings& settings) -: settings(settings) +LazyObject::LazyObject(const Element& element, const Document& doc) +: doc(doc) , element(element) { @@ -370,15 +370,18 @@ const Object* LazyObject::Get() DOMError(err,&element); } - // this needs to be relatively fast since we do it a lot, + // this needs to be relatively fast since it happens a lot, // so avoid constructing strings all the time. const char* obtype = key.begin(); - if (!strncmp(obtype,"Geometry",static_cast(key.end()-key.begin()))) { - + const size_t length = static_cast(key.end()-key.begin()); + if (!strncmp(obtype,"Geometry",length)) { if (!strcmp(classtag.c_str(),"Mesh")) { - object.reset(new MeshGeometry(element,name,settings)); + object.reset(new MeshGeometry(element,name,doc.Settings())); } } + else if (!strncmp(obtype,"Material",length)) { + object.reset(new Material(element,doc,name)); + } if (!object.get()) { //DOMError("failed to convert element to DOM object, class: " + classtag + ", name: " + name,&element); @@ -430,10 +433,6 @@ Document::~Document() BOOST_FOREACH(ObjectMap::value_type& v, objects) { delete v.second; } - - BOOST_FOREACH(PropertyTemplateMap::value_type& v, templates) { - delete v.second; - } } // ------------------------------------------------------------------------------------------------ @@ -463,7 +462,7 @@ void Document::ReadObjects() DOMError(err,el.second); } - objects[id] = new LazyObject(*el.second, settings); + objects[id] = new LazyObject(*el.second, *this); // DEBUG - evaluate all objects const Object* o = objects[id]->Get(); } @@ -517,7 +516,10 @@ void Document::ReadPropertyTemplates() const Element* Properties70 = (*sc)["Properties70"]; if(Properties70) { - PropertyTable* const props = new PropertyTable(*Properties70,NULL); + boost::shared_ptr props = boost::make_shared( + *Properties70,boost::shared_ptr(NULL) + ); + templates[oname+"."+pname] = props; } } diff --git a/code/FBXDocument.h b/code/FBXDocument.h index 2dfc9addf..58837398c 100644 --- a/code/FBXDocument.h +++ b/code/FBXDocument.h @@ -56,6 +56,7 @@ namespace FBX { struct ImportSettings; class PropertyTable; + class Document; /** Represents a delay-parsed FBX objects. Many objects in the scene @@ -65,7 +66,7 @@ class LazyObject { public: - LazyObject(const Element& element, const ImportSettings& settings); + LazyObject(const Element& element, const Document& doc); ~LazyObject(); public: @@ -80,7 +81,7 @@ public: private: - const ImportSettings& settings; + const Document& doc; const Element& element; boost::scoped_ptr object; }; @@ -103,6 +104,36 @@ protected: }; +/** DOM class for generic FBX materials */ +class Material : public Object +{ +public: + + Material(const Element& element, const Document& doc, const std::string& name); + ~Material(); + +public: + + const std::string& GetShadingModel() const { + return shading; + } + + bool IsMultilayer() const { + return multilayer; + } + + const PropertyTable* Props() const { + return props; + } + +private: + + std::string shading; + bool multilayer; + boost::shared_ptr props; +}; + + /** DOM base class for all kinds of FBX geometry */ class Geometry : public Object { @@ -229,7 +260,7 @@ private: // up to many thousands of objects (most of which we never use), // so the memory overhead for them should be kept at a minimum. typedef std::map ObjectMap; - typedef std::fbx_unordered_map PropertyTemplateMap; + typedef std::fbx_unordered_map > PropertyTemplateMap; /** DOM root for a FBX file */ class Document diff --git a/code/FBXMaterial.cpp b/code/FBXMaterial.cpp index 1585b9c98..27ab2d07c 100644 --- a/code/FBXMaterial.cpp +++ b/code/FBXMaterial.cpp @@ -50,13 +50,75 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FBXImporter.h" #include "FBXImportSettings.h" #include "FBXDocumentUtil.h" +#include "FBXProperties.h" namespace Assimp { namespace FBX { using namespace Util; +// ------------------------------------------------------------------------------------------------ +Material::Material(const Element& element, const Document& doc, const std::string& name) +: Object(element,name) +{ + const Scope& sc = GetRequiredScope(element); + + const Element* const ShadingModel = sc["ShadingModel"]; + const Element* const MultiLayer = sc["MultiLayer"]; + const Element* const Properties70 = sc["Properties70"]; + if(MultiLayer) { + multilayer = !!ParseTokenAsInt(GetRequiredToken(*MultiLayer,0)); + } + + if(ShadingModel) { + shading = ParseTokenAsString(GetRequiredToken(*ShadingModel,0)); + } + else { + DOMWarning("shading mode not specified, assuming phong",&element); + shading = "phong"; + } + + std::string templateName; + + const char* const sh = shading.c_str(); + if(!strcmp(sh,"phong")) { + templateName = "Material.FbxSurfacePhong"; + } + else if(!strcmp(sh,"lambert")) { + templateName = "Material.FbxSurfaceLambert"; + } + else { + DOMWarning("shading mode not recognized: " + shading,&element); + } + + boost::shared_ptr templateProps = boost::shared_ptr(NULL); + if(templateName.length()) { + PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName); + if(it != doc.Templates().end()) { + templateProps = (*it).second; + } + } + + if(!Properties70) { + DOMWarning("material property table (Properties70) not found",&element); + if(templateProps) { + props = templateProps; + } + else { + props = boost::make_shared(); + } + } + else { + props = boost::make_shared(*Properties70,templateProps); + } +} + + +// ------------------------------------------------------------------------------------------------ +Material::~Material() +{ +} } //!FBX } //!Assimp diff --git a/code/FBXProperties.cpp b/code/FBXProperties.cpp index 00b0b5b58..091d0d846 100644 --- a/code/FBXProperties.cpp +++ b/code/FBXProperties.cpp @@ -119,9 +119,17 @@ std::string PeekPropertyName(const Element& element) } //! anon + // ------------------------------------------------------------------------------------------------ -PropertyTable::PropertyTable(const Element& element, const PropertyTable* templateProps) -: element(element) +PropertyTable::PropertyTable() +: element() +, templateProps() +{ +} + +// ------------------------------------------------------------------------------------------------ +PropertyTable::PropertyTable(const Element& element, boost::shared_ptr templateProps) +: element(&element) , templateProps(templateProps) { const Scope& scope = GetRequiredScope(element); diff --git a/code/FBXProperties.h b/code/FBXProperties.h index cdd8af6b7..cf930c5b3 100644 --- a/code/FBXProperties.h +++ b/code/FBXProperties.h @@ -109,14 +109,18 @@ class PropertyTable { public: - PropertyTable(const Element& element, const PropertyTable* templateProps); + // in-memory property table with no source element + PropertyTable(); + + PropertyTable(const Element& element, boost::shared_ptr templateProps); ~PropertyTable(); public: const Property* Get(const std::string& name) const; - const Element& GetElement() const { + // PropertyTable's need not be coupled with FBX elements so this can be NULL + const Element* GetElement() const { return element; } @@ -128,8 +132,8 @@ private: LazyPropertyMap lazyProps; mutable PropertyMap props; - const PropertyTable* const templateProps; - const Element& element; + const boost::shared_ptr templateProps; + const Element* const element; };