vrshoot

annotate libs/assimp/MD5Parser.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 MD5Parser.cpp
nuclear@0 43 * @brief Implementation of the MD5 parser class
nuclear@0 44 */
nuclear@0 45 #include "AssimpPCH.h"
nuclear@0 46
nuclear@0 47 // internal headers
nuclear@0 48 #include "MD5Loader.h"
nuclear@0 49 #include "MaterialSystem.h"
nuclear@0 50 #include "fast_atof.h"
nuclear@0 51 #include "ParsingUtils.h"
nuclear@0 52 #include "StringComparison.h"
nuclear@0 53
nuclear@0 54 using namespace Assimp;
nuclear@0 55 using namespace Assimp::MD5;
nuclear@0 56
nuclear@0 57 // ------------------------------------------------------------------------------------------------
nuclear@0 58 // Parse the segment structure fo a MD5 file
nuclear@0 59 MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
nuclear@0 60 {
nuclear@0 61 ai_assert(NULL != _buffer && 0 != _fileSize);
nuclear@0 62
nuclear@0 63 buffer = _buffer;
nuclear@0 64 fileSize = _fileSize;
nuclear@0 65 lineNumber = 0;
nuclear@0 66
nuclear@0 67 DefaultLogger::get()->debug("MD5Parser begin");
nuclear@0 68
nuclear@0 69 // parse the file header
nuclear@0 70 ParseHeader();
nuclear@0 71
nuclear@0 72 // and read all sections until we're finished
nuclear@0 73 bool running = true;
nuclear@0 74 while (running) {
nuclear@0 75 mSections.push_back(Section());
nuclear@0 76 Section& sec = mSections.back();
nuclear@0 77 if(!ParseSection(sec)) {
nuclear@0 78 break;
nuclear@0 79 }
nuclear@0 80 }
nuclear@0 81
nuclear@0 82 if ( !DefaultLogger::isNullLogger()) {
nuclear@0 83 char szBuffer[128]; // should be sufficiently large
nuclear@0 84 ::sprintf(szBuffer,"MD5Parser end. Parsed %i sections",(int)mSections.size());
nuclear@0 85 DefaultLogger::get()->debug(szBuffer);
nuclear@0 86 }
nuclear@0 87 }
nuclear@0 88
nuclear@0 89 // ------------------------------------------------------------------------------------------------
nuclear@0 90 // Report error to the log stream
nuclear@0 91 /*static*/ void MD5Parser::ReportError (const char* error, unsigned int line)
nuclear@0 92 {
nuclear@0 93 char szBuffer[1024];
nuclear@0 94 ::sprintf(szBuffer,"[MD5] Line %i: %s",line,error);
nuclear@0 95 throw DeadlyImportError(szBuffer);
nuclear@0 96 }
nuclear@0 97
nuclear@0 98 // ------------------------------------------------------------------------------------------------
nuclear@0 99 // Report warning to the log stream
nuclear@0 100 /*static*/ void MD5Parser::ReportWarning (const char* warn, unsigned int line)
nuclear@0 101 {
nuclear@0 102 char szBuffer[1024];
nuclear@0 103 ::sprintf(szBuffer,"[MD5] Line %i: %s",line,warn);
nuclear@0 104 DefaultLogger::get()->warn(szBuffer);
nuclear@0 105 }
nuclear@0 106
nuclear@0 107 // ------------------------------------------------------------------------------------------------
nuclear@0 108 // Parse and validate the MD5 header
nuclear@0 109 void MD5Parser::ParseHeader()
nuclear@0 110 {
nuclear@0 111 // parse and validate the file version
nuclear@0 112 SkipSpaces();
nuclear@0 113 if (!TokenMatch(buffer,"MD5Version",10)) {
nuclear@0 114 ReportError("Invalid MD5 file: MD5Version tag has not been found");
nuclear@0 115 }
nuclear@0 116 SkipSpaces();
nuclear@0 117 unsigned int iVer = ::strtoul10(buffer,(const char**)&buffer);
nuclear@0 118 if (10 != iVer) {
nuclear@0 119 ReportError("MD5 version tag is unknown (10 is expected)");
nuclear@0 120 }
nuclear@0 121 SkipLine();
nuclear@0 122
nuclear@0 123 // print the command line options to the console
nuclear@0 124 // FIX: can break the log length limit, so we need to be careful
nuclear@0 125 char* sz = buffer;
nuclear@0 126 while (!IsLineEnd( *buffer++));
nuclear@0 127 DefaultLogger::get()->info(std::string(sz,std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer-sz))));
nuclear@0 128 SkipSpacesAndLineEnd();
nuclear@0 129 }
nuclear@0 130
nuclear@0 131 // ------------------------------------------------------------------------------------------------
nuclear@0 132 // Recursive MD5 parsing function
nuclear@0 133 bool MD5Parser::ParseSection(Section& out)
nuclear@0 134 {
nuclear@0 135 // store the current line number for use in error messages
nuclear@0 136 out.iLineNumber = lineNumber;
nuclear@0 137
nuclear@0 138 // first parse the name of the section
nuclear@0 139 char* sz = buffer;
nuclear@0 140 while (!IsSpaceOrNewLine( *buffer))buffer++;
nuclear@0 141 out.mName = std::string(sz,(uintptr_t)(buffer-sz));
nuclear@0 142 SkipSpaces();
nuclear@0 143
nuclear@0 144 bool running = true;
nuclear@0 145 while (running) {
nuclear@0 146 if ('{' == *buffer) {
nuclear@0 147 // it is a normal section so read all lines
nuclear@0 148 buffer++;
nuclear@0 149 bool run = true;
nuclear@0 150 while (run)
nuclear@0 151 {
nuclear@0 152 if (!SkipSpacesAndLineEnd()) {
nuclear@0 153 return false; // seems this was the last section
nuclear@0 154 }
nuclear@0 155 if ('}' == *buffer) {
nuclear@0 156 buffer++;
nuclear@0 157 break;
nuclear@0 158 }
nuclear@0 159
nuclear@0 160 out.mElements.push_back(Element());
nuclear@0 161 Element& elem = out.mElements.back();
nuclear@0 162
nuclear@0 163 elem.iLineNumber = lineNumber;
nuclear@0 164 elem.szStart = buffer;
nuclear@0 165
nuclear@0 166 // terminate the line with zero
nuclear@0 167 while (!IsLineEnd( *buffer))buffer++;
nuclear@0 168 if (*buffer) {
nuclear@0 169 ++lineNumber;
nuclear@0 170 *buffer++ = '\0';
nuclear@0 171 }
nuclear@0 172 }
nuclear@0 173 break;
nuclear@0 174 }
nuclear@0 175 else if (!IsSpaceOrNewLine(*buffer)) {
nuclear@0 176 // it is an element at global scope. Parse its value and go on
nuclear@0 177 sz = buffer;
nuclear@0 178 while (!IsSpaceOrNewLine( *buffer++));
nuclear@0 179 out.mGlobalValue = std::string(sz,(uintptr_t)(buffer-sz));
nuclear@0 180 continue;
nuclear@0 181 }
nuclear@0 182 break;
nuclear@0 183 }
nuclear@0 184 return SkipSpacesAndLineEnd();
nuclear@0 185 }
nuclear@0 186
nuclear@0 187 // ------------------------------------------------------------------------------------------------
nuclear@0 188 // Some dirty macros just because they're so funny and easy to debug
nuclear@0 189
nuclear@0 190 // skip all spaces ... handle EOL correctly
nuclear@0 191 #define AI_MD5_SKIP_SPACES() if(!SkipSpaces(&sz)) \
nuclear@0 192 MD5Parser::ReportWarning("Unexpected end of line",(*eit).iLineNumber);
nuclear@0 193
nuclear@0 194 // read a triple float in brackets: (1.0 1.0 1.0)
nuclear@0 195 #define AI_MD5_READ_TRIPLE(vec) \
nuclear@0 196 AI_MD5_SKIP_SPACES(); \
nuclear@0 197 if ('(' != *sz++) \
nuclear@0 198 MD5Parser::ReportWarning("Unexpected token: ( was expected",(*eit).iLineNumber); \
nuclear@0 199 AI_MD5_SKIP_SPACES(); \
nuclear@0 200 sz = fast_atoreal_move<float>(sz,(float&)vec.x); \
nuclear@0 201 AI_MD5_SKIP_SPACES(); \
nuclear@0 202 sz = fast_atoreal_move<float>(sz,(float&)vec.y); \
nuclear@0 203 AI_MD5_SKIP_SPACES(); \
nuclear@0 204 sz = fast_atoreal_move<float>(sz,(float&)vec.z); \
nuclear@0 205 AI_MD5_SKIP_SPACES(); \
nuclear@0 206 if (')' != *sz++) \
nuclear@0 207 MD5Parser::ReportWarning("Unexpected token: ) was expected",(*eit).iLineNumber);
nuclear@0 208
nuclear@0 209 // parse a string, enclosed in quotation marks or not
nuclear@0 210 #define AI_MD5_PARSE_STRING(out) \
nuclear@0 211 bool bQuota = (*sz == '\"'); \
nuclear@0 212 const char* szStart = sz; \
nuclear@0 213 while (!IsSpaceOrNewLine(*sz))++sz; \
nuclear@0 214 const char* szEnd = sz; \
nuclear@0 215 if (bQuota) { \
nuclear@0 216 szStart++; \
nuclear@0 217 if ('\"' != *(szEnd-=1)) { \
nuclear@0 218 MD5Parser::ReportWarning("Expected closing quotation marks in string", \
nuclear@0 219 (*eit).iLineNumber); \
nuclear@0 220 continue; \
nuclear@0 221 } \
nuclear@0 222 } \
nuclear@0 223 out.length = (size_t)(szEnd - szStart); \
nuclear@0 224 ::memcpy(out.data,szStart,out.length); \
nuclear@0 225 out.data[out.length] = '\0';
nuclear@0 226
nuclear@0 227 // ------------------------------------------------------------------------------------------------
nuclear@0 228 // .MD5MESH parsing function
nuclear@0 229 MD5MeshParser::MD5MeshParser(SectionList& mSections)
nuclear@0 230 {
nuclear@0 231 DefaultLogger::get()->debug("MD5MeshParser begin");
nuclear@0 232
nuclear@0 233 // now parse all sections
nuclear@0 234 for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter){
nuclear@0 235 if ( (*iter).mName == "numMeshes") {
nuclear@0 236 mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
nuclear@0 237 }
nuclear@0 238 else if ( (*iter).mName == "numJoints") {
nuclear@0 239 mJoints.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
nuclear@0 240 }
nuclear@0 241 else if ((*iter).mName == "joints") {
nuclear@0 242 // "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
nuclear@0 243 for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end();eit != eitEnd; ++eit){
nuclear@0 244 mJoints.push_back(BoneDesc());
nuclear@0 245 BoneDesc& desc = mJoints.back();
nuclear@0 246
nuclear@0 247 const char* sz = (*eit).szStart;
nuclear@0 248 AI_MD5_PARSE_STRING(desc.mName);
nuclear@0 249 AI_MD5_SKIP_SPACES();
nuclear@0 250
nuclear@0 251 // negative values, at least -1, is allowed here
nuclear@0 252 desc.mParentIndex = (int)strtol10(sz,&sz);
nuclear@0 253
nuclear@0 254 AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
nuclear@0 255 AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
nuclear@0 256 }
nuclear@0 257 }
nuclear@0 258 else if ((*iter).mName == "mesh") {
nuclear@0 259 mMeshes.push_back(MeshDesc());
nuclear@0 260 MeshDesc& desc = mMeshes.back();
nuclear@0 261
nuclear@0 262 for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end();eit != eitEnd; ++eit){
nuclear@0 263 const char* sz = (*eit).szStart;
nuclear@0 264
nuclear@0 265 // shader attribute
nuclear@0 266 if (TokenMatch(sz,"shader",6)) {
nuclear@0 267 AI_MD5_SKIP_SPACES();
nuclear@0 268 AI_MD5_PARSE_STRING(desc.mShader);
nuclear@0 269 }
nuclear@0 270 // numverts attribute
nuclear@0 271 else if (TokenMatch(sz,"numverts",8)) {
nuclear@0 272 AI_MD5_SKIP_SPACES();
nuclear@0 273 desc.mVertices.resize(strtoul10(sz));
nuclear@0 274 }
nuclear@0 275 // numtris attribute
nuclear@0 276 else if (TokenMatch(sz,"numtris",7)) {
nuclear@0 277 AI_MD5_SKIP_SPACES();
nuclear@0 278 desc.mFaces.resize(strtoul10(sz));
nuclear@0 279 }
nuclear@0 280 // numweights attribute
nuclear@0 281 else if (TokenMatch(sz,"numweights",10)) {
nuclear@0 282 AI_MD5_SKIP_SPACES();
nuclear@0 283 desc.mWeights.resize(strtoul10(sz));
nuclear@0 284 }
nuclear@0 285 // vert attribute
nuclear@0 286 // "vert 0 ( 0.394531 0.513672 ) 0 1"
nuclear@0 287 else if (TokenMatch(sz,"vert",4)) {
nuclear@0 288 AI_MD5_SKIP_SPACES();
nuclear@0 289 const unsigned int idx = ::strtoul10(sz,&sz);
nuclear@0 290 AI_MD5_SKIP_SPACES();
nuclear@0 291 if (idx >= desc.mVertices.size())
nuclear@0 292 desc.mVertices.resize(idx+1);
nuclear@0 293
nuclear@0 294 VertexDesc& vert = desc.mVertices[idx];
nuclear@0 295 if ('(' != *sz++)
nuclear@0 296 MD5Parser::ReportWarning("Unexpected token: ( was expected",(*eit).iLineNumber);
nuclear@0 297 AI_MD5_SKIP_SPACES();
nuclear@0 298 sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.x);
nuclear@0 299 AI_MD5_SKIP_SPACES();
nuclear@0 300 sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.y);
nuclear@0 301 AI_MD5_SKIP_SPACES();
nuclear@0 302 if (')' != *sz++)
nuclear@0 303 MD5Parser::ReportWarning("Unexpected token: ) was expected",(*eit).iLineNumber);
nuclear@0 304 AI_MD5_SKIP_SPACES();
nuclear@0 305 vert.mFirstWeight = ::strtoul10(sz,&sz);
nuclear@0 306 AI_MD5_SKIP_SPACES();
nuclear@0 307 vert.mNumWeights = ::strtoul10(sz,&sz);
nuclear@0 308 }
nuclear@0 309 // tri attribute
nuclear@0 310 // "tri 0 15 13 12"
nuclear@0 311 else if (TokenMatch(sz,"tri",3)) {
nuclear@0 312 AI_MD5_SKIP_SPACES();
nuclear@0 313 const unsigned int idx = strtoul10(sz,&sz);
nuclear@0 314 if (idx >= desc.mFaces.size())
nuclear@0 315 desc.mFaces.resize(idx+1);
nuclear@0 316
nuclear@0 317 aiFace& face = desc.mFaces[idx];
nuclear@0 318 face.mIndices = new unsigned int[face.mNumIndices = 3];
nuclear@0 319 for (unsigned int i = 0; i < 3;++i) {
nuclear@0 320 AI_MD5_SKIP_SPACES();
nuclear@0 321 face.mIndices[i] = strtoul10(sz,&sz);
nuclear@0 322 }
nuclear@0 323 }
nuclear@0 324 // weight attribute
nuclear@0 325 // "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )"
nuclear@0 326 else if (TokenMatch(sz,"weight",6)) {
nuclear@0 327 AI_MD5_SKIP_SPACES();
nuclear@0 328 const unsigned int idx = strtoul10(sz,&sz);
nuclear@0 329 AI_MD5_SKIP_SPACES();
nuclear@0 330 if (idx >= desc.mWeights.size())
nuclear@0 331 desc.mWeights.resize(idx+1);
nuclear@0 332
nuclear@0 333 WeightDesc& weight = desc.mWeights[idx];
nuclear@0 334 weight.mBone = strtoul10(sz,&sz);
nuclear@0 335 AI_MD5_SKIP_SPACES();
nuclear@0 336 sz = fast_atoreal_move<float>(sz,weight.mWeight);
nuclear@0 337 AI_MD5_READ_TRIPLE(weight.vOffsetPosition);
nuclear@0 338 }
nuclear@0 339 }
nuclear@0 340 }
nuclear@0 341 }
nuclear@0 342 DefaultLogger::get()->debug("MD5MeshParser end");
nuclear@0 343 }
nuclear@0 344
nuclear@0 345 // ------------------------------------------------------------------------------------------------
nuclear@0 346 // .MD5ANIM parsing function
nuclear@0 347 MD5AnimParser::MD5AnimParser(SectionList& mSections)
nuclear@0 348 {
nuclear@0 349 DefaultLogger::get()->debug("MD5AnimParser begin");
nuclear@0 350
nuclear@0 351 fFrameRate = 24.0f;
nuclear@0 352 mNumAnimatedComponents = UINT_MAX;
nuclear@0 353 for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
nuclear@0 354 if ((*iter).mName == "hierarchy") {
nuclear@0 355 // "sheath" 0 63 6
nuclear@0 356 for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end();eit != eitEnd; ++eit) {
nuclear@0 357 mAnimatedBones.push_back ( AnimBoneDesc () );
nuclear@0 358 AnimBoneDesc& desc = mAnimatedBones.back();
nuclear@0 359
nuclear@0 360 const char* sz = (*eit).szStart;
nuclear@0 361 AI_MD5_PARSE_STRING(desc.mName);
nuclear@0 362 AI_MD5_SKIP_SPACES();
nuclear@0 363
nuclear@0 364 // parent index - negative values are allowed (at least -1)
nuclear@0 365 desc.mParentIndex = ::strtol10(sz,&sz);
nuclear@0 366
nuclear@0 367 // flags (highest is 2^6-1)
nuclear@0 368 AI_MD5_SKIP_SPACES();
nuclear@0 369 if(63 < (desc.iFlags = ::strtoul10(sz,&sz))){
nuclear@0 370 MD5Parser::ReportWarning("Invalid flag combination in hierarchy section",(*eit).iLineNumber);
nuclear@0 371 }
nuclear@0 372 AI_MD5_SKIP_SPACES();
nuclear@0 373
nuclear@0 374 // index of the first animation keyframe component for this joint
nuclear@0 375 desc.iFirstKeyIndex = ::strtoul10(sz,&sz);
nuclear@0 376 }
nuclear@0 377 }
nuclear@0 378 else if((*iter).mName == "baseframe") {
nuclear@0 379 // ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000242 0.707107 )
nuclear@0 380 for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit) {
nuclear@0 381 const char* sz = (*eit).szStart;
nuclear@0 382
nuclear@0 383 mBaseFrames.push_back ( BaseFrameDesc () );
nuclear@0 384 BaseFrameDesc& desc = mBaseFrames.back();
nuclear@0 385
nuclear@0 386 AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
nuclear@0 387 AI_MD5_READ_TRIPLE(desc.vRotationQuat);
nuclear@0 388 }
nuclear@0 389 }
nuclear@0 390 else if((*iter).mName == "frame") {
nuclear@0 391 if (!(*iter).mGlobalValue.length()) {
nuclear@0 392 MD5Parser::ReportWarning("A frame section must have a frame index",(*iter).iLineNumber);
nuclear@0 393 continue;
nuclear@0 394 }
nuclear@0 395
nuclear@0 396 mFrames.push_back ( FrameDesc () );
nuclear@0 397 FrameDesc& desc = mFrames.back();
nuclear@0 398 desc.iIndex = strtoul10((*iter).mGlobalValue.c_str());
nuclear@0 399
nuclear@0 400 // we do already know how much storage we will presumably need
nuclear@0 401 if (UINT_MAX != mNumAnimatedComponents) {
nuclear@0 402 desc.mValues.reserve(mNumAnimatedComponents);
nuclear@0 403 }
nuclear@0 404
nuclear@0 405 // now read all elements (continous list of floats)
nuclear@0 406 for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit){
nuclear@0 407 const char* sz = (*eit).szStart;
nuclear@0 408 while (SkipSpacesAndLineEnd(&sz)) {
nuclear@0 409 float f;sz = fast_atoreal_move<float>(sz,f);
nuclear@0 410 desc.mValues.push_back(f);
nuclear@0 411 }
nuclear@0 412 }
nuclear@0 413 }
nuclear@0 414 else if((*iter).mName == "numFrames") {
nuclear@0 415 mFrames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
nuclear@0 416 }
nuclear@0 417 else if((*iter).mName == "numJoints") {
nuclear@0 418 const unsigned int num = strtoul10((*iter).mGlobalValue.c_str());
nuclear@0 419 mAnimatedBones.reserve(num);
nuclear@0 420
nuclear@0 421 // try to guess the number of animated components if that element is not given
nuclear@0 422 if (UINT_MAX == mNumAnimatedComponents) {
nuclear@0 423 mNumAnimatedComponents = num * 6;
nuclear@0 424 }
nuclear@0 425 }
nuclear@0 426 else if((*iter).mName == "numAnimatedComponents") {
nuclear@0 427 mAnimatedBones.reserve( strtoul10((*iter).mGlobalValue.c_str()));
nuclear@0 428 }
nuclear@0 429 else if((*iter).mName == "frameRate") {
nuclear@0 430 fast_atoreal_move<float>((*iter).mGlobalValue.c_str(),fFrameRate);
nuclear@0 431 }
nuclear@0 432 }
nuclear@0 433 DefaultLogger::get()->debug("MD5AnimParser end");
nuclear@0 434 }
nuclear@0 435
nuclear@0 436 // ------------------------------------------------------------------------------------------------
nuclear@0 437 // .MD5CAMERA parsing function
nuclear@0 438 MD5CameraParser::MD5CameraParser(SectionList& mSections)
nuclear@0 439 {
nuclear@0 440 DefaultLogger::get()->debug("MD5CameraParser begin");
nuclear@0 441 fFrameRate = 24.0f;
nuclear@0 442
nuclear@0 443 for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
nuclear@0 444 if ((*iter).mName == "numFrames") {
nuclear@0 445 frames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
nuclear@0 446 }
nuclear@0 447 else if ((*iter).mName == "frameRate") {
nuclear@0 448 fFrameRate = fast_atof ((*iter).mGlobalValue.c_str());
nuclear@0 449 }
nuclear@0 450 else if ((*iter).mName == "numCuts") {
nuclear@0 451 cuts.reserve(strtoul10((*iter).mGlobalValue.c_str()));
nuclear@0 452 }
nuclear@0 453 else if ((*iter).mName == "cuts") {
nuclear@0 454 for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit){
nuclear@0 455 cuts.push_back(strtoul10((*eit).szStart)+1);
nuclear@0 456 }
nuclear@0 457 }
nuclear@0 458 else if ((*iter).mName == "camera") {
nuclear@0 459 for (ElementList::const_iterator eit = (*iter).mElements.begin(), eitEnd = (*iter).mElements.end(); eit != eitEnd; ++eit){
nuclear@0 460 const char* sz = (*eit).szStart;
nuclear@0 461
nuclear@0 462 frames.push_back(CameraAnimFrameDesc());
nuclear@0 463 CameraAnimFrameDesc& cur = frames.back();
nuclear@0 464 AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
nuclear@0 465 AI_MD5_READ_TRIPLE(cur.vRotationQuat);
nuclear@0 466 AI_MD5_SKIP_SPACES();
nuclear@0 467 cur.fFOV = fast_atof(sz);
nuclear@0 468 }
nuclear@0 469 }
nuclear@0 470 }
nuclear@0 471 DefaultLogger::get()->debug("MD5CameraParser end");
nuclear@0 472 }
nuclear@0 473