vrshoot

annotate libs/assimp/B3DImporter.cpp @ 1:e7ca128b8713

looks nice :)
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 02 Feb 2014 00:35:22 +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 B3DImporter.cpp
nuclear@0 43 * @brief Implementation of the b3d importer class
nuclear@0 44 */
nuclear@0 45
nuclear@0 46 #include "AssimpPCH.h"
nuclear@0 47 #ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
nuclear@0 48
nuclear@0 49 // internal headers
nuclear@0 50 #include "B3DImporter.h"
nuclear@0 51 #include "TextureTransform.h"
nuclear@0 52 #include "ConvertToLHProcess.h"
nuclear@0 53
nuclear@0 54 using namespace Assimp;
nuclear@0 55 using namespace std;
nuclear@0 56
nuclear@0 57 static const aiImporterDesc desc = {
nuclear@0 58 "BlitzBasic 3D Importer",
nuclear@0 59 "",
nuclear@0 60 "",
nuclear@0 61 "http://www.blitzbasic.com/",
nuclear@0 62 aiImporterFlags_SupportBinaryFlavour,
nuclear@0 63 0,
nuclear@0 64 0,
nuclear@0 65 0,
nuclear@0 66 0,
nuclear@0 67 "b3d"
nuclear@0 68 };
nuclear@0 69
nuclear@0 70 // (fixme, Aramis) quick workaround to get rid of all those signed to unsigned warnings
nuclear@0 71 #ifdef _MSC_VER
nuclear@0 72 # pragma warning (disable: 4018)
nuclear@0 73 #endif
nuclear@0 74
nuclear@0 75 //#define DEBUG_B3D
nuclear@0 76
nuclear@0 77 // ------------------------------------------------------------------------------------------------
nuclear@0 78 bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const{
nuclear@0 79
nuclear@0 80 size_t pos=pFile.find_last_of( '.' );
nuclear@0 81 if( pos==string::npos ) return false;
nuclear@0 82
nuclear@0 83 string ext=pFile.substr( pos+1 );
nuclear@0 84 if( ext.size()!=3 ) return false;
nuclear@0 85
nuclear@0 86 return (ext[0]=='b' || ext[0]=='B') && (ext[1]=='3') && (ext[2]=='d' || ext[2]=='D');
nuclear@0 87 }
nuclear@0 88
nuclear@0 89 // ------------------------------------------------------------------------------------------------
nuclear@0 90 // Loader meta information
nuclear@0 91 const aiImporterDesc* B3DImporter::GetInfo () const
nuclear@0 92 {
nuclear@0 93 return &desc;
nuclear@0 94 }
nuclear@0 95
nuclear@0 96 #ifdef DEBUG_B3D
nuclear@0 97 extern "C"{ void _stdcall AllocConsole(); }
nuclear@0 98 #endif
nuclear@0 99 // ------------------------------------------------------------------------------------------------
nuclear@0 100 void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler){
nuclear@0 101
nuclear@0 102 #ifdef DEBUG_B3D
nuclear@0 103 AllocConsole();
nuclear@0 104 freopen( "conin$","r",stdin );
nuclear@0 105 freopen( "conout$","w",stdout );
nuclear@0 106 freopen( "conout$","w",stderr );
nuclear@0 107 cout<<"Hello world from the B3DImporter!"<<endl;
nuclear@0 108 #endif
nuclear@0 109
nuclear@0 110 boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
nuclear@0 111
nuclear@0 112 // Check whether we can read from the file
nuclear@0 113 if( file.get() == NULL)
nuclear@0 114 throw DeadlyImportError( "Failed to open B3D file " + pFile + ".");
nuclear@0 115
nuclear@0 116 // check whether the .b3d file is large enough to contain
nuclear@0 117 // at least one chunk.
nuclear@0 118 size_t fileSize = file->FileSize();
nuclear@0 119 if( fileSize<8 ) throw DeadlyImportError( "B3D File is too small.");
nuclear@0 120
nuclear@0 121 _pos=0;
nuclear@0 122 _buf.resize( fileSize );
nuclear@0 123 file->Read( &_buf[0],1,fileSize );
nuclear@0 124 _stack.clear();
nuclear@0 125
nuclear@0 126 ReadBB3D( pScene );
nuclear@0 127 }
nuclear@0 128
nuclear@0 129 // ------------------------------------------------------------------------------------------------
nuclear@0 130 void B3DImporter::Oops(){
nuclear@0 131 throw DeadlyImportError( "B3D Importer - INTERNAL ERROR" );
nuclear@0 132 }
nuclear@0 133
nuclear@0 134 // ------------------------------------------------------------------------------------------------
nuclear@0 135 void B3DImporter::Fail( string str ){
nuclear@0 136 #ifdef DEBUG_B3D
nuclear@0 137 cout<<"Error in B3D file data: "<<str<<endl;
nuclear@0 138 #endif
nuclear@0 139 throw DeadlyImportError( "B3D Importer - error in B3D file data: "+str );
nuclear@0 140 }
nuclear@0 141
nuclear@0 142 // ------------------------------------------------------------------------------------------------
nuclear@0 143 int B3DImporter::ReadByte(){
nuclear@0 144 if( _pos<_buf.size() ) return _buf[_pos++];
nuclear@0 145 Fail( "EOF" );
nuclear@0 146 return 0;
nuclear@0 147 }
nuclear@0 148
nuclear@0 149 // ------------------------------------------------------------------------------------------------
nuclear@0 150 int B3DImporter::ReadInt(){
nuclear@0 151 if( _pos+4<=_buf.size() ){
nuclear@0 152 int n=*(int*)&_buf[_pos];
nuclear@0 153 _pos+=4;
nuclear@0 154 return n;
nuclear@0 155 }
nuclear@0 156 Fail( "EOF" );
nuclear@0 157 return 0;
nuclear@0 158 }
nuclear@0 159
nuclear@0 160 // ------------------------------------------------------------------------------------------------
nuclear@0 161 float B3DImporter::ReadFloat(){
nuclear@0 162 if( _pos+4<=_buf.size() ){
nuclear@0 163 float n=*(float*)&_buf[_pos];
nuclear@0 164 _pos+=4;
nuclear@0 165 return n;
nuclear@0 166 }
nuclear@0 167 Fail( "EOF" );
nuclear@0 168 return 0.0f;
nuclear@0 169 }
nuclear@0 170
nuclear@0 171 // ------------------------------------------------------------------------------------------------
nuclear@0 172 aiVector2D B3DImporter::ReadVec2(){
nuclear@0 173 float x=ReadFloat();
nuclear@0 174 float y=ReadFloat();
nuclear@0 175 return aiVector2D( x,y );
nuclear@0 176 }
nuclear@0 177
nuclear@0 178 // ------------------------------------------------------------------------------------------------
nuclear@0 179 aiVector3D B3DImporter::ReadVec3(){
nuclear@0 180 float x=ReadFloat();
nuclear@0 181 float y=ReadFloat();
nuclear@0 182 float z=ReadFloat();
nuclear@0 183 return aiVector3D( x,y,z );
nuclear@0 184 }
nuclear@0 185
nuclear@0 186 // ------------------------------------------------------------------------------------------------
nuclear@0 187 aiQuaternion B3DImporter::ReadQuat(){
nuclear@0 188 // (aramis_acg) Fix to adapt the loader to changed quat orientation
nuclear@0 189 float w=-ReadFloat();
nuclear@0 190 float x=ReadFloat();
nuclear@0 191 float y=ReadFloat();
nuclear@0 192 float z=ReadFloat();
nuclear@0 193 return aiQuaternion( w,x,y,z );
nuclear@0 194 }
nuclear@0 195
nuclear@0 196 // ------------------------------------------------------------------------------------------------
nuclear@0 197 string B3DImporter::ReadString(){
nuclear@0 198 string str;
nuclear@0 199 while( _pos<_buf.size() ){
nuclear@0 200 char c=(char)ReadByte();
nuclear@0 201 if( !c ) return str;
nuclear@0 202 str+=c;
nuclear@0 203 }
nuclear@0 204 Fail( "EOF" );
nuclear@0 205 return string();
nuclear@0 206 }
nuclear@0 207
nuclear@0 208 // ------------------------------------------------------------------------------------------------
nuclear@0 209 string B3DImporter::ReadChunk(){
nuclear@0 210 string tag;
nuclear@0 211 for( int i=0;i<4;++i ){
nuclear@0 212 tag+=char( ReadByte() );
nuclear@0 213 }
nuclear@0 214 #ifdef DEBUG_B3D
nuclear@0 215 // cout<<"ReadChunk:"<<tag<<endl;
nuclear@0 216 #endif
nuclear@0 217 unsigned sz=(unsigned)ReadInt();
nuclear@0 218 _stack.push_back( _pos+sz );
nuclear@0 219 return tag;
nuclear@0 220 }
nuclear@0 221
nuclear@0 222 // ------------------------------------------------------------------------------------------------
nuclear@0 223 void B3DImporter::ExitChunk(){
nuclear@0 224 _pos=_stack.back();
nuclear@0 225 _stack.pop_back();
nuclear@0 226 }
nuclear@0 227
nuclear@0 228 // ------------------------------------------------------------------------------------------------
nuclear@0 229 unsigned B3DImporter::ChunkSize(){
nuclear@0 230 return _stack.back()-_pos;
nuclear@0 231 }
nuclear@0 232 // ------------------------------------------------------------------------------------------------
nuclear@0 233
nuclear@0 234 template<class T>
nuclear@0 235 T *B3DImporter::to_array( const vector<T> &v ){
nuclear@0 236 if( !v.size() ) return 0;
nuclear@0 237 T *p=new T[v.size()];
nuclear@0 238 for( size_t i=0;i<v.size();++i ){
nuclear@0 239 p[i]=v[i];
nuclear@0 240 }
nuclear@0 241 return p;
nuclear@0 242 }
nuclear@0 243
nuclear@0 244 // ------------------------------------------------------------------------------------------------
nuclear@0 245 void B3DImporter::ReadTEXS(){
nuclear@0 246 while( ChunkSize() ){
nuclear@0 247 string name=ReadString();
nuclear@0 248 /*int flags=*/ReadInt();
nuclear@0 249 /*int blend=*/ReadInt();
nuclear@0 250 /*aiVector2D pos=*/ReadVec2();
nuclear@0 251 /*aiVector2D scale=*/ReadVec2();
nuclear@0 252 /*float rot=*/ReadFloat();
nuclear@0 253
nuclear@0 254 _textures.push_back( name );
nuclear@0 255 }
nuclear@0 256 }
nuclear@0 257
nuclear@0 258 // ------------------------------------------------------------------------------------------------
nuclear@0 259 void B3DImporter::ReadBRUS(){
nuclear@0 260 int n_texs=ReadInt();
nuclear@0 261 if( n_texs<0 || n_texs>8 ){
nuclear@0 262 Fail( "Bad texture count" );
nuclear@0 263 }
nuclear@0 264 while( ChunkSize() ){
nuclear@0 265 string name=ReadString();
nuclear@0 266 aiVector3D color=ReadVec3();
nuclear@0 267 float alpha=ReadFloat();
nuclear@0 268 float shiny=ReadFloat();
nuclear@0 269 /*int blend=**/ReadInt();
nuclear@0 270 int fx=ReadInt();
nuclear@0 271
nuclear@0 272 aiMaterial *mat=new aiMaterial;
nuclear@0 273 _materials.push_back( mat );
nuclear@0 274
nuclear@0 275 // Name
nuclear@0 276 aiString ainame( name );
nuclear@0 277 mat->AddProperty( &ainame,AI_MATKEY_NAME );
nuclear@0 278
nuclear@0 279 // Diffuse color
nuclear@0 280 mat->AddProperty( &color,1,AI_MATKEY_COLOR_DIFFUSE );
nuclear@0 281
nuclear@0 282 // Opacity
nuclear@0 283 mat->AddProperty( &alpha,1,AI_MATKEY_OPACITY );
nuclear@0 284
nuclear@0 285 // Specular color
nuclear@0 286 aiColor3D speccolor( shiny,shiny,shiny );
nuclear@0 287 mat->AddProperty( &speccolor,1,AI_MATKEY_COLOR_SPECULAR );
nuclear@0 288
nuclear@0 289 // Specular power
nuclear@0 290 float specpow=shiny*128;
nuclear@0 291 mat->AddProperty( &specpow,1,AI_MATKEY_SHININESS );
nuclear@0 292
nuclear@0 293 // Double sided
nuclear@0 294 if( fx & 0x10 ){
nuclear@0 295 int i=1;
nuclear@0 296 mat->AddProperty( &i,1,AI_MATKEY_TWOSIDED );
nuclear@0 297 }
nuclear@0 298
nuclear@0 299 //Textures
nuclear@0 300 for( int i=0;i<n_texs;++i ){
nuclear@0 301 int texid=ReadInt();
nuclear@0 302 if( texid<-1 || (texid>=0 && texid>=static_cast<int>(_textures.size())) ){
nuclear@0 303 Fail( "Bad texture id" );
nuclear@0 304 }
nuclear@0 305 if( i==0 && texid>=0 ){
nuclear@0 306 aiString texname( _textures[texid] );
nuclear@0 307 mat->AddProperty( &texname,AI_MATKEY_TEXTURE_DIFFUSE(0) );
nuclear@0 308 }
nuclear@0 309 }
nuclear@0 310 }
nuclear@0 311 }
nuclear@0 312
nuclear@0 313 // ------------------------------------------------------------------------------------------------
nuclear@0 314 void B3DImporter::ReadVRTS(){
nuclear@0 315 _vflags=ReadInt();
nuclear@0 316 _tcsets=ReadInt();
nuclear@0 317 _tcsize=ReadInt();
nuclear@0 318 if( _tcsets<0 || _tcsets>4 || _tcsize<0 || _tcsize>4 ){
nuclear@0 319 Fail( "Bad texcoord data" );
nuclear@0 320 }
nuclear@0 321
nuclear@0 322 int sz=12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
nuclear@0 323 int n_verts=ChunkSize()/sz;
nuclear@0 324
nuclear@0 325 int v0=_vertices.size();
nuclear@0 326 _vertices.resize( v0+n_verts );
nuclear@0 327
nuclear@0 328 for( int i=0;i<n_verts;++i ){
nuclear@0 329 Vertex &v=_vertices[v0+i];
nuclear@0 330
nuclear@0 331 memset( v.bones,0,sizeof(v.bones) );
nuclear@0 332 memset( v.weights,0,sizeof(v.weights) );
nuclear@0 333
nuclear@0 334 v.vertex=ReadVec3();
nuclear@0 335
nuclear@0 336 if( _vflags & 1 ) v.normal=ReadVec3();
nuclear@0 337
nuclear@0 338 if( _vflags & 2 ) ReadQuat(); //skip v 4bytes...
nuclear@0 339
nuclear@0 340 for( int i=0;i<_tcsets;++i ){
nuclear@0 341 float t[4]={0,0,0,0};
nuclear@0 342 for( int j=0;j<_tcsize;++j ){
nuclear@0 343 t[j]=ReadFloat();
nuclear@0 344 }
nuclear@0 345 t[1]=1-t[1];
nuclear@0 346 if( !i ) v.texcoords=aiVector3D( t[0],t[1],t[2] );
nuclear@0 347 }
nuclear@0 348 }
nuclear@0 349 }
nuclear@0 350
nuclear@0 351 // ------------------------------------------------------------------------------------------------
nuclear@0 352 void B3DImporter::ReadTRIS( int v0 ){
nuclear@0 353 int matid=ReadInt();
nuclear@0 354 if( matid==-1 ){
nuclear@0 355 matid=0;
nuclear@0 356 }else if( matid<0 || matid>=(int)_materials.size() ){
nuclear@0 357 #ifdef DEBUG_B3D
nuclear@0 358 cout<<"material id="<<matid<<endl;
nuclear@0 359 #endif
nuclear@0 360 Fail( "Bad material id" );
nuclear@0 361 }
nuclear@0 362
nuclear@0 363 aiMesh *mesh=new aiMesh;
nuclear@0 364 _meshes.push_back( mesh );
nuclear@0 365
nuclear@0 366 mesh->mMaterialIndex=matid;
nuclear@0 367 mesh->mNumFaces=0;
nuclear@0 368 mesh->mPrimitiveTypes=aiPrimitiveType_TRIANGLE;
nuclear@0 369
nuclear@0 370 int n_tris=ChunkSize()/12;
nuclear@0 371 aiFace *face=mesh->mFaces=new aiFace[n_tris];
nuclear@0 372
nuclear@0 373 for( int i=0;i<n_tris;++i ){
nuclear@0 374 int i0=ReadInt()+v0;
nuclear@0 375 int i1=ReadInt()+v0;
nuclear@0 376 int i2=ReadInt()+v0;
nuclear@0 377 if( i0<0 || i0>=(int)_vertices.size() || i1<0 || i1>=(int)_vertices.size() || i2<0 || i2>=(int)_vertices.size() ){
nuclear@0 378 #ifdef DEBUG_B3D
nuclear@0 379 cout<<"Bad triangle index: i0="<<i0<<", i1="<<i1<<", i2="<<i2<<endl;
nuclear@0 380 #endif
nuclear@0 381 Fail( "Bad triangle index" );
nuclear@0 382 continue;
nuclear@0 383 }
nuclear@0 384 face->mNumIndices=3;
nuclear@0 385 face->mIndices=new unsigned[3];
nuclear@0 386 face->mIndices[0]=i0;
nuclear@0 387 face->mIndices[1]=i1;
nuclear@0 388 face->mIndices[2]=i2;
nuclear@0 389 ++mesh->mNumFaces;
nuclear@0 390 ++face;
nuclear@0 391 }
nuclear@0 392 }
nuclear@0 393
nuclear@0 394 // ------------------------------------------------------------------------------------------------
nuclear@0 395 void B3DImporter::ReadMESH(){
nuclear@0 396 /*int matid=*/ReadInt();
nuclear@0 397
nuclear@0 398 int v0=_vertices.size();
nuclear@0 399
nuclear@0 400 while( ChunkSize() ){
nuclear@0 401 string t=ReadChunk();
nuclear@0 402 if( t=="VRTS" ){
nuclear@0 403 ReadVRTS();
nuclear@0 404 }else if( t=="TRIS" ){
nuclear@0 405 ReadTRIS( v0 );
nuclear@0 406 }
nuclear@0 407 ExitChunk();
nuclear@0 408 }
nuclear@0 409 }
nuclear@0 410
nuclear@0 411 // ------------------------------------------------------------------------------------------------
nuclear@0 412 void B3DImporter::ReadBONE( int id ){
nuclear@0 413 while( ChunkSize() ){
nuclear@0 414 int vertex=ReadInt();
nuclear@0 415 float weight=ReadFloat();
nuclear@0 416 if( vertex<0 || vertex>=(int)_vertices.size() ){
nuclear@0 417 Fail( "Bad vertex index" );
nuclear@0 418 }
nuclear@0 419
nuclear@0 420 Vertex &v=_vertices[vertex];
nuclear@0 421 int i;
nuclear@0 422 for( i=0;i<4;++i ){
nuclear@0 423 if( !v.weights[i] ){
nuclear@0 424 v.bones[i]=id;
nuclear@0 425 v.weights[i]=weight;
nuclear@0 426 break;
nuclear@0 427 }
nuclear@0 428 }
nuclear@0 429 #ifdef DEBUG_B3D
nuclear@0 430 if( i==4 ){
nuclear@0 431 cout<<"Too many bone weights"<<endl;
nuclear@0 432 }
nuclear@0 433 #endif
nuclear@0 434 }
nuclear@0 435 }
nuclear@0 436
nuclear@0 437 // ------------------------------------------------------------------------------------------------
nuclear@0 438 void B3DImporter::ReadKEYS( aiNodeAnim *nodeAnim ){
nuclear@0 439 vector<aiVectorKey> trans,scale;
nuclear@0 440 vector<aiQuatKey> rot;
nuclear@0 441 int flags=ReadInt();
nuclear@0 442 while( ChunkSize() ){
nuclear@0 443 int frame=ReadInt();
nuclear@0 444 if( flags & 1 ){
nuclear@0 445 trans.push_back( aiVectorKey( frame,ReadVec3() ) );
nuclear@0 446 }
nuclear@0 447 if( flags & 2 ){
nuclear@0 448 scale.push_back( aiVectorKey( frame,ReadVec3() ) );
nuclear@0 449 }
nuclear@0 450 if( flags & 4 ){
nuclear@0 451 rot.push_back( aiQuatKey( frame,ReadQuat() ) );
nuclear@0 452 }
nuclear@0 453 }
nuclear@0 454
nuclear@0 455 if( flags & 1 ){
nuclear@0 456 nodeAnim->mNumPositionKeys=trans.size();
nuclear@0 457 nodeAnim->mPositionKeys=to_array( trans );
nuclear@0 458 }
nuclear@0 459
nuclear@0 460 if( flags & 2 ){
nuclear@0 461 nodeAnim->mNumScalingKeys=scale.size();
nuclear@0 462 nodeAnim->mScalingKeys=to_array( scale );
nuclear@0 463 }
nuclear@0 464
nuclear@0 465 if( flags & 4 ){
nuclear@0 466 nodeAnim->mNumRotationKeys=rot.size();
nuclear@0 467 nodeAnim->mRotationKeys=to_array( rot );
nuclear@0 468 }
nuclear@0 469 }
nuclear@0 470
nuclear@0 471 // ------------------------------------------------------------------------------------------------
nuclear@0 472 void B3DImporter::ReadANIM(){
nuclear@0 473 /*int flags=*/ReadInt();
nuclear@0 474 int frames=ReadInt();
nuclear@0 475 float fps=ReadFloat();
nuclear@0 476
nuclear@0 477 aiAnimation *anim=new aiAnimation;
nuclear@0 478 _animations.push_back( anim );
nuclear@0 479
nuclear@0 480 anim->mDuration=frames;
nuclear@0 481 anim->mTicksPerSecond=fps;
nuclear@0 482 }
nuclear@0 483
nuclear@0 484 // ------------------------------------------------------------------------------------------------
nuclear@0 485 aiNode *B3DImporter::ReadNODE( aiNode *parent ){
nuclear@0 486
nuclear@0 487 string name=ReadString();
nuclear@0 488 aiVector3D t=ReadVec3();
nuclear@0 489 aiVector3D s=ReadVec3();
nuclear@0 490 aiQuaternion r=ReadQuat();
nuclear@0 491
nuclear@0 492 aiMatrix4x4 trans,scale,rot;
nuclear@0 493
nuclear@0 494 aiMatrix4x4::Translation( t,trans );
nuclear@0 495 aiMatrix4x4::Scaling( s,scale );
nuclear@0 496 rot=aiMatrix4x4( r.GetMatrix() );
nuclear@0 497
nuclear@0 498 aiMatrix4x4 tform=trans * rot * scale;
nuclear@0 499
nuclear@0 500 int nodeid=_nodes.size();
nuclear@0 501
nuclear@0 502 aiNode *node=new aiNode( name );
nuclear@0 503 _nodes.push_back( node );
nuclear@0 504
nuclear@0 505 node->mParent=parent;
nuclear@0 506 node->mTransformation=tform;
nuclear@0 507
nuclear@0 508 aiNodeAnim *nodeAnim=0;
nuclear@0 509 vector<unsigned> meshes;
nuclear@0 510 vector<aiNode*> children;
nuclear@0 511
nuclear@0 512 while( ChunkSize() ){
nuclear@0 513 string t=ReadChunk();
nuclear@0 514 if( t=="MESH" ){
nuclear@0 515 int n=_meshes.size();
nuclear@0 516 ReadMESH();
nuclear@0 517 for( int i=n;i<(int)_meshes.size();++i ){
nuclear@0 518 meshes.push_back( i );
nuclear@0 519 }
nuclear@0 520 }else if( t=="BONE" ){
nuclear@0 521 ReadBONE( nodeid );
nuclear@0 522 }else if( t=="ANIM" ){
nuclear@0 523 ReadANIM();
nuclear@0 524 }else if( t=="KEYS" ){
nuclear@0 525 if( !nodeAnim ){
nuclear@0 526 nodeAnim=new aiNodeAnim;
nuclear@0 527 _nodeAnims.push_back( nodeAnim );
nuclear@0 528 nodeAnim->mNodeName=node->mName;
nuclear@0 529 }
nuclear@0 530 ReadKEYS( nodeAnim );
nuclear@0 531 }else if( t=="NODE" ){
nuclear@0 532 aiNode *child=ReadNODE( node );
nuclear@0 533 children.push_back( child );
nuclear@0 534 }
nuclear@0 535 ExitChunk();
nuclear@0 536 }
nuclear@0 537
nuclear@0 538 node->mNumMeshes=meshes.size();
nuclear@0 539 node->mMeshes=to_array( meshes );
nuclear@0 540
nuclear@0 541 node->mNumChildren=children.size();
nuclear@0 542 node->mChildren=to_array( children );
nuclear@0 543
nuclear@0 544 return node;
nuclear@0 545 }
nuclear@0 546
nuclear@0 547 // ------------------------------------------------------------------------------------------------
nuclear@0 548 void B3DImporter::ReadBB3D( aiScene *scene ){
nuclear@0 549
nuclear@0 550 _textures.clear();
nuclear@0 551 _materials.size();
nuclear@0 552
nuclear@0 553 _vertices.clear();
nuclear@0 554 _meshes.clear();
nuclear@0 555
nuclear@0 556 _nodes.clear();
nuclear@0 557 _nodeAnims.clear();
nuclear@0 558 _animations.clear();
nuclear@0 559
nuclear@0 560 string t=ReadChunk();
nuclear@0 561 if( t=="BB3D" ){
nuclear@0 562 int version=ReadInt();
nuclear@0 563
nuclear@0 564 if (!DefaultLogger::isNullLogger()) {
nuclear@0 565 char dmp[128];
nuclear@0 566 sprintf(dmp,"B3D file format version: %i",version);
nuclear@0 567 DefaultLogger::get()->info(dmp);
nuclear@0 568 }
nuclear@0 569
nuclear@0 570 while( ChunkSize() ){
nuclear@0 571 string t=ReadChunk();
nuclear@0 572 if( t=="TEXS" ){
nuclear@0 573 ReadTEXS();
nuclear@0 574 }else if( t=="BRUS" ){
nuclear@0 575 ReadBRUS();
nuclear@0 576 }else if( t=="NODE" ){
nuclear@0 577 ReadNODE( 0 );
nuclear@0 578 }
nuclear@0 579 ExitChunk();
nuclear@0 580 }
nuclear@0 581 }
nuclear@0 582 ExitChunk();
nuclear@0 583
nuclear@0 584 if( !_nodes.size() ) Fail( "No nodes" );
nuclear@0 585
nuclear@0 586 if( !_meshes.size() ) Fail( "No meshes" );
nuclear@0 587
nuclear@0 588 //Fix nodes/meshes/bones
nuclear@0 589 for(size_t i=0;i<_nodes.size();++i ){
nuclear@0 590 aiNode *node=_nodes[i];
nuclear@0 591
nuclear@0 592 for( size_t j=0;j<node->mNumMeshes;++j ){
nuclear@0 593 aiMesh *mesh=_meshes[node->mMeshes[j]];
nuclear@0 594
nuclear@0 595 int n_tris=mesh->mNumFaces;
nuclear@0 596 int n_verts=mesh->mNumVertices=n_tris * 3;
nuclear@0 597
nuclear@0 598 aiVector3D *mv=mesh->mVertices=new aiVector3D[ n_verts ],*mn=0,*mc=0;
nuclear@0 599 if( _vflags & 1 ) mn=mesh->mNormals=new aiVector3D[ n_verts ];
nuclear@0 600 if( _tcsets ) mc=mesh->mTextureCoords[0]=new aiVector3D[ n_verts ];
nuclear@0 601
nuclear@0 602 aiFace *face=mesh->mFaces;
nuclear@0 603
nuclear@0 604 vector< vector<aiVertexWeight> > vweights( _nodes.size() );
nuclear@0 605
nuclear@0 606 for( int i=0;i<n_verts;i+=3 ){
nuclear@0 607 for( int j=0;j<3;++j ){
nuclear@0 608 Vertex &v=_vertices[face->mIndices[j]];
nuclear@0 609
nuclear@0 610 *mv++=v.vertex;
nuclear@0 611 if( mn ) *mn++=v.normal;
nuclear@0 612 if( mc ) *mc++=v.texcoords;
nuclear@0 613
nuclear@0 614 face->mIndices[j]=i+j;
nuclear@0 615
nuclear@0 616 for( int k=0;k<4;++k ){
nuclear@0 617 if( !v.weights[k] ) break;
nuclear@0 618
nuclear@0 619 int bone=v.bones[k];
nuclear@0 620 float weight=v.weights[k];
nuclear@0 621
nuclear@0 622 vweights[bone].push_back( aiVertexWeight(i+j,weight) );
nuclear@0 623 }
nuclear@0 624 }
nuclear@0 625 ++face;
nuclear@0 626 }
nuclear@0 627
nuclear@0 628 vector<aiBone*> bones;
nuclear@0 629 for(size_t i=0;i<vweights.size();++i ){
nuclear@0 630 vector<aiVertexWeight> &weights=vweights[i];
nuclear@0 631 if( !weights.size() ) continue;
nuclear@0 632
nuclear@0 633 aiBone *bone=new aiBone;
nuclear@0 634 bones.push_back( bone );
nuclear@0 635
nuclear@0 636 aiNode *bnode=_nodes[i];
nuclear@0 637
nuclear@0 638 bone->mName=bnode->mName;
nuclear@0 639 bone->mNumWeights=weights.size();
nuclear@0 640 bone->mWeights=to_array( weights );
nuclear@0 641
nuclear@0 642 aiMatrix4x4 mat=bnode->mTransformation;
nuclear@0 643 while( bnode->mParent ){
nuclear@0 644 bnode=bnode->mParent;
nuclear@0 645 mat=bnode->mTransformation * mat;
nuclear@0 646 }
nuclear@0 647 bone->mOffsetMatrix=mat.Inverse();
nuclear@0 648 }
nuclear@0 649 mesh->mNumBones=bones.size();
nuclear@0 650 mesh->mBones=to_array( bones );
nuclear@0 651 }
nuclear@0 652 }
nuclear@0 653
nuclear@0 654 //nodes
nuclear@0 655 scene->mRootNode=_nodes[0];
nuclear@0 656
nuclear@0 657 //material
nuclear@0 658 if( !_materials.size() ){
nuclear@0 659 _materials.push_back( new aiMaterial );
nuclear@0 660 }
nuclear@0 661 scene->mNumMaterials=_materials.size();
nuclear@0 662 scene->mMaterials=to_array( _materials );
nuclear@0 663
nuclear@0 664 //meshes
nuclear@0 665 scene->mNumMeshes=_meshes.size();
nuclear@0 666 scene->mMeshes=to_array( _meshes );
nuclear@0 667
nuclear@0 668 //animations
nuclear@0 669 if( _animations.size()==1 && _nodeAnims.size() ){
nuclear@0 670
nuclear@0 671 aiAnimation *anim=_animations.back();
nuclear@0 672 anim->mNumChannels=_nodeAnims.size();
nuclear@0 673 anim->mChannels=to_array( _nodeAnims );
nuclear@0 674
nuclear@0 675 scene->mNumAnimations=_animations.size();
nuclear@0 676 scene->mAnimations=to_array( _animations );
nuclear@0 677 }
nuclear@0 678
nuclear@0 679 // convert to RH
nuclear@0 680 MakeLeftHandedProcess makeleft;
nuclear@0 681 makeleft.Execute( scene );
nuclear@0 682
nuclear@0 683 FlipWindingOrderProcess flip;
nuclear@0 684 flip.Execute( scene );
nuclear@0 685 }
nuclear@0 686
nuclear@0 687 #endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER