acgessler преди 13 години
родител
ревизия
131008cea1
променени са 5 файла, в които са добавени 129 реда и са изтрити 22 реда
  1. 14 12
      code/FBXDocument.cpp
  2. 34 3
      code/FBXDocument.h
  3. 63 1
      code/FBXMaterial.cpp
  4. 10 2
      code/FBXProperties.cpp
  5. 8 4
      code/FBXProperties.h

+ 14 - 12
code/FBXDocument.cpp

@@ -332,8 +332,8 @@ void ReadVectorDataArray(std::vector<unsigned int>& 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<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")) {
-			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<const PropertyTable> props = boost::make_shared<const PropertyTable>(
+					*Properties70,boost::shared_ptr<const PropertyTable>(NULL)
+				);
+
 				templates[oname+"."+pname] = props;
 			}
 		}

+ 34 - 3
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<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 */
 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<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 */
 class Document 

+ 63 - 1
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<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
 } //!Assimp

+ 10 - 2
code/FBXProperties.cpp

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

+ 8 - 4
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<const PropertyTable> 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<const PropertyTable> templateProps;
+	const Element* const element;
 };