Browse Source

FBXImporter: move MeshGeometry declaration into its own header

Kim Kulling 9 years ago
parent
commit
2b09199f4a
10 changed files with 352 additions and 358 deletions
  1. 1 0
      code/CMakeLists.txt
  2. 10 7
      code/FBXConverter.cpp
  3. 10 7
      code/FBXDocument.cpp
  4. 35 306
      code/FBXDocument.h
  5. 6 15
      code/FBXImporter.h
  6. 85 4
      code/FBXMeshGeometry.cpp
  7. 180 0
      code/FBXMeshGeometry.h
  8. 1 0
      code/FBXModel.cpp
  9. 17 8
      code/FBXParser.cpp
  10. 7 11
      code/FBXParser.h

+ 1 - 0
code/CMakeLists.txt

@@ -446,6 +446,7 @@ ADD_ASSIMP_IMPORTER(FBX
   FBXDocument.cpp
   FBXProperties.h
   FBXProperties.cpp
+  FBXMeshGeometry.h
   FBXMeshGeometry.cpp
   FBXMaterial.cpp
   FBXModel.cpp

+ 10 - 7
code/FBXConverter.cpp

@@ -44,18 +44,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
 
-#include <iterator>
-#include <sstream>
-#include <boost/tuple/tuple.hpp>
-#include <vector>
-#include "FBXParser.h"
 #include "FBXConverter.h"
+#include "FBXParser.h"
+#include "FBXMeshGeometry.h"
 #include "FBXDocument.h"
 #include "FBXUtil.h"
 #include "FBXProperties.h"
 #include "FBXImporter.h"
 #include "StringComparison.h"
+
 #include "../include/assimp/scene.h"
+#include <iterator>
+#include <sstream>
+#include <boost/tuple/tuple.hpp>
+#include <vector>
 #include <boost/foreach.hpp>
 #include <boost/scoped_array.hpp>
 
@@ -63,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace FBX {
 
-    using namespace Util;
+using namespace Util;
 
 
 #define MAGIC_NODE_TAG "_$AssimpFbx$"
@@ -154,7 +156,6 @@ public:
 
 
 private:
-
     // ------------------------------------------------------------------------------------------------
     // find scene root and trigger recursive scene conversion
     void ConvertRootNode()
@@ -385,6 +386,7 @@ private:
 
         out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
         out_camera->mPosition = cam.Position();
+        out_camera->mUp = cam.UpVector();
         out_camera->mLookAt = cam.InterestPosition() - out_camera->mPosition;
         out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
     }
@@ -426,6 +428,7 @@ private:
         case TransformationComp_GeometricTranslation:
             return "GeometricTranslation";
         case TransformationComp_MAXIMUM: // this is to silence compiler warnings
+        default:
             break;
         }
 

+ 10 - 7
code/FBXDocument.cpp

@@ -44,17 +44,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
 
-#include <functional>
-
-#include "FBXParser.h"
 #include "FBXDocument.h"
+#include "FBXMeshGeometry.h"
+#include "FBXParser.h"
 #include "FBXUtil.h"
 #include "FBXImporter.h"
 #include "FBXImportSettings.h"
 #include "FBXDocumentUtil.h"
 #include "FBXProperties.h"
+
 #include <boost/foreach.hpp>
 #include <boost/make_shared.hpp>
+#include <functional>
+
 
 namespace Assimp {
 namespace FBX {
@@ -135,6 +137,8 @@ const Object* LazyObject::Get(bool dieOnError)
         // so avoid constructing strings all the time.
         const char* obtype = key.begin();
         const size_t length = static_cast<size_t>(key.end()-key.begin());
+        DefaultLogger::get()->debug( "obtype: " + std::string(obtype ));
+        DefaultLogger::get()->debug( "Classtag: " + classtag );
         if (!strncmp(obtype,"Geometry",length)) {
             if (!strcmp(classtag.c_str(),"Mesh")) {
                 object.reset(new MeshGeometry(id,element,name,doc));
@@ -165,10 +169,10 @@ const Object* LazyObject::Get(bool dieOnError)
                 object.reset(new Skin(id,element,doc,name));
             }
         }
-        else if (!strncmp(obtype,"Model",length)) {
+        else if ( !strncmp( obtype, "Model", length ) ) {
             // FK and IK effectors are not supported
-            if (strcmp(classtag.c_str(),"IKEffector") && strcmp(classtag.c_str(),"FKEffector")) {
-                object.reset(new Model(id,element,doc,name));
+            if ( strcmp( classtag.c_str(), "IKEffector" ) && strcmp( classtag.c_str(), "FKEffector" ) ) {
+                object.reset( new Model( id, element, doc, name ) );
             }
         }
         else if (!strncmp(obtype,"Material",length)) {
@@ -408,7 +412,6 @@ void Document::ReadObjects()
     }
 }
 
-
 // ------------------------------------------------------------------------------------------------
 void Document::ReadPropertyTemplates()
 {

+ 35 - 306
code/FBXDocument.h

@@ -56,24 +56,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace FBX {
 
-    class Parser;
-    class Object;
-    struct ImportSettings;
+class Parser;
+class Object;
+struct ImportSettings;
 
-    class PropertyTable;
-    class Document;
-    class Material;
-    class Geometry;
+class PropertyTable;
+class Document;
+class Material;
+class Geometry;
 
-    class Video;
+class Video;
 
-    class AnimationCurve;
-    class AnimationCurveNode;
-    class AnimationLayer;
-    class AnimationStack;
+class AnimationCurve;
+class AnimationCurveNode;
+class AnimationLayer;
+class AnimationStack;
 
-    class Skin;
-    class Cluster;
+class Skin;
+class Cluster;
 
 
 /** Represents a delay-parsed FBX objects. Many objects in the scene
@@ -82,7 +82,6 @@ namespace FBX {
 class LazyObject
 {
 public:
-
     LazyObject(uint64_t id, const Element& element, const Document& doc);
     ~LazyObject();
 
@@ -117,7 +116,6 @@ public:
     }
 
 private:
-
     const Document& doc;
     const Element& element;
     boost::scoped_ptr<const Object> object;
@@ -138,11 +136,9 @@ private:
 class Object
 {
 public:
-
     Object(uint64_t id, const Element& element, const std::string& name);
-    virtual ~Object();
 
-public:
+    virtual ~Object();
 
     const Element& SourceElement() const {
         return element;
@@ -169,19 +165,15 @@ protected:
 class NodeAttribute : public Object
 {
 public:
-
     NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~NodeAttribute();
 
-public:
-
     const PropertyTable& Props() const {
         ai_assert(props.get());
         return *props.get();
     }
 
 private:
-
     boost::shared_ptr<const PropertyTable> props;
 };
 
@@ -190,12 +182,9 @@ private:
 class CameraSwitcher : public NodeAttribute
 {
 public:
-
     CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~CameraSwitcher();
 
-public:
-
     int CameraID() const {
         return cameraId;
     }
@@ -204,13 +193,11 @@ public:
         return cameraName;
     }
 
-
     const std::string& CameraIndexName() const {
         return cameraIndexName;
     }
 
 private:
-
     int cameraId;
     std::string cameraName;
     std::string cameraIndexName;
@@ -236,17 +223,14 @@ private:
 }
 
 
-
 /** DOM base class for FBX cameras attached to a node */
 class Camera : public NodeAttribute
 {
 public:
-
     Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual  ~Camera();
 
 public:
-
     fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0))
     fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0))
     fbx_simple_property(InterestPosition, aiVector3D, aiVector3D(0,0,0))
@@ -261,8 +245,6 @@ public:
 
     fbx_simple_property(FieldOfView, float, 1.0f)
     fbx_simple_property(FocalLength, float, 1.0f)
-
-private:
 };
 
 
@@ -270,7 +252,6 @@ private:
 class Null : public NodeAttribute
 {
 public:
-
     Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~Null();
 };
@@ -280,7 +261,6 @@ public:
 class LimbNode : public NodeAttribute
 {
 public:
-
     LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~LimbNode();
 };
@@ -294,7 +274,6 @@ public:
     virtual ~Light();
 
 public:
-
     enum Type
     {
         Type_Point,
@@ -317,7 +296,6 @@ public:
     };
 
 public:
-
     fbx_simple_property(Color, aiVector3D, aiVector3D(1,1,1))
     fbx_simple_enum_property(LightType, Type, 0)
     fbx_simple_property(CastLightOnObject, bool, false)
@@ -349,9 +327,6 @@ public:
     fbx_simple_property(TopBarnDoor, float, 20.0f)
     fbx_simple_property(BottomBarnDoor, float, 20.0f)
     fbx_simple_property(EnableBarnDoor, bool, true)
-
-
-private:
 };
 
 
@@ -359,12 +334,10 @@ private:
 class Model : public Object
 {
 public:
-
     Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~Model();
 
 public:
-
     enum RotOrder
     {
         RotOrder_EulerXYZ = 0,
@@ -390,7 +363,6 @@ public:
     };
 
 public:
-
     fbx_simple_property(QuaternionInterpolate, int, 0)
 
     fbx_simple_property(RotationOffset, aiVector3D, aiVector3D())
@@ -468,7 +440,6 @@ public:
     fbx_simple_property(Freeze, bool, false)
 
 public:
-
     const std::string& Shading() const {
         return shading;
     }
@@ -499,18 +470,14 @@ public:
         return attributes;
     }
 
-public:
-
     /** convenience method to check if the node has a Null node marker */
     bool IsNull() const;
 
 
 private:
-
     void ResolveLinks(const Element& element, const Document& doc);
 
 private:
-
     std::vector<const Material*> materials;
     std::vector<const Geometry*> geometry;
     std::vector<const NodeAttribute*> attributes;
@@ -524,12 +491,10 @@ private:
 class Texture : public Object
 {
 public:
-
     Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~Texture();
 
 public:
-
     const std::string& Type() const {
         return type;
     }
@@ -569,7 +534,6 @@ public:
     }
 
 private:
-
     aiVector2D uvTrans;
     aiVector2D uvScaling;
 
@@ -588,7 +552,6 @@ private:
 class LayeredTexture : public Object
 {
 public:
-
     LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~LayeredTexture();
 
@@ -635,14 +598,17 @@ public:
     {
         return texture;
     }
+
     BlendMode GetBlendMode()
     {
         return blendMode;
     }
+    
     float Alpha()
     {
         return alpha;
     }
+
 private:
     const Texture* texture;
     BlendMode blendMode;
@@ -657,12 +623,10 @@ typedef std::fbx_unordered_map<std::string, const LayeredTexture*> LayeredTextur
 class Video : public Object
 {
 public:
-
     Video(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~Video();
 
 public:
-
     const std::string& Type() const {
         return type;
     }
@@ -696,7 +660,6 @@ public:
     }
 
 private:
-
     std::string type;
     std::string relativeFileName;
     std::string fileName;
@@ -710,12 +673,9 @@ private:
 class Material : public Object
 {
 public:
-
     Material(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~Material();
 
-public:
-
     const std::string& GetShadingModel() const {
         return shading;
     }
@@ -738,7 +698,6 @@ public:
     }
 
 private:
-
     std::string shading;
     bool multilayer;
     boost::shared_ptr<const PropertyTable> props;
@@ -747,191 +706,6 @@ private:
     LayeredTextureMap layeredTextures;
 };
 
-
-/** DOM base class for all kinds of FBX geometry */
-class Geometry : public Object
-{
-public:
-
-    Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc);
-    virtual ~Geometry();
-
-public:
-
-    /** Get the Skin attached to this geometry or NULL */
-    const Skin* DeformerSkin() const {
-        return skin;
-    }
-
-private:
-
-    const Skin* skin;
-};
-
-
-typedef std::vector<int> MatIndexArray;
-
-
-/** DOM class for FBX geometry of type "Mesh"*/
-class MeshGeometry : public Geometry
-{
-
-public:
-
-    MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc);
-    virtual ~MeshGeometry();
-
-public:
-
-    /** Get a list of all vertex points, non-unique*/
-    const std::vector<aiVector3D>& GetVertices() const {
-        return vertices;
-    }
-
-    /** Get a list of all vertex normals or an empty array if
-     *  no normals are specified. */
-    const std::vector<aiVector3D>& GetNormals() const {
-        return normals;
-    }
-
-    /** Get a list of all vertex tangents or an empty array
-     *  if no tangents are specified */
-    const std::vector<aiVector3D>& GetTangents() const {
-        return tangents;
-    }
-
-    /** Get a list of all vertex binormals or an empty array
-     *  if no binormals are specified */
-    const std::vector<aiVector3D>& GetBinormals() const {
-        return binormals;
-    }
-
-    /** Return list of faces - each entry denotes a face and specifies
-     *  how many vertices it has. Vertices are taken from the
-     *  vertex data arrays in sequential order. */
-    const std::vector<unsigned int>& GetFaceIndexCounts() const {
-        return faces;
-    }
-
-    /** Get a UV coordinate slot, returns an empty array if
-     *  the requested slot does not exist. */
-    const std::vector<aiVector2D>& GetTextureCoords(unsigned int index) const {
-        static const std::vector<aiVector2D> empty;
-        return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index];
-    }
-
-
-    /** Get a UV coordinate slot, returns an empty array if
-     *  the requested slot does not exist. */
-    std::string GetTextureCoordChannelName(unsigned int index) const {
-        return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : uvNames[index];
-    }
-
-    /** Get a vertex color coordinate slot, returns an empty array if
-     *  the requested slot does not exist. */
-    const std::vector<aiColor4D>& GetVertexColors(unsigned int index) const {
-        static const std::vector<aiColor4D> empty;
-        return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : colors[index];
-    }
-
-
-    /** Get per-face-vertex material assignments */
-    const MatIndexArray& GetMaterialIndices() const {
-        return materials;
-    }
-
-
-    /** Convert from a fbx file vertex index (for example from a #Cluster weight) or NULL
-      * if the vertex index is not valid. */
-    const unsigned int* ToOutputVertexIndex(unsigned int in_index, unsigned int& count) const {
-        if(in_index >= mapping_counts.size()) {
-            return NULL;
-        }
-
-        ai_assert(mapping_counts.size() == mapping_offsets.size());
-        count = mapping_counts[in_index];
-
-        ai_assert(count != 0);
-        ai_assert(mapping_offsets[in_index] + count <= mappings.size());
-
-        return &mappings[mapping_offsets[in_index]];
-    }
-
-
-    /** Determine the face to which a particular output vertex index belongs.
-     *  This mapping is always unique. */
-    unsigned int FaceForVertexIndex(unsigned int in_index) const {
-        ai_assert(in_index < vertices.size());
-
-        // in the current conversion pattern this will only be needed if
-        // weights are present, so no need to always pre-compute this table
-        if (facesVertexStartIndices.empty()) {
-            facesVertexStartIndices.resize(faces.size() + 1, 0);
-
-            std::partial_sum(faces.begin(), faces.end(), facesVertexStartIndices.begin() + 1);
-            facesVertexStartIndices.pop_back();
-        }
-
-        ai_assert(facesVertexStartIndices.size() == faces.size());
-        const std::vector<unsigned int>::iterator it = std::upper_bound(
-            facesVertexStartIndices.begin(),
-            facesVertexStartIndices.end(),
-            in_index
-        );
-
-        return static_cast<unsigned int>(std::distance(facesVertexStartIndices.begin(), it - 1));
-    }
-
-private:
-
-    void ReadLayer(const Scope& layer);
-    void ReadLayerElement(const Scope& layerElement);
-    void ReadVertexData(const std::string& type, int index, const Scope& source);
-
-    void ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope& source,
-        const std::string& MappingInformationType,
-        const std::string& ReferenceInformationType);
-
-    void ReadVertexDataNormals(std::vector<aiVector3D>& normals_out, const Scope& source,
-        const std::string& MappingInformationType,
-        const std::string& ReferenceInformationType);
-
-    void ReadVertexDataColors(std::vector<aiColor4D>& colors_out, const Scope& source,
-        const std::string& MappingInformationType,
-        const std::string& ReferenceInformationType);
-
-    void ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source,
-        const std::string& MappingInformationType,
-        const std::string& ReferenceInformationType);
-
-    void ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source,
-        const std::string& MappingInformationType,
-        const std::string& ReferenceInformationType);
-
-    void ReadVertexDataMaterials(MatIndexArray& materials_out, const Scope& source,
-        const std::string& MappingInformationType,
-        const std::string& ReferenceInformationType);
-
-private:
-
-    // cached data arrays
-    MatIndexArray materials;
-    std::vector<aiVector3D> vertices;
-    std::vector<unsigned int> faces;
-    mutable std::vector<unsigned int> facesVertexStartIndices;
-    std::vector<aiVector3D> tangents;
-    std::vector<aiVector3D> binormals;
-    std::vector<aiVector3D> normals;
-
-    std::string uvNames[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-    std::vector<aiVector2D> uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-    std::vector<aiColor4D> colors[AI_MAX_NUMBER_OF_COLOR_SETS];
-
-    std::vector<unsigned int> mapping_counts;
-    std::vector<unsigned int> mapping_offsets;
-    std::vector<unsigned int> mappings;
-};
-
 typedef std::vector<int64_t> KeyTimeList;
 typedef std::vector<float> KeyValueList;
 
@@ -939,12 +713,9 @@ typedef std::vector<float> KeyValueList;
 class AnimationCurve : public Object
 {
 public:
-
     AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
     virtual ~AnimationCurve();
 
-public:
-
     /** get list of keyframe positions (time).
      *  Invariant: |GetKeys()| > 0 */
     const KeyTimeList& GetKeys() const {
@@ -968,7 +739,6 @@ public:
     }
 
 private:
-
     KeyTimeList keys;
     KeyValueList values;
     std::vector<float> attributes;
@@ -983,7 +753,6 @@ typedef std::map<std::string, const AnimationCurve*> AnimationCurveMap;
 class AnimationCurveNode : public Object
 {
 public:
-
     /* the optional white list specifies a list of property names for which the caller
     wants animations for. If the curve node does not match one of these, std::range_error
     will be thrown. */
@@ -992,8 +761,6 @@ public:
 
     virtual ~AnimationCurveNode();
 
-public:
-
     const PropertyTable& Props() const {
         ai_assert(props.get());
         return *props.get();
@@ -1023,7 +790,6 @@ public:
     }
 
 private:
-
     const Object* target;
     boost::shared_ptr<const PropertyTable> props;
     mutable AnimationCurveMap curves;
@@ -1039,13 +805,9 @@ typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList;
 class AnimationLayer : public Object
 {
 public:
-
-
     AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
     virtual ~AnimationLayer();
 
-public:
-
     const PropertyTable& Props() const {
         ai_assert(props.get());
         return *props.get();
@@ -1057,7 +819,6 @@ public:
     AnimationCurveNodeList Nodes(const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0) const;
 
 private:
-
     boost::shared_ptr<const PropertyTable> props;
     const Document& doc;
 };
@@ -1070,31 +831,25 @@ typedef std::vector<const AnimationLayer*> AnimationLayerList;
 class AnimationStack : public Object
 {
 public:
-
     AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
     virtual ~AnimationStack();
 
 public:
-
     fbx_simple_property(LocalStart, int64_t, 0L)
     fbx_simple_property(LocalStop, int64_t, 0L)
     fbx_simple_property(ReferenceStart, int64_t, 0L)
     fbx_simple_property(ReferenceStop, int64_t, 0L)
 
-
-
     const PropertyTable& Props() const {
         ai_assert(props.get());
         return *props.get();
     }
 
-
     const AnimationLayerList& Layers() const {
         return layers;
     }
 
 private:
-
     boost::shared_ptr<const PropertyTable> props;
     AnimationLayerList layers;
 };
@@ -1104,19 +859,15 @@ private:
 class Deformer : public Object
 {
 public:
-
     Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~Deformer();
 
-public:
-
     const PropertyTable& Props() const {
         ai_assert(props.get());
         return *props.get();
     }
 
 private:
-
     boost::shared_ptr<const PropertyTable> props;
 };
 
@@ -1128,11 +879,8 @@ typedef std::vector<unsigned int> WeightIndexArray;
 class Cluster : public Deformer
 {
 public:
-
     Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name);
-    ~Cluster();
-
-public:
+    virtual ~Cluster();
 
     /** get the list of deformer weights associated with this cluster.
      *  Use #GetIndices() to get the associated vertices. Both arrays
@@ -1162,7 +910,6 @@ public:
     }
 
 private:
-
     WeightArray weights;
     WeightIndexArray indices;
 
@@ -1178,34 +925,26 @@ private:
 class Skin : public Deformer
 {
 public:
-
     Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     virtual ~Skin();
 
-public:
-
     float DeformAccuracy() const {
         return accuracy;
     }
 
-
     const std::vector<const Cluster*>& Clusters() const {
         return clusters;
     }
 
 private:
-
     float accuracy;
     std::vector<const Cluster*> clusters;
 };
 
-
-
 /** Represents a link between two FBX objects. */
 class Connection
 {
 public:
-
     Connection(uint64_t insertionOrder,  uint64_t src, uint64_t dest, const std::string& prop, const Document& doc);
     ~Connection();
 
@@ -1231,6 +970,8 @@ public:
     }
 
     int CompareTo(const Connection* c) const {
+        ai_assert( NULL != c );
+
         // note: can't subtract because this would overflow uint64_t
         if(InsertionOrder() > c->InsertionOrder()) {
             return 1;
@@ -1242,11 +983,12 @@ public:
     }
 
     bool Compare(const Connection* c) const {
+        ai_assert( NULL != c );
+
         return InsertionOrder() < c->InsertionOrder();
     }
 
 public:
-
     uint64_t insertionOrder;
     const std::string prop;
 
@@ -1254,17 +996,16 @@ public:
     const Document& doc;
 };
 
+// XXX again, unique_ptr would be useful. shared_ptr is too
+// bloated since the objects have a well-defined single owner
+// during their entire lifetime (Document). FBX files have
+// 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, boost::shared_ptr<const PropertyTable> > PropertyTemplateMap;
 
-    // XXX again, unique_ptr would be useful. shared_ptr is too
-    // bloated since the objects have a well-defined single owner
-    // during their entire lifetime (Document). FBX files have
-    // 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, boost::shared_ptr<const PropertyTable> > PropertyTemplateMap;
 
-
-    typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
+typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
 
 
 /** DOM class for global document settings, a single instance per document can
@@ -1272,12 +1013,9 @@ public:
 class FileGlobalSettings
 {
 public:
-
     FileGlobalSettings(const Document& doc, boost::shared_ptr<const PropertyTable> props);
     ~FileGlobalSettings();
 
-public:
-
     const PropertyTable& Props() const {
         ai_assert(props.get());
         return *props.get();
@@ -1287,7 +1025,6 @@ public:
         return doc;
     }
 
-
     fbx_simple_property(UpAxis, int, 1)
     fbx_simple_property(UpAxisSign, int, 1)
     fbx_simple_property(FrontAxis, int, 2)
@@ -1327,9 +1064,7 @@ public:
     fbx_simple_property(TimeSpanStop, uint64_t, 0L)
     fbx_simple_property(CustomFrameRate, float, -1.0f)
 
-
 private:
-
     boost::shared_ptr<const PropertyTable> props;
     const Document& doc;
 };
@@ -1341,12 +1076,9 @@ private:
 class Document
 {
 public:
-
     Document(const Parser& parser, const ImportSettings& settings);
     ~Document();
 
-public:
-
     LazyObject* GetObject(uint64_t id) const;
 
     bool IsBinary() const {
@@ -1361,7 +1093,7 @@ public:
         return creator;
     }
 
-    // elements (in this order): Uear, Month, Day, Hour, Second, Millisecond
+    // elements (in this order): Year, Month, Day, Hour, Second, Millisecond
     const unsigned int* CreationTimeStamp() const {
         return creationTimeStamp;
     }
@@ -1412,7 +1144,6 @@ public:
     const std::vector<const AnimationStack*>& AnimationStacks() const;
 
 private:
-
     std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, const ConnectionMap&) const;
     std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, bool is_src,
         const ConnectionMap&,
@@ -1420,7 +1151,6 @@ private:
         size_t count) const;
 
 private:
-
     void ReadHeader();
     void ReadObjects();
     void ReadPropertyTemplates();
@@ -1428,7 +1158,6 @@ private:
     void ReadGlobalSettings();
 
 private:
-
     const ImportSettings& settings;
 
     ObjectMap objects;
@@ -1448,7 +1177,7 @@ private:
     boost::scoped_ptr<FileGlobalSettings> globals;
 };
 
-}
-}
+} // Namespace FBX
+} // Namespace Assimp
 
-#endif
+#endif // INCLUDED_AI_FBX_DOCUMENT_H

+ 6 - 15
code/FBXImporter.h

@@ -51,12 +51,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 namespace Assimp    {
 
-    // TinyFormatter.h
-    namespace Formatter {
-        template <typename T,typename TR, typename A> class basic_formatter;
-        typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
-    }
-
+// TinyFormatter.h
+namespace Formatter {
+    template <typename T,typename TR, typename A> class basic_formatter;
+    typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
+}
 
 // -------------------------------------------------------------------------------------------
 /** Load the Autodesk FBX file format.
@@ -68,10 +67,7 @@ class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter>
 {
 public:
     FBXImporter();
-    ~FBXImporter();
-
-
-public:
+    virtual ~FBXImporter();
 
     // --------------------
     bool CanRead( const std::string& pFile,
@@ -94,12 +90,7 @@ protected:
     );
 
 private:
-
-
-private:
-
     FBX::ImportSettings settings;
-
 }; // !class FBXImporter
 
 } // end of namespace Assimp

+ 85 - 4
code/FBXMeshGeometry.cpp

@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <functional>
 
-#include "FBXParser.h"
+#include "FBXMeshGeometry.h"
 #include "FBXDocument.h"
 #include "FBXImporter.h"
 #include "FBXImportSettings.h"
@@ -57,8 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace FBX {
 
-    using namespace Util;
-
+using namespace Util;
 
 // ------------------------------------------------------------------------------------------------
 Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
@@ -82,6 +81,9 @@ Geometry::~Geometry()
 
 }
 
+const Skin* Geometry::DeformerSkin() const {
+    return skin;
+}
 
 
 // ------------------------------------------------------------------------------------------------
@@ -182,14 +184,93 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
     }
 }
 
-
 // ------------------------------------------------------------------------------------------------
 MeshGeometry::~MeshGeometry()
 {
 
 }
 
+// ------------------------------------------------------------------------------------------------
+const std::vector<aiVector3D>& MeshGeometry::GetVertices() const {
+    return vertices;
+}
+
+// ------------------------------------------------------------------------------------------------
+const std::vector<aiVector3D>& MeshGeometry::GetNormals() const {
+    return normals;
+}
+
+// ------------------------------------------------------------------------------------------------
+const std::vector<aiVector3D>& MeshGeometry::GetTangents() const {
+    return tangents;
+}
 
+// ------------------------------------------------------------------------------------------------
+const std::vector<aiVector3D>& MeshGeometry::GetBinormals() const {
+    return binormals;
+}
+
+// ------------------------------------------------------------------------------------------------
+const std::vector<unsigned int>& MeshGeometry::GetFaceIndexCounts() const {
+    return faces;
+}
+
+// ------------------------------------------------------------------------------------------------
+const std::vector<aiVector2D>& MeshGeometry::GetTextureCoords( unsigned int index ) const {
+    static const std::vector<aiVector2D> empty;
+    return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[ index ];
+}
+
+std::string MeshGeometry::GetTextureCoordChannelName( unsigned int index ) const {
+    return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : uvNames[ index ];
+}
+
+const std::vector<aiColor4D>& MeshGeometry::GetVertexColors( unsigned int index ) const {
+    static const std::vector<aiColor4D> empty;
+    return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : colors[ index ];
+}
+
+const MatIndexArray& MeshGeometry::GetMaterialIndices() const {
+    return materials;
+}
+
+// ------------------------------------------------------------------------------------------------
+const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const {
+    if ( in_index >= mapping_counts.size() ) {
+        return NULL;
+    }
+
+    ai_assert( mapping_counts.size() == mapping_offsets.size() );
+    count = mapping_counts[ in_index ];
+
+    ai_assert( count != 0 );
+    ai_assert( mapping_offsets[ in_index ] + count <= mappings.size() );
+
+    return &mappings[ mapping_offsets[ in_index ] ];
+}
+
+// ------------------------------------------------------------------------------------------------
+unsigned int MeshGeometry::FaceForVertexIndex( unsigned int in_index ) const {
+    ai_assert( in_index < vertices.size() );
+
+    // in the current conversion pattern this will only be needed if
+    // weights are present, so no need to always pre-compute this table
+    if ( facesVertexStartIndices.empty() ) {
+        facesVertexStartIndices.resize( faces.size() + 1, 0 );
+
+        std::partial_sum( faces.begin(), faces.end(), facesVertexStartIndices.begin() + 1 );
+        facesVertexStartIndices.pop_back();
+    }
+
+    ai_assert( facesVertexStartIndices.size() == faces.size() );
+    const std::vector<unsigned int>::iterator it = std::upper_bound(
+        facesVertexStartIndices.begin(),
+        facesVertexStartIndices.end(),
+        in_index
+        );
+
+    return static_cast< unsigned int >( std::distance( facesVertexStartIndices.begin(), it - 1 ) );
+}
 
 // ------------------------------------------------------------------------------------------------
 void MeshGeometry::ReadLayer(const Scope& layer)

+ 180 - 0
code/FBXMeshGeometry.h

@@ -0,0 +1,180 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2016, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file  FBXImporter.h
+*  @brief Declaration of the FBX main importer class
+*/
+#ifndef INCLUDED_AI_FBX_MESHGEOMETRY_H
+#define INCLUDED_AI_FBX_MESHGEOMETRY_H
+
+#include "FBXParser.h"
+#include "FBXDocument.h"
+
+namespace Assimp {
+namespace FBX {
+
+/** 
+ *  DOM base class for all kinds of FBX geometry 
+ */
+class Geometry : public Object
+{
+public:
+    Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
+    virtual ~Geometry();
+
+    /** Get the Skin attached to this geometry or NULL */
+    const Skin* DeformerSkin() const;
+
+private:
+    const Skin* skin;
+};
+
+
+typedef std::vector<int> MatIndexArray;
+
+
+/** 
+ *  DOM class for FBX geometry of type "Mesh"
+ */
+class MeshGeometry : public Geometry
+{
+public:
+    /** The class constructor */
+    MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
+    
+    /** The class destructor */
+    virtual ~MeshGeometry();
+
+    /** Get a list of all vertex points, non-unique*/
+    const std::vector<aiVector3D>& GetVertices() const;
+
+    /** Get a list of all vertex normals or an empty array if
+    *  no normals are specified. */
+    const std::vector<aiVector3D>& GetNormals() const;
+
+    /** Get a list of all vertex tangents or an empty array
+    *  if no tangents are specified */
+    const std::vector<aiVector3D>& GetTangents() const;
+
+    /** Get a list of all vertex binormals or an empty array
+    *  if no binormals are specified */
+    const std::vector<aiVector3D>& GetBinormals() const;
+
+    /** Return list of faces - each entry denotes a face and specifies
+    *  how many vertices it has. Vertices are taken from the
+    *  vertex data arrays in sequential order. */
+    const std::vector<unsigned int>& GetFaceIndexCounts() const;
+
+    /** Get a UV coordinate slot, returns an empty array if
+    *  the requested slot does not exist. */
+    const std::vector<aiVector2D>& GetTextureCoords( unsigned int index ) const;
+
+    /** Get a UV coordinate slot, returns an empty array if
+    *  the requested slot does not exist. */
+    std::string GetTextureCoordChannelName( unsigned int index ) const;
+
+    /** Get a vertex color coordinate slot, returns an empty array if
+    *  the requested slot does not exist. */
+    const std::vector<aiColor4D>& GetVertexColors( unsigned int index ) const;
+
+    /** Get per-face-vertex material assignments */
+    const MatIndexArray& GetMaterialIndices() const;
+
+    /** Convert from a fbx file vertex index (for example from a #Cluster weight) or NULL
+    * if the vertex index is not valid. */
+    const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const;
+
+    /** Determine the face to which a particular output vertex index belongs.
+    *  This mapping is always unique. */
+    unsigned int FaceForVertexIndex( unsigned int in_index ) const;
+
+private:
+    void ReadLayer( const Scope& layer );
+    void ReadLayerElement( const Scope& layerElement );
+    void ReadVertexData( const std::string& type, int index, const Scope& source );
+
+    void ReadVertexDataUV( std::vector<aiVector2D>& uv_out, const Scope& source,
+        const std::string& MappingInformationType,
+        const std::string& ReferenceInformationType );
+
+    void ReadVertexDataNormals( std::vector<aiVector3D>& normals_out, const Scope& source,
+        const std::string& MappingInformationType,
+        const std::string& ReferenceInformationType );
+
+    void ReadVertexDataColors( std::vector<aiColor4D>& colors_out, const Scope& source,
+        const std::string& MappingInformationType,
+        const std::string& ReferenceInformationType );
+
+    void ReadVertexDataTangents( std::vector<aiVector3D>& tangents_out, const Scope& source,
+        const std::string& MappingInformationType,
+        const std::string& ReferenceInformationType );
+
+    void ReadVertexDataBinormals( std::vector<aiVector3D>& binormals_out, const Scope& source,
+        const std::string& MappingInformationType,
+        const std::string& ReferenceInformationType );
+
+    void ReadVertexDataMaterials( MatIndexArray& materials_out, const Scope& source,
+        const std::string& MappingInformationType,
+        const std::string& ReferenceInformationType );
+
+private:
+    // cached data arrays
+    MatIndexArray materials;
+    std::vector<aiVector3D> vertices;
+    std::vector<unsigned int> faces;
+    mutable std::vector<unsigned int> facesVertexStartIndices;
+    std::vector<aiVector3D> tangents;
+    std::vector<aiVector3D> binormals;
+    std::vector<aiVector3D> normals;
+
+    std::string uvNames[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
+    std::vector<aiVector2D> uvs[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
+    std::vector<aiColor4D> colors[ AI_MAX_NUMBER_OF_COLOR_SETS ];
+
+    std::vector<unsigned int> mapping_counts;
+    std::vector<unsigned int> mapping_offsets;
+    std::vector<unsigned int> mappings;
+};
+
+}
+}
+
+#endif // INCLUDED_AI_FBX_MESHGEOMETRY_H
+

+ 1 - 0
code/FBXModel.cpp

@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
 
 #include "FBXParser.h"
+#include "FBXMeshGeometry.h"
 #include "FBXDocument.h"
 #include "FBXImporter.h"
 #include "FBXImportSettings.h"

+ 17 - 8
code/FBXParser.cpp

@@ -61,6 +61,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <boost/foreach.hpp>
 #include "ByteSwapper.h"
 
+#include <iostream>
+
 using namespace Assimp;
 using namespace Assimp::FBX;
 
@@ -611,7 +613,7 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
 // read an array of float3 tuples
 void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
 {
-    out.clear();
+    out.resize( 0 );
 
     const TokenList& tok = el.Tokens();
     if(tok.empty()) {
@@ -653,6 +655,13 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
                     static_cast<float>(d[1]),
                     static_cast<float>(d[2])));
             }
+
+            for ( size_t i = 0; i < out.size(); i++ ) {
+                aiVector3D vec3( out[ i ] );
+                std::stringstream stream;
+                stream << " vec3.x = " << vec3.x << " vec3.y = " << vec3.y << " vec3.z = " << vec3.z << std::endl;
+                DefaultLogger::get()->info( stream.str() );
+            }
         }
         else if (type == 'f') {
             const float* f = reinterpret_cast<const float*>(&buff[0]);
@@ -692,7 +701,7 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
 // read an array of color4 tuples
 void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
 {
-    out.clear();
+    out.resize( 0 );
     const TokenList& tok = el.Tokens();
     if(tok.empty()) {
         ParseError("unexpected empty element",&el);
@@ -771,7 +780,7 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
 // read an array of float2 tuples
 void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
 {
-    out.clear();
+    out.resize( 0 );
     const TokenList& tok = el.Tokens();
     if(tok.empty()) {
         ParseError("unexpected empty element",&el);
@@ -847,7 +856,7 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
 // read an array of ints
 void ParseVectorDataArray(std::vector<int>& out, const Element& el)
 {
-    out.clear();
+    out.resize( 0 );
     const TokenList& tok = el.Tokens();
     if(tok.empty()) {
         ParseError("unexpected empty element",&el);
@@ -905,7 +914,7 @@ void ParseVectorDataArray(std::vector<int>& out, const Element& el)
 // read an array of floats
 void ParseVectorDataArray(std::vector<float>& out, const Element& el)
 {
-    out.clear();
+    out.resize( 0 );
     const TokenList& tok = el.Tokens();
     if(tok.empty()) {
         ParseError("unexpected empty element",&el);
@@ -967,7 +976,7 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
 // read an array of uints
 void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
 {
-    out.clear();
+    out.resize( 0 );
     const TokenList& tok = el.Tokens();
     if(tok.empty()) {
         ParseError("unexpected empty element",&el);
@@ -1032,7 +1041,7 @@ void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
 // read an array of uint64_ts
 void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
 {
-    out.clear();
+    out.resize( 0 );
     const TokenList& tok = el.Tokens();
     if(tok.empty()) {
         ParseError("unexpected empty element",&el);
@@ -1090,7 +1099,7 @@ void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
 // read an array of int64_ts
 void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
 {
-    out.clear();
+    out.resize( 0 );
     const TokenList& tok = el.Tokens();
     if (tok.empty()) {
         ParseError("unexpected empty element", &el);

+ 7 - 11
code/FBXParser.h

@@ -55,15 +55,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace FBX {
 
-    class Scope;
-    class Parser;
-    class Element;
+class Scope;
+class Parser;
+class Element;
 
-    // XXX should use C++11's unique_ptr - but assimp's need to keep working with 03
-    typedef std::vector< Scope* > ScopeList;
-    typedef std::fbx_unordered_multimap< std::string, Element* > ElementMap;
+// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03
+typedef std::vector< Scope* > ScopeList;
+typedef std::fbx_unordered_multimap< std::string, Element* > ElementMap;
 
-    typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> ElementCollection;
+typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> ElementCollection;
 
 #   define new_Scope new Scope
 #   define new_Element new Element
@@ -162,7 +162,6 @@ public:
     ~Parser();
 
 public:
-
     const Scope& GetRootScope() const {
         return *root.get();
     }
@@ -173,7 +172,6 @@ public:
     }
 
 private:
-
     friend class Scope;
     friend class Element;
 
@@ -183,9 +181,7 @@ private:
     TokenPtr CurrentToken() const;
 
 
-
 private:
-
     const TokenList& tokens;
 
     TokenPtr last, current;