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