diff options
Diffstat (limited to 'src/3rdparty/assimp/code/IRRMeshLoader.cpp')
-rw-r--r-- | src/3rdparty/assimp/code/IRRMeshLoader.cpp | 535 |
1 files changed, 0 insertions, 535 deletions
diff --git a/src/3rdparty/assimp/code/IRRMeshLoader.cpp b/src/3rdparty/assimp/code/IRRMeshLoader.cpp deleted file mode 100644 index a63a2a134..000000000 --- a/src/3rdparty/assimp/code/IRRMeshLoader.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2017, 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 IrrMesh importer class */ - - - -#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER - -#include "IRRMeshLoader.h" -#include "ParsingUtils.h" -#include "fast_atof.h" -#include <memory> -#include <assimp/IOSystem.hpp> -#include <assimp/mesh.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/material.h> -#include <assimp/scene.h> -#include <assimp/importerdesc.h> -#include "Macros.h" - -using namespace Assimp; -using namespace irr; -using namespace irr::io; - -static const aiImporterDesc desc = { - "Irrlicht Mesh Reader", - "", - "", - "http://irrlicht.sourceforge.net/", - aiImporterFlags_SupportTextFlavour, - 0, - 0, - 0, - 0, - "xml irrmesh" -}; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -IRRMeshImporter::IRRMeshImporter() -{} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -IRRMeshImporter::~IRRMeshImporter() -{} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the class can handle the format of the given file. -bool IRRMeshImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const -{ - /* NOTE: A simple check for the file extension is not enough - * here. Irrmesh and irr are easy, but xml is too generic - * and could be collada, too. So we need to open the file and - * search for typical tokens. - */ - const std::string extension = GetExtension(pFile); - - if (extension == "irrmesh")return true; - else if (extension == "xml" || checkSig) - { - /* If CanRead() is called to check whether the loader - * supports a specific file extension in general we - * must return true here. - */ - if (!pIOHandler)return true; - const char* tokens[] = {"irrmesh"}; - return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); - } - return false; -} - -// ------------------------------------------------------------------------------------------------ -// Get a list of all file extensions which are handled by this class -const aiImporterDesc* IRRMeshImporter::GetInfo () const -{ - return &desc; -} - -static void releaseMaterial( aiMaterial **mat ) { - if(*mat!= nullptr) { - delete *mat; - *mat = nullptr; - } -} - -static void releaseMesh( aiMesh **mesh ) { - if (*mesh != nullptr){ - delete *mesh; - *mesh = nullptr; - } -} - -// ------------------------------------------------------------------------------------------------ -// Imports the given file into the given scene structure. -void IRRMeshImporter::InternReadFile( const std::string& pFile, - aiScene* pScene, IOSystem* pIOHandler) -{ - std::unique_ptr<IOStream> file( pIOHandler->Open( pFile)); - - // Check whether we can read from the file - if( file.get() == NULL) - throw DeadlyImportError( "Failed to open IRRMESH file " + pFile + ""); - - // Construct the irrXML parser - CIrrXML_IOStreamReader st(file.get()); - reader = createIrrXMLReader((IFileReadCallBack*) &st); - - // final data - std::vector<aiMaterial*> materials; - std::vector<aiMesh*> meshes; - materials.reserve (5); - meshes.reserve(5); - - // temporary data - current mesh buffer - aiMaterial* curMat = nullptr; - aiMesh* curMesh = nullptr; - unsigned int curMatFlags = 0; - - std::vector<aiVector3D> curVertices,curNormals,curTangents,curBitangents; - std::vector<aiColor4D> curColors; - std::vector<aiVector3D> curUVs,curUV2s; - - // some temporary variables - int textMeaning = 0; - int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents - bool useColors = false; - - // Parse the XML file - while (reader->read()) { - switch (reader->getNodeType()) { - case EXN_ELEMENT: - - if (!ASSIMP_stricmp(reader->getNodeName(),"buffer") && (curMat || curMesh)) { - // end of previous buffer. A material and a mesh should be there - if ( !curMat || !curMesh) { - DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material"); - releaseMaterial( &curMat ); - releaseMesh( &curMesh ); - } else { - materials.push_back(curMat); - meshes.push_back(curMesh); - } - curMat = nullptr; - curMesh = nullptr; - - curVertices.clear(); - curColors.clear(); - curNormals.clear(); - curUV2s.clear(); - curUVs.clear(); - curTangents.clear(); - curBitangents.clear(); - } - - - if (!ASSIMP_stricmp(reader->getNodeName(),"material")) { - if (curMat) { - DefaultLogger::get()->warn("IRRMESH: Only one material description per buffer, please"); - releaseMaterial( &curMat ); - } - curMat = ParseMaterial(curMatFlags); - } - /* no else here! */ if (!ASSIMP_stricmp(reader->getNodeName(),"vertices")) - { - int num = reader->getAttributeValueAsInt("vertexCount"); - - if (!num) { - // This is possible ... remove the mesh from the list and skip further reading - DefaultLogger::get()->warn("IRRMESH: Found mesh with zero vertices"); - - releaseMaterial( &curMat ); - releaseMesh( &curMesh ); - textMeaning = 0; - continue; - } - - curVertices.reserve(num); - curNormals.reserve(num); - curColors.reserve(num); - curUVs.reserve(num); - - // Determine the file format - const char* t = reader->getAttributeValueSafe("type"); - if (!ASSIMP_stricmp("2tcoords", t)) { - curUV2s.reserve (num); - vertexFormat = 1; - - if (curMatFlags & AI_IRRMESH_EXTRA_2ND_TEXTURE) { - // ********************************************************* - // We have a second texture! So use this UV channel - // for it. The 2nd texture can be either a normal - // texture (solid_2layer or lightmap_xxx) or a normal - // map (normal_..., parallax_...) - // ********************************************************* - int idx = 1; - aiMaterial* mat = ( aiMaterial* ) curMat; - - if (curMatFlags & AI_IRRMESH_MAT_lightmap){ - mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_LIGHTMAP(0)); - } - else if (curMatFlags & AI_IRRMESH_MAT_normalmap_solid){ - mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_NORMALS(0)); - } - else if (curMatFlags & AI_IRRMESH_MAT_solid_2layer) { - mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(1)); - } - } - } - else if (!ASSIMP_stricmp("tangents", t)) { - curTangents.reserve (num); - curBitangents.reserve (num); - vertexFormat = 2; - } - else if (ASSIMP_stricmp("standard", t)) { - releaseMaterial( &curMat ); - DefaultLogger::get()->warn("IRRMESH: Unknown vertex format"); - } - else vertexFormat = 0; - textMeaning = 1; - } - else if (!ASSIMP_stricmp(reader->getNodeName(),"indices")) { - if (curVertices.empty() && curMat) { - releaseMaterial( &curMat ); - throw DeadlyImportError("IRRMESH: indices must come after vertices"); - } - - textMeaning = 2; - - // start a new mesh - curMesh = new aiMesh(); - - // allocate storage for all faces - curMesh->mNumVertices = reader->getAttributeValueAsInt("indexCount"); - if (!curMesh->mNumVertices) { - // This is possible ... remove the mesh from the list and skip further reading - DefaultLogger::get()->warn("IRRMESH: Found mesh with zero indices"); - - // mesh - away - releaseMesh( &curMesh ); - - // material - away - releaseMaterial( &curMat ); - - textMeaning = 0; - continue; - } - - if (curMesh->mNumVertices % 3) { - DefaultLogger::get()->warn("IRRMESH: Number if indices isn't divisible by 3"); - } - - curMesh->mNumFaces = curMesh->mNumVertices / 3; - curMesh->mFaces = new aiFace[curMesh->mNumFaces]; - - // setup some members - curMesh->mMaterialIndex = (unsigned int)materials.size(); - curMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; - - // allocate storage for all vertices - curMesh->mVertices = new aiVector3D[curMesh->mNumVertices]; - - if (curNormals.size() == curVertices.size()) { - curMesh->mNormals = new aiVector3D[curMesh->mNumVertices]; - } - if (curTangents.size() == curVertices.size()) { - curMesh->mTangents = new aiVector3D[curMesh->mNumVertices]; - } - if (curBitangents.size() == curVertices.size()) { - curMesh->mBitangents = new aiVector3D[curMesh->mNumVertices]; - } - if (curColors.size() == curVertices.size() && useColors) { - curMesh->mColors[0] = new aiColor4D[curMesh->mNumVertices]; - } - if (curUVs.size() == curVertices.size()) { - curMesh->mTextureCoords[0] = new aiVector3D[curMesh->mNumVertices]; - } - if (curUV2s.size() == curVertices.size()) { - curMesh->mTextureCoords[1] = new aiVector3D[curMesh->mNumVertices]; - } - } - break; - - case EXN_TEXT: - { - const char* sz = reader->getNodeData(); - if (textMeaning == 1) { - textMeaning = 0; - - // read vertices - do { - SkipSpacesAndLineEnd(&sz); - aiVector3D temp;aiColor4D c; - - // Read the vertex position - sz = fast_atoreal_move<float>(sz,(float&)temp.x); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.y); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.z); - SkipSpaces(&sz); - curVertices.push_back(temp); - - // Read the vertex normals - sz = fast_atoreal_move<float>(sz,(float&)temp.x); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.y); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.z); - SkipSpaces(&sz); - curNormals.push_back(temp); - - // read the vertex colors - uint32_t clr = strtoul16(sz,&sz); - ColorFromARGBPacked(clr,c); - - if (!curColors.empty() && c != *(curColors.end()-1)) - useColors = true; - - curColors.push_back(c); - SkipSpaces(&sz); - - - // read the first UV coordinate set - sz = fast_atoreal_move<float>(sz,(float&)temp.x); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.y); - SkipSpaces(&sz); - temp.z = 0.f; - temp.y = 1.f - temp.y; // DX to OGL - curUVs.push_back(temp); - - // read the (optional) second UV coordinate set - if (vertexFormat == 1) { - sz = fast_atoreal_move<float>(sz,(float&)temp.x); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.y); - temp.y = 1.f - temp.y; // DX to OGL - curUV2s.push_back(temp); - } - // read optional tangent and bitangent vectors - else if (vertexFormat == 2) { - // tangents - sz = fast_atoreal_move<float>(sz,(float&)temp.x); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.z); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.y); - SkipSpaces(&sz); - temp.y *= -1.0f; - curTangents.push_back(temp); - - // bitangents - sz = fast_atoreal_move<float>(sz,(float&)temp.x); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.z); - SkipSpaces(&sz); - - sz = fast_atoreal_move<float>(sz,(float&)temp.y); - SkipSpaces(&sz); - temp.y *= -1.0f; - curBitangents.push_back(temp); - } - } - - /* IMPORTANT: We assume that each vertex is specified in one - line. So we can skip the rest of the line - unknown vertex - elements are ignored. - */ - - while (SkipLine(&sz)); - } - else if (textMeaning == 2) { - textMeaning = 0; - - // read indices - aiFace* curFace = curMesh->mFaces; - aiFace* const faceEnd = curMesh->mFaces + curMesh->mNumFaces; - - aiVector3D* pcV = curMesh->mVertices; - aiVector3D* pcN = curMesh->mNormals; - aiVector3D* pcT = curMesh->mTangents; - aiVector3D* pcB = curMesh->mBitangents; - aiColor4D* pcC0 = curMesh->mColors[0]; - aiVector3D* pcT0 = curMesh->mTextureCoords[0]; - aiVector3D* pcT1 = curMesh->mTextureCoords[1]; - - unsigned int curIdx = 0; - unsigned int total = 0; - while(SkipSpacesAndLineEnd(&sz)) { - if (curFace >= faceEnd) { - DefaultLogger::get()->error("IRRMESH: Too many indices"); - break; - } - if (!curIdx) { - curFace->mNumIndices = 3; - curFace->mIndices = new unsigned int[3]; - } - - unsigned int idx = strtoul10(sz,&sz); - if (idx >= curVertices.size()) { - DefaultLogger::get()->error("IRRMESH: Index out of range"); - idx = 0; - } - - curFace->mIndices[curIdx] = total++; - - *pcV++ = curVertices[idx]; - if (pcN)*pcN++ = curNormals[idx]; - if (pcT)*pcT++ = curTangents[idx]; - if (pcB)*pcB++ = curBitangents[idx]; - if (pcC0)*pcC0++ = curColors[idx]; - if (pcT0)*pcT0++ = curUVs[idx]; - if (pcT1)*pcT1++ = curUV2s[idx]; - - if (++curIdx == 3) { - ++curFace; - curIdx = 0; - } - } - - if (curFace != faceEnd) - DefaultLogger::get()->error("IRRMESH: Not enough indices"); - - // Finish processing the mesh - do some small material workarounds - if (curMatFlags & AI_IRRMESH_MAT_trans_vertex_alpha && !useColors) { - // Take the opacity value of the current material - // from the common vertex color alpha - aiMaterial* mat = (aiMaterial*)curMat; - mat->AddProperty(&curColors[0].a,1,AI_MATKEY_OPACITY); - } - }} - break; - - default: - // GCC complains here ... - break; - - }; - } - - // End of the last buffer. A material and a mesh should be there - if (curMat || curMesh) { - if ( !curMat || !curMesh) { - DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material"); - releaseMaterial( &curMat ); - releaseMesh( &curMesh ); - } - else { - materials.push_back(curMat); - meshes.push_back(curMesh); - } - } - - if (materials.empty()) - throw DeadlyImportError("IRRMESH: Unable to read a mesh from this file"); - - - // now generate the output scene - pScene->mNumMeshes = (unsigned int)meshes.size(); - pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; - for (unsigned int i = 0; i < pScene->mNumMeshes;++i) { - pScene->mMeshes[i] = meshes[i]; - - // clean this value ... - pScene->mMeshes[i]->mNumUVComponents[3] = 0; - } - - pScene->mNumMaterials = (unsigned int)materials.size(); - pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; - ::memcpy(pScene->mMaterials,&materials[0],sizeof(void*)*pScene->mNumMaterials); - - pScene->mRootNode = new aiNode(); - pScene->mRootNode->mName.Set("<IRRMesh>"); - pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; - pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; - - for (unsigned int i = 0; i < pScene->mNumMeshes;++i) - pScene->mRootNode->mMeshes[i] = i; - - // clean up and return - delete reader; - AI_DEBUG_INVALIDATE_PTR(reader); -} - -#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER |