Merge pull request #1347 from rickomax/master

Fixed many FBX bugs
pull/1339/merge v4.0.0.rc1
Kim Kulling 2017-07-15 20:55:57 +02:00 committed by GitHub
commit 123d06ca1c
6 changed files with 93 additions and 40 deletions

View File

@ -436,6 +436,19 @@ private:
aiScene* const out; aiScene* const out;
const FBX::Document& doc; const FBX::Document& doc;
bool FindTextureIndexByFilename(const Video& video, unsigned int& index) {
index = 0;
const char* videoFileName = video.FileName().c_str();
for (auto texture = textures_converted.begin(); texture != textures_converted.end(); ++texture)
{
if (!strcmp(texture->first->FileName().c_str(), videoFileName)) {
return true;
}
index++;
}
return false;
}
}; };
Converter::Converter( aiScene* out, const Document& doc ) Converter::Converter( aiScene* out, const Document& doc )
@ -1749,7 +1762,7 @@ unsigned int Converter::ConvertVideo( const Video& video )
out_tex->mWidth = static_cast<unsigned int>( video.ContentLength() ); // total data size out_tex->mWidth = static_cast<unsigned int>( video.ContentLength() ); // total data size
out_tex->mHeight = 0; // fixed to 0 out_tex->mHeight = 0; // fixed to 0
// steal the data from the Video to avoid an additional copy // steal the data from the Video to avoid an additional copy
out_tex->pcData = reinterpret_cast<aiTexel*>( const_cast<Video&>( video ).RelinquishContent() ); out_tex->pcData = reinterpret_cast<aiTexel*>( const_cast<Video&>( video ).RelinquishContent() );
// try to extract a hint from the file extension // try to extract a hint from the file extension
@ -1783,22 +1796,32 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
path.Set( tex->RelativeFilename() ); path.Set( tex->RelativeFilename() );
const Video* media = tex->Media(); const Video* media = tex->Media();
if ( media != 0 && media->ContentLength() > 0 ) { if (media != 0) {
unsigned int index; bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
unsigned int index;
VideoMap::const_iterator it = textures_converted.find( media ); VideoMap::const_iterator it = textures_converted.find(media);
if ( it != textures_converted.end() ) { if (it != textures_converted.end()) {
index = ( *it ).second; index = (*it).second;
} textureReady = true;
else { }
index = ConvertVideo( *media ); else {
textures_converted[ media ] = index; if (media->ContentLength() > 0) {
} index = ConvertVideo(*media);
textures_converted[media] = index;
textureReady = true;
}
else if (doc.Settings().searchEmbeddedTextures) { //try to find the texture on the already-loaded textures by the filename, if the flag is on
textureReady = FindTextureIndexByFilename(*media, index);
}
}
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture) // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
path.data[ 0 ] = '*'; if (textureReady) {
path.length = 1 + ASSIMP_itoa10( path.data + 1, MAXLEN - 1, index ); path.data[0] = '*';
} path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
}
}
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 ); out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );

View File

@ -63,6 +63,7 @@ struct ImportSettings
, readWeights(true) , readWeights(true)
, preservePivots(true) , preservePivots(true)
, optimizeEmptyAnimationCurves(true) , optimizeEmptyAnimationCurves(true)
, searchEmbeddedTextures(false)
{} {}
@ -137,6 +138,10 @@ struct ImportSettings
* values matching the corresponding node transformation. * values matching the corresponding node transformation.
* The default value is true. */ * The default value is true. */
bool optimizeEmptyAnimationCurves; bool optimizeEmptyAnimationCurves;
/** search for embedded loaded textures, where no embedded texture data is provided.
* The default value is false. */
bool searchEmbeddedTextures;
}; };

View File

@ -131,6 +131,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false); settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true); settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
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);
settings.searchEmbeddedTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES, false);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -281,7 +281,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
const Scope& sc = GetRequiredScope(element); const Scope& sc = GetRequiredScope(element);
const Element* const Type = sc["Type"]; const Element* const Type = sc["Type"];
const Element* const FileName = sc["FileName"]; const Element* const FileName = sc.FindElementCaseInsensitive("FileName"); //some files retain the information as "Filename", others "FileName", who knows
const Element* const RelativeFilename = sc["RelativeFilename"]; const Element* const RelativeFilename = sc["RelativeFilename"];
const Element* const Content = sc["Content"]; const Element* const Content = sc["Content"];
@ -291,35 +291,40 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
if(FileName) { if(FileName) {
fileName = ParseTokenAsString(GetRequiredToken(*FileName,0)); fileName = ParseTokenAsString(GetRequiredToken(*FileName,0));
} }
if(RelativeFilename) { if(RelativeFilename) {
relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0)); relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0));
} }
if(Content) { if(Content) {
const Token& token = GetRequiredToken(*Content, 0); //this field is ommited when the embedded texture is already loaded, let's ignore if it´s not found
const char* data = token.begin(); try {
if(!token.IsBinary()) { const Token& token = GetRequiredToken(*Content, 0);
DOMWarning("video content is not binary data, ignoring", &element); const char* data = token.begin();
} if (!token.IsBinary()) {
else if(static_cast<size_t>(token.end() - data) < 5) { DOMWarning("video content is not binary data, ignoring", &element);
DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element); }
} else if (static_cast<size_t>(token.end() - data) < 5) {
else if(*data != 'R') { DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element);
DOMWarning("video content is not raw binary data, ignoring", &element); }
} else if (*data != 'R') {
else { DOMWarning("video content is not raw binary data, ignoring", &element);
// read number of elements }
uint32_t len = 0; else {
::memcpy(&len, data + 1, sizeof(len)); // read number of elements
AI_SWAP4(len); uint32_t len = 0;
::memcpy(&len, data + 1, sizeof(len));
AI_SWAP4(len);
contentLength = len; contentLength = len;
content = new uint8_t[len]; content = new uint8_t[len];
::memcpy(content, data + 5, len); ::memcpy(content, data + 5, len);
} }
} catch (runtime_error runtimeError) {
//we don´t need the content data for contents that has already been loaded
}
} }
props = GetPropertyTable(doc,"Video.FbxVideo",element,sc); props = GetPropertyTable(doc,"Video.FbxVideo",element,sc);

View File

@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <map> #include <map>
#include <memory> #include <memory>
#include "LogAux.h" #include "LogAux.h"
#include "fast_atof.h"
#include "FBXCompileConfig.h" #include "FBXCompileConfig.h"
#include "FBXTokenizer.h" #include "FBXTokenizer.h"
@ -137,6 +138,17 @@ public:
return it == elements.end() ? NULL : (*it).second; return it == elements.end() ? NULL : (*it).second;
} }
const Element* FindElementCaseInsensitive(const std::string& elementName) const {
const char* elementNameCStr = elementName.c_str();
for (auto element = elements.begin(); element != elements.end(); ++element)
{
if (!ASSIMP_strincmp(element->first.c_str(), elementNameCStr, MAXLEN)) {
return element->second;
}
}
return NULL;
}
ElementCollection GetCollection(const std::string& index) const { ElementCollection GetCollection(const std::string& index) const {
return elements.equal_range(index); return elements.equal_range(index);
} }

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2016, assimp team Copyright (c) 2006-2017, assimp team
All rights reserved. All rights reserved.
@ -632,8 +632,15 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \ #define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \
"IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES" "IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES"
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will search for embedded loaded textures, where no embedded texture data is provided.
*
* The default value is false (0)
* Property type: bool
*/
#define AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES \
"IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Set the vertex animation keyframe to be imported /** @brief Set the vertex animation keyframe to be imported
* *