/* =================== idRestoreGame::WriteTraceModel =================== */ void idSaveGame::WriteTraceModel( const idTraceModel &trace ) { int j, k; WriteInt( (int&)trace.type ); WriteInt( trace.numVerts ); for ( j = 0; j < MAX_TRACEMODEL_VERTS; j++ ) { WriteVec3( trace.verts[j] ); } WriteInt( trace.numEdges ); for ( j = 0; j < (MAX_TRACEMODEL_EDGES+1); j++ ) { WriteInt( trace.edges[j].v[0] ); WriteInt( trace.edges[j].v[1] ); WriteVec3( trace.edges[j].normal ); } WriteInt( trace.numPolys ); for ( j = 0; j < MAX_TRACEMODEL_POLYS; j++ ) { WriteVec3( trace.polys[j].normal ); WriteFloat( trace.polys[j].dist ); WriteBounds( trace.polys[j].bounds ); WriteInt( trace.polys[j].numEdges ); for ( k = 0; k < MAX_TRACEMODEL_POLYEDGES; k++ ) { WriteInt( trace.polys[j].edges[k] ); } } WriteVec3( trace.offset ); WriteBounds( trace.bounds ); WriteBool( trace.isConvex ); // padding win32 native structs char tmp[3]; memset( tmp, 0, sizeof( tmp ) ); file->Write( tmp, 3 ); }
/* ================ idSaveGame::WriteRenderEntity ================ */ void idSaveGame::WriteRenderEntity( const renderEntity_t &renderEntity ) { int i; WriteModel( renderEntity.hModel ); WriteInt( renderEntity.entityNum ); WriteInt( renderEntity.bodyId ); WriteBounds( renderEntity.bounds ); // callback is set by class's Restore function WriteInt( renderEntity.suppressSurfaceInViewID ); WriteInt( renderEntity.suppressShadowInViewID ); WriteInt( renderEntity.suppressShadowInLightID ); WriteInt( renderEntity.allowSurfaceInViewID ); WriteVec3( renderEntity.origin ); WriteMat3( renderEntity.axis ); WriteMaterial( renderEntity.customShader ); WriteMaterial( renderEntity.referenceShader ); WriteSkin( renderEntity.customSkin ); if( renderEntity.referenceSound != NULL ) { WriteInt( renderEntity.referenceSound->Index() ); } else { WriteInt( 0 ); } for( i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ ) { WriteFloat( renderEntity.shaderParms[ i ] ); } for( i = 0; i < MAX_RENDERENTITY_GUI; i++ ) { WriteUserInterface( renderEntity.gui[ i ], renderEntity.gui[ i ] ? renderEntity.gui[ i ]->IsUniqued() : false ); } WriteFloat( renderEntity.modelDepthHack ); WriteBool( renderEntity.noSelfShadow ); WriteBool( renderEntity.noShadow ); WriteBool( renderEntity.noDynamicInteractions ); WriteBool( renderEntity.weaponDepthHack ); WriteInt( renderEntity.forceUpdate ); }
// ----------------------------------------------------------------------------------- uint32_t WriteBinaryNodeAnim(const aiNodeAnim* nd) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODEANIM); len += Write<aiString>(nd->mNodeName); len += Write<unsigned int>(nd->mNumPositionKeys); len += Write<unsigned int>(nd->mNumRotationKeys); len += Write<unsigned int>(nd->mNumScalingKeys); len += Write<unsigned int>(nd->mPreState); len += Write<unsigned int>(nd->mPostState); if (nd->mPositionKeys) { if (shortened) { len += WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); } // else write as usual else len += fwrite(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey),out); } if (nd->mRotationKeys) { if (shortened) { len += WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); } // else write as usual else len += fwrite(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey),out); } if (nd->mScalingKeys) { if (shortened) { len += WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); } // else write as usual else len += fwrite(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey),out); } ChangeInteger(old,len); return len; }
int FrechetBounds1(LPTable table, const char* sFileName) { if(table == NULL) { printf("Error :: FrechetBounds1.\n"); return 0; } int k = table->nDimens; LPTable UpperBound = CreateMin(1, table); if(UpperBound == NULL) { printf("Error :: FrechetBounds1.\n"); return 0; } LPTable LowerBound = CreateS(1, table); if(LowerBound == NULL) { printf("Error :: FrechetBounds1.\n"); UpperBound->Reset(); delete UpperBound; return 0; } double n = table->GetGrandTotal(); int i; for(i=0; i<table->Total; i++) { LowerBound->Data[i] -= n*(k-1); if(LowerBound->Data[i] < 0.0) { LowerBound->Data[i] = 0.0; } } int rez = WriteBounds(UpperBound, LowerBound, sFileName); UpperBound->Reset(); LowerBound->Reset(); delete UpperBound; delete LowerBound; return rez; }
// ----------------------------------------------------------------------------------- uint32_t WriteBinaryBone(const aiBone* b) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIBONE); len += Write<aiString>(b->mName); len += Write<unsigned int>(b->mNumWeights); len += Write<aiMatrix4x4>(b->mOffsetMatrix); // for the moment we write dumb min/max values for the bones, too. // maybe I'll add a better, hash-like solution later if (shortened) { len += WriteBounds(b->mWeights,b->mNumWeights); } // else write as usual else len += fwrite(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight),out); ChangeInteger(old,len); return len; }
// ----------------------------------------------------------------------------------- uint32_t WriteBinaryMesh(const aiMesh* mesh) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMESH); len += Write<unsigned int>(mesh->mPrimitiveTypes); len += Write<unsigned int>(mesh->mNumVertices); len += Write<unsigned int>(mesh->mNumFaces); len += Write<unsigned int>(mesh->mNumBones); len += Write<unsigned int>(mesh->mMaterialIndex); // first of all, write bits for all existent vertex components unsigned int c = 0; if (mesh->mVertices) { c |= ASSBIN_MESH_HAS_POSITIONS; } if (mesh->mNormals) { c |= ASSBIN_MESH_HAS_NORMALS; } if (mesh->mTangents && mesh->mBitangents) { c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { if (!mesh->mTextureCoords[n]) { break; } c |= ASSBIN_MESH_HAS_TEXCOORD(n); } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { if (!mesh->mColors[n]) { break; } c |= ASSBIN_MESH_HAS_COLOR(n); } len += Write<unsigned int>(c); aiVector3D minVec, maxVec; if (mesh->mVertices) { if (shortened) { len += WriteBounds(mesh->mVertices,mesh->mNumVertices); } // else write as usual else len += fwrite(mesh->mVertices,1,12*mesh->mNumVertices,out); } if (mesh->mNormals) { if (shortened) { len += WriteBounds(mesh->mNormals,mesh->mNumVertices); } // else write as usual else len += fwrite(mesh->mNormals,1,12*mesh->mNumVertices,out); } if (mesh->mTangents && mesh->mBitangents) { if (shortened) { len += WriteBounds(mesh->mTangents,mesh->mNumVertices); len += WriteBounds(mesh->mBitangents,mesh->mNumVertices); } // else write as usual else { len += fwrite(mesh->mTangents,1,12*mesh->mNumVertices,out); len += fwrite(mesh->mBitangents,1,12*mesh->mNumVertices,out); } } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { if (!mesh->mColors[n]) break; if (shortened) { len += WriteBounds(mesh->mColors[n],mesh->mNumVertices); } // else write as usual else len += fwrite(mesh->mColors[n],16*mesh->mNumVertices,1,out); } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { if (!mesh->mTextureCoords[n]) break; // write number of UV components len += Write<unsigned int>(mesh->mNumUVComponents[n]); if (shortened) { len += WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); } // else write as usual else len += fwrite(mesh->mTextureCoords[n],12*mesh->mNumVertices,1,out); } // write faces. There are no floating-point calculations involved // in these, so we can write a simple hash over the face data // to the dump file. We generate a single 32 Bit hash for 512 faces // using Assimp's standard hashing function. if (shortened) { unsigned int processed = 0; for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) { uint32_t hash = 0; for (unsigned int a = 0; a < job;++a) { const aiFace& f = mesh->mFaces[processed+a]; uint32_t tmp = f.mNumIndices; hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash); for (unsigned int i = 0; i < f.mNumIndices; ++i) { BOOST_STATIC_ASSERT(AI_MAX_VERTICES <= 0xffffffff); tmp = static_cast<uint32_t>( f.mIndices[i] ); hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash); } } len += Write<unsigned int>(hash); } } else // else write as usual { // if there are less than 2^16 vertices, we can simply use 16 bit integers ... for (unsigned int i = 0; i < mesh->mNumFaces;++i) { const aiFace& f = mesh->mFaces[i]; BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); len += Write<uint16_t>(f.mNumIndices); for (unsigned int a = 0; a < f.mNumIndices;++a) { if (mesh->mNumVertices < (1u<<16)) { len += Write<uint16_t>(f.mIndices[a]); } else len += Write<unsigned int>(f.mIndices[a]); } } } // write bones if (mesh->mNumBones) { for (unsigned int a = 0; a < mesh->mNumBones;++a) { const aiBone* b = mesh->mBones[a]; len += WriteBinaryBone(b)+8; } } ChangeInteger(old,len); return len; }
int ShuttleBounds(LPTable table, int nIterations, const char* sFileName) { int k = table->nDimens; LPTable UpperBound = CreateMin(k-1, table); if(UpperBound == NULL) { printf("Error :: ShuttleBounds.\n"); return 0; } LPTable LowerBound = new Table; if(LowerBound == NULL) { printf("Error :: ShuttleBounds.\n"); UpperBound->Reset(); delete UpperBound; return 0; } if(!LowerBound->Alloc(table->Dimens, table->nDimens)) { printf("Error :: ShuttleBounds.\n"); UpperBound->Reset(); delete UpperBound; return 0; } int i; for(i=0; i<table->Total; i++) { LowerBound->Data[i] = 0; } int ind; int iteration; for(iteration=0; iteration<nIterations; iteration++) { LPTable OldUpperBound = UpperBound; LPTable OldLowerBound = LowerBound; UpperBound = ReduceOneShuttle(table, 0, OldLowerBound); if(UpperBound == NULL) { OldUpperBound->Reset(); delete OldUpperBound; OldLowerBound->Reset(); delete OldLowerBound; return 0; } for(ind=1; ind<k; ind++) { LPTable newtab = ReduceOneShuttle(table, ind, OldLowerBound); if(newtab == NULL) { UpperBound->Reset(); delete UpperBound; OldUpperBound->Reset(); delete OldUpperBound; OldLowerBound->Reset(); delete OldLowerBound; return 0; } for(i=0; i<table->Total; i++) { if(newtab->Data[i] < UpperBound->Data[i]) { UpperBound->Data[i] = newtab->Data[i]; } } newtab->Reset(); delete newtab; } LowerBound = ReduceOneShuttle(table, 0, OldUpperBound); if(LowerBound == NULL) { UpperBound->Reset(); delete UpperBound; OldUpperBound->Reset(); delete OldUpperBound; OldLowerBound->Reset(); delete OldLowerBound; return 0; } for(ind=1; ind<k; ind++) { LPTable newtab = ReduceOneShuttle(table, ind, OldUpperBound); if(newtab == NULL) { UpperBound->Reset(); delete UpperBound; LowerBound->Reset(); delete LowerBound; OldUpperBound->Reset(); delete OldUpperBound; OldLowerBound->Reset(); delete OldLowerBound; return 0; } for(i=0; i<table->Total; i++) { if(newtab->Data[i] > LowerBound->Data[i]) { LowerBound->Data[i] = newtab->Data[i]; } } newtab->Reset(); delete newtab; } OldUpperBound->Reset(); delete OldUpperBound; OldLowerBound->Reset(); delete OldLowerBound; } int rez = WriteBounds(UpperBound, LowerBound, sFileName); UpperBound->Reset(); LowerBound->Reset(); delete UpperBound; delete LowerBound; return rez; }
int Bonferroni(int m, LPTable table, const char* sFileName) { if(table == NULL) { printf("Error :: BonferroniBounds.\n"); return 0; } int i; double nGrandTotal; nGrandTotal = table->GetGrandTotal(); for(i=0; i<table->Total; i++) { table->Data[i] /= nGrandTotal; } table->WriteTable("tabinit.dat"); LPTable UpperBound; LPTable LowerBound = new Table; if(LowerBound == NULL) { printf("Error :: BonferroniBounds.\n"); return 0; } if(!LowerBound->Alloc(table->Dimens, table->nDimens)) { printf("Error :: BonferroniBounds.\n"); return 0; } LPTable nBar = CreateNBar(table); if(nBar == NULL) { printf("Error :: Bonferroni.\n"); return 0; } nBar->WriteTable("nbar.dat"); double nBarGrandTotal; nBarGrandTotal = nBar->GetGrandTotal(); int m1; int plus; UpperBound = CreateS(1, nBar); if(UpperBound == NULL) { printf("Error :: Bonferroni.\n"); nBar->Reset(); delete nBar; LowerBound->Reset(); delete LowerBound; return 0; } UpperBound->WriteTable("s1bar.dat"); for(i=0; i<table->Total; i++) { UpperBound->Data[i] = 1 - UpperBound->Data[i]; //nBarGrandTotal } plus = 1; for(m1=2; m1<=m-1; m1++) { LPTable sm1 = CreateS(m1, nBar); if(sm1 == NULL) { printf("Error :: Bonferroni.\n"); nBar->Reset(); delete nBar; UpperBound->Reset(); delete UpperBound; LowerBound->Reset(); delete LowerBound; return 0; } if(plus == 1) { for(i=0; i<table->Total; i++) { UpperBound->Data[i] += sm1->Data[i]; } } else //plus == -1 { for(i=0; i<table->Total; i++) { UpperBound->Data[i] -= sm1->Data[i]; } } sm1->Reset(); delete sm1; plus = - plus; } for(i=0; i<table->Total; i++) { LowerBound->Data[i] = UpperBound->Data[i]; } if(m < table->nDimens) { LPTable sm = CreateS(m, nBar); if(sm == NULL) { printf("Error :: Bonferroni.\n"); nBar->Reset(); delete nBar; UpperBound->Reset(); delete UpperBound; LowerBound->Reset(); delete LowerBound; return 0; } if(plus == 1) //m even { for(i=0; i<table->Total; i++) { UpperBound->Data[i] += sm->Data[i]; } } else //m odd { for(i=0; i<table->Total; i++) { LowerBound->Data[i] -= sm->Data[i]; } } sm->Reset(); delete sm; } else { if(plus == 1) //m even { for(i=0; i<table->Total; i++) { UpperBound->Data[i] += nBar->Data[i]; } } else //m odd { for(i=0; i<table->Total; i++) { LowerBound->Data[i] -= nBar->Data[i]; } } } WriteBounds(UpperBound, LowerBound, "extra.dat"); double ratio = nGrandTotal; // /nBarGrandTotal; printf("ratio = %lf\n", ratio); for(i=0; i<table->Total; i++) { UpperBound->Data[i] = ceil(UpperBound->Data[i]*ratio); LowerBound->Data[i] = floor(LowerBound->Data[i]*ratio); if(LowerBound->Data[i] < 0) { LowerBound->Data[i] = 0; } } int rez = WriteBounds(UpperBound, LowerBound, sFileName); nBar->Reset(); UpperBound->Reset(); LowerBound->Reset(); delete nBar; delete UpperBound; delete LowerBound; return rez; }
int FrechetBounds(LPTable table, const char* sFileName) { if(table == NULL) { printf("Error :: FrechetBounds.\n"); return 0; } int k = table->nDimens; LPTable UpperBound = CreateMin(k-1, table); if(UpperBound == NULL) { printf("Error :: FrechetBounds.\n"); return 0; } LPTable LowerBound = new Table; if(LowerBound == NULL) { printf("Error :: FrechetBounds.\n"); UpperBound->Reset(); delete UpperBound; return 0; } if(!LowerBound->Alloc(table->Dimens, table->nDimens)) { printf("Error :: FrechetBounds.\n"); UpperBound->Reset(); delete UpperBound; return 0; } double n = table->GetGrandTotal(); int m; int plus; int first = 1; //first iteration? int i; if(k%2 == 0) //k even { plus = 1; for(m=1; m<k; m++) { LPTable smtab = CreateS(m, table); if(smtab == NULL) { printf("Error :: FrechetBounds.\n"); UpperBound->Reset(); LowerBound->Reset(); delete UpperBound; delete LowerBound; return 0; } if(first) { for(i=0; i<table->Total; i++) { LowerBound->Data[i] = smtab->Data[i] - n; } first = 0; } else { if(plus == -1) { for(i=0; i<table->Total; i++) { LowerBound->Data[i] -= smtab->Data[i]; } } else //plus == 1 { for(i=0; i<table->Total; i++) { LowerBound->Data[i] += smtab->Data[i]; } } } plus = - plus; smtab->Reset(); delete smtab; } } else // k odd { LPTable nBar = CreateNBar(table); if(nBar == NULL) { printf("Error :: FrechetBounds.\n"); UpperBound->Reset(); LowerBound->Reset(); delete UpperBound; delete LowerBound; return 0; } LPTable nMinBar = CreateMin(k-1, nBar); nBar->Reset(); delete nBar; if(nMinBar == NULL) { printf("Error :: FrechetBounds.\n"); UpperBound->Reset(); LowerBound->Reset(); delete UpperBound; delete LowerBound; return 0; } plus = -1; for(m=1; m<k; m++) { LPTable smtab = CreateS(m, table); if(smtab == NULL) { printf("Error :: FrechetBounds.\n"); UpperBound->Reset(); LowerBound->Reset(); delete UpperBound; delete LowerBound; return 0; } if(first) { for(i=0; i<table->Total; i++) { LowerBound->Data[i] = n - smtab->Data[i]; } first = 0; } else { if(plus == -1) { for(i=0; i<table->Total; i++) { LowerBound->Data[i] -= smtab->Data[i]; } } else //plus == 1 { for(i=0; i<table->Total; i++) { LowerBound->Data[i] += smtab->Data[i]; } } } plus = - plus; smtab->Reset(); delete smtab; } for(i=0; i<table->Total; i++) { LowerBound->Data[i] -= nMinBar->Data[i]; } nMinBar->Reset(); delete nMinBar; } for(i=0; i<table->Total; i++) { if(LowerBound->Data[i] < 0) { LowerBound->Data[i] = 0; } } int rez = WriteBounds(UpperBound, LowerBound, sFileName); UpperBound->Reset(); LowerBound->Reset(); delete UpperBound; delete LowerBound; return rez; }
// ----------------------------------------------------------------------------------- // Write a binary model dump void WriteBinaryDump(const aiScene* scene, FILE* out, const char* src, const char* cmd, bool shortened, bool compressed, ImportData& imp) { time_t tt = ::time(NULL); tm* p = ::gmtime(&tt); // header ::fprintf(out,"ASSIMP.binary-dump.%s.",::asctime(p)); // == 45 bytes WriteInteger(aiGetVersionMajor(),out); WriteInteger(aiGetVersionMinor(),out); WriteInteger(aiGetVersionRevision(),out); WriteInteger(aiGetCompileFlags(),out); WriteShort(shortened,out); WriteShort(compressed,out); // == 20 bytes char buff[256]; ::strncpy(buff,src,256); ::fwrite(buff,256,1,out); ::strncpy(buff,cmd,128); ::fwrite(buff,128,1,out); // leave 41 bytes free for future extensions ::memset(buff,0xcd,41); ::fwrite(buff,32,1,out); // == 435 bytes // ==== total header size: 500 bytes // Up to here the data is uncompressed. For compressed files, the rest // is compressed using standard DEFLATE from zlib. // basic scene information WriteInteger(scene->mFlags,out); WriteInteger(scene->mNumAnimations,out); WriteInteger(scene->mNumTextures,out); WriteInteger(scene->mNumMaterials,out); WriteInteger(scene->mNumCameras,out); WriteInteger(scene->mNumLights,out); WriteInteger(scene->mNumMeshes,out); // write node graph WriteBinaryNode(scene->mRootNode,out); // write materials for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { const aiMaterial* mat = scene->mMaterials[i]; WriteMagic("#MA",out); WriteInteger(mat->mNumProperties,out); for (unsigned int a = 0; a < mat->mNumProperties;++a) { const aiMaterialProperty* prop = mat->mProperties[a]; WriteMagic("#MP",out); WriteAiString(prop->mKey,out); WriteInteger(prop->mSemantic,out); WriteInteger(prop->mIndex,out); WriteInteger(prop->mDataLength,out); ::fwrite(prop->mData,prop->mDataLength,1,out); } } // write cameras for (unsigned int i = 0; i < scene->mNumCameras;++i) { const aiCamera* cam = scene->mCameras[i]; WriteMagic("#CA",out); WriteAiString(cam->mName,out); WriteVec3(cam->mPosition,out); WriteVec3(cam->mLookAt,out); WriteVec3(cam->mUp,out); WriteFloat(cam->mClipPlaneNear,out); WriteFloat(cam->mClipPlaneFar,out); WriteFloat(cam->mHorizontalFOV,out); WriteFloat(cam->mAspect,out); } // write lights for (unsigned int i = 0; i < scene->mNumLights;++i) { const aiLight* l = scene->mLights[i]; WriteMagic("#LI",out); WriteAiString(l->mName,out); WriteInteger(l->mType,out); WriteVec3((const aiVector3D&)l->mColorDiffuse,out); WriteVec3((const aiVector3D&)l->mColorSpecular,out); WriteVec3((const aiVector3D&)l->mColorAmbient,out); if (l->mType != aiLightSource_DIRECTIONAL) { WriteVec3(l->mPosition,out); WriteFloat(l->mAttenuationLinear,out); WriteFloat(l->mAttenuationConstant,out); WriteFloat(l->mAttenuationQuadratic,out); } if (l->mType != aiLightSource_POINT) { WriteVec3(l->mDirection,out); } if (l->mType == aiLightSource_SPOT) { WriteFloat(l->mAttenuationConstant,out); WriteFloat(l->mAttenuationQuadratic,out); } } // write all animations for (unsigned int i = 0; i < scene->mNumAnimations;++i) { const aiAnimation* anim = scene->mAnimations[i]; WriteMagic("#AN",out); WriteAiString (anim->mName,out); WriteDouble (anim->mTicksPerSecond,out); WriteDouble (anim->mDuration,out); WriteInteger(anim->mNumChannels,out); for (unsigned int a = 0; a < anim->mNumChannels;++a) { const aiNodeAnim* nd = anim->mChannels[a]; WriteMagic("#NA",out); WriteAiString(nd->mNodeName,out); WriteInteger(nd->mPreState,out); WriteInteger(nd->mPostState,out); WriteInteger(nd->mNumPositionKeys,out); WriteInteger(nd->mNumRotationKeys,out); WriteInteger(nd->mNumScalingKeys,out); if (nd->mPositionKeys) { if (shortened) { WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys,out); } // else write as usual else ::fwrite(nd->mPositionKeys,sizeof(aiVectorKey),nd->mNumPositionKeys,out); } if (nd->mRotationKeys) { if (shortened) { WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys,out); } // else write as usual else ::fwrite(nd->mRotationKeys,sizeof(aiQuatKey),nd->mNumRotationKeys,out); } if (nd->mScalingKeys) { if (shortened) { WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys,out); } // else write as usual else ::fwrite(nd->mScalingKeys,sizeof(aiVectorKey),nd->mNumScalingKeys,out); } } } // write all meshes for (unsigned int i = 0; i < scene->mNumMeshes;++i) { const aiMesh* mesh = scene->mMeshes[i]; WriteMagic("#ME",out); WriteInteger(mesh->mPrimitiveTypes,out); WriteInteger(mesh->mNumBones,out); WriteInteger(mesh->mNumFaces,out); WriteInteger(mesh->mNumVertices,out); // write bones if (mesh->mNumBones) { for (unsigned int a = 0; a < mesh->mNumBones;++a) { const aiBone* b = mesh->mBones[a]; WriteMagic("#BN",out); WriteAiString(b->mName,out); WriteMat4x4(b->mOffsetMatrix,out); WriteInteger(b->mNumWeights,out); // for the moment we write dumb min/max values for the bones, too. // maybe I'll add a better, hash-like solution later if (shortened) { WriteBounds(b->mWeights,b->mNumWeights,out); } // else write as usual else ::fwrite(b->mWeights,sizeof(aiVertexWeight),b->mNumWeights,out); } } // write faces. There are no floating-point calculations involved // in these, so we can write a simple hash over the face data // to the dump file. We generate a single 32 Bit hash for 512 faces // using Assimp's standard hashing function. if (shortened) { unsigned int processed = 0; for (unsigned int job;job = std::min(mesh->mNumFaces-processed,512u);processed += job) { unsigned int hash = 0; for (unsigned int a = 0; a < job;++a) { const aiFace& f = mesh->mFaces[processed+a]; hash = SuperFastHash((const char*)&f.mNumIndices,sizeof(unsigned int),hash); hash = SuperFastHash((const char*) f.mIndices,f.mNumIndices*sizeof(unsigned int),hash); } WriteInteger(hash,out); } } else // else write as usual { for (unsigned int i = 0; i < mesh->mNumFaces;++i) { const aiFace& f = mesh->mFaces[i]; WriteInteger(f.mNumIndices,out); for (unsigned int a = 0; a < f.mNumIndices;++a) WriteInteger(f.mIndices[a],out); } } // first of all, write bits for all existent vertex components unsigned int c = 0; if (mesh->mVertices) c |= 1; if (mesh->mNormals) c |= 2; if (mesh->mTangents && mesh->mBitangents) c |= 4; for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { if (!mesh->mTextureCoords[n])break; c |= (8 << n); } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { if (!mesh->mColors[n])break; c |= (16 << n); } WriteInteger(c,out); aiVector3D minVec, maxVec; if (mesh->mVertices) { if (shortened) { WriteBounds(mesh->mVertices,mesh->mNumVertices,out); } // else write as usual else ::fwrite(mesh->mVertices,12*mesh->mNumVertices,1,out); } if (mesh->mNormals) { if (shortened) { WriteBounds(mesh->mNormals,mesh->mNumVertices,out); } // else write as usual else ::fwrite(mesh->mNormals,12*mesh->mNumVertices,1,out); } if (mesh->mTangents && mesh->mBitangents) { if (shortened) { WriteBounds(mesh->mTangents,mesh->mNumVertices,out); WriteBounds(mesh->mBitangents,mesh->mNumVertices,out); } // else write as usual else { ::fwrite(mesh->mTangents,12*mesh->mNumVertices,1,out); ::fwrite(mesh->mBitangents,12*mesh->mNumVertices,1,out); } } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { if (!mesh->mTextureCoords[n])break; // write number of UV components WriteInteger(mesh->mNumUVComponents[n],out); if (shortened) { WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices,out); } // else write as usual else ::fwrite(mesh->mTextureCoords[n],12*mesh->mNumVertices,1,out); } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { if (!mesh->mColors[n]) break; if (shortened) { WriteBounds(mesh->mColors[n],mesh->mNumVertices,out); } // else write as usual else ::fwrite(mesh->mColors[n],16*mesh->mNumVertices,1,out); } } }