- fbx: read materials.

pull/14/head
acgessler 2012-07-02 17:37:00 +02:00
parent b49cf16bc2
commit 131008cea1
5 changed files with 128 additions and 21 deletions

View File

@ -332,8 +332,8 @@ void ReadVectorDataArray(std::vector<unsigned int>& out, const Element& el)
using namespace Util; using namespace Util;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
LazyObject::LazyObject(const Element& element, const ImportSettings& settings) LazyObject::LazyObject(const Element& element, const Document& doc)
: settings(settings) : doc(doc)
, element(element) , element(element)
{ {
@ -370,15 +370,18 @@ const Object* LazyObject::Get()
DOMError(err,&element); 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. // so avoid constructing strings all the time.
const char* obtype = key.begin(); const char* obtype = key.begin();
if (!strncmp(obtype,"Geometry",static_cast<size_t>(key.end()-key.begin()))) { const size_t length = static_cast<size_t>(key.end()-key.begin());
if (!strncmp(obtype,"Geometry",length)) {
if (!strcmp(classtag.c_str(),"Mesh")) { 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()) { if (!object.get()) {
//DOMError("failed to convert element to DOM object, class: " + classtag + ", name: " + name,&element); //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) { BOOST_FOREACH(ObjectMap::value_type& v, objects) {
delete v.second; delete v.second;
} }
BOOST_FOREACH(PropertyTemplateMap::value_type& v, templates) {
delete v.second;
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -463,7 +462,7 @@ void Document::ReadObjects()
DOMError(err,el.second); DOMError(err,el.second);
} }
objects[id] = new LazyObject(*el.second, settings); objects[id] = new LazyObject(*el.second, *this);
// DEBUG - evaluate all objects // DEBUG - evaluate all objects
const Object* o = objects[id]->Get(); const Object* o = objects[id]->Get();
} }
@ -517,7 +516,10 @@ void Document::ReadPropertyTemplates()
const Element* Properties70 = (*sc)["Properties70"]; const Element* Properties70 = (*sc)["Properties70"];
if(Properties70) { if(Properties70) {
PropertyTable* const props = new PropertyTable(*Properties70,NULL); boost::shared_ptr<const PropertyTable> props = boost::make_shared<const PropertyTable>(
*Properties70,boost::shared_ptr<const PropertyTable>(NULL)
);
templates[oname+"."+pname] = props; templates[oname+"."+pname] = props;
} }
} }

View File

@ -56,6 +56,7 @@ namespace FBX {
struct ImportSettings; struct ImportSettings;
class PropertyTable; class PropertyTable;
class Document;
/** Represents a delay-parsed FBX objects. Many objects in the scene /** Represents a delay-parsed FBX objects. Many objects in the scene
@ -65,7 +66,7 @@ class LazyObject
{ {
public: public:
LazyObject(const Element& element, const ImportSettings& settings); LazyObject(const Element& element, const Document& doc);
~LazyObject(); ~LazyObject();
public: public:
@ -80,7 +81,7 @@ public:
private: private:
const ImportSettings& settings; const Document& doc;
const Element& element; const Element& element;
boost::scoped_ptr<const Object> object; boost::scoped_ptr<const Object> 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<const PropertyTable> props;
};
/** DOM base class for all kinds of FBX geometry */ /** DOM base class for all kinds of FBX geometry */
class Geometry : public Object class Geometry : public Object
{ {
@ -229,7 +260,7 @@ private:
// up to many thousands of objects (most of which we never use), // up to many thousands of objects (most of which we never use),
// so the memory overhead for them should be kept at a minimum. // so the memory overhead for them should be kept at a minimum.
typedef std::map<uint64_t, LazyObject*> ObjectMap; typedef std::map<uint64_t, LazyObject*> ObjectMap;
typedef std::fbx_unordered_map<std::string, PropertyTable*> PropertyTemplateMap; typedef std::fbx_unordered_map<std::string, boost::shared_ptr<const PropertyTable> > PropertyTemplateMap;
/** DOM root for a FBX file */ /** DOM root for a FBX file */
class Document class Document

View File

@ -50,13 +50,75 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXImporter.h" #include "FBXImporter.h"
#include "FBXImportSettings.h" #include "FBXImportSettings.h"
#include "FBXDocumentUtil.h" #include "FBXDocumentUtil.h"
#include "FBXProperties.h"
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
using namespace Util; 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<const PropertyTable> templateProps = boost::shared_ptr<const PropertyTable>(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<const PropertyTable>();
}
}
else {
props = boost::make_shared<const PropertyTable>(*Properties70,templateProps);
}
}
// ------------------------------------------------------------------------------------------------
Material::~Material()
{
}
} //!FBX } //!FBX
} //!Assimp } //!Assimp

View File

@ -119,9 +119,17 @@ std::string PeekPropertyName(const Element& element)
} //! anon } //! anon
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
PropertyTable::PropertyTable(const Element& element, const PropertyTable* templateProps) PropertyTable::PropertyTable()
: element(element) : element()
, templateProps()
{
}
// ------------------------------------------------------------------------------------------------
PropertyTable::PropertyTable(const Element& element, boost::shared_ptr<const PropertyTable> templateProps)
: element(&element)
, templateProps(templateProps) , templateProps(templateProps)
{ {
const Scope& scope = GetRequiredScope(element); const Scope& scope = GetRequiredScope(element);

View File

@ -109,14 +109,18 @@ class PropertyTable
{ {
public: public:
PropertyTable(const Element& element, const PropertyTable* templateProps); // in-memory property table with no source element
PropertyTable();
PropertyTable(const Element& element, boost::shared_ptr<const PropertyTable> templateProps);
~PropertyTable(); ~PropertyTable();
public: public:
const Property* Get(const std::string& name) const; 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; return element;
} }
@ -128,8 +132,8 @@ private:
LazyPropertyMap lazyProps; LazyPropertyMap lazyProps;
mutable PropertyMap props; mutable PropertyMap props;
const PropertyTable* const templateProps; const boost::shared_ptr<const PropertyTable> templateProps;
const Element& element; const Element* const element;
}; };