// ----------------------------------------------------------------------------------- uint32_t WriteBinaryLight(const aiLight* l) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AILIGHT); len += Write<aiString>(l->mName); len += Write<unsigned int>(l->mType); if (l->mType != aiLightSource_DIRECTIONAL) { len += Write<float>(l->mAttenuationConstant); len += Write<float>(l->mAttenuationLinear); len += Write<float>(l->mAttenuationQuadratic); } len += Write<aiVector3D>((const aiVector3D&)l->mColorDiffuse); len += Write<aiVector3D>((const aiVector3D&)l->mColorSpecular); len += Write<aiVector3D>((const aiVector3D&)l->mColorAmbient); if (l->mType == aiLightSource_SPOT) { len += Write<float>(l->mAngleInnerCone); len += Write<float>(l->mAngleOuterCone); } ChangeInteger(old,len); return len; }
// ----------------------------------------------------------------------------------- uint32_t WriteBinaryScene(const aiScene* scene) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AISCENE); // basic scene information len += Write<unsigned int>(scene->mFlags); len += Write<unsigned int>(scene->mNumMeshes); len += Write<unsigned int>(scene->mNumMaterials); len += Write<unsigned int>(scene->mNumAnimations); len += Write<unsigned int>(scene->mNumTextures); len += Write<unsigned int>(scene->mNumLights); len += Write<unsigned int>(scene->mNumCameras); // write node graph len += WriteBinaryNode(scene->mRootNode)+8; // write all meshes for (unsigned int i = 0; i < scene->mNumMeshes;++i) { const aiMesh* mesh = scene->mMeshes[i]; len += WriteBinaryMesh(mesh)+8; } // write materials for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { const aiMaterial* mat = scene->mMaterials[i]; len += WriteBinaryMaterial(mat)+8; } // write all animations for (unsigned int i = 0; i < scene->mNumAnimations;++i) { const aiAnimation* anim = scene->mAnimations[i]; len += WriteBinaryAnim(anim)+8; } // write all textures for (unsigned int i = 0; i < scene->mNumTextures;++i) { const aiTexture* mesh = scene->mTextures[i]; len += WriteBinaryTexture(mesh)+8; } // write lights for (unsigned int i = 0; i < scene->mNumLights;++i) { const aiLight* l = scene->mLights[i]; len += WriteBinaryLight(l)+8; } // write cameras for (unsigned int i = 0; i < scene->mNumCameras;++i) { const aiCamera* cam = scene->mCameras[i]; len += WriteBinaryCamera(cam)+8; } ChangeInteger(old,len); return len; }
// ----------------------------------------------------------------------------------- uint32_t WriteBinaryMaterial(const aiMaterial* mat) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIAL); len += Write<unsigned int>(mat->mNumProperties); for (unsigned int i = 0; i < mat->mNumProperties;++i) { len += WriteBinaryMaterialProperty(mat->mProperties[i])+8; } ChangeInteger(old,len); return len; }
// ----------------------------------------------------------------------------------- // Write a single node in a binary dump void WriteBinaryNode(const aiNode* node, FILE* out) { WriteMagic("#ND",out); WriteAiString(node->mName,out); WriteMat4x4(node->mTransformation,out); WriteInteger(node->mNumMeshes,out); for (unsigned int i = 0; i < node->mNumMeshes;++i) WriteInteger(node->mMeshes[i],out); WriteInteger(node->mNumChildren,out); for (unsigned int i = 0; i < node->mNumChildren;++i) WriteBinaryNode(node->mChildren[i],out); }
int EXRFile::OpenOutputFile(const char* i_fileName) { m_file = fopen(i_fileName, "wb"); if (!m_file) { return IMF_ERROR_ERROR; } m_channelList = new ChannelList(*m_header->GetChannelList()); m_channelList->Sort(); m_header->GetAttribute("dataWindow", "box2i", (char*)&m_dataWindow[0]); m_header->GetAttribute("compression", "compression", (char*)&m_compression); int width = m_dataWindow[2] - m_dataWindow[0] + 1; size_t datasize = m_channelList->GetPixelSize() * width; if (m_compression == IMF_ZIP_COMPRESSION) { m_scanline_block = new ScanLineZipBlock( m_file, datasize, m_dataWindow[1]); } else { m_scanline_block = new ScanLineBlock( m_file, datasize, m_dataWindow[1]); } int height = m_dataWindow[3] - m_dataWindow[1] + 1; m_blocks = height / m_scanline_block->NumLinesInBlock(); m_blocks += height % m_scanline_block->NumLinesInBlock() > 0; m_offset_table = new uint64_t [m_blocks]; m_offset_table_counter = 0; WriteMagic(); WriteVersion(); WriteHeader(); WriteZerroOffsets(); return IMF_ERROR_NOERROR; }
// ----------------------------------------------------------------------------------- uint32_t WriteBinaryMaterialProperty(const aiMaterialProperty* prop) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIALPROPERTY); len += Write<aiString>(prop->mKey); len += Write<unsigned int>(prop->mSemantic); len += Write<unsigned int>(prop->mIndex); len += Write<unsigned int>(prop->mDataLength); len += Write<unsigned int>((unsigned int)prop->mType); len += fwrite(prop->mData,1,prop->mDataLength,out); ChangeInteger(old,len); return len; }
// ----------------------------------------------------------------------------------- uint32_t WriteBinaryCamera(const aiCamera* cam) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AICAMERA); len += Write<aiString>(cam->mName); len += Write<aiVector3D>(cam->mPosition); len += Write<aiVector3D>(cam->mLookAt); len += Write<aiVector3D>(cam->mUp); len += Write<float>(cam->mHorizontalFOV); len += Write<float>(cam->mClipPlaneNear); len += Write<float>(cam->mClipPlaneFar); len += Write<float>(cam->mAspect); ChangeInteger(old,len); return len; }
// ----------------------------------------------------------------------------------- uint32_t WriteBinaryAnim(const aiAnimation* anim) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIANIMATION); len += Write<aiString> (anim->mName); len += Write<double> (anim->mDuration); len += Write<double> (anim->mTicksPerSecond); len += Write<unsigned int>(anim->mNumChannels); for (unsigned int a = 0; a < anim->mNumChannels;++a) { const aiNodeAnim* nd = anim->mChannels[a]; len += WriteBinaryNodeAnim(nd)+8; } ChangeInteger(old,len); return len; }
// ----------------------------------------------------------------------------------- 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 WriteBinaryNode(const aiNode* node) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODE); len += Write<aiString>(node->mName); len += Write<aiMatrix4x4>(node->mTransformation); len += Write<unsigned int>(node->mNumChildren); len += Write<unsigned int>(node->mNumMeshes); for (unsigned int i = 0; i < node->mNumMeshes;++i) { len += Write<unsigned int>(node->mMeshes[i]); } for (unsigned int i = 0; i < node->mNumChildren;++i) { len += WriteBinaryNode(node->mChildren[i])+8; } ChangeInteger(old,len); return len; }
// ----------------------------------------------------------------------------------- uint32_t WriteBinaryTexture(const aiTexture* tex) { uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AITEXTURE); len += Write<unsigned int>(tex->mWidth); len += Write<unsigned int>(tex->mHeight); len += fwrite(tex->achFormatHint,1,4,out); if(!shortened) { if (!tex->mHeight) { len += fwrite(tex->pcData,1,tex->mWidth,out); } else { len += fwrite(tex->pcData,1,tex->mWidth*tex->mHeight*4,out); } } ChangeInteger(old,len); return len; }
// ----------------------------------------------------------------------------------- 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 EXRFile::OpenOutputFile(const char* i_fileName) { m_file = fopen(i_fileName, "wb"); if (!m_file) { return IMF_ERROR_ERROR; } m_channelList = new ChannelList(*m_header->GetChannelList()); m_channelList->Sort(); m_header->GetAttribute("dataWindow", "box2i", (char*)&m_dataWindow[0]); m_header->GetAttribute("compression", "compression", (char*)&m_compression); /* TODO: Get and use length of the attribute */ char type[256]; const char* deepscanline = "deepscanline"; m_header->GetAttribute("type", "string", type); if (strncmp(type, deepscanline, strlen(deepscanline)) == 0) { m_dataType = IMF_DEEPSCANLINE; } else { m_dataType = IMF_SCANLINEIMAGE; } int width = m_dataWindow[2] - m_dataWindow[0] + 1; size_t datasize = m_channelList->GetPixelSize() * width; if( m_dataType == IMF_DEEPSCANLINE ) { if (m_compression == IMF_ZIPS_COMPRESSION) { m_scanline_block = new ScanLineDeepZipSBlock( m_file, width * sizeof(m_fb_sampleCount[0]), m_channelList->GetPixelSize(), m_dataWindow[1]); } else { m_scanline_block = new ScanLineDeepBlock( m_file, width * sizeof(m_fb_sampleCount[0]), m_channelList->GetPixelSize(), m_dataWindow[1]); } } else switch( m_compression ) { case IMF_ZIP_COMPRESSION: m_scanline_block = new ScanLineZipBlock( m_file, datasize, m_dataWindow[1], ScanLineZipBlock::kDefaultBlockSize); break; case IMF_ZIPS_COMPRESSION: m_scanline_block = new ScanLineZipBlock( m_file, datasize, m_dataWindow[1], 1); break; default: m_scanline_block = new ScanLineBlock( m_file, datasize, m_dataWindow[1]); } int height = m_dataWindow[3] - m_dataWindow[1] + 1; m_blocks = height / m_scanline_block->NumLinesInBlock(); m_blocks += height % m_scanline_block->NumLinesInBlock() > 0; m_offset_table = new uint64_t [m_blocks]; // Initialize table to 0, so that valgrind doesn't complain about writing it out to file before we initialize it for( int i = 0; i < m_blocks; i++ ) m_offset_table[i] = 0; m_offset_table_counter = 0; WriteMagic(); WriteVersion(); WriteHeader(); WriteZerroOffsets(); return IMF_ERROR_NOERROR; }
// ----------------------------------------------------------------------------------- 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; }
// ----------------------------------------------------------------------------------- // 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); } } }