From 2b09199f4a34b2fa9137e161e174e519656d3ceb Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 3 Mar 2016 15:19:38 +0100 Subject: [PATCH] FBXImporter: move MeshGeometry declaration into its own header --- code/CMakeLists.txt | 1 + code/FBXConverter.cpp | 17 +- code/FBXDocument.cpp | 17 +- code/FBXDocument.h | 341 ++++----------------------------------- code/FBXImporter.h | 21 +-- code/FBXMeshGeometry.cpp | 89 +++++++++- code/FBXMeshGeometry.h | 180 +++++++++++++++++++++ code/FBXModel.cpp | 1 + code/FBXParser.cpp | 25 ++- code/FBXParser.h | 18 +-- 10 files changed, 352 insertions(+), 358 deletions(-) create mode 100644 code/FBXMeshGeometry.h diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 5088d5433..30aa19772 100644 --- a/code/CMakeLists.txt +++ b/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 diff --git a/code/FBXConverter.cpp b/code/FBXConverter.cpp index c1a816dd8..289a84ac6 100644 --- a/code/FBXConverter.cpp +++ b/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 -#include -#include -#include -#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 +#include +#include +#include #include #include @@ -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; } diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index b59527611..1e9ea6f3c 100644 --- a/code/FBXDocument.cpp +++ b/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 - -#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 #include +#include + 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(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() { diff --git a/code/FBXDocument.h b/code/FBXDocument.h index 126a96820..f74348ab5 100644 --- a/code/FBXDocument.h +++ b/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 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 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 materials; std::vector geometry; std::vector 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 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 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 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& GetVertices() const { - return vertices; - } - - /** Get a list of all vertex normals or an empty array if - * no normals are specified. */ - const std::vector& GetNormals() const { - return normals; - } - - /** Get a list of all vertex tangents or an empty array - * if no tangents are specified */ - const std::vector& GetTangents() const { - return tangents; - } - - /** Get a list of all vertex binormals or an empty array - * if no binormals are specified */ - const std::vector& 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& GetFaceIndexCounts() const { - return faces; - } - - /** Get a UV coordinate slot, returns an empty array if - * the requested slot does not exist. */ - const std::vector& GetTextureCoords(unsigned int index) const { - static const std::vector 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& GetVertexColors(unsigned int index) const { - static const std::vector 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::iterator it = std::upper_bound( - facesVertexStartIndices.begin(), - facesVertexStartIndices.end(), - in_index - ); - - return static_cast(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& uv_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType); - - void ReadVertexDataNormals(std::vector& normals_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType); - - void ReadVertexDataColors(std::vector& colors_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType); - - void ReadVertexDataTangents(std::vector& tangents_out, const Scope& source, - const std::string& MappingInformationType, - const std::string& ReferenceInformationType); - - void ReadVertexDataBinormals(std::vector& 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 vertices; - std::vector faces; - mutable std::vector facesVertexStartIndices; - std::vector tangents; - std::vector binormals; - std::vector normals; - - std::string uvNames[AI_MAX_NUMBER_OF_TEXTURECOORDS]; - std::vector uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS]; - std::vector colors[AI_MAX_NUMBER_OF_COLOR_SETS]; - - std::vector mapping_counts; - std::vector mapping_offsets; - std::vector mappings; -}; - typedef std::vector KeyTimeList; typedef std::vector KeyValueList; @@ -939,12 +713,9 @@ typedef std::vector 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 attributes; @@ -983,7 +753,6 @@ typedef std::map 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 props; mutable AnimationCurveMap curves; @@ -1039,13 +805,9 @@ typedef std::vector 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 props; const Document& doc; }; @@ -1070,31 +831,25 @@ typedef std::vector 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 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 props; }; @@ -1128,11 +879,8 @@ typedef std::vector 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& Clusters() const { return clusters; } private: - float accuracy; std::vector 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 ObjectMap; - typedef std::fbx_unordered_map > 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 ObjectMap; +typedef std::fbx_unordered_map > PropertyTemplateMap; - typedef std::multimap ConnectionMap; +typedef std::multimap 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 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 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& AnimationStacks() const; private: - std::vector GetConnectionsSequenced(uint64_t id, const ConnectionMap&) const; std::vector 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 globals; }; -} -} +} // Namespace FBX +} // Namespace Assimp -#endif +#endif // INCLUDED_AI_FBX_DOCUMENT_H diff --git a/code/FBXImporter.h b/code/FBXImporter.h index 0c50709fc..350ecfb67 100644 --- a/code/FBXImporter.h +++ b/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 class basic_formatter; - typedef class basic_formatter< char, std::char_traits, std::allocator > format; - } - +// TinyFormatter.h +namespace Formatter { + template class basic_formatter; + typedef class basic_formatter< char, std::char_traits, std::allocator > format; +} // ------------------------------------------------------------------------------------------- /** Load the Autodesk FBX file format. @@ -68,10 +67,7 @@ class FBXImporter : public BaseImporter, public LogFunctions { 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 diff --git a/code/FBXMeshGeometry.cpp b/code/FBXMeshGeometry.cpp index 28ce924cb..49bdca92a 100644 --- a/code/FBXMeshGeometry.cpp +++ b/code/FBXMeshGeometry.cpp @@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#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& MeshGeometry::GetVertices() const { + return vertices; +} +// ------------------------------------------------------------------------------------------------ +const std::vector& MeshGeometry::GetNormals() const { + return normals; +} + +// ------------------------------------------------------------------------------------------------ +const std::vector& MeshGeometry::GetTangents() const { + return tangents; +} + +// ------------------------------------------------------------------------------------------------ +const std::vector& MeshGeometry::GetBinormals() const { + return binormals; +} + +// ------------------------------------------------------------------------------------------------ +const std::vector& MeshGeometry::GetFaceIndexCounts() const { + return faces; +} + +// ------------------------------------------------------------------------------------------------ +const std::vector& MeshGeometry::GetTextureCoords( unsigned int index ) const { + static const std::vector 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& MeshGeometry::GetVertexColors( unsigned int index ) const { + static const std::vector 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::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) diff --git a/code/FBXMeshGeometry.h b/code/FBXMeshGeometry.h new file mode 100644 index 000000000..48ac550c1 --- /dev/null +++ b/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 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& GetVertices() const; + + /** Get a list of all vertex normals or an empty array if + * no normals are specified. */ + const std::vector& GetNormals() const; + + /** Get a list of all vertex tangents or an empty array + * if no tangents are specified */ + const std::vector& GetTangents() const; + + /** Get a list of all vertex binormals or an empty array + * if no binormals are specified */ + const std::vector& 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& GetFaceIndexCounts() const; + + /** Get a UV coordinate slot, returns an empty array if + * the requested slot does not exist. */ + const std::vector& 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& 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& uv_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType ); + + void ReadVertexDataNormals( std::vector& normals_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType ); + + void ReadVertexDataColors( std::vector& colors_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType ); + + void ReadVertexDataTangents( std::vector& tangents_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType ); + + void ReadVertexDataBinormals( std::vector& 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 vertices; + std::vector faces; + mutable std::vector facesVertexStartIndices; + std::vector tangents; + std::vector binormals; + std::vector normals; + + std::string uvNames[ AI_MAX_NUMBER_OF_TEXTURECOORDS ]; + std::vector uvs[ AI_MAX_NUMBER_OF_TEXTURECOORDS ]; + std::vector colors[ AI_MAX_NUMBER_OF_COLOR_SETS ]; + + std::vector mapping_counts; + std::vector mapping_offsets; + std::vector mappings; +}; + +} +} + +#endif // INCLUDED_AI_FBX_MESHGEOMETRY_H + diff --git a/code/FBXModel.cpp b/code/FBXModel.cpp index c16439724..c3018e4af 100644 --- a/code/FBXModel.cpp +++ b/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" diff --git a/code/FBXParser.cpp b/code/FBXParser.cpp index 09a18b6e0..3f982c64a 100644 --- a/code/FBXParser.cpp +++ b/code/FBXParser.cpp @@ -61,6 +61,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "ByteSwapper.h" +#include + 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& 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& out, const Element& el) static_cast(d[1]), static_cast(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(&buff[0]); @@ -692,7 +701,7 @@ void ParseVectorDataArray(std::vector& out, const Element& el) // read an array of color4 tuples void ParseVectorDataArray(std::vector& 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& out, const Element& el) // read an array of float2 tuples void ParseVectorDataArray(std::vector& 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& out, const Element& el) // read an array of ints void ParseVectorDataArray(std::vector& 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& out, const Element& el) // read an array of floats void ParseVectorDataArray(std::vector& 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& out, const Element& el) // read an array of uints void ParseVectorDataArray(std::vector& 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& out, const Element& el) // read an array of uint64_ts void ParseVectorDataArray(std::vector& 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& out, const Element& el) // read an array of int64_ts void ParseVectorDataArray(std::vector& out, const Element& el) { - out.clear(); + out.resize( 0 ); const TokenList& tok = el.Tokens(); if (tok.empty()) { ParseError("unexpected empty element", &el); diff --git a/code/FBXParser.h b/code/FBXParser.h index 4f165c13f..fb4ec99fe 100644 --- a/code/FBXParser.h +++ b/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 ElementCollection; +typedef std::pair 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;