1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
5 
6 Copyright (c) 2006-2016, assimp team
7 
8 All rights reserved.
9 
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the following
12 conditions are met:
13 
14 * Redistributions of source code must retain the above
15   copyright notice, this list of conditions and the
16   following disclaimer.
17 
18 * Redistributions in binary form must reproduce the above
19   copyright notice, this list of conditions and the
20   following disclaimer in the documentation and/or other
21   materials provided with the distribution.
22 
23 * Neither the name of the assimp team, nor the names of its
24   contributors may be used to endorse or promote products
25   derived from this software without specific prior
26   written permission of the assimp team.
27 
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ---------------------------------------------------------------------------
40 */
41 
42 /** @file  AssbinLoader.cpp
43  *  @brief Implementation of the .assbin importer class
44  *
45  *  see assbin_chunks.h
46  */
47 
48 #ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
49 
50 // internal headers
51 #include "AssbinLoader.h"
52 #include "assbin_chunks.h"
53 #include "MemoryIOWrapper.h"
54 #include <assimp/mesh.h>
55 #include <assimp/anim.h>
56 #include <assimp/scene.h>
57 
58 #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
59 #   include <zlib.h>
60 #else
61 #   include <contrib/zlib/zlib.h>
62 #endif
63 
64 using namespace Assimp;
65 
66 static const aiImporterDesc desc = {
67     ".assbin Importer",
68     "Gargaj / Conspiracy",
69     "",
70     "",
71     aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour,
72     0,
73     0,
74     0,
75     0,
76     "assbin"
77 };
78 
GetInfo() const79 const aiImporterDesc* AssbinImporter::GetInfo() const
80 {
81     return &desc;
82 }
83 
CanRead(const std::string & pFile,IOSystem * pIOHandler,bool) const84 bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const
85 {
86     IOStream * in = pIOHandler->Open(pFile);
87     if (!in)
88         return false;
89 
90     char s[32];
91     in->Read( s, sizeof(char), 32 );
92 
93     pIOHandler->Close(in);
94 
95     return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0;
96 }
97 
98 template <typename T>
Read(IOStream * stream)99 T Read(IOStream * stream)
100 {
101     T t;
102     stream->Read( &t, sizeof(T), 1 );
103     return t;
104 }
105 
106 template <>
Read(IOStream * stream)107 aiVector3D Read<aiVector3D>(IOStream * stream)
108 {
109     aiVector3D v;
110     v.x = Read<float>(stream);
111     v.y = Read<float>(stream);
112     v.z = Read<float>(stream);
113     return v;
114 }
115 
116 template <>
Read(IOStream * stream)117 aiColor4D Read<aiColor4D>(IOStream * stream)
118 {
119     aiColor4D c;
120     c.r = Read<float>(stream);
121     c.g = Read<float>(stream);
122     c.b = Read<float>(stream);
123     c.a = Read<float>(stream);
124     return c;
125 }
126 
127 template <>
Read(IOStream * stream)128 aiQuaternion Read<aiQuaternion>(IOStream * stream)
129 {
130     aiQuaternion v;
131     v.w = Read<float>(stream);
132     v.x = Read<float>(stream);
133     v.y = Read<float>(stream);
134     v.z = Read<float>(stream);
135     return v;
136 }
137 
138 template <>
Read(IOStream * stream)139 aiString Read<aiString>(IOStream * stream)
140 {
141     aiString s;
142     stream->Read(&s.length,4,1);
143     stream->Read(s.data,s.length,1);
144     s.data[s.length] = 0;
145     return s;
146 }
147 
148 template <>
Read(IOStream * stream)149 aiVertexWeight Read<aiVertexWeight>(IOStream * stream)
150 {
151     aiVertexWeight w;
152     w.mVertexId = Read<unsigned int>(stream);
153     w.mWeight = Read<float>(stream);
154     return w;
155 }
156 
157 template <>
Read(IOStream * stream)158 aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
159 {
160     aiMatrix4x4 m;
161     for (unsigned int i = 0; i < 4;++i) {
162         for (unsigned int i2 = 0; i2 < 4;++i2) {
163             m[i][i2] = Read<float>(stream);
164         }
165     }
166     return m;
167 }
168 
169 template <>
Read(IOStream * stream)170 aiVectorKey Read<aiVectorKey>(IOStream * stream)
171 {
172     aiVectorKey v;
173     v.mTime = Read<double>(stream);
174     v.mValue = Read<aiVector3D>(stream);
175     return v;
176 }
177 
178 template <>
Read(IOStream * stream)179 aiQuatKey Read<aiQuatKey>(IOStream * stream)
180 {
181     aiQuatKey v;
182     v.mTime = Read<double>(stream);
183     v.mValue = Read<aiQuaternion>(stream);
184     return v;
185 }
186 
187 template <typename T>
ReadArray(IOStream * stream,T * out,unsigned int size)188 void ReadArray(IOStream * stream, T * out, unsigned int size)
189 {
190     for (unsigned int i=0; i<size; i++) out[i] = Read<T>(stream);
191 }
192 
ReadBounds(IOStream * stream,T *,unsigned int n)193 template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n )
194 {
195     // not sure what to do here, the data isn't really useful.
196     stream->Seek( sizeof(T) * n, aiOrigin_CUR );
197 }
198 
ReadBinaryNode(IOStream * stream,aiNode ** node)199 void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node )
200 {
201     uint32_t chunkID = Read<uint32_t>(stream);
202     ai_assert(chunkID == ASSBIN_CHUNK_AINODE);
203     /*uint32_t size =*/ Read<uint32_t>(stream);
204 
205     *node = new aiNode();
206 
207     (*node)->mName = Read<aiString>(stream);
208     (*node)->mTransformation = Read<aiMatrix4x4>(stream);
209     (*node)->mNumChildren = Read<unsigned int>(stream);
210     (*node)->mNumMeshes = Read<unsigned int>(stream);
211 
212     if ((*node)->mNumMeshes)
213     {
214         (*node)->mMeshes = new unsigned int[(*node)->mNumMeshes];
215         for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) {
216             (*node)->mMeshes[i] = Read<unsigned int>(stream);
217         }
218     }
219 
220     if ((*node)->mNumChildren)
221     {
222         (*node)->mChildren = new aiNode*[(*node)->mNumChildren];
223         for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) {
224             ReadBinaryNode( stream, &(*node)->mChildren[i] );
225         }
226     }
227 
228 }
229 
230 // -----------------------------------------------------------------------------------
ReadBinaryBone(IOStream * stream,aiBone * b)231 void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
232 {
233     uint32_t chunkID = Read<uint32_t>(stream);
234     ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
235     /*uint32_t size =*/ Read<uint32_t>(stream);
236 
237     b->mName = Read<aiString>(stream);
238     b->mNumWeights = Read<unsigned int>(stream);
239     b->mOffsetMatrix = Read<aiMatrix4x4>(stream);
240 
241     // for the moment we write dumb min/max values for the bones, too.
242     // maybe I'll add a better, hash-like solution later
243     if (shortened)
244     {
245         ReadBounds(stream,b->mWeights,b->mNumWeights);
246     } // else write as usual
247     else
248     {
249         b->mWeights = new aiVertexWeight[b->mNumWeights];
250         ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights);
251     }
252 }
253 
254 
ReadBinaryMesh(IOStream * stream,aiMesh * mesh)255 void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
256 {
257     uint32_t chunkID = Read<uint32_t>(stream);
258     ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
259     /*uint32_t size =*/ Read<uint32_t>(stream);
260 
261     mesh->mPrimitiveTypes = Read<unsigned int>(stream);
262     mesh->mNumVertices = Read<unsigned int>(stream);
263     mesh->mNumFaces = Read<unsigned int>(stream);
264     mesh->mNumBones = Read<unsigned int>(stream);
265     mesh->mMaterialIndex = Read<unsigned int>(stream);
266 
267     // first of all, write bits for all existent vertex components
268     unsigned int c = Read<unsigned int>(stream);
269 
270     if (c & ASSBIN_MESH_HAS_POSITIONS)
271     {
272         if (shortened) {
273             ReadBounds(stream,mesh->mVertices,mesh->mNumVertices);
274         } // else write as usual
275         else
276         {
277             mesh->mVertices = new aiVector3D[mesh->mNumVertices];
278             ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices);
279         }
280     }
281     if (c & ASSBIN_MESH_HAS_NORMALS)
282     {
283         if (shortened) {
284             ReadBounds(stream,mesh->mNormals,mesh->mNumVertices);
285         } // else write as usual
286         else
287         {
288             mesh->mNormals = new aiVector3D[mesh->mNumVertices];
289             ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices);
290         }
291     }
292     if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS)
293     {
294         if (shortened) {
295             ReadBounds(stream,mesh->mTangents,mesh->mNumVertices);
296             ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices);
297         } // else write as usual
298         else
299         {
300             mesh->mTangents = new aiVector3D[mesh->mNumVertices];
301             ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices);
302             mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
303             ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices);
304         }
305     }
306     for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n)
307     {
308         if (!(c & ASSBIN_MESH_HAS_COLOR(n)))
309             break;
310 
311         if (shortened)
312         {
313             ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices);
314         } // else write as usual
315         else
316         {
317             mesh->mColors[n] = new aiColor4D[mesh->mNumVertices];
318             ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices);
319         }
320     }
321     for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
322     {
323         if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n)))
324             break;
325 
326         // write number of UV components
327         mesh->mNumUVComponents[n] = Read<unsigned int>(stream);
328 
329         if (shortened) {
330             ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
331         } // else write as usual
332         else
333         {
334             mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
335             ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
336         }
337     }
338 
339     // write faces. There are no floating-point calculations involved
340     // in these, so we can write a simple hash over the face data
341     // to the dump file. We generate a single 32 Bit hash for 512 faces
342     // using Assimp's standard hashing function.
343     if (shortened) {
344         Read<unsigned int>(stream);
345     }
346     else // else write as usual
347     {
348         // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
349         mesh->mFaces = new aiFace[mesh->mNumFaces];
350         for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
351             aiFace& f = mesh->mFaces[i];
352 
353             static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
354             f.mNumIndices = Read<uint16_t>(stream);
355             f.mIndices = new unsigned int[f.mNumIndices];
356 
357             for (unsigned int a = 0; a < f.mNumIndices;++a) {
358                 if (mesh->mNumVertices < (1u<<16))
359                 {
360                     f.mIndices[a] = Read<uint16_t>(stream);
361                 }
362                 else
363                 {
364                     f.mIndices[a] = Read<unsigned int>(stream);
365                 }
366             }
367         }
368     }
369 
370     // write bones
371     if (mesh->mNumBones) {
372         mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones];
373         for (unsigned int a = 0; a < mesh->mNumBones;++a) {
374             mesh->mBones[a] = new aiBone();
375             ReadBinaryBone(stream,mesh->mBones[a]);
376         }
377     }
378 }
379 
ReadBinaryMaterialProperty(IOStream * stream,aiMaterialProperty * prop)380 void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
381 {
382     uint32_t chunkID = Read<uint32_t>(stream);
383     ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
384     /*uint32_t size =*/ Read<uint32_t>(stream);
385 
386     prop->mKey = Read<aiString>(stream);
387     prop->mSemantic = Read<unsigned int>(stream);
388     prop->mIndex = Read<unsigned int>(stream);
389 
390     prop->mDataLength = Read<unsigned int>(stream);
391     prop->mType = (aiPropertyTypeInfo)Read<unsigned int>(stream);
392     prop->mData = new char [ prop->mDataLength ];
393     stream->Read(prop->mData,1,prop->mDataLength);
394 }
395 
396 // -----------------------------------------------------------------------------------
ReadBinaryMaterial(IOStream * stream,aiMaterial * mat)397 void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
398 {
399     uint32_t chunkID = Read<uint32_t>(stream);
400     ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
401     /*uint32_t size =*/ Read<uint32_t>(stream);
402 
403     mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
404     if (mat->mNumProperties)
405     {
406         if (mat->mProperties)
407         {
408             delete[] mat->mProperties;
409         }
410         mat->mProperties = new aiMaterialProperty*[mat->mNumProperties];
411         for (unsigned int i = 0; i < mat->mNumProperties;++i) {
412             mat->mProperties[i] = new aiMaterialProperty();
413             ReadBinaryMaterialProperty( stream, mat->mProperties[i]);
414         }
415     }
416 }
417 
418 // -----------------------------------------------------------------------------------
ReadBinaryNodeAnim(IOStream * stream,aiNodeAnim * nd)419 void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
420 {
421     uint32_t chunkID = Read<uint32_t>(stream);
422     ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
423     /*uint32_t size =*/ Read<uint32_t>(stream);
424 
425     nd->mNodeName = Read<aiString>(stream);
426     nd->mNumPositionKeys = Read<unsigned int>(stream);
427     nd->mNumRotationKeys = Read<unsigned int>(stream);
428     nd->mNumScalingKeys = Read<unsigned int>(stream);
429     nd->mPreState = (aiAnimBehaviour)Read<unsigned int>(stream);
430     nd->mPostState = (aiAnimBehaviour)Read<unsigned int>(stream);
431 
432     if (nd->mNumPositionKeys) {
433         if (shortened) {
434             ReadBounds(stream,nd->mPositionKeys,nd->mNumPositionKeys);
435 
436         } // else write as usual
437         else {
438             nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
439             ReadArray<aiVectorKey>(stream,nd->mPositionKeys,nd->mNumPositionKeys);
440         }
441     }
442     if (nd->mNumRotationKeys) {
443         if (shortened) {
444             ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys);
445 
446         } // else write as usual
447         else
448         {
449             nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
450             ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys);
451         }
452     }
453     if (nd->mNumScalingKeys) {
454         if (shortened) {
455             ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys);
456 
457         } // else write as usual
458         else
459         {
460             nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
461             ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys);
462         }
463     }
464 }
465 
466 
467 // -----------------------------------------------------------------------------------
ReadBinaryAnim(IOStream * stream,aiAnimation * anim)468 void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
469 {
470     uint32_t chunkID = Read<uint32_t>(stream);
471     ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
472     /*uint32_t size =*/ Read<uint32_t>(stream);
473 
474     anim->mName = Read<aiString> (stream);
475     anim->mDuration = Read<double> (stream);
476     anim->mTicksPerSecond = Read<double> (stream);
477     anim->mNumChannels = Read<unsigned int>(stream);
478 
479     if (anim->mNumChannels)
480     {
481         anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ];
482         for (unsigned int a = 0; a < anim->mNumChannels;++a) {
483             anim->mChannels[a] = new aiNodeAnim();
484             ReadBinaryNodeAnim(stream,anim->mChannels[a]);
485         }
486     }
487 }
488 
ReadBinaryTexture(IOStream * stream,aiTexture * tex)489 void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
490 {
491     uint32_t chunkID = Read<uint32_t>(stream);
492     ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
493     /*uint32_t size =*/ Read<uint32_t>(stream);
494 
495     tex->mWidth = Read<unsigned int>(stream);
496     tex->mHeight = Read<unsigned int>(stream);
497     stream->Read( tex->achFormatHint, sizeof(char), 4 );
498 
499     if(!shortened) {
500         if (!tex->mHeight) {
501             tex->pcData = new aiTexel[ tex->mWidth ];
502             stream->Read(tex->pcData,1,tex->mWidth);
503         }
504         else {
505             tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ];
506             stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4);
507         }
508     }
509 
510 }
511 
512 // -----------------------------------------------------------------------------------
ReadBinaryLight(IOStream * stream,aiLight * l)513 void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
514 {
515     uint32_t chunkID = Read<uint32_t>(stream);
516     ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
517     /*uint32_t size =*/ Read<uint32_t>(stream);
518 
519     l->mName = Read<aiString>(stream);
520     l->mType = (aiLightSourceType)Read<unsigned int>(stream);
521 
522     if (l->mType != aiLightSource_DIRECTIONAL) {
523         l->mAttenuationConstant = Read<float>(stream);
524         l->mAttenuationLinear = Read<float>(stream);
525         l->mAttenuationQuadratic = Read<float>(stream);
526     }
527 
528     l->mColorDiffuse = Read<aiColor3D>(stream);
529     l->mColorSpecular = Read<aiColor3D>(stream);
530     l->mColorAmbient = Read<aiColor3D>(stream);
531 
532     if (l->mType == aiLightSource_SPOT) {
533         l->mAngleInnerCone = Read<float>(stream);
534         l->mAngleOuterCone = Read<float>(stream);
535     }
536 
537 }
538 
539 // -----------------------------------------------------------------------------------
ReadBinaryCamera(IOStream * stream,aiCamera * cam)540 void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
541 {
542     uint32_t chunkID = Read<uint32_t>(stream);
543     ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
544     /*uint32_t size =*/ Read<uint32_t>(stream);
545 
546     cam->mName = Read<aiString>(stream);
547     cam->mPosition = Read<aiVector3D>(stream);
548     cam->mLookAt = Read<aiVector3D>(stream);
549     cam->mUp = Read<aiVector3D>(stream);
550     cam->mHorizontalFOV = Read<float>(stream);
551     cam->mClipPlaneNear = Read<float>(stream);
552     cam->mClipPlaneFar = Read<float>(stream);
553     cam->mAspect = Read<float>(stream);
554 }
555 
ReadBinaryScene(IOStream * stream,aiScene * scene)556 void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
557 {
558     uint32_t chunkID = Read<uint32_t>(stream);
559     ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
560     /*uint32_t size =*/ Read<uint32_t>(stream);
561 
562     scene->mFlags         = Read<unsigned int>(stream);
563     scene->mNumMeshes     = Read<unsigned int>(stream);
564     scene->mNumMaterials  = Read<unsigned int>(stream);
565     scene->mNumAnimations = Read<unsigned int>(stream);
566     scene->mNumTextures   = Read<unsigned int>(stream);
567     scene->mNumLights     = Read<unsigned int>(stream);
568     scene->mNumCameras    = Read<unsigned int>(stream);
569 
570     // Read node graph
571     scene->mRootNode = new aiNode[1];
572     ReadBinaryNode( stream, &scene->mRootNode );
573 
574     // Read all meshes
575     if (scene->mNumMeshes)
576     {
577         scene->mMeshes = new aiMesh*[scene->mNumMeshes];
578         for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
579             scene->mMeshes[i] = new aiMesh();
580             ReadBinaryMesh( stream,scene->mMeshes[i]);
581         }
582     }
583 
584     // Read materials
585     if (scene->mNumMaterials)
586     {
587         scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
588         for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
589             scene->mMaterials[i] = new aiMaterial();
590             ReadBinaryMaterial(stream,scene->mMaterials[i]);
591         }
592     }
593 
594     // Read all animations
595     if (scene->mNumAnimations)
596     {
597         scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
598         for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
599             scene->mAnimations[i] = new aiAnimation();
600             ReadBinaryAnim(stream,scene->mAnimations[i]);
601         }
602     }
603 
604     // Read all textures
605     if (scene->mNumTextures)
606     {
607         scene->mTextures = new aiTexture*[scene->mNumTextures];
608         for (unsigned int i = 0; i < scene->mNumTextures;++i) {
609             scene->mTextures[i] = new aiTexture();
610             ReadBinaryTexture(stream,scene->mTextures[i]);
611         }
612     }
613 
614     // Read lights
615     if (scene->mNumLights)
616     {
617         scene->mLights = new aiLight*[scene->mNumLights];
618         for (unsigned int i = 0; i < scene->mNumLights;++i) {
619             scene->mLights[i] = new aiLight();
620             ReadBinaryLight(stream,scene->mLights[i]);
621         }
622     }
623 
624     // Read cameras
625     if (scene->mNumCameras)
626     {
627         scene->mCameras = new aiCamera*[scene->mNumCameras];
628         for (unsigned int i = 0; i < scene->mNumCameras;++i) {
629             scene->mCameras[i] = new aiCamera();
630             ReadBinaryCamera(stream,scene->mCameras[i]);
631         }
632     }
633 
634 }
635 
InternReadFile(const std::string & pFile,aiScene * pScene,IOSystem * pIOHandler)636 void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
637 {
638     IOStream * stream = pIOHandler->Open(pFile,"rb");
639     if (!stream)
640         return;
641 
642     stream->Seek( 44, aiOrigin_CUR ); // signature
643 
644     /*unsigned int versionMajor =*/ Read<unsigned int>(stream);
645     /*unsigned int versionMinor =*/ Read<unsigned int>(stream);
646     /*unsigned int versionRevision =*/ Read<unsigned int>(stream);
647     /*unsigned int compileFlags =*/ Read<unsigned int>(stream);
648 
649     shortened = Read<uint16_t>(stream) > 0;
650     compressed = Read<uint16_t>(stream) > 0;
651 
652     if (shortened)
653         throw DeadlyImportError( "Shortened binaries are not supported!" );
654 
655     stream->Seek( 256, aiOrigin_CUR ); // original filename
656     stream->Seek( 128, aiOrigin_CUR ); // options
657     stream->Seek( 64, aiOrigin_CUR ); // padding
658 
659     if (compressed)
660     {
661         uLongf uncompressedSize = Read<uint32_t>(stream);
662         uLongf compressedSize = stream->FileSize() - stream->Tell();
663 
664         unsigned char * compressedData = new unsigned char[ compressedSize ];
665         stream->Read( compressedData, 1, compressedSize );
666 
667         unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
668 
669         uncompress( uncompressedData, &uncompressedSize, compressedData, compressedSize );
670 
671         MemoryIOStream io( uncompressedData, uncompressedSize );
672 
673         ReadBinaryScene(&io,pScene);
674 
675         delete[] uncompressedData;
676         delete[] compressedData;
677     }
678     else
679     {
680         ReadBinaryScene(stream,pScene);
681     }
682 
683     pIOHandler->Close(stream);
684 }
685 
686 #endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER
687