nuclear@0: /* nuclear@0: Open Asset Import Library (assimp) nuclear@0: ---------------------------------------------------------------------- nuclear@0: nuclear@0: Copyright (c) 2006-2012, assimp team nuclear@0: All rights reserved. nuclear@0: nuclear@0: Redistribution and use of this software in source and binary forms, nuclear@0: with or without modification, are permitted provided that the nuclear@0: following conditions are met: nuclear@0: nuclear@0: * Redistributions of source code must retain the above nuclear@0: copyright notice, this list of conditions and the nuclear@0: following disclaimer. nuclear@0: nuclear@0: * Redistributions in binary form must reproduce the above nuclear@0: copyright notice, this list of conditions and the nuclear@0: following disclaimer in the documentation and/or other nuclear@0: materials provided with the distribution. nuclear@0: nuclear@0: * Neither the name of the assimp team, nor the names of its nuclear@0: contributors may be used to endorse or promote products nuclear@0: derived from this software without specific prior nuclear@0: written permission of the assimp team. nuclear@0: nuclear@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS nuclear@0: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT nuclear@0: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR nuclear@0: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT nuclear@0: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, nuclear@0: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT nuclear@0: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, nuclear@0: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY nuclear@0: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT nuclear@0: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE nuclear@0: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. nuclear@0: nuclear@0: ---------------------------------------------------------------------- nuclear@0: */ nuclear@0: nuclear@0: /** @file FBXImporter.cpp nuclear@0: * @brief Implementation of the FBX importer. nuclear@0: */ nuclear@0: #include "AssimpPCH.h" nuclear@0: nuclear@0: #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER nuclear@0: nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: nuclear@0: #include "FBXImporter.h" nuclear@0: nuclear@0: #include "FBXTokenizer.h" nuclear@0: #include "FBXParser.h" nuclear@0: #include "FBXUtil.h" nuclear@0: #include "FBXDocument.h" nuclear@0: #include "FBXConverter.h" nuclear@0: nuclear@0: #include "StreamReader.h" nuclear@0: #include "MemoryIOWrapper.h" nuclear@0: nuclear@0: namespace Assimp { nuclear@0: template<> const std::string LogFunctions::log_prefix = "FBX: "; nuclear@0: } nuclear@0: nuclear@0: using namespace Assimp; nuclear@0: using namespace Assimp::Formatter; nuclear@0: using namespace Assimp::FBX; nuclear@0: nuclear@0: namespace { nuclear@0: static const aiImporterDesc desc = { nuclear@0: "Autodesk FBX Importer", nuclear@0: "", nuclear@0: "", nuclear@0: "", nuclear@0: aiImporterFlags_SupportTextFlavour, nuclear@0: 0, nuclear@0: 0, nuclear@0: 0, nuclear@0: 0, nuclear@0: "fbx" nuclear@0: }; nuclear@0: } nuclear@0: nuclear@0: // ------------------------------------------------------------------------------------------------ nuclear@0: // Constructor to be privately used by #Importer nuclear@0: FBXImporter::FBXImporter() nuclear@0: {} nuclear@0: nuclear@0: // ------------------------------------------------------------------------------------------------ nuclear@0: // Destructor, private as well nuclear@0: FBXImporter::~FBXImporter() nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: // ------------------------------------------------------------------------------------------------ nuclear@0: // Returns whether the class can handle the format of the given file. nuclear@0: bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const nuclear@0: { nuclear@0: const std::string& extension = GetExtension(pFile); nuclear@0: if (extension == "fbx") { nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: else if ((!extension.length() || checkSig) && pIOHandler) { nuclear@0: // at least ascii FBX files usually have a 'FBX' somewhere in their head nuclear@0: const char* tokens[] = {"FBX"}; nuclear@0: return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); nuclear@0: } nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: // ------------------------------------------------------------------------------------------------ nuclear@0: // List all extensions handled by this loader nuclear@0: const aiImporterDesc* FBXImporter::GetInfo () const nuclear@0: { nuclear@0: return &desc; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------------------------------------ nuclear@0: // Setup configuration properties for the loader nuclear@0: void FBXImporter::SetupProperties(const Importer* pImp) nuclear@0: { nuclear@0: settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true); nuclear@0: settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false); nuclear@0: settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true); nuclear@0: settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true); nuclear@0: settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true); nuclear@0: settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true); nuclear@0: settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false); nuclear@0: settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true); nuclear@0: settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------------------------------------ nuclear@0: // Imports the given file into the given scene structure. nuclear@0: void FBXImporter::InternReadFile( const std::string& pFile, nuclear@0: aiScene* pScene, IOSystem* pIOHandler) nuclear@0: { nuclear@0: boost::scoped_ptr stream(pIOHandler->Open(pFile,"rb")); nuclear@0: if (!stream) { nuclear@0: ThrowException("Could not open file for reading"); nuclear@0: } nuclear@0: nuclear@0: // read entire file into memory - no streaming for this, fbx nuclear@0: // files can grow large, but the assimp output data structure nuclear@0: // then becomes very large, too. Assimp doesn't support nuclear@0: // streaming for its output data structures so the net win with nuclear@0: // streaming input data would be very low. nuclear@0: std::vector contents; nuclear@0: contents.resize(stream->FileSize()); nuclear@0: nuclear@0: stream->Read(&*contents.begin(),contents.size(),1); nuclear@0: const char* const begin = &*contents.begin(); nuclear@0: nuclear@0: // broadphase tokenizing pass in which we identify the core nuclear@0: // syntax elements of FBX (brackets, commas, key:value mappings) nuclear@0: TokenList tokens; nuclear@0: try { nuclear@0: nuclear@0: bool is_binary = false; nuclear@0: if (!strncmp(begin,"Kaydara FBX Binary",18)) { nuclear@0: is_binary = true; nuclear@0: TokenizeBinary(tokens,begin,contents.size()); nuclear@0: } nuclear@0: else { nuclear@0: Tokenize(tokens,begin); nuclear@0: } nuclear@0: nuclear@0: // use this information to construct a very rudimentary nuclear@0: // parse-tree representing the FBX scope structure nuclear@0: Parser parser(tokens, is_binary); nuclear@0: nuclear@0: // take the raw parse-tree and convert it to a FBX DOM nuclear@0: Document doc(parser,settings); nuclear@0: nuclear@0: // convert the FBX DOM to aiScene nuclear@0: ConvertToAssimpScene(pScene,doc); nuclear@0: } nuclear@0: catch(std::exception&) { nuclear@0: std::for_each(tokens.begin(),tokens.end(),Util::delete_fun()); nuclear@0: throw; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: #endif // !ASSIMP_BUILD_NO_FBX_IMPORTER