提问人:StudenteChamp 提问时间:8/27/2023 最后编辑:StudenteChamp 更新时间:9/3/2023 访问量:45
提高网格几何序列化性能
Improve mesh geometry serialization performance
问:
我想缩短 3D 应用程序的序列化时间。 我使用以下场景进行测试: https://www.dropbox.com/scl/fi/j8ays9phm2xs45icla4bo/TestScene.zip?rlkey=qy8jpwgz3s8b95mz62l8axcug&dl=0
我用 Blender 和 3DS Max 进行了性能比较。
搅拌机:1 秒 3DS 最大:2 秒 我的应用程序:15 秒
!
为了序列化网格,我使用 OBJ 文件格式和 Assimp。
Assimp 序列化时间过长。
我应该编写自己的格式吗?有什么我应该知道的技巧吗?
谢谢。为了方便起见,我的序列化代码如下:
aiScene* scene = new aiScene();
// Allocate materials memory
scene->mNumMaterials = 1;
scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
// Allocate mesh memory
scene->mNumMeshes = (unsigned)m_flatMeshContainer.size();
scene->mMeshes = new aiMesh*[m_flatMeshContainer.size()];
scene->mRootNode = new aiNode();
scene->mRootNode->mNumMeshes = 0;
// Create materials
for (Uint32 i = 0u; i < scene->mNumMaterials; ++i)
{
scene->mMaterials[i] = new aiMaterial();
}
// Create meshes
std::mutex mtx;
tbb::parallel_for(size_t(0), m_meshGroupIdentifiers.size(), [&](size_t idx) {
const auto& groupId = m_meshGroupIdentifiers[idx];
const auto group = getMeshGroupPtr_FromEntity(groupId);
// Create meshes
const auto nbMeshes = (unsigned)group->m_meshes.size();
aiNode* node = new aiNode();
node->mMeshes = new unsigned int[nbMeshes];
node->mNumMeshes = nbMeshes;
for (Uint32 i = 0u; i < nbMeshes; ++i)
{
// Init mesh
const Mesh* nativeMesh = group->m_meshes[i];
const auto flatMeshIdx = nativeMesh->getFlatId();
scene->mMeshes[flatMeshIdx] = new aiMesh();
node->mMeshes[i] = flatMeshIdx;
aiMesh* mesh = scene->mMeshes[flatMeshIdx];
mesh->mName = group->getName();
mesh->mMaterialIndex = 0;
// Build vertices
const auto& vertices = nativeMesh->getRealVertices();
const auto nbVertex = (unsigned)vertices.size();
mesh->mVertices = new aiVector3D[nbVertex];
mesh->mNormals = new aiVector3D[nbVertex];
mesh->mNumVertices = nbVertex;
mesh->mTextureCoords[0] = new aiVector3D[nbVertex];
mesh->mNumUVComponents[0] = nbVertex;
for (Uint32 j = 0u; j < nbVertex; ++j)
{
const auto& vtx = vertices[j];
mesh->mVertices[j] = aiVector3D(vtx.position.x, vtx.position.y, vtx.position.z);
mesh->mNormals[j] = aiVector3D(vtx.normal.x, vtx.normal.y, vtx.normal.z);
mesh->mTextureCoords[0][j] = aiVector3D(vtx.texCoord.x, vtx.texCoord.y, 0);
}
// Build faces
const auto& indices = nativeMesh->getRealIndices();
mesh->mNumFaces = (unsigned)indices.size() / PRIMITIVE_NB_VTX;
mesh->mFaces = new aiFace[mesh->mNumFaces];
for (Uint32 j = 0u; j < indices.size(); j += PRIMITIVE_NB_VTX)
{
aiFace &face = mesh->mFaces[j / PRIMITIVE_NB_VTX];
face.mIndices = new unsigned int[PRIMITIVE_NB_VTX];
face.mNumIndices = PRIMITIVE_NB_VTX;
for (Uint32 k = 0; k < PRIMITIVE_NB_VTX; ++k)
{
face.mIndices[k] = indices[k + j];
}
}
}
std::lock_guard<std::mutex> lock(mtx);
scene->mRootNode->addChildren(1, &node);
});
const auto objPath = m_serializationFullPath.string();
Assimp::Exporter exporter;
// HERE : SLOW --------------------------------------------------------------------------------------------
exporter.Export(scene, "obj", objPath);
// ---------------------------------------------------------------------------------------------------------
delete scene;
答:
0赞
leandro
8/29/2023
#1
我会尽量避免在循环中调用任何构造函数或内存分配。这段代码如下所示
mesh->mVertices = new aiVector3D[nbVertex]();
mesh->mNormals = new aiVector3D[nbVertex]();
mesh->mNumVertices = nbVertex;
mesh->mTextureCoords[0] = new aiVector3D[nbVertex]();
mesh->mNumUVComponents[0] = nbVertex;
for (Uint32 j = 0u; j < nbVertex; ++j)
{
const auto& vtx = vertices[j];
mesh->mVertices[j].x = vtx.position.x;
mesh->mVertices[j].y = vtx.position.y;
mesh->mVertices[j].z = vtx.position.z;
mesh->mNormals[j].x = vtx.normal.x;
mesh->mNormals[j].y = vtx.normal.y;
mesh->mNormals[j].z = vtx.normal.z;
mesh->mTextureCoords[0][j].x = vtx.texCoord.x;
mesh->mTextureCoords[0][j].y = vtx.texCoord.y;
mesh->mTextureCoords[0][j].z = vtx.texCoord.z;
}
评论
0赞
StudenteChamp
8/30/2023
循环本身很快。慢代码是:exporter。导出(scene, “obj”, objPath);
0赞
StudenteChamp
9/3/2023
#2
我通过实现自己的二进制文件格式解决了它。
为了写入我使用的文件:
std::ofstream fileStream(filePath, std::ios::out | std::ios::binary)
阅读:
std::ifstream fileStream(filePath, std::ios::out | std::ios::binary);
评论