FBX: woraround for issue 1089.

pull/1091/head
Kim Kulling 2016-12-02 11:32:34 +01:00
parent c80777f13f
commit dcfc696e86
9 changed files with 80 additions and 44 deletions

View File

@ -146,18 +146,20 @@ void TokenizeError(const std::string& message, const char* begin, const char* cu
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
uint32_t ReadWord(const char* input, const char*& cursor, const char* end) uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
{ {
if(Offset(cursor, end) < 4) { const size_t k_to_read = sizeof( uint32_t );
if(Offset(cursor, end) < k_to_read ) {
TokenizeError("cannot ReadWord, out of bounds",input, cursor); TokenizeError("cannot ReadWord, out of bounds",input, cursor);
} }
uint32_t word = *reinterpret_cast<const uint32_t*>(cursor); uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
AI_SWAP4(word); AI_SWAP4(word);
cursor += 4; cursor += k_to_read;
return word; return word;
} }
// ------------------------------------------------------------------------------------------------
uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end) uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
{ {
const size_t k_to_read = sizeof(uint64_t); const size_t k_to_read = sizeof(uint64_t);
@ -177,7 +179,7 @@ uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
uint8_t ReadByte(const char* input, const char*& cursor, const char* end) uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
{ {
if(Offset(cursor, end) < 1) { if(Offset(cursor, end) < sizeof( uint8_t ) ) {
TokenizeError("cannot ReadByte, out of bounds",input, cursor); TokenizeError("cannot ReadByte, out of bounds",input, cursor);
} }
@ -220,8 +222,6 @@ unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const ch
return length; return length;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end) void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end)
{ {
@ -345,7 +345,7 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, uint32_t const flags) bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, uint32_t const flags)
{ {
// the first word contains the offset at which this block ends // the first word contains the offset at which this block ends
const uint64_t end_offset = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); const uint64_t end_offset = /*check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : */ReadWord(input, cursor, end);
// we may get 0 if reading reached the end of the file - // we may get 0 if reading reached the end of the file -
// fbx files have a mysterious extra footer which I don't know // fbx files have a mysterious extra footer which I don't know
@ -363,10 +363,10 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
} }
// the second data word contains the number of properties in the scope // the second data word contains the number of properties in the scope
const uint64_t prop_count = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); const uint64_t prop_count = /*check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : */ReadWord(input, cursor, end);
// the third data word contains the length of the property list // the third data word contains the length of the property list
const uint64_t prop_length = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); const uint64_t prop_length = /*check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) :*/ ReadWord(input, cursor, end);
// now comes the name of the scope/key // now comes the name of the scope/key
const char* sbeg, *send; const char* sbeg, *send;
@ -393,7 +393,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
// at the end of each nested block, there is a NUL record to indicate // at the end of each nested block, there is a NUL record to indicate
// that the sub-scope exists (i.e. to distinguish between P: and P : {}) // that the sub-scope exists (i.e. to distinguish between P: and P : {})
// this NUL record is 13 bytes long on 32 bit version and 25 bytes long on 64 bit. // this NUL record is 13 bytes long on 32 bit version and 25 bytes long on 64 bit.
const size_t sentinel_block_length = check_flag(flags, e_flag_field_size_64_bit) ? (sizeof(uint64_t) * 3 + 1) : (sizeof(uint32_t) * 3 + 1); const size_t sentinel_block_length = /*check_flag(flags, e_flag_field_size_64_bit) ? (sizeof(uint64_t) * 3 + 1) : */(sizeof(uint32_t) * 3 + 1);
if (Offset(input, cursor) < end_offset) { if (Offset(input, cursor) < end_offset) {
if (end_offset - Offset(input, cursor) < sentinel_block_length) { if (end_offset - Offset(input, cursor) < sentinel_block_length) {

View File

@ -71,7 +71,7 @@ using namespace Util;
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
// XXX vc9's debugger won't step into anonymous namespaces // XXX vc9's debugger won't step into anonymous namespaces
//namespace { //namespace {
/** Dummy class to encapsulate the conversion process */ /** Dummy class to encapsulate the conversion process */
@ -114,11 +114,9 @@ private:
// collect and assign child nodes // collect and assign child nodes
void ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4() ); void ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4() );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertLights( const Model& model ); void ConvertLights( const Model& model );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertCameras( const Model& model ); void ConvertCameras( const Model& model );
@ -189,7 +187,6 @@ private:
static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */ static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
static_cast<unsigned int>(-1); static_cast<unsigned int>(-1);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/** /**
* - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into * - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into
@ -341,8 +338,6 @@ private:
typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList; typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
typedef std::vector<KeyFrameList> KeyFrameListList; typedef std::vector<KeyFrameList> KeyFrameListList;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
KeyFrameListList GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop ); KeyFrameListList GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop );
@ -899,7 +894,6 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
} }
} }
bool Converter::NeedsComplexTransformationChain( const Model& model ) bool Converter::NeedsComplexTransformationChain( const Model& model )
{ {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
@ -923,7 +917,6 @@ bool Converter::NeedsComplexTransformationChain( const Model& model )
return false; return false;
} }
std::string Converter::NameTransformationChainNode( const std::string& name, TransformationComp comp ) std::string Converter::NameTransformationChainNode( const std::string& name, TransformationComp comp )
{ {
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp ); return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
@ -1067,7 +1060,6 @@ void Converter::GenerateTransformationNodeChain( const Model& model,
} }
} }
void Converter::SetupNodeMetadata( const Model& model, aiNode& nd ) void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
{ {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
@ -1132,7 +1124,6 @@ void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4&
} }
} }
std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform ) const aiMatrix4x4& node_global_transform )
{ {
@ -1168,7 +1159,6 @@ std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, cons
return temp; return temp;
} }
aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh ) aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh )
{ {
aiMesh* const out_mesh = new aiMesh(); aiMesh* const out_mesh = new aiMesh();
@ -1188,7 +1178,6 @@ aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh )
return out_mesh; return out_mesh;
} }
unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model, unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform ) const aiMatrix4x4& node_global_transform )
{ {
@ -1511,7 +1500,6 @@ unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, cons
return static_cast<unsigned int>( meshes.size() - 1 ); return static_cast<unsigned int>( meshes.size() - 1 );
} }
void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo, void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
const aiMatrix4x4& node_global_transform , const aiMatrix4x4& node_global_transform ,
unsigned int materialIndex, unsigned int materialIndex,
@ -1658,7 +1646,6 @@ void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*mode
} }
} }
void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo, void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
MatIndexArray::value_type materialIndex ) MatIndexArray::value_type materialIndex )
{ {

View File

@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
using namespace Util; using namespace Util;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name) Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name)
@ -159,8 +159,6 @@ Skin::~Skin()
} }
} }
} }

View File

@ -252,17 +252,15 @@ FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<cons
: props(props) : props(props)
, doc(doc) , doc(doc)
{ {
// empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
FileGlobalSettings::~FileGlobalSettings() FileGlobalSettings::~FileGlobalSettings()
{ {
// empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Document::Document(const Parser& parser, const ImportSettings& settings) Document::Document(const Parser& parser, const ImportSettings& settings)
: settings(settings) : settings(settings)
@ -285,7 +283,6 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
ReadConnections(); ReadConnections();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Document::~Document() Document::~Document()
{ {
@ -315,7 +312,7 @@ void Document::ReadHeader()
const Scope& shead = *ehead->Compound(); const Scope& shead = *ehead->Compound();
fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0)); fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
// While we maye have some success with newer files, we don't support // While we may have some success with newer files, we don't support
// the older 6.n fbx format // the older 6.n fbx format
if(fbxVersion < LowerSupportedVersion ) { if(fbxVersion < LowerSupportedVersion ) {
DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013"); DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013");
@ -331,7 +328,6 @@ void Document::ReadHeader()
} }
} }
const Element* const ecreator = shead["Creator"]; const Element* const ecreator = shead["Creator"];
if(ecreator) { if(ecreator) {
creator = ParseTokenAsString(GetRequiredToken(*ecreator,0)); creator = ParseTokenAsString(GetRequiredToken(*ecreator,0));

View File

@ -44,9 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#include <exception>
#include <iterator>
#include "FBXImporter.h" #include "FBXImporter.h"
#include "FBXTokenizer.h" #include "FBXTokenizer.h"
@ -59,6 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MemoryIOWrapper.h" #include "MemoryIOWrapper.h"
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <exception>
#include <iterator>
namespace Assimp { namespace Assimp {
template<> const std::string LogFunctions<FBXImporter>::log_prefix = "FBX: "; template<> const std::string LogFunctions<FBXImporter>::log_prefix = "FBX: ";
} }
@ -99,7 +99,7 @@ FBXImporter::~FBXImporter()
bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{ {
const std::string& extension = GetExtension(pFile); const std::string& extension = GetExtension(pFile);
if (extension == "fbx") { if (extension == std::string( desc.mFileExtensions ) ) {
return true; return true;
} }
@ -118,7 +118,6 @@ const aiImporterDesc* FBXImporter::GetInfo () const
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader // Setup configuration properties for the loader
void FBXImporter::SetupProperties(const Importer* pImp) void FBXImporter::SetupProperties(const Importer* pImp)
@ -135,7 +134,6 @@ void FBXImporter::SetupProperties(const Importer* pImp)
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true); settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void FBXImporter::InternReadFile( const std::string& pFile, void FBXImporter::InternReadFile( const std::string& pFile,

View File

@ -84,13 +84,10 @@ enum TokenType
* Offers iterator protocol. Tokens are immutable. */ * Offers iterator protocol. Tokens are immutable. */
class Token class Token
{ {
private: private:
static const unsigned int BINARY_MARKER = static_cast<unsigned int>(-1); static const unsigned int BINARY_MARKER = static_cast<unsigned int>(-1);
public: public:
/** construct a textual token */ /** construct a textual token */
Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column); Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column);
@ -100,13 +97,11 @@ public:
~Token(); ~Token();
public: public:
std::string StringContents() const { std::string StringContents() const {
return std::string(begin(),end()); return std::string(begin(),end());
} }
public: public:
bool IsBinary() const { bool IsBinary() const {
return column == BINARY_MARKER; return column == BINARY_MARKER;
} }

View File

@ -67,6 +67,7 @@ SET( TEST_SRCS
unit/utColladaExportLight.cpp unit/utColladaExportLight.cpp
unit/utDefaultIOStream.cpp unit/utDefaultIOStream.cpp
unit/utFastAtof.cpp unit/utFastAtof.cpp
unit/utFBXImporterExporter.cpp
unit/utFindDegenerates.cpp unit/utFindDegenerates.cpp
unit/utFindInvalidData.cpp unit/utFindInvalidData.cpp
unit/utFixInfacingNormals.cpp unit/utFixInfacingNormals.cpp

Binary file not shown.

View File

@ -0,0 +1,61 @@
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "SceneDiffer.h"
#include "AbstractImportExportBase.h"
#include <assimp/Importer.hpp>
using namespace Assimp;
class utFBXImporterExporter : public AbstractImportExportBase {
public:
virtual bool importerTest() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/FBX/spider.FBX", 0 );
return nullptr != scene;
}
};
TEST_F( utFBXImporterExporter, importXFromFileTest ) {
EXPECT_TRUE( importerTest() );
}