vrshoot
diff libs/assimp/B3DImporter.cpp @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/B3DImporter.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,687 @@ 1.4 +/* 1.5 +--------------------------------------------------------------------------- 1.6 +Open Asset Import Library (assimp) 1.7 +--------------------------------------------------------------------------- 1.8 + 1.9 +Copyright (c) 2006-2012, assimp team 1.10 + 1.11 +All rights reserved. 1.12 + 1.13 +Redistribution and use of this software in source and binary forms, 1.14 +with or without modification, are permitted provided that the following 1.15 +conditions are met: 1.16 + 1.17 +* Redistributions of source code must retain the above 1.18 + copyright notice, this list of conditions and the 1.19 + following disclaimer. 1.20 + 1.21 +* Redistributions in binary form must reproduce the above 1.22 + copyright notice, this list of conditions and the 1.23 + following disclaimer in the documentation and/or other 1.24 + materials provided with the distribution. 1.25 + 1.26 +* Neither the name of the assimp team, nor the names of its 1.27 + contributors may be used to endorse or promote products 1.28 + derived from this software without specific prior 1.29 + written permission of the assimp team. 1.30 + 1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.42 +--------------------------------------------------------------------------- 1.43 +*/ 1.44 + 1.45 +/** @file B3DImporter.cpp 1.46 + * @brief Implementation of the b3d importer class 1.47 + */ 1.48 + 1.49 +#include "AssimpPCH.h" 1.50 +#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER 1.51 + 1.52 +// internal headers 1.53 +#include "B3DImporter.h" 1.54 +#include "TextureTransform.h" 1.55 +#include "ConvertToLHProcess.h" 1.56 + 1.57 +using namespace Assimp; 1.58 +using namespace std; 1.59 + 1.60 +static const aiImporterDesc desc = { 1.61 + "BlitzBasic 3D Importer", 1.62 + "", 1.63 + "", 1.64 + "http://www.blitzbasic.com/", 1.65 + aiImporterFlags_SupportBinaryFlavour, 1.66 + 0, 1.67 + 0, 1.68 + 0, 1.69 + 0, 1.70 + "b3d" 1.71 +}; 1.72 + 1.73 +// (fixme, Aramis) quick workaround to get rid of all those signed to unsigned warnings 1.74 +#ifdef _MSC_VER 1.75 +# pragma warning (disable: 4018) 1.76 +#endif 1.77 + 1.78 +//#define DEBUG_B3D 1.79 + 1.80 +// ------------------------------------------------------------------------------------------------ 1.81 +bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const{ 1.82 + 1.83 + size_t pos=pFile.find_last_of( '.' ); 1.84 + if( pos==string::npos ) return false; 1.85 + 1.86 + string ext=pFile.substr( pos+1 ); 1.87 + if( ext.size()!=3 ) return false; 1.88 + 1.89 + return (ext[0]=='b' || ext[0]=='B') && (ext[1]=='3') && (ext[2]=='d' || ext[2]=='D'); 1.90 +} 1.91 + 1.92 +// ------------------------------------------------------------------------------------------------ 1.93 +// Loader meta information 1.94 +const aiImporterDesc* B3DImporter::GetInfo () const 1.95 +{ 1.96 + return &desc; 1.97 +} 1.98 + 1.99 +#ifdef DEBUG_B3D 1.100 + extern "C"{ void _stdcall AllocConsole(); } 1.101 +#endif 1.102 +// ------------------------------------------------------------------------------------------------ 1.103 +void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler){ 1.104 + 1.105 +#ifdef DEBUG_B3D 1.106 + AllocConsole(); 1.107 + freopen( "conin$","r",stdin ); 1.108 + freopen( "conout$","w",stdout ); 1.109 + freopen( "conout$","w",stderr ); 1.110 + cout<<"Hello world from the B3DImporter!"<<endl; 1.111 +#endif 1.112 + 1.113 + boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile)); 1.114 + 1.115 + // Check whether we can read from the file 1.116 + if( file.get() == NULL) 1.117 + throw DeadlyImportError( "Failed to open B3D file " + pFile + "."); 1.118 + 1.119 + // check whether the .b3d file is large enough to contain 1.120 + // at least one chunk. 1.121 + size_t fileSize = file->FileSize(); 1.122 + if( fileSize<8 ) throw DeadlyImportError( "B3D File is too small."); 1.123 + 1.124 + _pos=0; 1.125 + _buf.resize( fileSize ); 1.126 + file->Read( &_buf[0],1,fileSize ); 1.127 + _stack.clear(); 1.128 + 1.129 + ReadBB3D( pScene ); 1.130 +} 1.131 + 1.132 +// ------------------------------------------------------------------------------------------------ 1.133 +void B3DImporter::Oops(){ 1.134 + throw DeadlyImportError( "B3D Importer - INTERNAL ERROR" ); 1.135 +} 1.136 + 1.137 +// ------------------------------------------------------------------------------------------------ 1.138 +void B3DImporter::Fail( string str ){ 1.139 +#ifdef DEBUG_B3D 1.140 + cout<<"Error in B3D file data: "<<str<<endl; 1.141 +#endif 1.142 + throw DeadlyImportError( "B3D Importer - error in B3D file data: "+str ); 1.143 +} 1.144 + 1.145 +// ------------------------------------------------------------------------------------------------ 1.146 +int B3DImporter::ReadByte(){ 1.147 + if( _pos<_buf.size() ) return _buf[_pos++]; 1.148 + Fail( "EOF" ); 1.149 + return 0; 1.150 +} 1.151 + 1.152 +// ------------------------------------------------------------------------------------------------ 1.153 +int B3DImporter::ReadInt(){ 1.154 + if( _pos+4<=_buf.size() ){ 1.155 + int n=*(int*)&_buf[_pos]; 1.156 + _pos+=4; 1.157 + return n; 1.158 + } 1.159 + Fail( "EOF" ); 1.160 + return 0; 1.161 +} 1.162 + 1.163 +// ------------------------------------------------------------------------------------------------ 1.164 +float B3DImporter::ReadFloat(){ 1.165 + if( _pos+4<=_buf.size() ){ 1.166 + float n=*(float*)&_buf[_pos]; 1.167 + _pos+=4; 1.168 + return n; 1.169 + } 1.170 + Fail( "EOF" ); 1.171 + return 0.0f; 1.172 +} 1.173 + 1.174 +// ------------------------------------------------------------------------------------------------ 1.175 +aiVector2D B3DImporter::ReadVec2(){ 1.176 + float x=ReadFloat(); 1.177 + float y=ReadFloat(); 1.178 + return aiVector2D( x,y ); 1.179 +} 1.180 + 1.181 +// ------------------------------------------------------------------------------------------------ 1.182 +aiVector3D B3DImporter::ReadVec3(){ 1.183 + float x=ReadFloat(); 1.184 + float y=ReadFloat(); 1.185 + float z=ReadFloat(); 1.186 + return aiVector3D( x,y,z ); 1.187 +} 1.188 + 1.189 +// ------------------------------------------------------------------------------------------------ 1.190 +aiQuaternion B3DImporter::ReadQuat(){ 1.191 + // (aramis_acg) Fix to adapt the loader to changed quat orientation 1.192 + float w=-ReadFloat(); 1.193 + float x=ReadFloat(); 1.194 + float y=ReadFloat(); 1.195 + float z=ReadFloat(); 1.196 + return aiQuaternion( w,x,y,z ); 1.197 +} 1.198 + 1.199 +// ------------------------------------------------------------------------------------------------ 1.200 +string B3DImporter::ReadString(){ 1.201 + string str; 1.202 + while( _pos<_buf.size() ){ 1.203 + char c=(char)ReadByte(); 1.204 + if( !c ) return str; 1.205 + str+=c; 1.206 + } 1.207 + Fail( "EOF" ); 1.208 + return string(); 1.209 +} 1.210 + 1.211 +// ------------------------------------------------------------------------------------------------ 1.212 +string B3DImporter::ReadChunk(){ 1.213 + string tag; 1.214 + for( int i=0;i<4;++i ){ 1.215 + tag+=char( ReadByte() ); 1.216 + } 1.217 +#ifdef DEBUG_B3D 1.218 +// cout<<"ReadChunk:"<<tag<<endl; 1.219 +#endif 1.220 + unsigned sz=(unsigned)ReadInt(); 1.221 + _stack.push_back( _pos+sz ); 1.222 + return tag; 1.223 +} 1.224 + 1.225 +// ------------------------------------------------------------------------------------------------ 1.226 +void B3DImporter::ExitChunk(){ 1.227 + _pos=_stack.back(); 1.228 + _stack.pop_back(); 1.229 +} 1.230 + 1.231 +// ------------------------------------------------------------------------------------------------ 1.232 +unsigned B3DImporter::ChunkSize(){ 1.233 + return _stack.back()-_pos; 1.234 +} 1.235 +// ------------------------------------------------------------------------------------------------ 1.236 + 1.237 +template<class T> 1.238 +T *B3DImporter::to_array( const vector<T> &v ){ 1.239 + if( !v.size() ) return 0; 1.240 + T *p=new T[v.size()]; 1.241 + for( size_t i=0;i<v.size();++i ){ 1.242 + p[i]=v[i]; 1.243 + } 1.244 + return p; 1.245 +} 1.246 + 1.247 +// ------------------------------------------------------------------------------------------------ 1.248 +void B3DImporter::ReadTEXS(){ 1.249 + while( ChunkSize() ){ 1.250 + string name=ReadString(); 1.251 + /*int flags=*/ReadInt(); 1.252 + /*int blend=*/ReadInt(); 1.253 + /*aiVector2D pos=*/ReadVec2(); 1.254 + /*aiVector2D scale=*/ReadVec2(); 1.255 + /*float rot=*/ReadFloat(); 1.256 + 1.257 + _textures.push_back( name ); 1.258 + } 1.259 +} 1.260 + 1.261 +// ------------------------------------------------------------------------------------------------ 1.262 +void B3DImporter::ReadBRUS(){ 1.263 + int n_texs=ReadInt(); 1.264 + if( n_texs<0 || n_texs>8 ){ 1.265 + Fail( "Bad texture count" ); 1.266 + } 1.267 + while( ChunkSize() ){ 1.268 + string name=ReadString(); 1.269 + aiVector3D color=ReadVec3(); 1.270 + float alpha=ReadFloat(); 1.271 + float shiny=ReadFloat(); 1.272 + /*int blend=**/ReadInt(); 1.273 + int fx=ReadInt(); 1.274 + 1.275 + aiMaterial *mat=new aiMaterial; 1.276 + _materials.push_back( mat ); 1.277 + 1.278 + // Name 1.279 + aiString ainame( name ); 1.280 + mat->AddProperty( &ainame,AI_MATKEY_NAME ); 1.281 + 1.282 + // Diffuse color 1.283 + mat->AddProperty( &color,1,AI_MATKEY_COLOR_DIFFUSE ); 1.284 + 1.285 + // Opacity 1.286 + mat->AddProperty( &alpha,1,AI_MATKEY_OPACITY ); 1.287 + 1.288 + // Specular color 1.289 + aiColor3D speccolor( shiny,shiny,shiny ); 1.290 + mat->AddProperty( &speccolor,1,AI_MATKEY_COLOR_SPECULAR ); 1.291 + 1.292 + // Specular power 1.293 + float specpow=shiny*128; 1.294 + mat->AddProperty( &specpow,1,AI_MATKEY_SHININESS ); 1.295 + 1.296 + // Double sided 1.297 + if( fx & 0x10 ){ 1.298 + int i=1; 1.299 + mat->AddProperty( &i,1,AI_MATKEY_TWOSIDED ); 1.300 + } 1.301 + 1.302 + //Textures 1.303 + for( int i=0;i<n_texs;++i ){ 1.304 + int texid=ReadInt(); 1.305 + if( texid<-1 || (texid>=0 && texid>=static_cast<int>(_textures.size())) ){ 1.306 + Fail( "Bad texture id" ); 1.307 + } 1.308 + if( i==0 && texid>=0 ){ 1.309 + aiString texname( _textures[texid] ); 1.310 + mat->AddProperty( &texname,AI_MATKEY_TEXTURE_DIFFUSE(0) ); 1.311 + } 1.312 + } 1.313 + } 1.314 +} 1.315 + 1.316 +// ------------------------------------------------------------------------------------------------ 1.317 +void B3DImporter::ReadVRTS(){ 1.318 + _vflags=ReadInt(); 1.319 + _tcsets=ReadInt(); 1.320 + _tcsize=ReadInt(); 1.321 + if( _tcsets<0 || _tcsets>4 || _tcsize<0 || _tcsize>4 ){ 1.322 + Fail( "Bad texcoord data" ); 1.323 + } 1.324 + 1.325 + int sz=12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4); 1.326 + int n_verts=ChunkSize()/sz; 1.327 + 1.328 + int v0=_vertices.size(); 1.329 + _vertices.resize( v0+n_verts ); 1.330 + 1.331 + for( int i=0;i<n_verts;++i ){ 1.332 + Vertex &v=_vertices[v0+i]; 1.333 + 1.334 + memset( v.bones,0,sizeof(v.bones) ); 1.335 + memset( v.weights,0,sizeof(v.weights) ); 1.336 + 1.337 + v.vertex=ReadVec3(); 1.338 + 1.339 + if( _vflags & 1 ) v.normal=ReadVec3(); 1.340 + 1.341 + if( _vflags & 2 ) ReadQuat(); //skip v 4bytes... 1.342 + 1.343 + for( int i=0;i<_tcsets;++i ){ 1.344 + float t[4]={0,0,0,0}; 1.345 + for( int j=0;j<_tcsize;++j ){ 1.346 + t[j]=ReadFloat(); 1.347 + } 1.348 + t[1]=1-t[1]; 1.349 + if( !i ) v.texcoords=aiVector3D( t[0],t[1],t[2] ); 1.350 + } 1.351 + } 1.352 +} 1.353 + 1.354 +// ------------------------------------------------------------------------------------------------ 1.355 +void B3DImporter::ReadTRIS( int v0 ){ 1.356 + int matid=ReadInt(); 1.357 + if( matid==-1 ){ 1.358 + matid=0; 1.359 + }else if( matid<0 || matid>=(int)_materials.size() ){ 1.360 +#ifdef DEBUG_B3D 1.361 + cout<<"material id="<<matid<<endl; 1.362 +#endif 1.363 + Fail( "Bad material id" ); 1.364 + } 1.365 + 1.366 + aiMesh *mesh=new aiMesh; 1.367 + _meshes.push_back( mesh ); 1.368 + 1.369 + mesh->mMaterialIndex=matid; 1.370 + mesh->mNumFaces=0; 1.371 + mesh->mPrimitiveTypes=aiPrimitiveType_TRIANGLE; 1.372 + 1.373 + int n_tris=ChunkSize()/12; 1.374 + aiFace *face=mesh->mFaces=new aiFace[n_tris]; 1.375 + 1.376 + for( int i=0;i<n_tris;++i ){ 1.377 + int i0=ReadInt()+v0; 1.378 + int i1=ReadInt()+v0; 1.379 + int i2=ReadInt()+v0; 1.380 + if( i0<0 || i0>=(int)_vertices.size() || i1<0 || i1>=(int)_vertices.size() || i2<0 || i2>=(int)_vertices.size() ){ 1.381 +#ifdef DEBUG_B3D 1.382 + cout<<"Bad triangle index: i0="<<i0<<", i1="<<i1<<", i2="<<i2<<endl; 1.383 +#endif 1.384 + Fail( "Bad triangle index" ); 1.385 + continue; 1.386 + } 1.387 + face->mNumIndices=3; 1.388 + face->mIndices=new unsigned[3]; 1.389 + face->mIndices[0]=i0; 1.390 + face->mIndices[1]=i1; 1.391 + face->mIndices[2]=i2; 1.392 + ++mesh->mNumFaces; 1.393 + ++face; 1.394 + } 1.395 +} 1.396 + 1.397 +// ------------------------------------------------------------------------------------------------ 1.398 +void B3DImporter::ReadMESH(){ 1.399 + /*int matid=*/ReadInt(); 1.400 + 1.401 + int v0=_vertices.size(); 1.402 + 1.403 + while( ChunkSize() ){ 1.404 + string t=ReadChunk(); 1.405 + if( t=="VRTS" ){ 1.406 + ReadVRTS(); 1.407 + }else if( t=="TRIS" ){ 1.408 + ReadTRIS( v0 ); 1.409 + } 1.410 + ExitChunk(); 1.411 + } 1.412 +} 1.413 + 1.414 +// ------------------------------------------------------------------------------------------------ 1.415 +void B3DImporter::ReadBONE( int id ){ 1.416 + while( ChunkSize() ){ 1.417 + int vertex=ReadInt(); 1.418 + float weight=ReadFloat(); 1.419 + if( vertex<0 || vertex>=(int)_vertices.size() ){ 1.420 + Fail( "Bad vertex index" ); 1.421 + } 1.422 + 1.423 + Vertex &v=_vertices[vertex]; 1.424 + int i; 1.425 + for( i=0;i<4;++i ){ 1.426 + if( !v.weights[i] ){ 1.427 + v.bones[i]=id; 1.428 + v.weights[i]=weight; 1.429 + break; 1.430 + } 1.431 + } 1.432 +#ifdef DEBUG_B3D 1.433 + if( i==4 ){ 1.434 + cout<<"Too many bone weights"<<endl; 1.435 + } 1.436 +#endif 1.437 + } 1.438 +} 1.439 + 1.440 +// ------------------------------------------------------------------------------------------------ 1.441 +void B3DImporter::ReadKEYS( aiNodeAnim *nodeAnim ){ 1.442 + vector<aiVectorKey> trans,scale; 1.443 + vector<aiQuatKey> rot; 1.444 + int flags=ReadInt(); 1.445 + while( ChunkSize() ){ 1.446 + int frame=ReadInt(); 1.447 + if( flags & 1 ){ 1.448 + trans.push_back( aiVectorKey( frame,ReadVec3() ) ); 1.449 + } 1.450 + if( flags & 2 ){ 1.451 + scale.push_back( aiVectorKey( frame,ReadVec3() ) ); 1.452 + } 1.453 + if( flags & 4 ){ 1.454 + rot.push_back( aiQuatKey( frame,ReadQuat() ) ); 1.455 + } 1.456 + } 1.457 + 1.458 + if( flags & 1 ){ 1.459 + nodeAnim->mNumPositionKeys=trans.size(); 1.460 + nodeAnim->mPositionKeys=to_array( trans ); 1.461 + } 1.462 + 1.463 + if( flags & 2 ){ 1.464 + nodeAnim->mNumScalingKeys=scale.size(); 1.465 + nodeAnim->mScalingKeys=to_array( scale ); 1.466 + } 1.467 + 1.468 + if( flags & 4 ){ 1.469 + nodeAnim->mNumRotationKeys=rot.size(); 1.470 + nodeAnim->mRotationKeys=to_array( rot ); 1.471 + } 1.472 +} 1.473 + 1.474 +// ------------------------------------------------------------------------------------------------ 1.475 +void B3DImporter::ReadANIM(){ 1.476 + /*int flags=*/ReadInt(); 1.477 + int frames=ReadInt(); 1.478 + float fps=ReadFloat(); 1.479 + 1.480 + aiAnimation *anim=new aiAnimation; 1.481 + _animations.push_back( anim ); 1.482 + 1.483 + anim->mDuration=frames; 1.484 + anim->mTicksPerSecond=fps; 1.485 +} 1.486 + 1.487 +// ------------------------------------------------------------------------------------------------ 1.488 +aiNode *B3DImporter::ReadNODE( aiNode *parent ){ 1.489 + 1.490 + string name=ReadString(); 1.491 + aiVector3D t=ReadVec3(); 1.492 + aiVector3D s=ReadVec3(); 1.493 + aiQuaternion r=ReadQuat(); 1.494 + 1.495 + aiMatrix4x4 trans,scale,rot; 1.496 + 1.497 + aiMatrix4x4::Translation( t,trans ); 1.498 + aiMatrix4x4::Scaling( s,scale ); 1.499 + rot=aiMatrix4x4( r.GetMatrix() ); 1.500 + 1.501 + aiMatrix4x4 tform=trans * rot * scale; 1.502 + 1.503 + int nodeid=_nodes.size(); 1.504 + 1.505 + aiNode *node=new aiNode( name ); 1.506 + _nodes.push_back( node ); 1.507 + 1.508 + node->mParent=parent; 1.509 + node->mTransformation=tform; 1.510 + 1.511 + aiNodeAnim *nodeAnim=0; 1.512 + vector<unsigned> meshes; 1.513 + vector<aiNode*> children; 1.514 + 1.515 + while( ChunkSize() ){ 1.516 + string t=ReadChunk(); 1.517 + if( t=="MESH" ){ 1.518 + int n=_meshes.size(); 1.519 + ReadMESH(); 1.520 + for( int i=n;i<(int)_meshes.size();++i ){ 1.521 + meshes.push_back( i ); 1.522 + } 1.523 + }else if( t=="BONE" ){ 1.524 + ReadBONE( nodeid ); 1.525 + }else if( t=="ANIM" ){ 1.526 + ReadANIM(); 1.527 + }else if( t=="KEYS" ){ 1.528 + if( !nodeAnim ){ 1.529 + nodeAnim=new aiNodeAnim; 1.530 + _nodeAnims.push_back( nodeAnim ); 1.531 + nodeAnim->mNodeName=node->mName; 1.532 + } 1.533 + ReadKEYS( nodeAnim ); 1.534 + }else if( t=="NODE" ){ 1.535 + aiNode *child=ReadNODE( node ); 1.536 + children.push_back( child ); 1.537 + } 1.538 + ExitChunk(); 1.539 + } 1.540 + 1.541 + node->mNumMeshes=meshes.size(); 1.542 + node->mMeshes=to_array( meshes ); 1.543 + 1.544 + node->mNumChildren=children.size(); 1.545 + node->mChildren=to_array( children ); 1.546 + 1.547 + return node; 1.548 +} 1.549 + 1.550 +// ------------------------------------------------------------------------------------------------ 1.551 +void B3DImporter::ReadBB3D( aiScene *scene ){ 1.552 + 1.553 + _textures.clear(); 1.554 + _materials.size(); 1.555 + 1.556 + _vertices.clear(); 1.557 + _meshes.clear(); 1.558 + 1.559 + _nodes.clear(); 1.560 + _nodeAnims.clear(); 1.561 + _animations.clear(); 1.562 + 1.563 + string t=ReadChunk(); 1.564 + if( t=="BB3D" ){ 1.565 + int version=ReadInt(); 1.566 + 1.567 + if (!DefaultLogger::isNullLogger()) { 1.568 + char dmp[128]; 1.569 + sprintf(dmp,"B3D file format version: %i",version); 1.570 + DefaultLogger::get()->info(dmp); 1.571 + } 1.572 + 1.573 + while( ChunkSize() ){ 1.574 + string t=ReadChunk(); 1.575 + if( t=="TEXS" ){ 1.576 + ReadTEXS(); 1.577 + }else if( t=="BRUS" ){ 1.578 + ReadBRUS(); 1.579 + }else if( t=="NODE" ){ 1.580 + ReadNODE( 0 ); 1.581 + } 1.582 + ExitChunk(); 1.583 + } 1.584 + } 1.585 + ExitChunk(); 1.586 + 1.587 + if( !_nodes.size() ) Fail( "No nodes" ); 1.588 + 1.589 + if( !_meshes.size() ) Fail( "No meshes" ); 1.590 + 1.591 + //Fix nodes/meshes/bones 1.592 + for(size_t i=0;i<_nodes.size();++i ){ 1.593 + aiNode *node=_nodes[i]; 1.594 + 1.595 + for( size_t j=0;j<node->mNumMeshes;++j ){ 1.596 + aiMesh *mesh=_meshes[node->mMeshes[j]]; 1.597 + 1.598 + int n_tris=mesh->mNumFaces; 1.599 + int n_verts=mesh->mNumVertices=n_tris * 3; 1.600 + 1.601 + aiVector3D *mv=mesh->mVertices=new aiVector3D[ n_verts ],*mn=0,*mc=0; 1.602 + if( _vflags & 1 ) mn=mesh->mNormals=new aiVector3D[ n_verts ]; 1.603 + if( _tcsets ) mc=mesh->mTextureCoords[0]=new aiVector3D[ n_verts ]; 1.604 + 1.605 + aiFace *face=mesh->mFaces; 1.606 + 1.607 + vector< vector<aiVertexWeight> > vweights( _nodes.size() ); 1.608 + 1.609 + for( int i=0;i<n_verts;i+=3 ){ 1.610 + for( int j=0;j<3;++j ){ 1.611 + Vertex &v=_vertices[face->mIndices[j]]; 1.612 + 1.613 + *mv++=v.vertex; 1.614 + if( mn ) *mn++=v.normal; 1.615 + if( mc ) *mc++=v.texcoords; 1.616 + 1.617 + face->mIndices[j]=i+j; 1.618 + 1.619 + for( int k=0;k<4;++k ){ 1.620 + if( !v.weights[k] ) break; 1.621 + 1.622 + int bone=v.bones[k]; 1.623 + float weight=v.weights[k]; 1.624 + 1.625 + vweights[bone].push_back( aiVertexWeight(i+j,weight) ); 1.626 + } 1.627 + } 1.628 + ++face; 1.629 + } 1.630 + 1.631 + vector<aiBone*> bones; 1.632 + for(size_t i=0;i<vweights.size();++i ){ 1.633 + vector<aiVertexWeight> &weights=vweights[i]; 1.634 + if( !weights.size() ) continue; 1.635 + 1.636 + aiBone *bone=new aiBone; 1.637 + bones.push_back( bone ); 1.638 + 1.639 + aiNode *bnode=_nodes[i]; 1.640 + 1.641 + bone->mName=bnode->mName; 1.642 + bone->mNumWeights=weights.size(); 1.643 + bone->mWeights=to_array( weights ); 1.644 + 1.645 + aiMatrix4x4 mat=bnode->mTransformation; 1.646 + while( bnode->mParent ){ 1.647 + bnode=bnode->mParent; 1.648 + mat=bnode->mTransformation * mat; 1.649 + } 1.650 + bone->mOffsetMatrix=mat.Inverse(); 1.651 + } 1.652 + mesh->mNumBones=bones.size(); 1.653 + mesh->mBones=to_array( bones ); 1.654 + } 1.655 + } 1.656 + 1.657 + //nodes 1.658 + scene->mRootNode=_nodes[0]; 1.659 + 1.660 + //material 1.661 + if( !_materials.size() ){ 1.662 + _materials.push_back( new aiMaterial ); 1.663 + } 1.664 + scene->mNumMaterials=_materials.size(); 1.665 + scene->mMaterials=to_array( _materials ); 1.666 + 1.667 + //meshes 1.668 + scene->mNumMeshes=_meshes.size(); 1.669 + scene->mMeshes=to_array( _meshes ); 1.670 + 1.671 + //animations 1.672 + if( _animations.size()==1 && _nodeAnims.size() ){ 1.673 + 1.674 + aiAnimation *anim=_animations.back(); 1.675 + anim->mNumChannels=_nodeAnims.size(); 1.676 + anim->mChannels=to_array( _nodeAnims ); 1.677 + 1.678 + scene->mNumAnimations=_animations.size(); 1.679 + scene->mAnimations=to_array( _animations ); 1.680 + } 1.681 + 1.682 + // convert to RH 1.683 + MakeLeftHandedProcess makeleft; 1.684 + makeleft.Execute( scene ); 1.685 + 1.686 + FlipWindingOrderProcess flip; 1.687 + flip.Execute( scene ); 1.688 +} 1.689 + 1.690 +#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER