Skip to content

Commit 123d06c

Browse files
authored
Merge pull request assimp#1347 from rickomax/master
Fixed many FBX bugs
2 parents c9d18eb + 328646f commit 123d06c

File tree

6 files changed

+97
-44
lines changed

6 files changed

+97
-44
lines changed

code/FBXConverter.cpp

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,19 @@ class Converter
436436

437437
aiScene* const out;
438438
const FBX::Document& doc;
439+
440+
bool FindTextureIndexByFilename(const Video& video, unsigned int& index) {
441+
index = 0;
442+
const char* videoFileName = video.FileName().c_str();
443+
for (auto texture = textures_converted.begin(); texture != textures_converted.end(); ++texture)
444+
{
445+
if (!strcmp(texture->first->FileName().c_str(), videoFileName)) {
446+
return true;
447+
}
448+
index++;
449+
}
450+
return false;
451+
}
439452
};
440453

441454
Converter::Converter( aiScene* out, const Document& doc )
@@ -1749,7 +1762,7 @@ unsigned int Converter::ConvertVideo( const Video& video )
17491762
out_tex->mWidth = static_cast<unsigned int>( video.ContentLength() ); // total data size
17501763
out_tex->mHeight = 0; // fixed to 0
17511764

1752-
// steal the data from the Video to avoid an additional copy
1765+
// steal the data from the Video to avoid an additional copy
17531766
out_tex->pcData = reinterpret_cast<aiTexel*>( const_cast<Video&>( video ).RelinquishContent() );
17541767

17551768
// try to extract a hint from the file extension
@@ -1783,22 +1796,32 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
17831796
path.Set( tex->RelativeFilename() );
17841797

17851798
const Video* media = tex->Media();
1786-
if ( media != 0 && media->ContentLength() > 0 ) {
1787-
unsigned int index;
1788-
1789-
VideoMap::const_iterator it = textures_converted.find( media );
1790-
if ( it != textures_converted.end() ) {
1791-
index = ( *it ).second;
1792-
}
1793-
else {
1794-
index = ConvertVideo( *media );
1795-
textures_converted[ media ] = index;
1796-
}
1797-
1798-
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
1799-
path.data[ 0 ] = '*';
1800-
path.length = 1 + ASSIMP_itoa10( path.data + 1, MAXLEN - 1, index );
1801-
}
1799+
if (media != 0) {
1800+
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
1801+
unsigned int index;
1802+
1803+
VideoMap::const_iterator it = textures_converted.find(media);
1804+
if (it != textures_converted.end()) {
1805+
index = (*it).second;
1806+
textureReady = true;
1807+
}
1808+
else {
1809+
if (media->ContentLength() > 0) {
1810+
index = ConvertVideo(*media);
1811+
textures_converted[media] = index;
1812+
textureReady = true;
1813+
}
1814+
else if (doc.Settings().searchEmbeddedTextures) { //try to find the texture on the already-loaded textures by the filename, if the flag is on
1815+
textureReady = FindTextureIndexByFilename(*media, index);
1816+
}
1817+
}
1818+
1819+
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
1820+
if (textureReady) {
1821+
path.data[0] = '*';
1822+
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
1823+
}
1824+
}
18021825

18031826
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );
18041827

code/FBXImportSettings.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct ImportSettings
6363
, readWeights(true)
6464
, preservePivots(true)
6565
, optimizeEmptyAnimationCurves(true)
66+
, searchEmbeddedTextures(false)
6667
{}
6768

6869

@@ -137,6 +138,10 @@ struct ImportSettings
137138
* values matching the corresponding node transformation.
138139
* The default value is true. */
139140
bool optimizeEmptyAnimationCurves;
141+
142+
/** search for embedded loaded textures, where no embedded texture data is provided.
143+
* The default value is false. */
144+
bool searchEmbeddedTextures;
140145
};
141146

142147

code/FBXImporter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
131131
settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
132132
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
133133
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
134+
settings.searchEmbeddedTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES, false);
134135
}
135136

136137
// ------------------------------------------------------------------------------------------------

code/FBXMaterial.cpp

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
281281
const Scope& sc = GetRequiredScope(element);
282282

283283
const Element* const Type = sc["Type"];
284-
const Element* const FileName = sc["FileName"];
284+
const Element* const FileName = sc.FindElementCaseInsensitive("FileName"); //some files retain the information as "Filename", others "FileName", who knows
285285
const Element* const RelativeFilename = sc["RelativeFilename"];
286286
const Element* const Content = sc["Content"];
287287

@@ -291,35 +291,40 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
291291

292292
if(FileName) {
293293
fileName = ParseTokenAsString(GetRequiredToken(*FileName,0));
294-
}
294+
}
295295

296296
if(RelativeFilename) {
297297
relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0));
298298
}
299299

300300
if(Content) {
301-
const Token& token = GetRequiredToken(*Content, 0);
302-
const char* data = token.begin();
303-
if(!token.IsBinary()) {
304-
DOMWarning("video content is not binary data, ignoring", &element);
305-
}
306-
else if(static_cast<size_t>(token.end() - data) < 5) {
307-
DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element);
308-
}
309-
else if(*data != 'R') {
310-
DOMWarning("video content is not raw binary data, ignoring", &element);
311-
}
312-
else {
313-
// read number of elements
314-
uint32_t len = 0;
315-
::memcpy(&len, data + 1, sizeof(len));
316-
AI_SWAP4(len);
317-
318-
contentLength = len;
319-
320-
content = new uint8_t[len];
321-
::memcpy(content, data + 5, len);
322-
}
301+
//this field is ommited when the embedded texture is already loaded, let's ignore if it´s not found
302+
try {
303+
const Token& token = GetRequiredToken(*Content, 0);
304+
const char* data = token.begin();
305+
if (!token.IsBinary()) {
306+
DOMWarning("video content is not binary data, ignoring", &element);
307+
}
308+
else if (static_cast<size_t>(token.end() - data) < 5) {
309+
DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element);
310+
}
311+
else if (*data != 'R') {
312+
DOMWarning("video content is not raw binary data, ignoring", &element);
313+
}
314+
else {
315+
// read number of elements
316+
uint32_t len = 0;
317+
::memcpy(&len, data + 1, sizeof(len));
318+
AI_SWAP4(len);
319+
320+
contentLength = len;
321+
322+
content = new uint8_t[len];
323+
::memcpy(content, data + 5, len);
324+
}
325+
} catch (runtime_error runtimeError) {
326+
//we don´t need the content data for contents that has already been loaded
327+
}
323328
}
324329

325330
props = GetPropertyTable(doc,"Video.FbxVideo",element,sc);

code/FBXParser.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4949
#include <map>
5050
#include <memory>
5151
#include "LogAux.h"
52+
#include "fast_atof.h"
5253

5354
#include "FBXCompileConfig.h"
5455
#include "FBXTokenizer.h"
@@ -137,6 +138,17 @@ class Scope
137138
return it == elements.end() ? NULL : (*it).second;
138139
}
139140

141+
const Element* FindElementCaseInsensitive(const std::string& elementName) const {
142+
const char* elementNameCStr = elementName.c_str();
143+
for (auto element = elements.begin(); element != elements.end(); ++element)
144+
{
145+
if (!ASSIMP_strincmp(element->first.c_str(), elementNameCStr, MAXLEN)) {
146+
return element->second;
147+
}
148+
}
149+
return NULL;
150+
}
151+
140152
ElementCollection GetCollection(const std::string& index) const {
141153
return elements.equal_range(index);
142154
}

include/assimp/config.h.in

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Open Asset Import Library (assimp)
44
---------------------------------------------------------------------------
55
6-
Copyright (c) 2006-2016, assimp team
6+
Copyright (c) 2006-2017, assimp team
77
88
All rights reserved.
99
@@ -632,8 +632,15 @@ enum aiComponent
632632
#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \
633633
"IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES"
634634

635-
636-
635+
// ---------------------------------------------------------------------------
636+
/** @brief Set whether the fbx importer will search for embedded loaded textures, where no embedded texture data is provided.
637+
*
638+
* The default value is false (0)
639+
* Property type: bool
640+
*/
641+
#define AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES \
642+
"IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES"
643+
637644
// ---------------------------------------------------------------------------
638645
/** @brief Set the vertex animation keyframe to be imported
639646
*

0 commit comments

Comments
 (0)