void CompareOnTheFlyMesh(comparer_context& comp) { scoped_chunk chunk(comp,"aiMesh"); comp.cmp<uint32_t>("mPrimitiveTypes"); comp.cmp<uint32_t>("mNumVertices"); const uint32_t nf = comp.cmp<uint32_t>("mNumFaces"); comp.cmp<uint32_t>("mNumBones"); comp.cmp<uint32_t>("mMaterialIndex"); const uint32_t present = comp.cmp<uint32_t>("<vertex-components-present>"); if(present & ASSBIN_MESH_HAS_POSITIONS) { comp.cmp_bounds<aiVector3D>("mVertices"); } if(present & ASSBIN_MESH_HAS_NORMALS) { comp.cmp_bounds<aiVector3D>("mNormals"); } if(present & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) { comp.cmp_bounds<aiVector3D>("mTangents"); comp.cmp_bounds<aiVector3D>("mBitangents"); } for(unsigned int i = 0; present & ASSBIN_MESH_HAS_COLOR(i); ++i) { std::stringstream ss; comp.cmp_bounds<aiColor4D>((ss<<"mColors["<<i<<"]",ss.str())); } for(unsigned int i = 0; present & ASSBIN_MESH_HAS_TEXCOORD(i); ++i) { std::stringstream ss; comp.cmp<uint32_t>((ss<<"mNumUVComponents["<<i<<"]",ss.str())); comp.cmp_bounds<aiVector3D>((ss.clear(),ss<<"mTextureCoords["<<i<<"]",ss.str())); } for(unsigned int i = 0; i< ((nf+511)/512); ++i) { std::stringstream ss; comp.cmp<uint32_t>((ss<<"mFaces["<<i*512<<"-"<<std::min(static_cast< uint32_t>((i+1)*512),nf)<<"]",ss.str())); } sliced_chunk_reader reader(comp); for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) { if ((*it).first == ASSBIN_CHUNK_AIBONE) { CompareOnTheFlyBone(comp); } } }
// ----------------------------------------------------------------------------------- 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; }