vrshoot
view libs/assimp/NDOLoader.cpp @ 1:e7ca128b8713
looks nice :)
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 02 Feb 2014 00:35:22 +0200 |
parents | |
children |
line source
1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
6 Copyright (c) 2006-2012, assimp team
8 All rights reserved.
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the following
12 conditions are met:
14 * Redistributions of source code must retain the above
15 copyright notice, this list of conditions and the
16 following disclaimer.
18 * Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the
20 following disclaimer in the documentation and/or other
21 materials provided with the distribution.
23 * Neither the name of the assimp team, nor the names of its
24 contributors may be used to endorse or promote products
25 derived from this software without specific prior
26 written permission of the assimp team.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ---------------------------------------------------------------------------
40 */
42 /** @file NDOLoader.cpp
43 * Implementation of the NDO importer class.
44 */
46 #include "AssimpPCH.h"
47 #ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
48 #include "NDOLoader.h"
50 using namespace Assimp;
51 #define for_each BOOST_FOREACH
53 static const aiImporterDesc desc = {
54 "Nendo Mesh Importer",
55 "",
56 "",
57 "http://www.izware.com/nendo/index.htm",
58 aiImporterFlags_SupportBinaryFlavour,
59 0,
60 0,
61 0,
62 0,
63 "ndo"
64 };
66 // ------------------------------------------------------------------------------------------------
67 // Constructor to be privately used by Importer
68 NDOImporter::NDOImporter()
69 {}
71 // ------------------------------------------------------------------------------------------------
72 // Destructor, private as well
73 NDOImporter::~NDOImporter()
74 {}
76 // ------------------------------------------------------------------------------------------------
77 // Returns whether the class can handle the format of the given file.
78 bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
79 {
80 // check file extension
81 const std::string extension = GetExtension(pFile);
83 if( extension == "ndo")
84 return true;
86 if ((checkSig || !extension.length()) && pIOHandler) {
87 const char* tokens[] = {"nendo"};
88 return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,5);
89 }
90 return false;
91 }
93 // ------------------------------------------------------------------------------------------------
94 // Build a string of all file extensions supported
95 const aiImporterDesc* NDOImporter::GetInfo () const
96 {
97 return &desc;
98 }
100 // ------------------------------------------------------------------------------------------------
101 // Setup configuration properties for the loader
102 void NDOImporter::SetupProperties(const Importer* /*pImp*/)
103 {
104 // nothing to be done for the moment
105 }
107 // ------------------------------------------------------------------------------------------------
108 // Imports the given file into the given scene structure.
109 void NDOImporter::InternReadFile( const std::string& pFile,
110 aiScene* pScene, IOSystem* pIOHandler)
111 {
112 StreamReaderBE reader(pIOHandler->Open( pFile, "rb"));
114 // first 9 bytes are nendo file format ("nendo 1.n")
115 const char* head = (const char*)reader.GetPtr();
116 reader.IncPtr(9);
118 if (strncmp("nendo ",head,6)) {
119 throw DeadlyImportError("Not a Nendo file; magic signature missing");
120 }
121 // check if this is a supported version. if not, continue, too -- users,
122 // please don't complain if it doesn't work then ...
123 unsigned int file_format = 12;
124 if (!strncmp("1.0",head+6,3)) {
125 file_format = 10;
126 DefaultLogger::get()->info("NDO file format is 1.0");
127 }
128 else if (!strncmp("1.1",head+6,3)) {
129 file_format = 11;
130 DefaultLogger::get()->info("NDO file format is 1.1");
131 }
132 else if (!strncmp("1.2",head+6,3)) {
133 file_format = 12;
134 DefaultLogger::get()->info("NDO file format is 1.2");
135 }
136 else {
137 DefaultLogger::get()->warn(std::string("Unrecognized nendo file format version, continuing happily ... :") + (head+6));
138 }
140 reader.IncPtr(2); /* skip flags */
141 if (file_format >= 12) {
142 reader.IncPtr(2);
143 }
144 unsigned int temp = reader.GetU1();
146 std::vector<Object> objects(temp); /* buffer to store all the loaded objects in */
148 // read all objects
149 for (unsigned int o = 0; o < objects.size(); ++o) {
151 // if (file_format < 12) {
152 if (!reader.GetI1()) {
153 continue; /* skip over empty object */
154 }
155 // reader.GetI2();
156 // }
157 Object& obj = objects[o];
159 temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
160 head = (const char*)reader.GetPtr();
161 reader.IncPtr(temp + 76); /* skip unknown stuff */
163 obj.name = std::string(head, temp);
165 // read edge table
166 temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
167 obj.edges.reserve(temp);
168 for (unsigned int e = 0; e < temp; ++e) {
170 obj.edges.push_back(Edge());
171 Edge& edge = obj.edges.back();
173 for (unsigned int i = 0; i< 8; ++i) {
174 edge.edge[i] = file_format >= 12 ? reader.GetU4() : reader.GetU2();
175 }
176 edge.hard = file_format >= 11 ? reader.GetU1() : 0;
177 for (unsigned int i = 0; i< 8; ++i) {
178 edge.color[i] = reader.GetU1();
179 }
180 }
182 // read face table
183 temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
184 obj.faces.reserve(temp);
185 for (unsigned int e = 0; e < temp; ++e) {
187 obj.faces.push_back(Face());
188 Face& face = obj.faces.back();
190 face.elem = file_format >= 12 ? reader.GetU4() : reader.GetU2();
191 }
193 // read vertex table
194 temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
195 obj.vertices.reserve(temp);
196 for (unsigned int e = 0; e < temp; ++e) {
198 obj.vertices.push_back(Vertex());
199 Vertex& v = obj.vertices.back();
201 v.num = file_format >= 12 ? reader.GetU4() : reader.GetU2();
202 v.val.x = reader.GetF4();
203 v.val.y = reader.GetF4();
204 v.val.z = reader.GetF4();
205 }
207 // read UVs
208 temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
209 for (unsigned int e = 0; e < temp; ++e) {
210 file_format >= 12 ? reader.GetU4() : reader.GetU2();
211 }
213 temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
214 for (unsigned int e = 0; e < temp; ++e) {
215 file_format >= 12 ? reader.GetU4() : reader.GetU2();
216 }
218 if (reader.GetU1()) {
219 const unsigned int x = reader.GetU2(), y = reader.GetU2();
220 temp = 0;
221 while (temp < x*y) {
222 unsigned int repeat = reader.GetU1();
223 reader.GetU1();
224 reader.GetU1();
225 reader.GetU1();
226 temp += repeat;
227 }
228 }
229 }
231 // construct a dummy node graph and add all named objects as child nodes
232 aiNode* root = pScene->mRootNode = new aiNode("$NDODummyRoot");
233 aiNode** cc = root->mChildren = new aiNode* [ root->mNumChildren = static_cast<unsigned int>( objects.size()) ] ();
234 pScene->mMeshes = new aiMesh* [ root->mNumChildren] ();
236 std::vector<aiVector3D> vertices;
237 std::vector<unsigned int> indices;
239 for_each(const Object& obj,objects) {
240 aiNode* nd = *cc++ = new aiNode(obj.name);
241 nd->mParent = root;
243 // translated from a python dict() - a vector might be sufficient as well
244 typedef std::map<unsigned int, unsigned int> FaceTable;
245 FaceTable face_table;
247 unsigned int n = 0;
248 for_each(const Edge& edge, obj.edges) {
250 face_table[edge.edge[2]] = n;
251 face_table[edge.edge[3]] = n;
253 ++n;
254 }
256 aiMesh* mesh = new aiMesh();
257 aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces=face_table.size()];
259 vertices.clear();
260 vertices.reserve(4 * face_table.size()); // arbitrarily choosen
261 for_each(FaceTable::value_type& v, face_table) {
262 indices.clear();
264 aiFace& f = *faces++;
266 const unsigned int key = v.first;
267 unsigned int cur_edge = v.second;
268 while (1) {
269 unsigned int next_edge, next_vert;
270 if (key == obj.edges[cur_edge].edge[3]) {
271 next_edge = obj.edges[cur_edge].edge[5];
272 next_vert = obj.edges[cur_edge].edge[1];
273 }
274 else {
275 next_edge = obj.edges[cur_edge].edge[4];
276 next_vert = obj.edges[cur_edge].edge[0];
277 }
278 indices.push_back( vertices.size() );
279 vertices.push_back(obj.vertices[ next_vert ].val);
281 cur_edge = next_edge;
282 if (cur_edge == v.second) {
283 break;
284 }
285 }
287 f.mIndices = new unsigned int[f.mNumIndices = indices.size()];
288 std::copy(indices.begin(),indices.end(),f.mIndices);
289 }
291 mesh->mVertices = new aiVector3D[mesh->mNumVertices = vertices.size()];
292 std::copy(vertices.begin(),vertices.end(),mesh->mVertices);
294 if (mesh->mNumVertices) {
295 pScene->mMeshes[pScene->mNumMeshes] = mesh;
297 (nd->mMeshes = new unsigned int[nd->mNumMeshes=1])[0]=pScene->mNumMeshes++;
298 }
299 }
300 }
302 #endif