vrshoot
view libs/assimp/RawLoader.cpp @ 2:334d17aed7de
visual studio project files
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 02 Feb 2014 18:36:38 +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 RawLoader.cpp
43 * @brief Implementation of the RAW importer class
44 */
46 #include "AssimpPCH.h"
47 #ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
49 // internal headers
50 #include "RawLoader.h"
51 #include "ParsingUtils.h"
52 #include "fast_atof.h"
54 using namespace Assimp;
56 static const aiImporterDesc desc = {
57 "Raw Importer",
58 "",
59 "",
60 "",
61 aiImporterFlags_SupportTextFlavour,
62 0,
63 0,
64 0,
65 0,
66 "raw"
67 };
69 // ------------------------------------------------------------------------------------------------
70 // Constructor to be privately used by Importer
71 RAWImporter::RAWImporter()
72 {}
74 // ------------------------------------------------------------------------------------------------
75 // Destructor, private as well
76 RAWImporter::~RAWImporter()
77 {}
79 // ------------------------------------------------------------------------------------------------
80 // Returns whether the class can handle the format of the given file.
81 bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
82 {
83 return SimpleExtensionCheck(pFile,"raw");
84 }
86 // ------------------------------------------------------------------------------------------------
87 const aiImporterDesc* RAWImporter::GetInfo () const
88 {
89 return &desc;
90 }
92 // ------------------------------------------------------------------------------------------------
93 // Imports the given file into the given scene structure.
94 void RAWImporter::InternReadFile( const std::string& pFile,
95 aiScene* pScene, IOSystem* pIOHandler)
96 {
97 boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
99 // Check whether we can read from the file
100 if( file.get() == NULL) {
101 throw DeadlyImportError( "Failed to open RAW file " + pFile + ".");
102 }
104 // allocate storage and copy the contents of the file to a memory buffer
105 // (terminate it with zero)
106 std::vector<char> mBuffer2;
107 TextFileToBuffer(file.get(),mBuffer2);
108 const char* buffer = &mBuffer2[0];
110 // list of groups loaded from the file
111 std::vector< GroupInformation > outGroups(1,GroupInformation("<default>"));
112 std::vector< GroupInformation >::iterator curGroup = outGroups.begin();
114 // now read all lines
115 char line[4096];
116 while (GetNextLine(buffer,line))
117 {
118 // if the line starts with a non-numeric identifier, it marks
119 // the beginning of a new group
120 const char* sz = line;SkipSpaces(&sz);
121 if (IsLineEnd(*sz))continue;
122 if (!IsNumeric(*sz))
123 {
124 const char* sz2 = sz;
125 while (!IsSpaceOrNewLine(*sz2))++sz2;
126 const unsigned int length = (unsigned int)(sz2-sz);
128 // find an existing group with this name
129 for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
130 it != end;++it)
131 {
132 if (length == (*it).name.length() && !::strcmp(sz,(*it).name.c_str()))
133 {
134 curGroup = it;sz2 = NULL;
135 break;
136 }
137 }
138 if (sz2)
139 {
140 outGroups.push_back(GroupInformation(std::string(sz,length)));
141 curGroup = outGroups.end()-1;
142 }
143 }
144 else
145 {
146 // there can be maximally 12 floats plus an extra texture file name
147 float data[12];
148 unsigned int num;
149 for (num = 0; num < 12;++num)
150 {
151 if(!SkipSpaces(&sz) || !IsNumeric(*sz))break;
152 sz = fast_atoreal_move<float>(sz,data[num]);
153 }
154 if (num != 12 && num != 9)
155 {
156 DefaultLogger::get()->error("A line may have either 9 or 12 floats and an optional texture");
157 continue;
158 }
160 MeshInformation* output = NULL;
162 const char* sz2 = sz;
163 unsigned int length;
164 if (!IsLineEnd(*sz))
165 {
166 while (!IsSpaceOrNewLine(*sz2))++sz2;
167 length = (unsigned int)(sz2-sz);
168 }
169 else if (9 == num)
170 {
171 sz = "%default%";
172 length = 9;
173 }
174 else
175 {
176 sz = "";
177 length = 0;
178 }
180 // search in the list of meshes whether we have one with this texture
181 for (std::vector< MeshInformation >::iterator it = (*curGroup).meshes.begin(),
182 end = (*curGroup).meshes.end(); it != end; ++it)
183 {
184 if (length == (*it).name.length() && (length ? !::strcmp(sz,(*it).name.c_str()) : true))
185 {
186 output = &(*it);
187 break;
188 }
189 }
190 // if we don't have the mesh, create it
191 if (!output)
192 {
193 (*curGroup).meshes.push_back(MeshInformation(std::string(sz,length)));
194 output = &((*curGroup).meshes.back());
195 }
196 if (12 == num)
197 {
198 aiColor4D v(data[0],data[1],data[2],1.0f);
199 output->colors.push_back(v);
200 output->colors.push_back(v);
201 output->colors.push_back(v);
203 output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
204 output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
205 output->vertices.push_back(aiVector3D(data[9],data[10],data[11]));
206 }
207 else
208 {
209 output->vertices.push_back(aiVector3D(data[0],data[1],data[2]));
210 output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
211 output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
212 }
213 }
214 }
216 pScene->mRootNode = new aiNode();
217 pScene->mRootNode->mName.Set("<RawRoot>");
219 // count the number of valid groups
220 // (meshes can't be empty)
221 for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
222 it != end;++it)
223 {
224 if (!(*it).meshes.empty())
225 {
226 ++pScene->mRootNode->mNumChildren;
227 pScene->mNumMeshes += (unsigned int)(*it).meshes.size();
228 }
229 }
231 if (!pScene->mNumMeshes)
232 {
233 throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty.");
234 }
236 pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
237 aiNode** cc;
238 if (1 == pScene->mRootNode->mNumChildren)
239 {
240 cc = &pScene->mRootNode;
241 pScene->mRootNode->mNumChildren = 0;
242 }
243 else cc = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
245 pScene->mNumMaterials = pScene->mNumMeshes;
246 aiMaterial** mats = pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
248 unsigned int meshIdx = 0;
249 for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
250 it != end;++it)
251 {
252 if ((*it).meshes.empty())continue;
254 aiNode* node;
255 if (pScene->mRootNode->mNumChildren)
256 {
257 node = *cc = new aiNode();
258 node->mParent = pScene->mRootNode;
259 }
260 else node = *cc;++cc;
261 node->mName.Set((*it).name);
263 // add all meshes
264 node->mNumMeshes = (unsigned int)(*it).meshes.size();
265 unsigned int* pi = node->mMeshes = new unsigned int[ node->mNumMeshes ];
266 for (std::vector< MeshInformation >::iterator it2 = (*it).meshes.begin(),
267 end2 = (*it).meshes.end(); it2 != end2; ++it2)
268 {
269 ai_assert(!(*it2).vertices.empty());
271 // allocate the mesh
272 *pi++ = meshIdx;
273 aiMesh* mesh = pScene->mMeshes[meshIdx] = new aiMesh();
274 mesh->mMaterialIndex = meshIdx++;
276 mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
278 // allocate storage for the vertex components and copy them
279 mesh->mNumVertices = (unsigned int)(*it2).vertices.size();
280 mesh->mVertices = new aiVector3D[ mesh->mNumVertices ];
281 ::memcpy(mesh->mVertices,&(*it2).vertices[0],sizeof(aiVector3D)*mesh->mNumVertices);
283 if ((*it2).colors.size())
284 {
285 ai_assert((*it2).colors.size() == mesh->mNumVertices);
287 mesh->mColors[0] = new aiColor4D[ mesh->mNumVertices ];
288 ::memcpy(mesh->mColors[0],&(*it2).colors[0],sizeof(aiColor4D)*mesh->mNumVertices);
289 }
291 // generate triangles
292 ai_assert(0 == mesh->mNumVertices % 3);
293 aiFace* fc = mesh->mFaces = new aiFace[ mesh->mNumFaces = mesh->mNumVertices/3 ];
294 aiFace* const fcEnd = fc + mesh->mNumFaces;
295 unsigned int n = 0;
296 while (fc != fcEnd)
297 {
298 aiFace& f = *fc++;
299 f.mIndices = new unsigned int[f.mNumIndices = 3];
300 for (unsigned int m = 0; m < 3;++m)
301 f.mIndices[m] = n++;
302 }
304 // generate a material for the mesh
305 aiMaterial* mat = new aiMaterial();
307 aiColor4D clr(1.0f,1.0f,1.0f,1.0f);
308 if ("%default%" == (*it2).name) // a gray default material
309 {
310 clr.r = clr.g = clr.b = 0.6f;
311 }
312 else if ((*it2).name.length() > 0) // a texture
313 {
314 aiString s;
315 s.Set((*it2).name);
316 mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
317 }
318 mat->AddProperty<aiColor4D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
319 *mats++ = mat;
320 }
321 }
322 }
324 #endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER