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