vrshoot

annotate libs/assimp/RawLoader.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
rev   line source
nuclear@0 1 /*
nuclear@0 2 ---------------------------------------------------------------------------
nuclear@0 3 Open Asset Import Library (assimp)
nuclear@0 4 ---------------------------------------------------------------------------
nuclear@0 5
nuclear@0 6 Copyright (c) 2006-2012, assimp team
nuclear@0 7
nuclear@0 8 All rights reserved.
nuclear@0 9
nuclear@0 10 Redistribution and use of this software in source and binary forms,
nuclear@0 11 with or without modification, are permitted provided that the following
nuclear@0 12 conditions are met:
nuclear@0 13
nuclear@0 14 * Redistributions of source code must retain the above
nuclear@0 15 copyright notice, this list of conditions and the
nuclear@0 16 following disclaimer.
nuclear@0 17
nuclear@0 18 * Redistributions in binary form must reproduce the above
nuclear@0 19 copyright notice, this list of conditions and the
nuclear@0 20 following disclaimer in the documentation and/or other
nuclear@0 21 materials provided with the distribution.
nuclear@0 22
nuclear@0 23 * Neither the name of the assimp team, nor the names of its
nuclear@0 24 contributors may be used to endorse or promote products
nuclear@0 25 derived from this software without specific prior
nuclear@0 26 written permission of the assimp team.
nuclear@0 27
nuclear@0 28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
nuclear@0 29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
nuclear@0 30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
nuclear@0 31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
nuclear@0 32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
nuclear@0 33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
nuclear@0 34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
nuclear@0 35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
nuclear@0 36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
nuclear@0 37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
nuclear@0 38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nuclear@0 39 ---------------------------------------------------------------------------
nuclear@0 40 */
nuclear@0 41
nuclear@0 42 /** @file RawLoader.cpp
nuclear@0 43 * @brief Implementation of the RAW importer class
nuclear@0 44 */
nuclear@0 45
nuclear@0 46 #include "AssimpPCH.h"
nuclear@0 47 #ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
nuclear@0 48
nuclear@0 49 // internal headers
nuclear@0 50 #include "RawLoader.h"
nuclear@0 51 #include "ParsingUtils.h"
nuclear@0 52 #include "fast_atof.h"
nuclear@0 53
nuclear@0 54 using namespace Assimp;
nuclear@0 55
nuclear@0 56 static const aiImporterDesc desc = {
nuclear@0 57 "Raw Importer",
nuclear@0 58 "",
nuclear@0 59 "",
nuclear@0 60 "",
nuclear@0 61 aiImporterFlags_SupportTextFlavour,
nuclear@0 62 0,
nuclear@0 63 0,
nuclear@0 64 0,
nuclear@0 65 0,
nuclear@0 66 "raw"
nuclear@0 67 };
nuclear@0 68
nuclear@0 69 // ------------------------------------------------------------------------------------------------
nuclear@0 70 // Constructor to be privately used by Importer
nuclear@0 71 RAWImporter::RAWImporter()
nuclear@0 72 {}
nuclear@0 73
nuclear@0 74 // ------------------------------------------------------------------------------------------------
nuclear@0 75 // Destructor, private as well
nuclear@0 76 RAWImporter::~RAWImporter()
nuclear@0 77 {}
nuclear@0 78
nuclear@0 79 // ------------------------------------------------------------------------------------------------
nuclear@0 80 // Returns whether the class can handle the format of the given file.
nuclear@0 81 bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
nuclear@0 82 {
nuclear@0 83 return SimpleExtensionCheck(pFile,"raw");
nuclear@0 84 }
nuclear@0 85
nuclear@0 86 // ------------------------------------------------------------------------------------------------
nuclear@0 87 const aiImporterDesc* RAWImporter::GetInfo () const
nuclear@0 88 {
nuclear@0 89 return &desc;
nuclear@0 90 }
nuclear@0 91
nuclear@0 92 // ------------------------------------------------------------------------------------------------
nuclear@0 93 // Imports the given file into the given scene structure.
nuclear@0 94 void RAWImporter::InternReadFile( const std::string& pFile,
nuclear@0 95 aiScene* pScene, IOSystem* pIOHandler)
nuclear@0 96 {
nuclear@0 97 boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
nuclear@0 98
nuclear@0 99 // Check whether we can read from the file
nuclear@0 100 if( file.get() == NULL) {
nuclear@0 101 throw DeadlyImportError( "Failed to open RAW file " + pFile + ".");
nuclear@0 102 }
nuclear@0 103
nuclear@0 104 // allocate storage and copy the contents of the file to a memory buffer
nuclear@0 105 // (terminate it with zero)
nuclear@0 106 std::vector<char> mBuffer2;
nuclear@0 107 TextFileToBuffer(file.get(),mBuffer2);
nuclear@0 108 const char* buffer = &mBuffer2[0];
nuclear@0 109
nuclear@0 110 // list of groups loaded from the file
nuclear@0 111 std::vector< GroupInformation > outGroups(1,GroupInformation("<default>"));
nuclear@0 112 std::vector< GroupInformation >::iterator curGroup = outGroups.begin();
nuclear@0 113
nuclear@0 114 // now read all lines
nuclear@0 115 char line[4096];
nuclear@0 116 while (GetNextLine(buffer,line))
nuclear@0 117 {
nuclear@0 118 // if the line starts with a non-numeric identifier, it marks
nuclear@0 119 // the beginning of a new group
nuclear@0 120 const char* sz = line;SkipSpaces(&sz);
nuclear@0 121 if (IsLineEnd(*sz))continue;
nuclear@0 122 if (!IsNumeric(*sz))
nuclear@0 123 {
nuclear@0 124 const char* sz2 = sz;
nuclear@0 125 while (!IsSpaceOrNewLine(*sz2))++sz2;
nuclear@0 126 const unsigned int length = (unsigned int)(sz2-sz);
nuclear@0 127
nuclear@0 128 // find an existing group with this name
nuclear@0 129 for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
nuclear@0 130 it != end;++it)
nuclear@0 131 {
nuclear@0 132 if (length == (*it).name.length() && !::strcmp(sz,(*it).name.c_str()))
nuclear@0 133 {
nuclear@0 134 curGroup = it;sz2 = NULL;
nuclear@0 135 break;
nuclear@0 136 }
nuclear@0 137 }
nuclear@0 138 if (sz2)
nuclear@0 139 {
nuclear@0 140 outGroups.push_back(GroupInformation(std::string(sz,length)));
nuclear@0 141 curGroup = outGroups.end()-1;
nuclear@0 142 }
nuclear@0 143 }
nuclear@0 144 else
nuclear@0 145 {
nuclear@0 146 // there can be maximally 12 floats plus an extra texture file name
nuclear@0 147 float data[12];
nuclear@0 148 unsigned int num;
nuclear@0 149 for (num = 0; num < 12;++num)
nuclear@0 150 {
nuclear@0 151 if(!SkipSpaces(&sz) || !IsNumeric(*sz))break;
nuclear@0 152 sz = fast_atoreal_move<float>(sz,data[num]);
nuclear@0 153 }
nuclear@0 154 if (num != 12 && num != 9)
nuclear@0 155 {
nuclear@0 156 DefaultLogger::get()->error("A line may have either 9 or 12 floats and an optional texture");
nuclear@0 157 continue;
nuclear@0 158 }
nuclear@0 159
nuclear@0 160 MeshInformation* output = NULL;
nuclear@0 161
nuclear@0 162 const char* sz2 = sz;
nuclear@0 163 unsigned int length;
nuclear@0 164 if (!IsLineEnd(*sz))
nuclear@0 165 {
nuclear@0 166 while (!IsSpaceOrNewLine(*sz2))++sz2;
nuclear@0 167 length = (unsigned int)(sz2-sz);
nuclear@0 168 }
nuclear@0 169 else if (9 == num)
nuclear@0 170 {
nuclear@0 171 sz = "%default%";
nuclear@0 172 length = 9;
nuclear@0 173 }
nuclear@0 174 else
nuclear@0 175 {
nuclear@0 176 sz = "";
nuclear@0 177 length = 0;
nuclear@0 178 }
nuclear@0 179
nuclear@0 180 // search in the list of meshes whether we have one with this texture
nuclear@0 181 for (std::vector< MeshInformation >::iterator it = (*curGroup).meshes.begin(),
nuclear@0 182 end = (*curGroup).meshes.end(); it != end; ++it)
nuclear@0 183 {
nuclear@0 184 if (length == (*it).name.length() && (length ? !::strcmp(sz,(*it).name.c_str()) : true))
nuclear@0 185 {
nuclear@0 186 output = &(*it);
nuclear@0 187 break;
nuclear@0 188 }
nuclear@0 189 }
nuclear@0 190 // if we don't have the mesh, create it
nuclear@0 191 if (!output)
nuclear@0 192 {
nuclear@0 193 (*curGroup).meshes.push_back(MeshInformation(std::string(sz,length)));
nuclear@0 194 output = &((*curGroup).meshes.back());
nuclear@0 195 }
nuclear@0 196 if (12 == num)
nuclear@0 197 {
nuclear@0 198 aiColor4D v(data[0],data[1],data[2],1.0f);
nuclear@0 199 output->colors.push_back(v);
nuclear@0 200 output->colors.push_back(v);
nuclear@0 201 output->colors.push_back(v);
nuclear@0 202
nuclear@0 203 output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
nuclear@0 204 output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
nuclear@0 205 output->vertices.push_back(aiVector3D(data[9],data[10],data[11]));
nuclear@0 206 }
nuclear@0 207 else
nuclear@0 208 {
nuclear@0 209 output->vertices.push_back(aiVector3D(data[0],data[1],data[2]));
nuclear@0 210 output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
nuclear@0 211 output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
nuclear@0 212 }
nuclear@0 213 }
nuclear@0 214 }
nuclear@0 215
nuclear@0 216 pScene->mRootNode = new aiNode();
nuclear@0 217 pScene->mRootNode->mName.Set("<RawRoot>");
nuclear@0 218
nuclear@0 219 // count the number of valid groups
nuclear@0 220 // (meshes can't be empty)
nuclear@0 221 for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
nuclear@0 222 it != end;++it)
nuclear@0 223 {
nuclear@0 224 if (!(*it).meshes.empty())
nuclear@0 225 {
nuclear@0 226 ++pScene->mRootNode->mNumChildren;
nuclear@0 227 pScene->mNumMeshes += (unsigned int)(*it).meshes.size();
nuclear@0 228 }
nuclear@0 229 }
nuclear@0 230
nuclear@0 231 if (!pScene->mNumMeshes)
nuclear@0 232 {
nuclear@0 233 throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty.");
nuclear@0 234 }
nuclear@0 235
nuclear@0 236 pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
nuclear@0 237 aiNode** cc;
nuclear@0 238 if (1 == pScene->mRootNode->mNumChildren)
nuclear@0 239 {
nuclear@0 240 cc = &pScene->mRootNode;
nuclear@0 241 pScene->mRootNode->mNumChildren = 0;
nuclear@0 242 }
nuclear@0 243 else cc = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
nuclear@0 244
nuclear@0 245 pScene->mNumMaterials = pScene->mNumMeshes;
nuclear@0 246 aiMaterial** mats = pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
nuclear@0 247
nuclear@0 248 unsigned int meshIdx = 0;
nuclear@0 249 for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
nuclear@0 250 it != end;++it)
nuclear@0 251 {
nuclear@0 252 if ((*it).meshes.empty())continue;
nuclear@0 253
nuclear@0 254 aiNode* node;
nuclear@0 255 if (pScene->mRootNode->mNumChildren)
nuclear@0 256 {
nuclear@0 257 node = *cc = new aiNode();
nuclear@0 258 node->mParent = pScene->mRootNode;
nuclear@0 259 }
nuclear@0 260 else node = *cc;++cc;
nuclear@0 261 node->mName.Set((*it).name);
nuclear@0 262
nuclear@0 263 // add all meshes
nuclear@0 264 node->mNumMeshes = (unsigned int)(*it).meshes.size();
nuclear@0 265 unsigned int* pi = node->mMeshes = new unsigned int[ node->mNumMeshes ];
nuclear@0 266 for (std::vector< MeshInformation >::iterator it2 = (*it).meshes.begin(),
nuclear@0 267 end2 = (*it).meshes.end(); it2 != end2; ++it2)
nuclear@0 268 {
nuclear@0 269 ai_assert(!(*it2).vertices.empty());
nuclear@0 270
nuclear@0 271 // allocate the mesh
nuclear@0 272 *pi++ = meshIdx;
nuclear@0 273 aiMesh* mesh = pScene->mMeshes[meshIdx] = new aiMesh();
nuclear@0 274 mesh->mMaterialIndex = meshIdx++;
nuclear@0 275
nuclear@0 276 mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
nuclear@0 277
nuclear@0 278 // allocate storage for the vertex components and copy them
nuclear@0 279 mesh->mNumVertices = (unsigned int)(*it2).vertices.size();
nuclear@0 280 mesh->mVertices = new aiVector3D[ mesh->mNumVertices ];
nuclear@0 281 ::memcpy(mesh->mVertices,&(*it2).vertices[0],sizeof(aiVector3D)*mesh->mNumVertices);
nuclear@0 282
nuclear@0 283 if ((*it2).colors.size())
nuclear@0 284 {
nuclear@0 285 ai_assert((*it2).colors.size() == mesh->mNumVertices);
nuclear@0 286
nuclear@0 287 mesh->mColors[0] = new aiColor4D[ mesh->mNumVertices ];
nuclear@0 288 ::memcpy(mesh->mColors[0],&(*it2).colors[0],sizeof(aiColor4D)*mesh->mNumVertices);
nuclear@0 289 }
nuclear@0 290
nuclear@0 291 // generate triangles
nuclear@0 292 ai_assert(0 == mesh->mNumVertices % 3);
nuclear@0 293 aiFace* fc = mesh->mFaces = new aiFace[ mesh->mNumFaces = mesh->mNumVertices/3 ];
nuclear@0 294 aiFace* const fcEnd = fc + mesh->mNumFaces;
nuclear@0 295 unsigned int n = 0;
nuclear@0 296 while (fc != fcEnd)
nuclear@0 297 {
nuclear@0 298 aiFace& f = *fc++;
nuclear@0 299 f.mIndices = new unsigned int[f.mNumIndices = 3];
nuclear@0 300 for (unsigned int m = 0; m < 3;++m)
nuclear@0 301 f.mIndices[m] = n++;
nuclear@0 302 }
nuclear@0 303
nuclear@0 304 // generate a material for the mesh
nuclear@0 305 aiMaterial* mat = new aiMaterial();
nuclear@0 306
nuclear@0 307 aiColor4D clr(1.0f,1.0f,1.0f,1.0f);
nuclear@0 308 if ("%default%" == (*it2).name) // a gray default material
nuclear@0 309 {
nuclear@0 310 clr.r = clr.g = clr.b = 0.6f;
nuclear@0 311 }
nuclear@0 312 else if ((*it2).name.length() > 0) // a texture
nuclear@0 313 {
nuclear@0 314 aiString s;
nuclear@0 315 s.Set((*it2).name);
nuclear@0 316 mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
nuclear@0 317 }
nuclear@0 318 mat->AddProperty<aiColor4D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
nuclear@0 319 *mats++ = mat;
nuclear@0 320 }
nuclear@0 321 }
nuclear@0 322 }
nuclear@0 323
nuclear@0 324 #endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER