diff options
Diffstat (limited to 'src/3rdparty/assimp/code/ACLoader.cpp')
-rw-r--r-- | src/3rdparty/assimp/code/ACLoader.cpp | 866 |
1 files changed, 0 insertions, 866 deletions
diff --git a/src/3rdparty/assimp/code/ACLoader.cpp b/src/3rdparty/assimp/code/ACLoader.cpp deleted file mode 100644 index 93e739b4e..000000000 --- a/src/3rdparty/assimp/code/ACLoader.cpp +++ /dev/null @@ -1,866 +0,0 @@ - -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2012, 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 Implementation of the AC3D importer class */ - -#include "AssimpPCH.h" - -#ifndef ASSIMP_BUILD_NO_AC_IMPORTER - -// internal headers -#include "ACLoader.h" -#include "ParsingUtils.h" -#include "fast_atof.h" -#include "Subdivision.h" - -using namespace Assimp; - -static const aiImporterDesc desc = { - "AC3D Importer", - "", - "", - "", - aiImporterFlags_SupportTextFlavour, - 0, - 0, - 0, - 0, - "ac acc ac3d" -}; - -// ------------------------------------------------------------------------------------------------ -// skip to the next token -#define AI_AC_SKIP_TO_NEXT_TOKEN() \ - if (!SkipSpaces(&buffer)) \ - { \ - DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL"); \ - continue; \ - } - -// ------------------------------------------------------------------------------------------------ -// read a string (may be enclosed in double quotation marks). buffer must point to " -#define AI_AC_GET_STRING(out) \ - ++buffer; \ - const char* sz = buffer; \ - while ('\"' != *buffer) \ - { \ - if (IsLineEnd( *buffer )) \ - { \ - DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL in string"); \ - out = "ERROR"; \ - break; \ - } \ - ++buffer; \ - } \ - if (IsLineEnd( *buffer ))continue; \ - out = std::string(sz,(unsigned int)(buffer-sz)); \ - ++buffer; - - -// ------------------------------------------------------------------------------------------------ -// read 1 to n floats prefixed with an optional predefined identifier -#define AI_AC_CHECKED_LOAD_FLOAT_ARRAY(name,name_length,num,out) \ - AI_AC_SKIP_TO_NEXT_TOKEN(); \ - if (name_length) \ - { \ - if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \ - { \ - DefaultLogger::get()->error("AC3D: Unexpexted token. " name " was expected."); \ - continue; \ - } \ - buffer += name_length+1; \ - } \ - for (unsigned int i = 0; i < num;++i) \ - { \ - AI_AC_SKIP_TO_NEXT_TOKEN(); \ - buffer = fast_atoreal_move<float>(buffer,((float*)out)[i]); \ - } - - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -AC3DImporter::AC3DImporter() -{ - // nothing to be done here -} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -AC3DImporter::~AC3DImporter() -{ - // nothing to be done here -} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the class can handle the format of the given file. -bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const -{ - std::string extension = GetExtension(pFile); - - // fixme: are acc and ac3d *really* used? Some sources say they are - if(extension == "ac" || extension == "ac3d" || extension == "acc") { - return true; - } - if (!extension.length() || checkSig) { - uint32_t token = AI_MAKE_MAGIC("AC3D"); - return CheckMagicToken(pIOHandler,pFile,&token,1,0); - } - return false; -} - -// ------------------------------------------------------------------------------------------------ -// Loader meta information -const aiImporterDesc* AC3DImporter::GetInfo () const -{ - return &desc; -} - -// ------------------------------------------------------------------------------------------------ -// Get a pointer to the next line from the file -bool AC3DImporter::GetNextLine( ) -{ - SkipLine(&buffer); - return SkipSpaces(&buffer); -} - -// ------------------------------------------------------------------------------------------------ -// Parse an object section in an AC file -void AC3DImporter::LoadObjectSection(std::vector<Object>& objects) -{ - if (!TokenMatch(buffer,"OBJECT",6)) - return; - - SkipSpaces(&buffer); - - ++mNumMeshes; - - objects.push_back(Object()); - Object& obj = objects.back(); - - aiLight* light = NULL; - if (!ASSIMP_strincmp(buffer,"light",5)) - { - // This is a light source. Add it to the list - mLights->push_back(light = new aiLight()); - - // Return a point light with no attenuation - light->mType = aiLightSource_POINT; - light->mColorDiffuse = light->mColorSpecular = aiColor3D(1.f,1.f,1.f); - light->mAttenuationConstant = 1.f; - - // Generate a default name for both the light source and the node - // FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version. - light->mName.length = ::sprintf(light->mName.data,"ACLight_%i",static_cast<unsigned int>(mLights->size())-1); - obj.name = std::string( light->mName.data ); - - DefaultLogger::get()->debug("AC3D: Light source encountered"); - obj.type = Object::Light; - } - else if (!ASSIMP_strincmp(buffer,"group",5)) - { - obj.type = Object::Group; - } - else if (!ASSIMP_strincmp(buffer,"world",5)) - { - obj.type = Object::World; - } - else obj.type = Object::Poly; - while (GetNextLine()) - { - if (TokenMatch(buffer,"kids",4)) - { - SkipSpaces(&buffer); - unsigned int num = strtoul10(buffer,&buffer); - GetNextLine(); - if (num) - { - // load the children of this object recursively - obj.children.reserve(num); - for (unsigned int i = 0; i < num; ++i) - LoadObjectSection(obj.children); - } - return; - } - else if (TokenMatch(buffer,"name",4)) - { - SkipSpaces(&buffer); - AI_AC_GET_STRING(obj.name); - - // If this is a light source, we'll also need to store - // the name of the node in it. - if (light) - { - light->mName.Set(obj.name); - } - } - else if (TokenMatch(buffer,"texture",7)) - { - SkipSpaces(&buffer); - AI_AC_GET_STRING(obj.texture); - } - else if (TokenMatch(buffer,"texrep",6)) - { - SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texRepeat); - if (!obj.texRepeat.x || !obj.texRepeat.y) - obj.texRepeat = aiVector2D (1.f,1.f); - } - else if (TokenMatch(buffer,"texoff",6)) - { - SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texOffset); - } - else if (TokenMatch(buffer,"rot",3)) - { - SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,9,&obj.rotation); - } - else if (TokenMatch(buffer,"loc",3)) - { - SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&obj.translation); - } - else if (TokenMatch(buffer,"subdiv",6)) - { - SkipSpaces(&buffer); - obj.subDiv = strtoul10(buffer,&buffer); - } - else if (TokenMatch(buffer,"crease",6)) - { - SkipSpaces(&buffer); - obj.crease = fast_atof(buffer); - } - else if (TokenMatch(buffer,"numvert",7)) - { - SkipSpaces(&buffer); - - unsigned int t = strtoul10(buffer,&buffer); - obj.vertices.reserve(t); - for (unsigned int i = 0; i < t;++i) - { - if (!GetNextLine()) - { - DefaultLogger::get()->error("AC3D: Unexpected EOF: not all vertices have been parsed yet"); - break; - } - else if (!IsNumeric(*buffer)) - { - DefaultLogger::get()->error("AC3D: Unexpected token: not all vertices have been parsed yet"); - --buffer; // make sure the line is processed a second time - break; - } - obj.vertices.push_back(aiVector3D()); - aiVector3D& v = obj.vertices.back(); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x); - } - } - else if (TokenMatch(buffer,"numsurf",7)) - { - SkipSpaces(&buffer); - - bool Q3DWorkAround = false; - - const unsigned int t = strtoul10(buffer,&buffer); - obj.surfaces.reserve(t); - for (unsigned int i = 0; i < t;++i) - { - GetNextLine(); - if (!TokenMatch(buffer,"SURF",4)) - { - // FIX: this can occur for some files - Quick 3D for - // example writes no surf chunks - if (!Q3DWorkAround) - { - DefaultLogger::get()->warn("AC3D: SURF token was expected"); - DefaultLogger::get()->debug("Continuing with Quick3D Workaround enabled"); - } - --buffer; // make sure the line is processed a second time - // break; --- see fix notes above - - Q3DWorkAround = true; - } - SkipSpaces(&buffer); - obj.surfaces.push_back(Surface()); - Surface& surf = obj.surfaces.back(); - surf.flags = strtoul_cppstyle(buffer); - - while (1) - { - if(!GetNextLine()) - { - DefaultLogger::get()->error("AC3D: Unexpected EOF: surface is incomplete"); - break; - } - if (TokenMatch(buffer,"mat",3)) - { - SkipSpaces(&buffer); - surf.mat = strtoul10(buffer); - } - else if (TokenMatch(buffer,"refs",4)) - { - // --- see fix notes above - if (Q3DWorkAround) - { - if (!surf.entries.empty()) - { - buffer -= 6; - break; - } - } - - SkipSpaces(&buffer); - const unsigned int m = strtoul10(buffer); - surf.entries.reserve(m); - - obj.numRefs += m; - - for (unsigned int k = 0; k < m; ++k) - { - if(!GetNextLine()) - { - DefaultLogger::get()->error("AC3D: Unexpected EOF: surface references are incomplete"); - break; - } - surf.entries.push_back(Surface::SurfaceEntry()); - Surface::SurfaceEntry& entry = surf.entries.back(); - - entry.first = strtoul10(buffer,&buffer); - SkipSpaces(&buffer); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&entry.second); - } - } - else - { - - --buffer; // make sure the line is processed a second time - break; - } - } - } - } - } - DefaultLogger::get()->error("AC3D: Unexpected EOF: \'kids\' line was expected"); -} - -// ------------------------------------------------------------------------------------------------ -// Convert a material from AC3DImporter::Material to aiMaterial -void AC3DImporter::ConvertMaterial(const Object& object, - const Material& matSrc, - aiMaterial& matDest) -{ - aiString s; - - if (matSrc.name.length()) - { - s.Set(matSrc.name); - matDest.AddProperty(&s,AI_MATKEY_NAME); - } - if (object.texture.length()) - { - s.Set(object.texture); - matDest.AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0)); - - // UV transformation - if (1.f != object.texRepeat.x || 1.f != object.texRepeat.y || - object.texOffset.x || object.texOffset.y) - { - aiUVTransform transform; - transform.mScaling = object.texRepeat; - transform.mTranslation = object.texOffset; - matDest.AddProperty(&transform,1,AI_MATKEY_UVTRANSFORM_DIFFUSE(0)); - } - } - - matDest.AddProperty<aiColor3D>(&matSrc.rgb,1, AI_MATKEY_COLOR_DIFFUSE); - matDest.AddProperty<aiColor3D>(&matSrc.amb,1, AI_MATKEY_COLOR_AMBIENT); - matDest.AddProperty<aiColor3D>(&matSrc.emis,1,AI_MATKEY_COLOR_EMISSIVE); - matDest.AddProperty<aiColor3D>(&matSrc.spec,1,AI_MATKEY_COLOR_SPECULAR); - - int n; - if (matSrc.shin) - { - n = aiShadingMode_Phong; - matDest.AddProperty<float>(&matSrc.shin,1,AI_MATKEY_SHININESS); - } - else n = aiShadingMode_Gouraud; - matDest.AddProperty<int>(&n,1,AI_MATKEY_SHADING_MODEL); - - float f = 1.f - matSrc.trans; - matDest.AddProperty<float>(&f,1,AI_MATKEY_OPACITY); -} - -// ------------------------------------------------------------------------------------------------ -// Converts the loaded data to the internal verbose representation -aiNode* AC3DImporter::ConvertObjectSection(Object& object, - std::vector<aiMesh*>& meshes, - std::vector<aiMaterial*>& outMaterials, - const std::vector<Material>& materials, - aiNode* parent) -{ - aiNode* node = new aiNode(); - node->mParent = parent; - if (object.vertices.size()) - { - if (!object.surfaces.size() || !object.numRefs) - { - /* " An object with 7 vertices (no surfaces, no materials defined). - This is a good way of getting point data into AC3D. - The Vertex->create convex-surface/object can be used on these - vertices to 'wrap' a 3d shape around them " - (http://www.opencity.info/html/ac3dfileformat.html) - - therefore: if no surfaces are defined return point data only - */ - - DefaultLogger::get()->info("AC3D: No surfaces defined in object definition, " - "a point list is returned"); - - meshes.push_back(new aiMesh()); - aiMesh* mesh = meshes.back(); - - mesh->mNumFaces = mesh->mNumVertices = (unsigned int)object.vertices.size(); - aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; - aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - - for (unsigned int i = 0; i < mesh->mNumVertices;++i,++faces,++verts) - { - *verts = object.vertices[i]; - faces->mNumIndices = 1; - faces->mIndices = new unsigned int[1]; - faces->mIndices[0] = i; - } - - // use the primary material in this case. this should be the - // default material if all objects of the file contain points - // and no faces. - mesh->mMaterialIndex = 0; - outMaterials.push_back(new aiMaterial()); - ConvertMaterial(object, materials[0], *outMaterials.back()); - } - else - { - // need to generate one or more meshes for this object. - // find out how many different materials we have - typedef std::pair< unsigned int, unsigned int > IntPair; - typedef std::vector< IntPair > MatTable; - MatTable needMat(materials.size(),IntPair(0,0)); - - std::vector<Surface>::iterator it,end = object.surfaces.end(); - std::vector<Surface::SurfaceEntry>::iterator it2,end2; - - for (it = object.surfaces.begin(); it != end; ++it) - { - register unsigned int idx = (*it).mat; - if (idx >= needMat.size()) - { - DefaultLogger::get()->error("AC3D: material index is out of range"); - idx = 0; - } - if ((*it).entries.empty()) - { - DefaultLogger::get()->warn("AC3D: surface her zero vertex references"); - } - - // validate all vertex indices to make sure we won't crash here - for (it2 = (*it).entries.begin(), - end2 = (*it).entries.end(); it2 != end2; ++it2) - { - if ((*it2).first >= object.vertices.size()) - { - DefaultLogger::get()->warn("AC3D: Invalid vertex reference"); - (*it2).first = 0; - } - } - - if (!needMat[idx].first)++node->mNumMeshes; - - switch ((*it).flags & 0xf) - { - // closed line - case 0x1: - - needMat[idx].first += (unsigned int)(*it).entries.size(); - needMat[idx].second += (unsigned int)(*it).entries.size()<<1u; - break; - - // unclosed line - case 0x2: - - needMat[idx].first += (unsigned int)(*it).entries.size()-1; - needMat[idx].second += ((unsigned int)(*it).entries.size()-1)<<1u; - break; - - // 0 == polygon, else unknown - default: - - if ((*it).flags & 0xf) - { - DefaultLogger::get()->warn("AC3D: The type flag of a surface is unknown"); - (*it).flags &= ~(0xf); - } - - // the number of faces increments by one, the number - // of vertices by surface.numref. - needMat[idx].first++; - needMat[idx].second += (unsigned int)(*it).entries.size(); - }; - } - unsigned int* pip = node->mMeshes = new unsigned int[node->mNumMeshes]; - unsigned int mat = 0; - const size_t oldm = meshes.size(); - for (MatTable::const_iterator cit = needMat.begin(), cend = needMat.end(); - cit != cend; ++cit, ++mat) - { - if (!(*cit).first)continue; - - // allocate a new aiMesh object - *pip++ = (unsigned int)meshes.size(); - aiMesh* mesh = new aiMesh(); - meshes.push_back(mesh); - - mesh->mMaterialIndex = (unsigned int)outMaterials.size(); - outMaterials.push_back(new aiMaterial()); - ConvertMaterial(object, materials[mat], *outMaterials.back()); - - // allocate storage for vertices and normals - mesh->mNumFaces = (*cit).first; - aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; - - mesh->mNumVertices = (*cit).second; - aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - unsigned int cur = 0; - - // allocate UV coordinates, but only if the texture name for the - // surface is not empty - aiVector3D* uv = NULL; - if(object.texture.length()) - { - uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; - mesh->mNumUVComponents[0] = 2; - } - - for (it = object.surfaces.begin(); it != end; ++it) - { - if (mat == (*it).mat) - { - const Surface& src = *it; - - // closed polygon - unsigned int type = (*it).flags & 0xf; - if (!type) - { - aiFace& face = *faces++; - if((face.mNumIndices = (unsigned int)src.entries.size())) - { - face.mIndices = new unsigned int[face.mNumIndices]; - for (unsigned int i = 0; i < face.mNumIndices;++i,++vertices) - { - const Surface::SurfaceEntry& entry = src.entries[i]; - face.mIndices[i] = cur++; - - // copy vertex positions - *vertices = object.vertices[entry.first] + object.translation; - - - // copy texture coordinates - if (uv) - { - uv->x = entry.second.x; - uv->y = entry.second.y; - ++uv; - } - } - } - } - else - { - - it2 = (*it).entries.begin(); - - // either a closed or an unclosed line - register unsigned int tmp = (unsigned int)(*it).entries.size(); - if (0x2 == type)--tmp; - for (unsigned int m = 0; m < tmp;++m) - { - aiFace& face = *faces++; - - face.mNumIndices = 2; - face.mIndices = new unsigned int[2]; - face.mIndices[0] = cur++; - face.mIndices[1] = cur++; - - // copy vertex positions - *vertices++ = object.vertices[(*it2).first]; - - // copy texture coordinates - if (uv) - { - uv->x = (*it2).second.x; - uv->y = (*it2).second.y; - ++uv; - } - - - if (0x1 == type && tmp-1 == m) - { - // if this is a closed line repeat its beginning now - it2 = (*it).entries.begin(); - } - else ++it2; - - // second point - *vertices++ = object.vertices[(*it2).first]; - - if (uv) - { - uv->x = (*it2).second.x; - uv->y = (*it2).second.y; - ++uv; - } - } - } - } - } - } - - // Now apply catmull clark subdivision if necessary. We split meshes into - // materials which is not done by AC3D during smoothing, so we need to - // collect all meshes using the same material group. - if (object.subDiv) { - if (configEvalSubdivision) { - boost::scoped_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE)); - DefaultLogger::get()->info("AC3D: Evaluating subdivision surface: "+object.name); - - std::vector<aiMesh*> cpy(meshes.size()-oldm,NULL); - div->Subdivide(&meshes[oldm],cpy.size(),&cpy.front(),object.subDiv,true); - std::copy(cpy.begin(),cpy.end(),meshes.begin()+oldm); - - // previous meshes are deleted vy Subdivide(). - } - else { - DefaultLogger::get()->info("AC3D: Letting the subdivision surface untouched due to my configuration: " - +object.name); - } - } - } - } - - if (object.name.length()) - node->mName.Set(object.name); - else - { - // generate a name depending on the type of the node - switch (object.type) - { - case Object::Group: - node->mName.length = ::sprintf(node->mName.data,"ACGroup_%i",groups++); - break; - case Object::Poly: - node->mName.length = ::sprintf(node->mName.data,"ACPoly_%i",polys++); - break; - case Object::Light: - node->mName.length = ::sprintf(node->mName.data,"ACLight_%i",lights++); - break; - - // there shouldn't be more than one world, but we don't care - case Object::World: - node->mName.length = ::sprintf(node->mName.data,"ACWorld_%i",worlds++); - break; - } - } - - - // setup the local transformation matrix of the object - // compute the transformation offset to the parent node - node->mTransformation = aiMatrix4x4 ( object.rotation ); - - if (object.type == Object::Group || !object.numRefs) - { - node->mTransformation.a4 = object.translation.x; - node->mTransformation.b4 = object.translation.y; - node->mTransformation.c4 = object.translation.z; - } - - // add children to the object - if (object.children.size()) - { - node->mNumChildren = (unsigned int)object.children.size(); - node->mChildren = new aiNode*[node->mNumChildren]; - for (unsigned int i = 0; i < node->mNumChildren;++i) - { - node->mChildren[i] = ConvertObjectSection(object.children[i],meshes,outMaterials,materials,node); - } - } - - return node; -} - -// ------------------------------------------------------------------------------------------------ -void AC3DImporter::SetupProperties(const Importer* pImp) -{ - configSplitBFCull = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL,1) ? true : false; - configEvalSubdivision = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION,1) ? true : false; -} - -// ------------------------------------------------------------------------------------------------ -// Imports the given file into the given scene structure. -void AC3DImporter::InternReadFile( const std::string& pFile, - aiScene* pScene, IOSystem* pIOHandler) -{ - boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); - - // Check whether we can read from the file - if( file.get() == NULL) - throw DeadlyImportError( "Failed to open AC3D file " + pFile + "."); - - // allocate storage and copy the contents of the file to a memory buffer - std::vector<char> mBuffer2; - TextFileToBuffer(file.get(),mBuffer2); - - buffer = &mBuffer2[0]; - mNumMeshes = 0; - - lights = polys = worlds = groups = 0; - - if (::strncmp(buffer,"AC3D",4)) { - throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found"); - } - - // print the file format version to the console - unsigned int version = HexDigitToDecimal( buffer[4] ); - char msg[3]; - ASSIMP_itoa10(msg,3,version); - DefaultLogger::get()->info(std::string("AC3D file format version: ") + msg); - - std::vector<Material> materials; - materials.reserve(5); - - std::vector<Object> rootObjects; - rootObjects.reserve(5); - - std::vector<aiLight*> lights; - mLights = & lights; - - while (GetNextLine()) - { - if (TokenMatch(buffer,"MATERIAL",8)) - { - materials.push_back(Material()); - Material& mat = materials.back(); - - // manually parse the material ... sscanf would use the buldin atof ... - // Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f - - AI_AC_SKIP_TO_NEXT_TOKEN(); - if ('\"' == *buffer) - { - AI_AC_GET_STRING(mat.name); - AI_AC_SKIP_TO_NEXT_TOKEN(); - } - - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("rgb",3,3,&mat.rgb); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb",3,3,&mat.amb); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis",4,3,&mat.emis); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec",4,3,&mat.spec); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("shi",3,1,&mat.shin); - AI_AC_CHECKED_LOAD_FLOAT_ARRAY("trans",5,1,&mat.trans); - } - LoadObjectSection(rootObjects); - } - - if (rootObjects.empty() || !mNumMeshes) - { - throw DeadlyImportError("AC3D: No meshes have been loaded"); - } - if (materials.empty()) - { - DefaultLogger::get()->warn("AC3D: No material has been found"); - materials.push_back(Material()); - } - - mNumMeshes += (mNumMeshes>>2u) + 1; - std::vector<aiMesh*> meshes; - meshes.reserve(mNumMeshes); - - std::vector<aiMaterial*> omaterials; - materials.reserve(mNumMeshes); - - // generate a dummy root if there are multiple objects on the top layer - Object* root; - if (1 == rootObjects.size()) - root = &rootObjects[0]; - else - { - root = new Object(); - } - - // now convert the imported stuff to our output data structure - pScene->mRootNode = ConvertObjectSection(*root,meshes,omaterials,materials); - if (1 != rootObjects.size())delete root; - - if (!::strncmp( pScene->mRootNode->mName.data, "Node", 4)) - pScene->mRootNode->mName.Set("<AC3DWorld>"); - - // copy meshes - if (meshes.empty()) - { - throw DeadlyImportError("An unknown error occured during converting"); - } - pScene->mNumMeshes = (unsigned int)meshes.size(); - pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; - ::memcpy(pScene->mMeshes,&meshes[0],pScene->mNumMeshes*sizeof(void*)); - - // copy materials - pScene->mNumMaterials = (unsigned int)omaterials.size(); - pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; - ::memcpy(pScene->mMaterials,&omaterials[0],pScene->mNumMaterials*sizeof(void*)); - - // copy lights - pScene->mNumLights = (unsigned int)lights.size(); - if (lights.size()) - { - pScene->mLights = new aiLight*[lights.size()]; - ::memcpy(pScene->mLights,&lights[0],lights.size()*sizeof(void*)); - } -} - -#endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER |