vrshoot
diff libs/assimp/NDOLoader.cpp @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/NDOLoader.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,302 @@ 1.4 +/* 1.5 +--------------------------------------------------------------------------- 1.6 +Open Asset Import Library (assimp) 1.7 +--------------------------------------------------------------------------- 1.8 + 1.9 +Copyright (c) 2006-2012, assimp team 1.10 + 1.11 +All rights reserved. 1.12 + 1.13 +Redistribution and use of this software in source and binary forms, 1.14 +with or without modification, are permitted provided that the following 1.15 +conditions are met: 1.16 + 1.17 +* Redistributions of source code must retain the above 1.18 + copyright notice, this list of conditions and the 1.19 + following disclaimer. 1.20 + 1.21 +* Redistributions in binary form must reproduce the above 1.22 + copyright notice, this list of conditions and the 1.23 + following disclaimer in the documentation and/or other 1.24 + materials provided with the distribution. 1.25 + 1.26 +* Neither the name of the assimp team, nor the names of its 1.27 + contributors may be used to endorse or promote products 1.28 + derived from this software without specific prior 1.29 + written permission of the assimp team. 1.30 + 1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.42 +--------------------------------------------------------------------------- 1.43 +*/ 1.44 + 1.45 +/** @file NDOLoader.cpp 1.46 + * Implementation of the NDO importer class. 1.47 + */ 1.48 + 1.49 +#include "AssimpPCH.h" 1.50 +#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER 1.51 +#include "NDOLoader.h" 1.52 + 1.53 +using namespace Assimp; 1.54 +#define for_each BOOST_FOREACH 1.55 + 1.56 +static const aiImporterDesc desc = { 1.57 + "Nendo Mesh Importer", 1.58 + "", 1.59 + "", 1.60 + "http://www.izware.com/nendo/index.htm", 1.61 + aiImporterFlags_SupportBinaryFlavour, 1.62 + 0, 1.63 + 0, 1.64 + 0, 1.65 + 0, 1.66 + "ndo" 1.67 +}; 1.68 + 1.69 +// ------------------------------------------------------------------------------------------------ 1.70 +// Constructor to be privately used by Importer 1.71 +NDOImporter::NDOImporter() 1.72 +{} 1.73 + 1.74 +// ------------------------------------------------------------------------------------------------ 1.75 +// Destructor, private as well 1.76 +NDOImporter::~NDOImporter() 1.77 +{} 1.78 + 1.79 +// ------------------------------------------------------------------------------------------------ 1.80 +// Returns whether the class can handle the format of the given file. 1.81 +bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const 1.82 +{ 1.83 + // check file extension 1.84 + const std::string extension = GetExtension(pFile); 1.85 + 1.86 + if( extension == "ndo") 1.87 + return true; 1.88 + 1.89 + if ((checkSig || !extension.length()) && pIOHandler) { 1.90 + const char* tokens[] = {"nendo"}; 1.91 + return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,5); 1.92 + } 1.93 + return false; 1.94 +} 1.95 + 1.96 +// ------------------------------------------------------------------------------------------------ 1.97 +// Build a string of all file extensions supported 1.98 +const aiImporterDesc* NDOImporter::GetInfo () const 1.99 +{ 1.100 + return &desc; 1.101 +} 1.102 + 1.103 +// ------------------------------------------------------------------------------------------------ 1.104 +// Setup configuration properties for the loader 1.105 +void NDOImporter::SetupProperties(const Importer* /*pImp*/) 1.106 +{ 1.107 + // nothing to be done for the moment 1.108 +} 1.109 + 1.110 +// ------------------------------------------------------------------------------------------------ 1.111 +// Imports the given file into the given scene structure. 1.112 +void NDOImporter::InternReadFile( const std::string& pFile, 1.113 + aiScene* pScene, IOSystem* pIOHandler) 1.114 +{ 1.115 + StreamReaderBE reader(pIOHandler->Open( pFile, "rb")); 1.116 + 1.117 + // first 9 bytes are nendo file format ("nendo 1.n") 1.118 + const char* head = (const char*)reader.GetPtr(); 1.119 + reader.IncPtr(9); 1.120 + 1.121 + if (strncmp("nendo ",head,6)) { 1.122 + throw DeadlyImportError("Not a Nendo file; magic signature missing"); 1.123 + } 1.124 + // check if this is a supported version. if not, continue, too -- users, 1.125 + // please don't complain if it doesn't work then ... 1.126 + unsigned int file_format = 12; 1.127 + if (!strncmp("1.0",head+6,3)) { 1.128 + file_format = 10; 1.129 + DefaultLogger::get()->info("NDO file format is 1.0"); 1.130 + } 1.131 + else if (!strncmp("1.1",head+6,3)) { 1.132 + file_format = 11; 1.133 + DefaultLogger::get()->info("NDO file format is 1.1"); 1.134 + } 1.135 + else if (!strncmp("1.2",head+6,3)) { 1.136 + file_format = 12; 1.137 + DefaultLogger::get()->info("NDO file format is 1.2"); 1.138 + } 1.139 + else { 1.140 + DefaultLogger::get()->warn(std::string("Unrecognized nendo file format version, continuing happily ... :") + (head+6)); 1.141 + } 1.142 + 1.143 + reader.IncPtr(2); /* skip flags */ 1.144 + if (file_format >= 12) { 1.145 + reader.IncPtr(2); 1.146 + } 1.147 + unsigned int temp = reader.GetU1(); 1.148 + 1.149 + std::vector<Object> objects(temp); /* buffer to store all the loaded objects in */ 1.150 + 1.151 + // read all objects 1.152 + for (unsigned int o = 0; o < objects.size(); ++o) { 1.153 + 1.154 +// if (file_format < 12) { 1.155 + if (!reader.GetI1()) { 1.156 + continue; /* skip over empty object */ 1.157 + } 1.158 + // reader.GetI2(); 1.159 +// } 1.160 + Object& obj = objects[o]; 1.161 + 1.162 + temp = file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.163 + head = (const char*)reader.GetPtr(); 1.164 + reader.IncPtr(temp + 76); /* skip unknown stuff */ 1.165 + 1.166 + obj.name = std::string(head, temp); 1.167 + 1.168 + // read edge table 1.169 + temp = file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.170 + obj.edges.reserve(temp); 1.171 + for (unsigned int e = 0; e < temp; ++e) { 1.172 + 1.173 + obj.edges.push_back(Edge()); 1.174 + Edge& edge = obj.edges.back(); 1.175 + 1.176 + for (unsigned int i = 0; i< 8; ++i) { 1.177 + edge.edge[i] = file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.178 + } 1.179 + edge.hard = file_format >= 11 ? reader.GetU1() : 0; 1.180 + for (unsigned int i = 0; i< 8; ++i) { 1.181 + edge.color[i] = reader.GetU1(); 1.182 + } 1.183 + } 1.184 + 1.185 + // read face table 1.186 + temp = file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.187 + obj.faces.reserve(temp); 1.188 + for (unsigned int e = 0; e < temp; ++e) { 1.189 + 1.190 + obj.faces.push_back(Face()); 1.191 + Face& face = obj.faces.back(); 1.192 + 1.193 + face.elem = file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.194 + } 1.195 + 1.196 + // read vertex table 1.197 + temp = file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.198 + obj.vertices.reserve(temp); 1.199 + for (unsigned int e = 0; e < temp; ++e) { 1.200 + 1.201 + obj.vertices.push_back(Vertex()); 1.202 + Vertex& v = obj.vertices.back(); 1.203 + 1.204 + v.num = file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.205 + v.val.x = reader.GetF4(); 1.206 + v.val.y = reader.GetF4(); 1.207 + v.val.z = reader.GetF4(); 1.208 + } 1.209 + 1.210 + // read UVs 1.211 + temp = file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.212 + for (unsigned int e = 0; e < temp; ++e) { 1.213 + file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.214 + } 1.215 + 1.216 + temp = file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.217 + for (unsigned int e = 0; e < temp; ++e) { 1.218 + file_format >= 12 ? reader.GetU4() : reader.GetU2(); 1.219 + } 1.220 + 1.221 + if (reader.GetU1()) { 1.222 + const unsigned int x = reader.GetU2(), y = reader.GetU2(); 1.223 + temp = 0; 1.224 + while (temp < x*y) { 1.225 + unsigned int repeat = reader.GetU1(); 1.226 + reader.GetU1(); 1.227 + reader.GetU1(); 1.228 + reader.GetU1(); 1.229 + temp += repeat; 1.230 + } 1.231 + } 1.232 + } 1.233 + 1.234 + // construct a dummy node graph and add all named objects as child nodes 1.235 + aiNode* root = pScene->mRootNode = new aiNode("$NDODummyRoot"); 1.236 + aiNode** cc = root->mChildren = new aiNode* [ root->mNumChildren = static_cast<unsigned int>( objects.size()) ] (); 1.237 + pScene->mMeshes = new aiMesh* [ root->mNumChildren] (); 1.238 + 1.239 + std::vector<aiVector3D> vertices; 1.240 + std::vector<unsigned int> indices; 1.241 + 1.242 + for_each(const Object& obj,objects) { 1.243 + aiNode* nd = *cc++ = new aiNode(obj.name); 1.244 + nd->mParent = root; 1.245 + 1.246 + // translated from a python dict() - a vector might be sufficient as well 1.247 + typedef std::map<unsigned int, unsigned int> FaceTable; 1.248 + FaceTable face_table; 1.249 + 1.250 + unsigned int n = 0; 1.251 + for_each(const Edge& edge, obj.edges) { 1.252 + 1.253 + face_table[edge.edge[2]] = n; 1.254 + face_table[edge.edge[3]] = n; 1.255 + 1.256 + ++n; 1.257 + } 1.258 + 1.259 + aiMesh* mesh = new aiMesh(); 1.260 + aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces=face_table.size()]; 1.261 + 1.262 + vertices.clear(); 1.263 + vertices.reserve(4 * face_table.size()); // arbitrarily choosen 1.264 + for_each(FaceTable::value_type& v, face_table) { 1.265 + indices.clear(); 1.266 + 1.267 + aiFace& f = *faces++; 1.268 + 1.269 + const unsigned int key = v.first; 1.270 + unsigned int cur_edge = v.second; 1.271 + while (1) { 1.272 + unsigned int next_edge, next_vert; 1.273 + if (key == obj.edges[cur_edge].edge[3]) { 1.274 + next_edge = obj.edges[cur_edge].edge[5]; 1.275 + next_vert = obj.edges[cur_edge].edge[1]; 1.276 + } 1.277 + else { 1.278 + next_edge = obj.edges[cur_edge].edge[4]; 1.279 + next_vert = obj.edges[cur_edge].edge[0]; 1.280 + } 1.281 + indices.push_back( vertices.size() ); 1.282 + vertices.push_back(obj.vertices[ next_vert ].val); 1.283 + 1.284 + cur_edge = next_edge; 1.285 + if (cur_edge == v.second) { 1.286 + break; 1.287 + } 1.288 + } 1.289 + 1.290 + f.mIndices = new unsigned int[f.mNumIndices = indices.size()]; 1.291 + std::copy(indices.begin(),indices.end(),f.mIndices); 1.292 + } 1.293 + 1.294 + mesh->mVertices = new aiVector3D[mesh->mNumVertices = vertices.size()]; 1.295 + std::copy(vertices.begin(),vertices.end(),mesh->mVertices); 1.296 + 1.297 + if (mesh->mNumVertices) { 1.298 + pScene->mMeshes[pScene->mNumMeshes] = mesh; 1.299 + 1.300 + (nd->mMeshes = new unsigned int[nd->mNumMeshes=1])[0]=pScene->mNumMeshes++; 1.301 + } 1.302 + } 1.303 +} 1.304 + 1.305 +#endif